grub启动流程及原理

GNU GRUB(简称“GRUB”,GRand Unified Bootloader)是一个来自GNU项目的多操作系统启动管理器,它允许用户可以在计算机内同时安装有多个操作系统,比如不同版本的Windows和Linux,并在计算机启动时选择希望运行的操作系统。Grub一直在发展,现在的发行版都用Grub 2了,但是基本的启动引导原理是差不多的,所以还是以传统的Grub为例(在CentOS 5.5上)。


我们知道,引导扇区是每个分区(Partition)的第一扇区,而主引导扇区是硬盘的第一扇区。主引导扇区由三个部分组成,主引导记录MBR、硬盘分区表DPT和硬盘有效标志。在总共512字节的主引导扇区里MBR占446个字节。第二部分是分区表,即DPT(Disk Partition Table),占64个字节。分区表含4个分区项,偏移地址01BEH--01FDH,每个分区表项长16个字节。这也就是为什么一个硬盘最多只能有4个主分区(包括一个扩展分区,(扩展分区可以再分为多个逻辑分区))的原因。第三部分是硬盘有效标志,占2个字节,固定为55AA,如果该标志错误系统就不能启动。


Grub的实质是一个mini os,它拥有shell,支持script,支持特定文件系统……grub由stage1,stage1-5,stage2以及/boot/grub目录下的诸多文件(包括Grub的配置文件与相关文件系统定义文件等)组成,其核心是stage2,主要功能在于完成操作系统的引导工作。Grub可以安装在MBR,也可以安装在一个Linux分区的引导扇区,这2种情况是略有不同的。


先介绍一下Grub的三个文件:
1) stage1的代码文件,是源码目录下stage1/stage1.S,汇编后便成了一个512字节的img,被写在硬盘的0面0道第1扇区,作为硬盘的主引导扇区。(这512字节还包括分区表DPT以及主引导扇区标志“55AA”)
2) stage1_5就是文件系统的解释代码,根据/boot分区(或/boot所在分区)的具体文件系统类型而异,如:ext3分区的话就是 e2fs_stage1_5。在stage1_5没有被加载以前,系统无法识别任何文件系统(但是可以通过BIOS中断方式INT 13h读取磁盘指定扇区的内容)。
3) stage2是grub最核心的部分。它运行后,会把系统切入保护模式,设置好c运行环境然后寻找menulist,如果没有的话就执行一个shell,等待我们输入命令,并在执行boot命令以后就会把控制权转交出去。


我们看一下/boot/grub目录:
[cent@localhost ~]$ ls -l /boot/grub
总计 328
-rw-r--r-- 1 root root     63 2010-10-23 device.map
-rw-r--r-- 1 root root   7584 2010-10-23 e2fs_stage1_5
-rw-r--r-- 1 root root   7456 2010-10-23 fat_stage1_5
-rw-r--r-- 1 root root   6720 2010-10-23 ffs_stage1_5
-rw------- 1 root root    656 2010-10-23 grub.conf
-rw-r--r-- 1 root root   6720 2010-10-23 iso9660_stage1_5
-rw-r--r-- 1 root root   8192 2010-10-23 jfs_stage1_5
lrwxrwxrwx 1 root root     11 2010-10-23 menu.lst -> ./grub.conf
-rw-r--r-- 1 root root   6880 2010-10-23 minix_stage1_5
-rw-r--r-- 1 root root   9248 2010-10-23 reiserfs_stage1_5
-rw-r--r-- 1 root root  55808 2009-03-13 splash.xpm.gz
-rw-r--r-- 1 root root    512 2010-10-23 stage1
-rw-r--r-- 1 root root 104988 2010-10-23 stage2
-rw-r--r-- 1 root root   7072 2010-10-23 ufs2_stage1_5
-rw-r--r-- 1 root root   6272 2010-10-23 vstafs_stage1_5
-rw-r--r-- 1 root root   8904 2010-10-23 xfs_stage1_5
[cent@localhost ~]$ 


现在我们把Grub再安装一次,安装在MBR(MBR广义可指主引导扇区):
[cent@localhost ~]$ sudo grub
    GNU GRUB  version 0.97  (640K lower / 3072K upper memory)


 [ Minimal BASH-like line editing is supported.  For the first word, TAB
   lists possible command completions.  Anywhere else TAB lists the possible
   completions of a device/filename.]


grub> root (hd0,7)
 Filesystem type is ext2fs, partition type 0x83


grub> setup (hd0)
 Checking if "/boot/grub/stage1" exists... yes
 Checking if "/boot/grub/stage2" exists... yes
 Checking if "/boot/grub/e2fs_stage1_5" exists... yes
 Running "embed /boot/grub/e2fs_stage1_5 (hd0)"...  15 sectors are embedded.
succeeded
 Running "install /boot/grub/stage1 (hd0) (hd0)1+15 p (hd0,7)/boot/grub/stage2
/boot/grub/grub.conf"... succeeded
Done.


grub> quit


由上面的命令看出,stage1写进了(hd0)的MBR中,stage1_5写进了(hd0)MBR以后的15个扇区中(因为e2fs_stage1_5大小为7.5k)。将stage1_5写进MBR以后的扇区中,会不会影响正常的文件系统分区?不会,因为stage1_5较小,只占15个扇区,硬盘上第一个文件系统分区的开始扇区最小也只能从0柱面,1磁头,1扇区开始。就是说MBR所在0磁头就只用到了1个扇区而已(其它扇区都是未用的,不属于任何分区),按照现在硬盘的规格来说,一般一个柱面磁头都有60+个扇区,所以这些扇区可以用来放stage1_5,但是放stage2就不够了(100多k),所以只能将stage2放进文件系统中了。


我们再来把Grub安装一次,安装在Linux分区的引导扇区:
[cent@localhost ~]$ sudo grub
    GNU GRUB  version 0.97  (640K lower / 3072K upper memory)


 [ Minimal BASH-like line editing is supported.  For the first word, TAB
   lists possible command completions.  Anywhere else TAB lists the possible
   completions of a device/filename.]


grub> root (hd0,7)
 Filesystem type is ext2fs, partition type 0x83


grub> setup (hd0,7)
 Checking if "/boot/grub/stage1" exists... yes
 Checking if "/boot/grub/stage2" exists... yes
 Checking if "/boot/grub/e2fs_stage1_5" exists... yes
 Running "embed /boot/grub/e2fs_stage1_5 (hd0,7)"... failed (this is not fatal)
 Running "embed /boot/grub/e2fs_stage1_5 (hd0,7)"... failed (this is not fatal)
 Running "install /boot/grub/stage1 (hd0,7) /boot/grub/stage2 p /boot/grub/grub
.conf "... succeeded
Done.


grub> quit


可以看到,这次e2fs_stage1_5嵌入/安置失败(但Grub仍然安装成功了),因为Linux分区没有文件系统之外的未用扇区。但是在一个ext2文件系统里,引导扇区boot sector应该会占有1024字节的大小(ext3文件系统应该一样),而stage1只有512字节,甚至此时不包括DPT,故引导扇区最多多余了64+2+512个字节保留下来。我猜测这么多保留的字节,可以把e2fs_stage1_5文件在硬盘上实际占用的物理扇区地址,按顺序全部记录在这些保留的字节里,从而可以间接的读取e2fs_stage1_5。甚至用这种方式间接的读取stage2,就不需要stage1_5了,stage2自身具有解释文件系统的功能,所以可以加载kernel。


如果Grub是安装在一个活动分区的引导扇区,则MBR可以安装OSL2000等第三方启动管理器,它也是占用MBR和硬盘0磁道的未用扇区,独立于任何文件系统和操作系统。


最后叙述一下计算机启动简要流程:
(1)系统上电开机后,主板BIOS(Basic Input / Output System)运行POST(Power on self test)代码,检测系统外围关键设备(如:CPU、内存、显卡、I/O、键盘鼠标等)。硬件配置信息及一些用户配置参数存储在主板的CMOS(Complementary Metal Oxide Semiconductor)上(一般64字节),实际上就是主板上一块可读写的RAM芯片,由主板上的电池供电,系统掉电后,信息不会丢失。执行POST代码对系统外围关键设备检测通过后,系统启动自举程序,根据我们在BIOS中设置的启动顺序搜索启动驱动器(比如硬盘、光驱、网络服务器等)。选择合适的启动器,比如通常情况下的硬盘设备,BIOS会读取硬盘设备的第一个扇区(MBR,512字节),并执行其中的代码。实际上这里BIOS并不关心启动设备第一个扇区中是什么内容,它只是负责读取该扇区内容、并执行,BIOS的任务就完成了。此后将系统启动的控制权移交到MBR部分的代码。
(2)如上BIOS加载硬盘主引导扇区总共512字节的二进制代码,执行Initial Program Loader(IPL),IPL就是存储于446个字节的MBR中,因此IPL仅仅是GRUB的第一个部分(stage1)。
(3) stage1的工作是加载 stage1_5(ext3文件系统就是e2fs_stage1_5),它位于0面0道第2扇区开始的十几个扇区内。stage1_5运行后,就可以识别/boot所在分区的文件系统了,所以:
(4) 加载stage2并运行。此后grub会根据menulist或用户输入加载kernel,然后控制权就转到Linux了。


关于Grub 2(懒得翻译了):
The image files (see Images) that make up GRUB have been reorganised; Stage 1, Stage 1.5, and Stage 2 are no more. 
stage1
    Stage 1 from GRUB Legacy was very similar to boot.img in GRUB 2, and they serve the same function.
*_stage1_5
    In GRUB Legacy, Stage 1.5's function was to include enough filesystem code to allow the much larger Stage 2 to be read from an ordinary filesystem. In this respect, its function was similar to core.img in GRUB 2. 
stage2
    GRUB 2 has no single Stage 2 image. Instead, it loads modules from /boot/grub at run-time. 


注:以上参考了网络上的不少资料、笔记等,主要是一个整理;对于Grub安装在Linux分区的引导扇区这种情况,也提出了猜测。但是因为Grub一直在发展,细节上可能有所不同,加上根本不可能去读Grub的相应部分的源代码,所以以上表述都是不严谨的,仅为探讨。

你可能感兴趣的:(linux)