操作系统引导扇区
程序员文章站
2022-06-19 16:46:27
...
操作系统全部笔记目录见:操作系统笔记整理
go: mov ax,cs //cs=0x9000
mov ds,ax mov es,ax mov ss,ax mov sp,#0xff00
load_setup: //载入setup模块
mov dx,#0x0000 mov cx,#0x0002 mov bx,#0x0200
mov ax,#0x0200+SETUPLEN int 0x13 //BIOS中断
jnc ok_load_setup
mov dx,#0x0000
mov ax,#0x0000 //复位
int 0x13
j load_setup //重读
0x13是BIOS读磁盘扇区的中断: ah=0x02-读磁盘,al= 扇区数量(SETUPLEN=4), ch=柱面号,cl=开始扇区(即cx的低八位,这里是2,因为第一个扇区是引导扇区,要从第2个扇区开始读), dh=磁头号,dl=驱动器号, es:bx=内存地址
读磁盘读到哪里?肯定是bootset的上面,bootset从90000开始,偏移512字节,为90200。es:bx从上面的程序确实可以看出,是90200。
读完四个扇区还需要读进去操作系统。
Ok_load_setup: //载入setup模块
mov dl,#0x00 mov ax,#0x0800 //ah=8获得磁盘参数
int 0x13 mov ch,#0x00 mov sectors,cx
mov ah,#0x03 xor bh,bh int 0x10 //读光标
mov cx,#24 mov bx,#0x0007
mov bp,#msg1 mov ax,#1301 int 0x10 //显示字符
mov ax,#SYSSEG //SYSSEG=0x1000
mov es,ax
call read_it //读入system模块
jmpi 0,SETUPSEG
int 0x10 是显示字符,bp告诉你要显示的东西在内存中什么区域,例如:
bootsect.s中的数据 //在文件末尾
sectors: .word 0 //磁道扇区数
msg1:.byte 13,10
.ascii “Loading system...”
.byte 13,10,13,10
肯定是要把字符打印到光标位置,所以前面有一个读光标位置的操作。
如果我们想替换一下字符串,还需要改一些配置,例如如果mov cx,#24这里的24表示要输出的字符个数,则把前面的mov cx,#24修改一下。
boot的工作:读setup, 读system。注意,为什么读入 要跨越磁道! system模块还需要定义一个函数?
因为system模块可能很大,读入要跨越磁道。
read_it: mov ax,es cmp ax,#ENDSEG jb ok1_read
ret
ok1_read:
mov ax,sectors
sub ax,sread //sread是当前磁道已读扇区数,ax未读扇区数
call read_track //读磁道...
ENDSEG=SYSSEG+SYSSIZE SYSSIZE=0x8000 //该变量可根据 Image大小设定(编译操作系统时)
引导扇区的末尾 //BIOS用以识别引导扇区:
.org 510
.word 0xAA55 //扇区的最后两个字节
.org 510 指定一个地址,后面的程序或数据从这个地址值开始分配,即以后语句从地址510(0x1FE)开始存放
.word 0xAA55 表示有效引导扇区标志,供BIOS加载引导扇区使用
可以转入setup执行了:
jmpi 0, SETUPSEG
注意该跳转语句,上一节里代码中显示SETUPSEG=9020,作为cs,再与ip=0组合成90200,即跳转后执行的地址。