实验2
此次实验的基本内容是:
- 阅读《Linux 内核完全注释》的第 6 章,对计算机和 Linux 0.11 的引导过程进行初步的了解;
- 按照下面的要求改写 0.11 的引导程序 bootsect.s
- 有兴趣同学可以做做进入保护模式前的设置程序 setup.s。
改写 bootsect.s 主要完成如下功能:
- bootsect.s 能在屏幕上打印一段提示信息“XXX is booting…”,其中 XXX 是你给自己的操作系统起的名字,例如 LZJos、Sunix 等(可以上论坛上秀秀谁的 OS 名字最帅,也可以显示一个特色 logo,以表示自己操作系统的与众不同。)
改写 setup.s 主要完成如下功能:
- bootsect.s 能完成 setup.s 的载入,并跳转到 setup.s 开始地址执行。而 setup.s 向屏幕输出一行”Now we are in SETUP”。
- setup.s 能获取至少一个基本的硬件参数(如内存参数、显卡参数、硬盘参数等),将其存放在内存的特定地址,并输出到屏幕上。
- setup.s 不再加载 Linux 内核,保持上述信息显示在屏幕上即可。
Bootsect.s 简易版 :::info bootsect被存在第一个扇区内(引导磁盘 0磁道 0磁头 第一个扇区)会由bios程序将其加载到内存0x7c0处,bootsect在执行时会把自己移动到0x90000的地方,然后再加载setup(0磁道第二个扇区)到紧跟着他的后面0x90200(bootsect有512字节) :::
SETUPLEN=2
SETUPSEG=0x07e0 !0x7c00+0200
entry _start
_start:
mov ah,#0x03 !读光标位置
xor bh,bh
int 0x10
mov cx,#36 !传入的字符串长度
mov bx,#0x0007 !页号和属性:BL=07黑白
mov bp,#msg1 !偏移地址
mov ax,#0x07c0 !段地址还是当前
mov es,ax
mov ax,#0x1301 !显示字符串
int 0x10
load_setup:
mov dx,#0x0000 !从0磁道0驱动器读
mov cx,#0x0002 !扇区号2和柱面号(磁道)0
mov bx,#0x0200 !设置读入的内存地址:BOOTSEG+address = 512,BX表示偏移512字节
mov ax,#0x0200+SETUPLEN !AL:读入的扇区个数
int 0x13
jnc ok_load_setup !读成功 ⇒ AH = 00H, AL = 读取的扇区数,CF = 0
mov dx,#0x0000
mov ax,#0x0000
int 0x13 !磁盘复位
jmp load_setup
ok_load_setup:
jmpi 0,SETUPSEG
msg1:
.byte 13,10
.ascii "Hello OS world, my name is LZJ"
.byte 13,10,13,10
.org 510
boot_flag:
.word 0xAA55
INT0x10
INT 10H 是由 BIOS 对屏幕及显示器所提供的服务程序,使用 INT 10H 中断服务程序时,先指定 AH 寄存器为下表编号其中之一,该编号表示欲调用的功用,而其他寄存器的详细说明,参考表后文字,当一切设定好之后再调用 INT 10H。
读光标位置:
- 功能号:AH = 03H
- 传入参数:BH = 页号
- 返回参数:
- CH = 光标起始行
- CL = 光标结束行
- DH/DL = 行/列
显示字符串:
- 功能号:AH = 13H
- 输入参数:
- ES:BP = 字符串地址
- AL = 写方式(0~3)
- CX = 字符串长度
- DH/DL = 起始行/列
- BH/BL = 页号/属性
:::info
int 0x13中断向量所指向的中断服务程序实质上就是磁盘服务程序。
用途:将指定扇区的代码加载到内存的指定位置。
因此,在使用int 0x13中断时要将参数传递给服务程序:例如:将指定扇区和加载的内存位置传递给服务程序 :::
INT 0x13
读磁盘扇区:
- 功能号:AH = 02H
- 调用参数:AL = 扇区数
- CX中的0~5位代表扇区号,CX中的6~15位代表柱面号(其中,CL的6~7为柱面数的高两位,CH存低8位)
- DH/DL = 磁头号/驱动器号
- ES:BX = 数据缓冲区地址
- 返回参数:
- 读成功 ⇒ AH = 00H, AL = 读取的扇区数,CF = 0
- 读失败 ⇒ AH = 错误码
磁盘复位:
- 功能号:AH = 00H
- 调用参数:DL = 驱动器号 (00H~7FH为软盘;80H~0FFH为硬盘)
- 返回参数:读成功 ⇒ AH = 00H, CF = 0
- 读失败 ⇒ AH = 错误码
setup.s 将获得硬件参数放在内存的 0x90000 处。原版 setup.s 中已经完成了光标位置、内存大小、显存大小、显卡参数、第一和第二硬盘参数的保存。
用ah=#0x03
调用 0x10
中断可以读出光标的位置,用 ah=#0x88
调用0x15
中断可以读出内存的大小。有些硬件参数的获取要稍微复杂一些,如磁盘参数表。在 PC 机中 BIOS 设定的中断向量表中 int 0x41
的中断向量位置(4*0x41 = 0x0000:0x0104
)存放的并不是中断程序的地址,而是第一个硬盘的基本参数表。第二个硬盘的基本参数表入口地址存于 int 0x46
中断向量位置处。每个硬盘参数表有 16 个字节大小。