GRUB2 分析 (一)

GRUB是目前较流行启动引导程序。其第二版被主流Linux发行版所包括。本文将探索和分析GRUB的设计和实现机制。

boot.S是第一个研究对象,因为boot.S将被编译成boot.img(512字节),安装时安装在0号扇区,即主引导扇区(MBR)。

BIOS引导时会把主引导扇区装载到0x7c00开始的512字节内存区域,并设置CS:IP为0x0000:7c00。接着CPU会执行0x7c00处的指令,即boot.img(boot.S)中的第一条指令: jmp LOCAL(after_BPB) /* 机器码: eb 63 */ ,跳转到偏移量0x65的地方。  

接下去的代码检查并设置正确的引导驱动器号码。

设置实模式堆栈指针为0x2000。

打印提示信息,如果没按SHIFT键并且不是SILENT引导的话。

调用BIOS中断INT 0x13, AH 0x41检测BIOS是否支持磁盘LBA模式。

如果支持LBA模式,通过BIOS中断INT 0x13, AH 0x42来装载1号扇区到地址0x70000(0x7000:0000)开始的内存区域。

如果不支持LBA模式,就使用CHS模式。通过BIOS中断INT 0x13, AH 0x02装载1号扇区到地址0x70000(0x7000:0000)开始的内存区域。这里会先调用BIOS中断INT 0x13, AH 0x13来获取磁盘参数。如果失败了并且启动盘是软盘的话,会进行软盘探测。有意思的是软盘探测的代码是放在偏移量0x1be开始的区域内的,也就是硬盘分区表在MBR中的相应位置。因为软盘是不使用硬盘分区表的,所以覆盖没有关系。而当boot.img被安装到硬盘上时,安装时这段代码将不会被复制,因为硬盘引导不需要进行软盘探测,失败就失败了。

接下来跳转到被命名为copy_buffer的一段代码来将前面装载到地址0x70000的1号扇区数据复制到内存地址0x8000开始的内存区域。

最后,在偏移量0x016f处执行指令 jmp *(kernel_address) /* 机器码: ff 26 5a 7c */ 会跳转到0x8000执行下一条指令。

至此boot.S中的代码执行完毕。

 

下一篇

GRUB2 分析 (一)

上一篇:sizeof,一个其貌不扬的家伙(转)


下一篇:[Leetcode]-- Swap Nodes in Pairs