实验1-操作系统的引导

操作系统的引导

实验内容

此次实验的基本内容是:

  1. 阅读《Linux内核完全注释》的第6章,对计算机和Linux 0.11的引导过程进行初步的了解;
  2. 按照下面的要求改写0.11的引导程序bootsect.s
  3. 有兴趣同学可以做做进入保护模式前的设置程序setup.s。

改写bootsect.s主要完成如下功能:

  1. bootsect.s能在屏幕上打印一段提示信息“XXX is booting…”,其中XXX是你给自己的操作系统起的名字,例如LZJos、Sunix等(可以上论坛上秀秀谁的OS名字最帅,也可以显示一个特色logo,以表示自己操作系统的与众不同。)

改写setup.s主要完成如下功能:

  1. bootsect.s能完成setup.s的载入,并跳转到setup.s开始地址执行。而setup.s向屏幕输出一行"Now we are in SETUP"。
  2. setup.s能获取至少一个基本的硬件参数(如内存参数、显卡参数、硬盘参数等),将其存放在内存的特定地址,并输出到屏幕上。
  3. setup.s不再加载Linux内核,保持上述信息显示在屏幕上即可。

实验结果

bootsect.s

在这里插入图片描述

.globl begtext, begdata, begbss, endtext, enddata, endbss
.text
begtext:
.data
begdata:
.bss 
begbss:
.text

! 设置初始段地址参数
SETUPLEN = 4        ! setup程序所占扇区
BOOTSEG = 0x07c0    ! bootsect原始内存地址
INITSEG = 0x9000   ! bootsect移动后内存地址
SETUPSEG = 0x9020   ! setup程序起始段地址

entry _start
_start:
    ! 移动bootsect 0x07c00 -> 0x90000
    ! 设置源地址 ds:si
    mov ax, #BOOTSEG
    mov ds, ax
    sub si, si
    ! 设置目的地址 es:di
    mov ax, #INITSEG
    mov es, ax
    sub di, di
    ! 移动512字节
    mov cx, #256
    rep 
    movw

    ! 跳转到go标号处开始,并将cs赋给ds,es
    jmpi go, INITSEG
go:
    mov ax, cs
    mov ds, ax
    mov es, ax

    
load_setup: ! 加载setup程序
    ! 将setup从磁盘中读到内存0x90200开始处
    ! setup在磁盘第2个扇区开始,共占4个扇区
    ! 磁道、磁头、驱动器均为0
    ! 使用BIOS int 0x13中断的0x02功能-读扇区
    ! ah = 0x02 选择中断功能    al = 要读扇区的数量
    ! ch = 磁道(柱面)号的低8位  cl = 开始扇区(0 - 5位),磁道号高两位(0 - 6位)
    ! dh = 磁头号              dl = 驱动器号(如果是硬盘则位7要置位)
    ! es:bx 指向数据缓冲区
    ! 若读写成功,CF = 0,ah = 0x00 
    ! 若读写错误,则标志位置位,ah = 状态码
    mov ax, #0x0200 + SETUPLEN
    mov cx, #0x0002
    mov dx, #0x0000
    mov bx, #0x0200
    int 0x13

    jnc ok_load_setup !若读写完毕,转到ok_load_setup

    ! 若读写错误,则复位驱动器
    ! 使用BIOS int 0x13中断的0x00功能-磁盘系统复位
    ! ah = 0x00 选择中断功能
    ! dl = 驱动器, 0x00~0x7f -> 软盘, 0x80~0xff -> 硬盘
    mov ax, #0x0000
    mov dx, #0x0000
    int 0x13

    j load_setup  !重新读写

ok_load_setup:  ! setup加载完毕,在屏幕输出msg1中的字符串
    ! 读取显示屏幕第0页光标位置
    ! 使用BIOS int 0x10中断的 0x03功能-读取光标位置
    ! 输入: ah = 0x03 选择功能 bh = 页号
    ! 返回: ch = 光标开始行 cl = 光标结束行
    !       dh = 行        dl = 列
    mov ah, #0x03
    xor bh, bh
    int 0x10

    ! 在当前光标位置显示msg1中的18个字符串
    ! 使用BIOS int 0x10中断的 0x13功能-显示字符串
    ! 输入: ah = 0x13 选择中断功能 al = 放置光标的方式及其规定属性
    !       al = 0x01 使用bl中的属性值,光标停留在字符转结尾处
    !       bh = 显示页面号     bl = 字符属性
    !       dh = 行号           dl = 列号
    !       es:bp 指向字符串起始处 cx = 字符数
    ! 属性:    0-2位 -> 文字RGB 
    !            3位 -> 高亮 
    !          4-6位 -> 背景RGB
    !            7位 -> 闪烁
    mov cx, #28 !显示18个字符
    mov bx, #0x008a !第0页,闪烁高亮黑底绿字
    mov bp, #msg1
    mov ax, #0x1301
    int 0x10

    ! 跳转到setup执行
    jmpi 0, SETUPSEG

msg1: ! 共28个字符
    .byte 13, 10 ! 换行+回车
    .ascii "LYP's os is loading..." 
    .byte 13, 10, 13, 10

.org 510
boot_flag:
    .word 0xAA55 !引导的必需

.text
endtext:
.data
enddata:
.bss
endbss:

setup.s

屏幕截图 2023-10-09 185721
.globl begtext, begdata, begbss, endtext, enddata, endbss
.text
begtext:
.data
begdata:
.bss
begbss:
.text

! 设置段地址常量
BOOTSEG = 0x07c0
INITSEG = 0x9000
SETUPSEG = 0x9020
entry _start
_start:
    ! 将cs赋给ds,es
    mov ax, cs
    mov ds, ax
    mov es, ax

    ! 显示msg1中的字符串,以表示当前程序在setup部分
    ! 读光标 
    mov ah, #0x03
    xor bh, bh
    int 0x10
    ! 显示字符串 
    mov cx, #28
    mov bp, #msg1
    mov bx, #0x008a
    mov ax, #0x1301
    int 0x10

    ! 将ds置为0x9000
    mov ax, #INITSEG
    mov ds, ax 

    ! 获取参数
    
    ! 获取光标位置,并存放在0x90000(2 byte)处
    ! 使用BIOS int 0x10中断的 ah = 0x03功能-读光标
    ! 输入:bh = 页号
    ! 返回:ch = 扫描开始线 cl = 扫描结束线
    !      dh = 行        dl = 列
    mov ah, #0x03
    xor bh, bh 
    int 0x10
    mov [0], dx

    ! 获取扩展内存大小,并存放在0x90002(2 byte)处
    ! 使用BIOS int 0x15中断的 ah = 0x88功能-从0x100000处开始的扩展内存大小
    ! 返回:ax = 从0x100000处开始的扩展内存大小
    mov ah, #0x88 
    int 0x15 
    mov [2], ax

    ! 获取硬盘信息,获取硬盘参数表的前16个byte
    ! 起始地址位为中断向量0x41的值
    ! 目的地址为0x9000:0x0080
    ! 设置源地址 ds:si
    mov ax, #0x0000 ! 将ds中的数值清除
    mov ds, ax 
    lds si, [4 * 0x41] !将中断向量的值放入ds:si
    ! 设置目标地址 es:di
    mov ax, #INITSEG
    mov es, ax
    mov di, #0x0080
    mov cx, #0x10 ! 传输16个字节
    rep
    movsb

    ! 重置ds,es
    mov ax, #INITSEG
    mov ds, ax
    mov ax, #SETUPSEG 
    mov es, ax

    ! 显示参数

    ! 显示字符串 "CUrsor POS"
    mov ah, #0x03
    xor bh, bh
    int 0x10
    mov cx, #11
    mov bx, #0x000a ! 黑底绿字高亮无闪
    mov bp, #cur
    mov ax, #0x1301
    int 0x10
    ! 打印光标位置
    mov ax, [0]
    call print_hex
    call print_nl

    ! 显示字符串 "Memory SIZE:"
    mov ah, #0x03
    xor bh, bh 
    int 0x10 
    mov cx, #12
    mov bx, #0x000a
    mov bp, #mem
    mov ax, #0x1301
    int 0x10
    ! 打印内存大小
    mov ax, [2]
    call print_hex

    ! 显示提示信息
    mov ah, #0x03
    xor bh, bh 
    int 0x10 
    mov cx, #25
    mov bx, #0x000a
    mov bp, #syl
    mov ax, #0x1301
    int 0x10

    ! 打印柱面数
    mov ax, [0x80]
    call print_hex
    call print_nl

    ! 显示字符串 "Headers:"
    mov ah, #0x03 
    xor bh, bh 
    int 0x10
    mov cx, #8
    mov bx, #0x000a
    mov bp, #head 
    mov ax, #0x1301
    int 0x10
    ! 打印磁头数
    mov ax, [0x80 + 0x02]
    call print_hex
    call print_nl

    ! 显示字符串 "Sectors:"
    mov ah, #0x03 
    xor bh, bh 
    int 0x10 
    mov cx, #8
    mov bx, #0x000a
    mov bp, #sect 
    mov ax, #0x1301
    int 0x10 
    ! 打印扇区数
    mov ax, [0x80 + 0x0e]
    call print_hex 
    call print_nl 

    ! 死循环,使程序一直停留在setup中
    l: jmp l

! 以16进制方式打印栈顶的16位数
! 使用BIOS int 0x10中断的 ah = 0x0e功能-显示一个字符 
! 输入:al = 要显示字符的ASCII码
print_hex:
    mov cx, #4 ! 打印4次,每次一个16进制位-4bit
    mov dx, ax ! 将ax所指的值放入dx中
print_digit:
    rol dx, #4 ! dx循环左移4位,每次只打印最低4位的内容
    mov ax, #0xe0f ! ah = 中断功能, al = 显示的字符
    and al, dl ! 取dl的低4位
    add al, #0x30 ! 转化为ascii码,默认为数字
    cmp al, #0x3a ! 判断是否是数字
    jl outp ! 是数字
    add al, #0x07 ! 不是数字,再加0x07,转为字母
outp:
    int 0x10
    loop print_digit
    ret

    !打印回车换行
print_nl:
    mov ax, #0xe0d ! 回车
    int 0x10
    mov al, #0xa ! 换行
    int 0x10
    ret

msg1: ! 共25个字节
    .byte 13, 10
    .ascii "Now we are in setup..."
    .byte 13, 10, 13, 10
cur: ! 光标位置
    .ascii "Cursor POS:"
mem: ! 内存大小
    .ascii "Memory SIZE:"
syl:
    .ascii "KB"
    .byte 13, 10, 13, 10
    .ascii "HD Info"
    .byte 13, 10
    .ascii "Cylinders:"
head:
    .ascii "Headers:"
sect:
    .ascii "Secotors"
.text
endtext:
.data
enddata:
.bss
endbss:
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值