1 引导启动程序Boot学习
1.1 bootsect.s 程序学习
该程序驻留在启动盘的第一个扇区中,系统上电后会由bios自动加载到0x 7c 00处,之后它会将自己转移到0x90000处继续执行,之所以移动是为以后的system腾出位置。
该程序主要完成了三项工作:
<1> 加载setup模块的2K代码到0x90200处。
<2> 加载system模块到0x10000处
<3> 确定跟文件系统的所在设备号,如果跟文件系统所在位置没有被明确指定,则通过获取启动盘的每磁道扇区数来确定根文件系统所在设备号。
1.2 setup.s程序学习
该程序驻留在启动盘的2到5个扇区中,该模块被bootsect加载到了0x90200处(576.5K),长度为2K。
该模块主要完成了以下六项工作:
<1> 通过BIOS中断调用来获取系统参数,包括光标位置,硬盘参数……。该参数表霸占了原来Bootsect模块的位置。即其存在于0x90000到0x90200的区域。原来bootsect中的根文件系统所在设备号字段(0x901FC—0x901FD)并没有被覆盖掉。获取后的参数表如下:
注:硬盘参数表的获取足够BT,第一个硬盘参数表的收地址竟然是中断向量0x41的向量值。中断向量0x46的向量值则指向第二个硬盘的参数表首地址。
<2> 将system模块从0x10000(64K)处,移到0地址处,因为自此以后就不会再用到bios中断调用了。
<3> 加载中断向量表和全局描述符表。中断向量表为一个空表,全局描述附表为一个长度为2K的表,它存在于setup模块的数据段(和代码段重合)中。
<4> 开启A20地址线,让处理器能够访问 1M 以上的地址空间。
<5> 重新设置 8259A 芯片,设置外部中断的向量号为0x20—0x 2F 。
<6> 将处理器切换到保护模式、并转向system模块中的head模块运行。
该模块结束后内存中程序的布局如下:
1.3 head.s程序学习
该部分代码驻留在system模块的头部,这也是其称为head的原因。该模块主要完成以
下五方面的工作:
<1> 重新设置系统堆栈,这次将堆栈设置在了user_stack[]的尾端。这已经是第二次设置堆栈了,第一次是在bootseck中。该堆栈将来就被用做了task0和task1的用户态堆栈。
<2> 重新设置了IDT表和GDT表,这两个表紧密相连,每个大小为2K,IDT表存在与0x5000位置处。IDT表将所有中断门描述符设置为了一同一个处理函数,该函数简单的调用printk来打印一些提示信息而已。GDT表与先前在setup模块中设置的GDT表除了所处位置和内核代码段/数据段的长度不同外没有其它的不同。
<3> 监测A20地址线是否已经成功开启了
<4> 探测数字协处理器是否存在,根据探测结果正确配置CR0中的EM(协处理器仿真位)和MP位(协处理器存在位)。这两个为在任务切换过程中要被参考。
<5> 初始化了公共资源页目录和内核需要使用的4个页表(覆盖 16M 线性空间)。并初始化了映射关系,使内核的线性地址就等于物理地址。之后开启了分页功能,并转入到main中去执行。
该模块结束后内存布局如下: