从BIOS到Boot再到Loader它们各自都干了些什么
BIOS
CPU加电启动
CS:IP
寄存器的初始值为0xF000:0xFFF0
,此时CPU处于实模式
下,这个CS:IP指向的地址的求法是
CS<<4+IP
,即CS*16+IP
,对应的物理地址为0xFFFF0
,这个位置对应一条长跳转指令jmp F000:E05B
,此时就会跳转到
BIOS固件
所在的内存地址,然后控制权交由BIOS固件,此时BIOS固件完成下列操作:
- 检测各个硬件设备是否正常运行
- 从磁盘(软盘)的第一扇区里面读出启动程序(Boot)
BIOS的能力有限,因为是固化在ROM上的一块程序段,完成硬件的检测已经十分吃力,后序的内核的加载操作可能BIOS就完成不了了,所以在此基础上,BIOS会将这个任务交给BooLoader,而BootLoader又可以细分为Boot和Loader,BIOS另外一个重要的任务就是从主磁道中将这个Boot程序给他加载出来,所以BIOS会在磁盘里面搜索这个Boot,而找到这个Boot的依据就是,这个扇区的最后两个字节是不是
0x55 0xaa
,当找到这个Boot程序之后,BIOS会将它加载到0x7c00
处,然后跳转到这个位置,将控制权交给Boot程序
Boot
Boot被加载到内存中之后,它的唯一的任务就是加载Loader到内存中,我看的这本书的软盘组织形式是FAT12,现今是,即将磁盘组织为文件结构的形式,FAT12简要的分为起始扇区、FAT表扇区(2个)、根目录扇区、数据扇区,关于FAT12文件结构的组织形式可以看(96条消息) 详解FAT12文件系统_洋葱汪的博客-CSDN博客_fat12,其加载Loader的原理就是,从根目录扇区去找FileName为loader.bin的目录,然后找到后,根据簇号去找到对应的数据,加载到内存中,直到Loader加载完毕之后,跳转到Loader的起始地址
0x10000
,将控制权交给Loader,自此Boot使命完成
Loader
接力棒交给Loader之后,Loader要做的是
-
获取硬件的信息,如真实物理地址信息(哪些是内存的地址、那些是硬件的、哪些是地址空洞)、VBE显示信息等等,这些信息的获取主要是在
实模式
下通过BIOS的一系列中断服务例程来实现的 -
初始化更高级模式下各种所需的数据结构,比如GDT(全局描述符表,用于支持段寻址),IDT(中断/异常处理程序),TSS(多任务下记录各个程序段的状态,特权级的段描述符),以及初始化控制寄存器,将这些寄存器的某系BIT置位,在一系列初始化准备工作完成之后,进行模式切换,从
实模式到保护模式再到长模式(IA-32)
-
因为内核是运行在很高的模式下的,他需要知道很多的硬件信息,而这些硬件信息的捕获只能在实模式下获得,所以Loader还要在实模式下将这些硬件信息以一定的组织形式转存到特定的内存位置,方便内核获得与使用这些信息
-
然后就是从软盘中加载内核到相应的内存空间,其加载原理跟Boot加载Loader一个样子
在这些准备工作都做完之后,Loader执行一条长跳转指令,到kernel所在的位置,Loader的使命完成,自此go die实现从BIOS -> Boot -> Loader