这里介绍, 操作系统启动中的
bootsect.S
文件
1. bootsect.s
的作用概览
bootsect.s代码是磁盘引导块程序,驻留在磁盘的第一个扇区中(引导扇区,0磁道(柱面),0磁头,第一个扇区, 如图中的黄色区域)
在PC机加电ROM BIOS自检后,ROM BIOS会把引导扇区代码bootsect加载到内存地址0x7C00开始处并执行之。
-
在bootsect代码执行期间,将自身的位置移动:
bootsect.S
刚开始由BIOS 载入内存中的时候, 是放在内存ox7c00
的地址处, 现在在执行的过程中, 他将位置移动到0x90000
处, 将原来的位置腾出来, 给其他人使用。 -
bootsect.S
将setup.s
拷贝到内存中, 放在ox90200
处,从磁盘第2个扇区开始的4个扇区是 setup.s模块 .bootsect.S
从0x90000
处占用了512KB 的大小, 表示成十六进制是 2 ∗ 1 6 2 + 0 ∗ 1 6 1 + 0 ∗ 1 6 0 = 200 2 * 16^2 + 0 * 16^1 + 0 * 16^0 = 200 2∗162+0∗161+0∗160=200, 所以为了将setup.s
放在bootsect.S
的后面, 故放在往后移动的512 K个字节处。
然后利用BIOS中断 0x13 ,取磁盘参数表中当前启动引导盘的参数,接着在屏幕上显示“Loading system.”字符串
bootsect.S
将system
模块读入到内存的0x10000
处,随后确定根文件系统的设备号。
若没有指定,则根据所保存的引导盘的每磁道扇区数判别出盘的类型和种类.
并保存其设备号于 root_dev(引导块的508地址处),
最后长跳转到setup程序的开始处(0x90200)执行setup程序。
1.1 移动自身位置
由BIOS读入内存绝对地址0x7C00处,当它被执行时就会把自己移动到内存绝对地址0X90000处。
; bootsect启动程序将它自身从内容0x07c00(BOOTSEG)处复制至内存0x9000(INITSEG)处
entry start ;关键字entry告诉链接器"程序入口"
start:
mov ax,#BOOTSEG ;BOOTSEG = 0x07c0 赋值给ax,
mov ds,ax ;源地址
mov ax,#INITSEG ;INITSEG = 0x9000 赋值给bx
mov es,ax ;目标地址
mov cx,#256 ;循环次数,每次循环完次数减一
sub si,si ;清零
sub di,di ;清零
rep ;rep是repeat,rep配合 movw(movsb) 就是多次复制直到cx=0为止 复制的次数放在cx中
movw ;用于把内容从ds:si 复制es:di 以字位单位
jmpi go,INITSEG ;间接跳转 即程序跳到9000:0 去继续执行 CS=INITSEG,IP=go(偏移地址)
; 从这里开始cpu已经跳到内存0x90000去执行,
; BIOS把引导扇区加载到0x7c00处并把执行权交给引导程序,(ss=0x00,sp=0xfffe)
; 将ds,es,ss,都设置成移动后代码所在段(0x9000)
go: mov ax,cs ;ax = cs = INITSEG = 0x9000
mov ds,ax ;数据段地址
mov es,ax ;附加段地址
! put stack at 0x9ff00. ;将堆栈指针sp指向0x9fff00(0x9000:0xff00)
mov ss,ax ;栈段地址
; 保证栈指针sp只要指向远大于512byte字节偏移(即地址0x90200)
; 因为在0x90200后要存放setup程序,大约为4个扇区 sp指向大于(0x200+0x200*4+堆栈大小)
mov sp,#0xFF00 ! arbitrary value >>512
! load the setup-sectors directly after the bootblock.
; 在bootsect程序紧跟着加载setup程序
! Note that 'es' is already set up.
; es在移动代码时设置好了指向目的地址0x9000