在系统启动的第二步中,开始执行引导程序,那引导程序是哪里来的呢?引导程序是GRUB安装到MBR中。
GRUB,一个引导加载程序,属于GNU项目。它是「多引导规范」的「参考实现」,可以用户在安装了多个操作系统的主机上选择要启动的系统,或者选择特定的内核配置。
引导加载程序的任务
任务一、识别文件系统
操作系统的内核通常保存在文件系统中的,但是BIOS并没有文件系统的概念,因此BIOS无法直接启动内核。因此需要加入中间层,系统启动的大概为 BIOS -> BOOTLOADER -> KERNEL。因此在基于BIOS的系统中,读取文件系统的文件由 BOOTLOADER 负责。由引导加载程序加载内核到内存执行。这有两种途径:
**途径一,直接读取物理扇区**:不管用什么文件系统,数据在磁盘上还是数据。所以,只要找到保存文件的扇区,将扇区依照顺序拼凑起来,即使不理解文件系统,也能够获取到文件。鉴于此,定义一个“间接层”,该层保存了内核所在的物理扇区,引导程序直接读取这个间接层来获取内核,这样就可以了。但是,这也带来了一些问题。内核文件不能动,移动、碎片整理、更新内核都会导致物理扇区发生变化。一旦变化,就要重新更新”间接层“,同时可能还要更新MBR中的代码(因为它要知道间接层的开始和结束位置)。这个方案不好。
**途径二,理解文件系统**:让引导程序理解文件系统,这样就可以通过文件路径找到内核。这就要求引导程序中包含某些驱动程序,以识别文件系统。这种方法减少了对物理扇区的依赖,并且在内核文件发生修改之后,不需要更新引导程序。并且,由于可以理解文件系统,引导程序的配置文件可以保存在文件系统中。但是也存在一些缺点,这种途径增加了引导加载程序的大小和复杂性。
我们使用的GRUB就是第二种途径,通过理解底层的文件系统。引导加载程序也被分成了多个阶段,以适合MBR引导方案。目前GRUB由两个版本,GRUB Legacy(存在于旧的发行版中)与GRUB 2(从头开始开发,意图替换之前的版本)。目前GRUB 2已经在大多数Linux发行版中使用。
任务二、多阶段执行
在主引导记录中,留给引导程序的空间只有434到446字节。对于简单的引导程序,这个空间足够了。对于相对复杂的引导,这个空间是远远不足的。因此复杂的引导程序只能被分为两部分:一部分位于主引导记录中,一部分位于其他位置。由主引导记录中的引导程序加载另一部分引导程序。
第一版 - GRUB Legacy
该版本采用两阶段方法。包含在MBR中的是第一阶段(或者包含一个标准的MBR实现,然后从活动「分区的引导扇区」中加载第一阶段)。由于大小的限制,第一阶段只能从磁盘的固定位置加载几个扇区,来加载下一阶段的引导程序。
阶段一可以直接加载阶段二,但通常设置为加载「阶段1.5」(位于MBR之后和第一个分区之前的前30KiB中)。 如果此空间不可用,则「阶段1.5」的安装将会失败。「阶段1.5」镜像包含文件系统驱动程序,使其能够从文件系统中的任何已知位置直接加载「阶段二」,例如从/boot/grub加载文件。然后,「阶段二」将加载默认配置文件和所需的任何其他模块(比如内核等等)。
第二版 - GRUB 2
BIOS + MBR
第一步,在MBR的前440字节,写入了boot.img镜像(或写入分区的引导扇区中),通过64位的LBA地址来定位diskboot.img镜像,因此它可以从MBR的2 GiB限制以上加载。实际的扇区号由grub-install写入。
第二步,那么diskboot.img是什么呢?它是core.img(在GRUB Legacy中Stage 1.5的)的第一个扇区,其唯一目的是加载core.img的其余的部分。在 MBR 分区表中,第一扇区和第一分区之间由 1MiB 的空隙,而core.img就存在与这个空隙中。由于处理器当前处于 Real Mode,此时内存上限为 1MiB,因此只能载入 1Mib 内容到内存中。
第三步,然后core.img进行32位 Protected Mode,自解压,从grub-install配置的分区加载/boot/grub/<platform>/normal.mod模块。如果你的GRUB找不到normal.mod模块,它就进入救援模式,显示grub>提示符。可以从任何地方加载/boot/grub目录,这取决与你是如何配置的。
第四步,加载normal.mod之后,它就可以读取并解析/boot/grub/grub.cfg文件,显示菜单。
第五步、用户选择菜单项,根据用户选择将 KERNEL 与 initramfs 文件加载到内存。
BIOS + GPT
执行流程与BIOS + MBR类似,只是core.img保存位置不同。在GPT中,由于分区不限于4个,因此core.img被写入其自己的小型(1 MiB)的、无文件系统的「BIOS启动分区」。
使用UEFI固件
# TODO 指用UEFI固件的系统启动
相关链接
Multiboot Specification
Comparison of boot loaders
4 Best Linux Boot Loaders
相关文章
「GRUB」- 安装
「Grub」- 手动引导启动
「GRUB」- 在BIOS系统上的GRUB引导
「Kernel」- 内核(Linux)
参考文献
6 Stages of Linux Boot Process (Startup Sequence)
Stages of Linux booting process – explanation, step by step tutorial
Hard Disk [HDD] Internal Structure
Wikipedia/GNU GRUB
Wikipedia/BIOS boot partition