欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

操作系统引导扇区

程序员文章站 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,即跳转后执行的地址。