启动引导程序(Boot Loader,也就是 GRUB)会在启动过程中加载内核,之后内核才能取代 BIOS 接管启动过程。如果没有启动引导程序,那么内核是不能被加载的。在 CentOS 6.x 中,启动引导程序默认是 GRUB,GRUB 是现在最为流行的启动引导程序,我们也用 GRUB 来说明启动引导程序的作用, initramfs 这个虚拟文件系统也是要靠启动引导程序调用的。
早期的 LILO 引导程序已经不是很常见了,GRUB 相比来讲有很多优势,主要有:
GRUB加载内核的过程:GRUB 的作用有以下几个:
按照启动流程,BIOS 在自检完成后,会到第一个启动设备的 MBR 中读取 GRUB。在 MBR 中用来放置启动引导程序的空间只有 446 Byte,那么 GRUB 可以放到这里吗?答案是空间不够,GRUB 的功能非常强大,MBR空间是不够使用的。那么 Linux 的解决办法是把 GRUB 的程序分成了三个阶段来执行。
stage1:执行GRUB主程序
第一阶段是用来执行 GRUB 主程序的,这个主程序必须放在启动区中(也就是 MBR 或者引导扇区中)。但是 MBR 太小了,所以只能安装 GRUB 的最小的主程序,而不能安装 GRUB 的相关配置文件。这个主程序主要是用来启动 Stage 1.5 和 Stage 2 的。
stage1.5:识别不同的文件系统
Stage 2 比较大,只能放在文件系统中(分区),但是 Stage 1 不能识别不同的文件系统,所以不能直接加载 Stage 2。这时需要先加载 Stage 1.5,由 Stage 1.5 来加载不同文件系统中的 Stage 2。 Stage 1.5 不是放在文件系统中的吗?如果是,那么 Stage 1 同样不能找到 Stage 1.5。其实,Stage 1.5 没有放在文件系统中,而是在安装 GRUB 时,直接安装到紧跟 MBR 之后的 32KB 的空间中,这段硬盘空间是空白无用的,而且是没有文件系统的,所以 Stage 1 可以直接读取 Stage 1.5。读取了 Stage 1.5 就能识别不同的文件系统,才能加载 Stage 2。
stage2:加载GRUB的配置文件
Stage 2 阶段主要就是加载 GRUB 的配置文件 /boot/grub/grub.conf,然后根据配置文件中的定义,加载内核和虚拟文件系统。接下来内核就可以接管启动过程,继续自检与加载硬件模块了。
BIOS 在进行完成系统检测之后,就会找到第一个可以启动的设备,并读取该设备的 MBR(主引导记录)以及加载 MBR 中的 boot loader(启动引导程序),这个启动引导程序可以具有菜单功能、直接加载核心文件以及控制权移交的功能等。系统必须要借助启动引导程序,才能加载内核,那么问题来了,MBR 只是占据整个设备的第一个扇区中,其大小也就只有 446 字节而已,但启动引导程序功能这么强大,光程序代码即配置数据就肯定不止 446 字节,是怎么安装的吗?
是这样的,Linux 系统将启动引导程序的程序代码运行与配置数据加载分为以下 2 个阶段:
其中,与 GRUB(启动引导程序)相关的配置文件,都放置在 /boot/grub 目录中。我们来看看这个目录下到底有哪些文件。
[root@CncLucZK ~]# ll /boot/grub2
total 32
#GRUB中硬盘的设备文件名与系统的设备文件名的对应文件
-rw-r--r--. 1 root root 64 Nov 26 2019 device.map
#ext2/ext3文件系统的Stage 1.5文件
-rw-r--r--. 1 root root 14K 4月 10 21:49 e2fs_stage1_5
#FAT文件系统的Stage 1文件
-rw-r--r--. 1 root root 13K 4月 10 21:49 fat_stage1_5
#FFS文件系统的Stage 1.5文件
-rw-r--r--. 1 root root 12K 4月 10 21:49 ffs_stage1_5
drwxr-xr-x. 2 root root 4096 Nov 26 2019 fonts
#GRUB的配置文件
-rw-r--r--. 1 root root 4630 Mar 9 2020 grub.cfg
-rw-r--r--. 1 root root 1024 Nov 26 2019 grubenv
drwxr-xr-x. 2 root root 12288 Nov 26 2019 i386-pc
#iso9660文件系统的Stage 1.5文件
-rw-r--r--. 1 root root 12K 4 月 10 21:49 iso9660_stage1_5
#JFS文件系统的Stage 1.5文件
-rw-r--r--. 1 root root 13K 4月 10 21:49 jfs_stage1_5
#GRUB的配置文件。和grub.conf是软链接,所以两个文件修改哪一个都可以
Irwxrwxrwx. 1 root root 11 4月 10 21:49 menu.lst ->./grub.conf
#MINIX文件系统的Stage 1.5文件
-rw-r--r--. 1 root root 12K 4 月 10 21:49 minix_stage1_5
#ReiserFS文件系统的Stage 1.5文件
-rw-r--r--. 1 root root 15K 4 月 10 21:49 reiserfs_stage1_5
#系统启动时,GRUB程序的背景图像
-rw-r--r--. 1 root root 1.4K 11 月 15 2010 splash.xpm.gz
#安装到引导扇区中的Stage 1的备份文件
-rw-r--r--. 1 root root 512 4月 10 21:49 stage1
#Stage2的备份文件
-rw-r--r--. 1 raot root 124K 4月 10 21:49 stage2
#UFS文件系统的Stage 1.
-rw-r--r--. 1 root root 12K 4月 10 21:49 ufs2_stage1_5
#vstafs文件系统的Stage 1.5文件
-rw-r--r--. 1 root root 12K 4 月 10 21:49 vstafs_stage1_5
#XFS文件系统的Stage 1.5文件
-rw-r--r--. 1 root root 14K 4月 10 21:49 xfs_stage1_5
Linux 系统分区的设备文件名的命名是有严格规范的,类似于 /dev/sda1 代表第一块 SCSI 硬盘的第一个主分区。但是在 GRUB 中分区的表示方法却完全不同,采用了类似 hd(0,0) 的方式来表示分区。
其实也很好理解,其中:
也就是说,hd(0,0) 代表的是第一块硬盘的第一个分区,和 Linux 系统中 /dev/sda1 的含义类似,只是不再区分是 SCSI 硬盘还是 IDE 硬盘。我们说明一下 Linux 系统对分区的描述和 GRUB 中对硬盘的描述。
硬 盘 | 分 区 | Linux中的设备文件名 | GRUB中的设备文件名 |
---|---|---|---|
第一块 SCSI 硬盘 | 第一个主分区 | /dev/sda1 | hd(0,0) |
第二个主分区 | /dev/sda2 | hd(0,1) | hd(0,1) |
扩展分区 | /dev/sda3 | hd(0,2) | hd(0,2) |
第一个逻辑分区 | /dev/sda5 | hd(0,4) | hd(0,4) |
第二块 SCSI 硬盘 | 第一个主分区 | /dev/sdb1 | hd(1,0) |
第二个主分区 | /dev/sdb2 | hd(1,1) | hd(1,1) |
扩展分区 | /dev/sdb3 | hd(1,2) | hd(1,2) |
第一个逻辑分区 | /dev/sdb5 | hd(1,4) | hd(1,4) |
[root@CncLucZK ~]# vi /boot/grub/grub.conf
default=0
timeout=5
splashimage=(hd0,0)/grub/splash.xpm.gz
hiddenmenu
#以上为GRUB的整体设置
title
CentOS (2.6.32-279.el6.i686)
root (hdO,0)
kernel /vmlinuz-2.6.32-279.el6.i686 ro root=OOID=b9a7ala8-767f-4a87-8a2b-a535edb362c9 rd_NO_LUKS KEYBOARDTYPE=pc KEYTABLE=us rd_NO_MD crashkernel= auto LANG=zh_CN.UTF-8 rd_NO_LVM rd_NO_DM rhgb quiet
initrd /initramfs-2.6.32-279.el6.i686.img
这个文件的内容可以分成两部分:前 4 行为 GRUB 的整体设置;title 以下 4 行为要启动的 CentOS 系统的具体配置。这里只安装了一个系统,如果多系统并存,那么每个系统都会有类似的 title 行存在(不一定都是 4 行)。
我们先看整体设置:
再来介绍 CentOS 系统的具体配置:
査询分区的 UUID 最简单的办法就查询 /ec/fstab 文件。命令如下:
[root@CncLucZK ~]# cat /etc/fstab
#
# /etc/fstab
# Created by anaconda on Tue Nov 26 02:11:36 2019
#
# Accessible filesystems, by reference, are maintained under '/dev/disk/'.
# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info.
#
# After editing this file, run 'systemctl daemon-reload' to update systemd
# units generated from this file.
#
UUID=b9a7a1a8-767f-4a87-8a2b-a535edb362c9 / ext4 defaults 1 1
/www/swap swap swap defaults 0 0
可以看到"/“分区的 UUID 和 kernel 行中的 UUID 是匹配的。注意一下 grep 后的”/“,在”/"后是有空格的。
以下禁用都只是在启动过程中禁用,是为了加速系统启动的:
除了以上这样,命令输出信息中还包含以下内容:
GRUB的配置文件的内容就是这样的,主要是 kernel 行较为复杂。不过,在这个 /boot/gmb/grub.conf 配置文件中,只启动了一个 Linux 系统。如果在 Linux 服务器中 既安装了 Linux 系统,又安装了 Windows 系统,那么 GRUB 的配置文件又是什么样子的呢?
每个系统都是用 title 字段来表示的,如果在服务器中又多了一个 Windows 系统,那么在 GRUB 的配置文件中只不过就是多了一个 title 字段而已。不过要注意,我们一般建议先安装 Windows 系统,后安装 Linux 系统。原因是 Windows 系统的启动引导程序无法把启动过程转交到 Linux 系统的 GRUB 中,自然就不能启动 Linux 系统了。如果我们后安装 Linux 系统,GRUB 就会安装到 MBR 中,覆盖 Windows 系统的启动引导程序。而 GRUB 是可以把启动过程转交到 Windows 系统的启动引导程序中的,所以 Windows 系统和 Linux 系统都可以顺利启动。
当然,如果真的是后安装 Windows 系统,则也可以通过手工再安装一次 GRUB 来覆盖 MBR 中的 Windows 系统的启动引导程序
查看Windows 和 Linux 双系统并存的 GRUB 的配置文件是什么样子的。命令如下:
[root@CncLucZK ~]#vi /boot/grub/grub.conf
default:0
timeout=-1
splashimage=(hd0,0)/grub/splash.xpm.gz
hiddenmenu
title WinXp
rootnoverify (hd0,0)
#指定Windows XP的启动分区。是第一块硬盘的第一个分区
#rootnoverify是不检测此分区的意思
makeactive
#设定分区为激活状态
chainloader +1
#把启动过程转交给此分区的第一个扇区
title CentOS (2.6.32-279.el6.i686)
root (hd0,5)
#Linux系统的/boot分区安装到了第一块硬盘的第六个分区中
kemel/vmlinuz-2.6.32-279.el6.i686 ro
root=UUID=23e5c9d6-77a8-403a-8c0e2bfeffcab5ef rd_NO_LUKS KEYBOARDTYPE=pc KEYTABLE=us rd_NO_MD crashkernel=auto LANG=zh_CN.UTF-8 rd_NO_LVM rd_NO_DM rhgb quiet
initrd/initramfs-2.6.32-279.el6.i686.img
参考文献:
Linux启动引导程序(GRUB)加载内核的过程