在系统启动的第二步中,开始执行引导程序,那引导程序是哪里来的呢?引导程序是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实现,然后从活动「分区的引导扇区」中加载第一阶段)。由于大小的限制,第一阶段只能从磁盘的固定位置加载几个扇区,来加载下一阶段的引导程序。
阶段[……]