- 论坛徽章:
- 0
|
Boot0的主要作用:
书上说得比较多了,大致的作用就跟MBR差不多,系统安装的时候把它放到硬盘的主引导记录当中,提供一个简单的多操作系统引导功能。如果选择启动FreeBSD,它会在对应的分区里面读“分区引导记录”,也就是Boot1,然后经由Boot1来引导BTX,boot2.bin,最终加载内核。
boot0.s是boot0的源代码,存在两个版本,一个大小是512K,占用一个扇区,还有一个是1024K,占用两个扇区,这两个文件分别是boot0.s,boot0ext.s,存放的目录是:
/usr/src/sys/boot/i386/boot0/boot0.s
在boot0.s这个源文件中采用的是AT&T的汇编语言语法格式,在指令上和windows环境下的汇编语言格式略有不同。
一、读这个代码的预备知识:根据PC机的体系结构,硬件启动的最后一个步骤是读取硬盘上的主引导记录,放到内存:0x0000:0x7c00这个地址,一个jmp跳转指令来执行主引导记录的第一条指令。
二、主要的代码:
boot0.s的主要工作流程是
1、代码搬移,从0x7c00这个地址挪到另外一个地址,主要是为了给后续读取分区引导记录boot1腾出空间。
2、扫描分区表,扫描引导扇区有效标志,打印多系统引导界面。
3、根据选择,读取相应分区的分区引导记录
4、出错处理
主要的代码:
1、变量定义:
.set ORIGIN,0x600 # Execution address
.set FAKE,0x800 # Partition entry
.set LOAD,0x7c00 # Load address
.set PRT_OFF,0x1be # Partition table
.set TBL0SZ,0x3 # Table 0 size
.set TBL1SZ,0xb # Table 1 size
.set MAGIC,0xaa55 # Magic: bootable
.set B0MAGIC,0xbb66 # Identification
.set KEY_ENTER,0x1c # Enter key scan code
.set KEY_F1,0x3b # F1 key scan code
.set KEY_1,0x02 # #1 key scan code
.set ASCII_BEL,0x07 # ASCII code for BEL>
.set ASCII_CR,0x0D # ASCII code for CR>
符号常量定义形式:
.set 符号常量,值 #注释
2、乾坤大挪移
start: cld # String ops inc
xorw %ax,%ax # Zero
movw %ax,%es # Address
movw %ax,%ds # data
movw %ax,%ss # Set up
movw $LOAD,%sp # stack
/*
* Copy this code to the address it was linked for
*/
movw %sp,%si # Source
movw $start,%di # Destination
movw $0x100,%cx # Word count
rep # Relocate
movsw # code
这段代码的作用就是DS:SI内存的数据转移到ES:DI当中,0x200个字节
movw $LOAD,%sp # stack
常量的引用:$常量名 $具体的数值
寄存器的使用:%寄存器名
指令格式:
操作码 原操作数,目的操作数 #注释
上面那条指令的作用就是把LOAD的值赋给sp寄存器,也就是这段代码运行期间,栈顶是0x7c00,向下增长。不会影响到0x7c00的代码。
movw $start,%di # Destination
start是代码中的标识,实际代表的是代码装载到内存时的地址,因此$start这个引用表示的是地址。
3、中间略去,最后的装载分区引导记录代码:
第312行的main.15
main.15:
movw $LOAD,%bx # Address for read
movb $0x2,%ah # Read sector
callw intx13 # from disk
jc main.10 # If error
cmpw $MAGIC,0x1fe(%bx) # Bootable?
jne main.10 # No
movw $crlf,%si # Leave some
callw puts # space
jmp *%bx # Invoke bootstrap
这段代码的作用:使用BIOS系统调用读扇区操作,读取分区引导记录扇区,这里设定是读取FreeBSD分区的分区引导记录boot1,放到DS:BX=0x0000:0x7c00处,如果读取成功,检测读取扇区的最后两个字节,如果成功jmp *%bx
两个寻址方式:
cmpw $MAGIC,0x1fe(%bx)
我的理解是:bx(=0x7c00)+0x1fe 把这个数值作为地址,把这个地址内的数值和$MAGIC对比,也就是检测可引导扇区有效标志。
jmp *%bx
很显然是无条件跳转到0000:0x7c00处,但是这条指令比较难理解,%bx表示寄存器引用,但是寄存器不能作为jmp的操作数,类似于C语言的做法,用到了地址求值,因为bx=0x7c00,我的理解就是“把BX寄存器的值作为操作数,作为跳转地址”——这种写法很类似C语言。
读boot1.s的代码,可知boot1.s汇编之后的二进制代码和BTX、boot2.bin在安装时是存放在FreeBSD可引导“Silce”中的前16个扇区里面,Jmp $0x7c00,就是运行boot1.s,然后加载BTX,然后运行boot2.c里面的程序,实现内核加载。
本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u/12258/showart_189716.html |
|