这里介绍, 操作系统启动中的
bootsect.S
文件
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∗162+0∗161+0∗160=2002 * 16^2 + 0 * 16^1 + 0 * 16^0 = 2002∗162+0∗161+0∗160=200, 所以为了将setup.s
放在bootsect.S
的后面, 故放在往后移动的512 K个字节处。
然后利用BIOS中断 0x13 ,取磁盘参数表中当前启动引导盘的参数,接着在屏幕上显示“Loading system.”字符串
bootsect.S
将 system
模块读入到内存的0x10000
处,随后确定根文件系统的设备号。由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 赋值给bxmov 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 = 0x9000mov 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