GRUB引导程序之承前启后的start.S—源码分析

启动阶段

    在查看了start.S代码之后,就会对GRUB Legacy启动阶段有了更清晰的认识。在传统的GRUB启动中,一般分为stage1、stage1.5和stage2三个阶段,当然,stage1.5是可以忽略的,这样就直接从stage1跳转到了stage2。stage1.5主要是为stage2构建其所需要的文件系统。

    目前只考虑GRUB legacy,不考虑GRUB 2.0的情况。像redhat/centos 5/6系列的系统一般使用的都是GRUB legacy代码,redhat/centos 7系列以后就开始使用GRUB 2.0(GRUB 2.0可以看作对stage1.5和stage2阶段代码进行了重构)。

    在之前编写的《GRUB引导程序之第一阶段stage1.S分析》就是GRUB引导程序第一阶段完整的代码。本文所分析的start.S文件,虽然位于stage1.5代码中,但从功能上来看是不应该划分到1.5阶段的。

承前启后的start.S

    start.S主要起到一个过渡功能,根据第一阶段分析可知,stage1.S的代码位于第一扇区,由BIOS加载到0x7c00地址处,该代码负责加载第二扇区的代码(start.S)至地址0x8000。

    start.S主要从0x8000开始运行,并根据配置选项选择加载stage1.5阶段代码还是stage2.0阶段代码。如果只考虑三个阶段的情况,start.S加载的是stage1.5阶段代码,stage1.5将从第三个扇区开始,占用了若干个扇区的位置。start.S负责将stage1.5阶段的代码加载到0x2200地址处,并开启后面的引导之旅。

源码分析

#define ASM_FILE
#include <shared.h>

#ifndef STAGE1_5
#include <stage2_size.h>
#endif
	
#ifdef STAGE1_5
# define ABS(x) (x-_start+0x2000)
#else
# define ABS(x) (x-_start+0x8000)
#endif /* STAGE1_5 */
	
//打印信息
#define MSG(x)	movw $ABS(x), %si; call message

	.file	"start.S"

	.text

//通知GAS汇编器使用16位的指令集,因此现在工作在实模式。
	.code16

//代码开始的位置,该部分代码被stage1.S加载到0x8000地址处
	.globl	start, _start
start:
_start:	

//在stage1.S处我们在地址0x2000处开辟了堆栈,现在继续是该堆栈	
//将DX进行压入堆栈,DX寄存器中存储的是磁盘号
	pushw	%dx

//将si压入堆栈,si在第一阶段指向的是sectors对应处的地址
	pushw	%si
	
//根据需要打印不同的信息
//我所找的代码是支持stage1.5阶段的,后续的分析均在支持1.5阶段基础之上
//此处将打印"Loading stage1.5",1.5阶段主要是用来构建文件系统供2阶段使用
//如果直接支持stage2,则打印“Loading stage2”
	MSG(notification_string)
//打印的时候用到了si寄存器,现在将si寄存器的值还原
	popw	%si
	
//BOOTSEC_LISTSIZE的值为8,firstlist标号指向文件的尾部
//movw以为着将blocklist_default_start标号处的绝对地址赋值给了DI寄存器
	movw	$ABS(firstlist - BOOTSEC_LISTSIZE), %di

//blocklist_default_start标号处指向的值为下一个阶段所在逻辑扇区的号,此处为2
//扇区标号是从0开始的,此处意味着1.5阶段是从第三个扇区开始的。
//movl将1.5阶段的扇区号赋值给了EBP栈基址寄存器。
	movl	(%di), %ebp

//从该标号开始为一个循环,读取下个阶段(1.5阶段)的引导程序
bootloop:

//4(%di)是变址寻址,既4(%di)为di所代表的地址加4,指向的是blocklist_default_len处的地址
//该地址指向的值代表了后续扇区块的长度,现在是1.5阶段,默认是0值,在grub装载时会被填充修正为真正的stage1.5的扇区数
//cmp比较指令做算数减法运算,结果为0,将ZF设置为1,正确设置后将不为0ÿ
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值