操作系统的启动是个很令人好奇的话题,从按下计算机电源的那一刻,计算机从裸机开始呈现一个丰富的系统界面,这个从只有硬件逻辑到软件逻辑的过程是如何完成的?这里我们将从硬盘分区,三方协议,grub引导启动程序进行讲述,首先介绍硬盘MBR分区形式,然后介绍CPU,BIOS,系统的三方协议,讲述从CPU的硬件逻辑最终运行内核的软件逻辑的过程,最后介绍一下引导启动程序的发展,在grub这些引导启动程序中如何继续遵守三方协议。
1, MBR硬盘分区
MBR(Master Boot Record)即主引导记录分区表。它由三个部分组成:主引导记录,硬盘分区表和有效标志,共512字节,位于硬盘的0柱面、0磁头、1扇区。其中主引导记录占前446字节,硬盘分区表(DPT)占64字节,分区表里有4个表项,每个表项占16字节,最后是2字节的结束标志(固定为0x55AA)。在MBR分区中,第一个扇区的内容是十分关键的,它是主引导记录,如果操作系统需要按照MBR分区形式安装在这个硬盘中,那么需要在主引导记录里填入引导系统启动的代码。MBR分区在硬盘上的组织形式大致如下:
2, 三方协议
想要把操作系统启动起来,是需要多方按照一定的协议进行协作才能完成的,以Linux0.11,BIOS MBR分区,Intel80x86CPU为例,首先电源加电后,主板会将BIOS从ROM里读取并放入内存RAM里,其在内存的位置是0xFE000~0xFFFF0,共计8KB,此时CPU加电后会进入16位实模式,通过硬件逻辑强行把自己的CS的值设置为0xF0000,IP的值设置为0xFFF0,这样CS:IP寻址就会指向内存的0xFFFF0,也就是BIOS的起始位置,那么BIOS程序就开始执行了,此时完成了CPU与BIOS的协同,彼此间的协议就是内存地址0xFFFF0!那么BIOS执行后,需要从硬盘或其他地方读取内核的代码,让内核执行起来,这如何做到呢?首先BIOS在开始执行时会把子机的中断向量表和BIOS数据放到内存的某个区域,中断向量表在0x00000~0x003FF,共计1KB,BIOS数据区在随后的0x00400~0x004FF,共计256B,建立好中断向量表以及其他操作后,BIOS会触发一个int0x19中断,CPU接收到这个中断后,会去内存的BIOS中断向量表里找到int0x19这个中断的中断服务程序(内存位置在0x0E6F2),这个中断服务程序的功能就是把磁盘里的第一个扇区(512B)读取到内存0x07C00(BOOTSEG)处,并开始执行它。此时内存第一次有了操作系统的代码,第一个扇区的内容其实就是linux/boot/bootsect.s的内容,其主要功能就是把第二批第三批代码加载到内存中规划好的位置。
bootsect.s的内存规划如下:
代码语言:c复制SETUPLEN = 4 ! nr of setup-sectors
BOOTSEG = 0x07c0 ! original address of boot-sector
INITSEG = 0x9000 ! we move boot here - out of the way
SETUPSEG = 0x9020 ! setup starts here
SYSSEG = 0x1000 ! system loaded at 0x10000 (65536).
ENDSEG = SYSSEG SYSSIZE ! where to stop loading
经过调整boosect自身在内存的位置之后,boosect开始把setup程序加载到内存中,此时使用的另一个中断向量int0x13,此中断向量可以指定扇区和内存位置,将指定扇区的内容读取的指定的内存位置。在bootsect中,读取的是从第二个扇区开始的4个扇区,加载到0x90200(SETUPSEG)处,这些内容对应linux/boot/setup.s这个文件。加载进来后,setup会再次调整内存规划,然后会使用int0x13中断向量继续加载240个扇区的内容,也就是system模块。setup还会做一些设置,例如关中断,设置中断描述符表和全局描述符表,打开A20实现32位寻址,对编程中断控制器8259A进行重编程,建立保护模式下的中断机制等等,为内核main函数的调用做准备。此时内存的视图如下:
所以,我们可以知道,当BIOS运行后,会通过int0x19中断读取第一扇区的内容,BIOS并不管这个扇区里是否有内容。如果我们系统安装在硬盘上,就得保证第一扇区是我们的bootsect,这样才可以通过int0x13读取其他扇区的setup和system,从而最终完成内核的启动。所以这个第一扇区是至关重要的,是BIOS与系统的协议。
3, grub
经过多年的发展,引导程序已经由最初像Linux0.11的bootsect.s,setup.s等发展为grub,grub2之类的启动引导程序,第一扇区(主引导记录)也从bootsect.s变成了stage1,boot.img这些形式的内容,这类引导程序可以引导多个操作系统,多种操作系统的启动,拥有配置文件和简单的命令行界面,功能变得十分强大。不过grub跟最初的引导程序一样,也是遵循BIOS MBR的规则的。gurb对系统的引导也是分为三个阶段,步骤1(stage1)的内容存放在主引导记录里,其功能主要是加载步骤1.5(stage1.5)的内容,也就是grub到内存中,步骤1.5会加载步骤2的内容,步骤2启动后,将会呈现一个选择启动的操作系统的界面。grub2是grub的升级版,在硬盘分区的内容与grub类似,只是stage1变成了boot.img,stage1.5变成core.img。