一篇比较老的笔记,从老博客上搬运过来的。
手头刚买了一本书,书名为《Linux操作系统之奥秘》,作者是邱世华,是台湾的一个资深工程师。当时买这本书的原因是,网上评论这本书适合已经入门但是呢对Linux又是一知半解的人。买了之后,看了一点,发现真得非常适合我,现在只是看到第二章(GRUB),但是真得受益匪浅。
之前装Linux系统,因此对GRUB也不陌生,但是顶多是停留在一些开启启动配置,又或者修复MBR等等层面,对它的原理、细节就完全不清楚了。大家都知道,MBR其实只有512字节的大小,其中bootloader更是只占了这其中的446字节,另外的分别是64字节的分区表信息(一个分区需要16字节,这也是为什么只能分4个主分区的原因)以及2字节的magic number。而GRUB的大小必然不只512字节,那么它怎么放置多出来的东西呢? 没看书之前,我估计只知道,肯定是把启动必须的代码放到MBR的前446字节,而其它的放到硬盘的其它地方,至于具体的处理方式,就....)
事实上,GRUB管理开机启动的过程分成了三个阶段,分别是stage1/stage1.5/stage2。其中,stage1主要负责BIOS和GRUB之间的交接,载入存放于各个分区中的开机文件(我的理解是,例如Linux下/boot/grub/..下面的一些文件)。这部分才是真正放在MBR中的bootloader。而后stage1.5是连接stage1和stage2之间的通道,起着过渡的作用。最后才是GRUB中真正核心的部分stage2,它可以让用户以选项的方式将操作系统加载、修改选项以及新增参数。
这些文件都是放在/boot/grub目录下:
tuantuan@~$ ls -l /boot/grub/ total 332 -rw-r--r-- 1 root root 7916 Apr 18 2010 e2fs_stage1_5 -rw-r--r-- 1 root root 7464 Apr 18 2010 fat_stage1_5 -rw-r--r-- 1 root root 6720 Apr 18 2010 ffs_stage1_5 -rw-r--r-- 1 root root 6728 Apr 18 2010 iso9660_stage1_5 -rw-r--r-- 1 root root 8180 Apr 18 2010 jfs_stage1_5 -rw-r--r-- 1 root root 512 Nov 1 12:30 mbr.txt -rw-r--r-- 1 root root 1494 Oct 22 20:03 menu.lst -rw-r--r-- 1 root root 6916 Apr 18 2010 minix_stage1_5 -rw-r--r-- 1 root root 32256 Nov 1 12:45 partition.img -rw-r--r-- 1 root root 9296 Apr 18 2010 reiserfs_stage1_5 -rw-r--r-- 1 root root 512 Apr 18 2010 stage1 -rw-r--r-- 1 root root 102106 Apr 18 2010 stage2 -rw-r--r-- 1 root root 102106 Apr 18 2010 stage2_eltorito -rw-r--r-- 1 root root 6988 Apr 18 2010 ufs2_stage1_5 -rw-r--r-- 1 root root 6340 Apr 18 2010 vstafs_stage1_5 -rw-r--r-- 1 root root 9108 Apr 18 2010 xfs_stage1_5
stage1
从上面可以看到,stage1文件的大小正好是512字节,事实上stage1文件其实就是MBR中bootloader的备份,而之所以是bootloader而不是MBR, 是因为这个文件的前446字节才是和MBR是一样的。可以自己比较下mbr和stage1:
tuantuan@grub$ sudo dd if=/dev/sda of=mbr bs=512 count=1 1+0 records in 1+0 records out 512 bytes (512 B) copied, 0.000103146 s, 5.0 MB/s
然后用hexdump -C命令查看下mbr和stage1两个文件的内容并比较下,确实是如此的。
stage1_5
上面可以看到stage1_5形式的文件有很多,如e2fs_stage1_5、jfs_stage1_5等等,这些都是stage1.5阶段的文件,只是每个都针对不同的文件系统格式,而e2fs_stage1_5是默认的(ext系列的文件系统?)。当stage1加载stage1.5之后,就可以识别相应的文件系统,从而可以加载stage2文件。我特地查看了下e2fs_stage1_5的内容,发现有两个地方可以看懂:
00000100 00 eb fe 4c 6f 61 64 69 6e 67 20 73 74 61 67 65 |...Loading stage| 00000110 31 2e 35 00 2e 00 0d 0a 00 47 65 6f 6d 00 52 65 |1.5......Geom.Re| 00000120 61 64 00 20 45 72 72 6f 72 00 bb 01 00 b4 0e cd |ad.
和
00000210 02 00 30 2e 39 37 00 ff ff ff ff 2f 62 6f 6f 74 |..0.97...../boot| 00000220 2f 67 72 75 62 2f 73 74 61 67 65 32 00 00 00 00 |/grub/stage2....| 00000230 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
这些信息都是在stage1.5执行的过程中才会产生的信息,而stage1.5要执行,是通过stage1加载它。而Grub的做法是把stage1.5安装在硬盘最前面的32K,由stage1负责去该区域将stage1.5找出来并执行。同样地,可以将硬盘最开始的32K内容(紧跟着MBR)和 stage1.5文件作一个比较:
tuantuan@grub$ sudo dd if=/dev/sda of=partition.img skip=1 bs=512 count=63 Password: 63+0 records in 63+0 records out 32256 bytes (32 kB) copied, 0.0113796 s, 2.8 MB/s tuantuan@grub$ hexdump -C partition.img >~/Backup/partition.txt tuantuan@grub$ hexdump -C e2fs_stage1_5 >~/Backup/stage1_5.txt tuantuan@grub$ vimdiff ~/Backup/partition.txt ~/Backup/stage1_5.txt
比较了一下,"几乎"是相同的,反正我这是有几处地方是不一样的。
stage2
平时开机启动的时候看到的Grub选项、信息,还有修改GRUB背景等功能都是stage2提供的,stage2会去读入/boot/grub/grub.conf或者menu.lst等配置文件。
总结
1. BIOS将控制权交给硬盘的主引导区,即MBR。
2. MBR中的bootloader(stage1)通过内置的地址加载stage1_5
3. bootloader通过stage1_5的内容,将分区中的stage2加载
4. stage2此时就可以在文件系统中将grub.conf文件加载,让用户看到选项界面。