Linux学习-70-启动引导程序(GRUB)加载内核的过程

114 篇文章 8 订阅
16.8 启动引导程序(GRUB)加载内核的过程
  • 启动引导程序(Boot Loader,也就是 GRUB)会在启动过程中加载内核,之后内核才能取代 BIOS 接管启动过程。如果没有启动引导程序,那么内核是不能被加载的。在 CentOS 6.x 中,启动引导程序默认是 GRUB,GRUB 是现在最为流行的启动引导程序,我们也用 GRUB 来说明启动引导程序的作用, initramfs 这个虚拟文件系统也是要靠启动引导程序调用的。

  • 早期的 LILO 引导程序已经不是很常见了,GRUB 相比来讲有很多优势,主要有:

    • 支持更多的文件系统。
    • GRUB 的主程序可以直接在文件系统中查找内核文件。
    • 在系统启动时,可以利用 GRUB 的交互界面编辑和修改启动选项。
    • 可以动态修改 GRUB 的配置文件,这样在修改配置文件之后不需要重新安装 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,然后根据配置文件中的定义,加载内核和虚拟文件系统。接下来内核就可以接管启动过程,继续自检与加载硬件模块了。

16.9 /boot/grub/目录分析
  • BIOS 在进行完成系统检测之后,就会找到第一个可以启动的设备,并读取该设备的 MBR(主引导记录)以及加载 MBR 中的 boot loader(启动引导程序),这个启动引导程序可以具有菜单功能、直接加载核心文件以及控制权移交的功能等。系统必须要借助启动引导程序,才能加载内核,那么问题来了,MBR 只是占据整个设备的第一个扇区中,其大小也就只有 446 字节而已,但启动引导程序功能这么强大,光程序代码即配置数据就肯定不止 446 字节,是怎么安装的吗?

  • 是这样的,Linux 系统将启动引导程序的程序代码运行与配置数据加载分为以下 2 个阶段:

    1. 第一个阶段负责运行启动引导的主程序,该主程序必须要被安装在启动区,或者是 MBR,或者是引导扇区,但我们说过,MBR 的容量实在太小,因此,MBR 或引导扇区通常只安装启动引导程序的最小主程序,并不安装相关的配置数据;
    2. 第二个阶段是为主程序加载配置文件,包括相关的环境参数文件(文件系统定义以及主要配置文件 menu.1st);
  • 其中,与 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
  • 可以看到,这个目录中主要就是 GRUB 的配置文件和各种文件系统的 Stage1.5 文件。不过 GRUB 的配置文件有两个:/boot/grub/grub.conf 和 /boot/grub/menu.lst,这两个配置文件是软链接,所以修改哪一个都可以。
16.10 GRUB磁盘分区表示法
  • Linux 系统分区的设备文件名的命名是有严格规范的,类似于 /dev/sda1 代表第一块 SCSI 硬盘的第一个主分区。但是在 GRUB 中分区的表示方法却完全不同,采用了类似 hd(0,0) 的方式来表示分区。

  • 其实也很好理解,其中:

    • hd 代表硬盘,不再区分是 SCSI 接口硬盘,还是 IDE 接口硬盘,都用 hd 代表;
    • 第一个 0 代表 Linux 系统查找到的第一块硬盘,第二块硬盘为 2,以此类推;
    • 第二个 0 代表这块硬盘的第一个分区,以此类推;
  • 也就是说,hd(0,0) 代表的是第一块硬盘的第一个分区,和 Linux 系统中 /dev/sda1 的含义类似,只是不再区分是 SCSI 硬盘还是 IDE 硬盘。我们说明一下 Linux 系统对分区的描述和 GRUB 中对硬盘的描述。

硬 盘分 区Linux中的设备文件名GRUB中的设备文件名
第一块 SCSI 硬盘第一个主分区/dev/sda1hd(0,0)
第二个主分区/dev/sda2hd(0,1)hd(0,1)
扩展分区/dev/sda3hd(0,2)hd(0,2)
第一个逻辑分区/dev/sda5hd(0,4)hd(0,4)
第二块 SCSI 硬盘第一个主分区/dev/sdb1hd(1,0)
第二个主分区/dev/sdb2hd(1,1)hd(1,1)
扩展分区/dev/sdb3hd(1,2)hd(1,2)
第一个逻辑分区/dev/sdb5hd(1,4)hd(1,4)
  • 在这张表中要注意,逻辑分区不能占用主分区与扩展分区的分区号,所以第一个逻辑分区在 Linux 系统中应该用 /dev/sda5 表示,在 GRUB 中应该用 hd(0,4) 表示,还要注意 GRUB 的表示方式只在 GRUB 的配置文件中生效,一旦离开了 GRUB 的配置文件,就要使用 Linux 中的设备文件名来表示分区了。
16.11 /boot/grub/grub.conf(GRUB配置文件)内容
  • 看看 GRUB 的配置文件 /boot/gmb/grub.conf 中到底写了什么。命令如下:
[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 行)。

  • 我们先看整体设置:

    • default=0:默认启动第一个系统。也就是说,如果在等待时间结束后,用户没有选择进入哪个系统,那么系统会默认进入第一个系统。如果有多系统并存,那么每个系统都会有自己的 title 字段,如果想要默认进入第二个系统,这里就可以设为 default=1。
    • timeout=5:等待时间,默认是 5 秒。也就是在进入系统时,如果 5 秒内用户没有按下任意键,那么系统会进入 default 字段定义的系统。当然,也可以手工修改这个等待时间,如果timeout=0,则不会等待直接进入系统;如果 timeout=-1,则会一直等待用户输入,而不会自动进入系统。
    • splashimage=(hd0,0)/gnjb/splash.xpm.gz:用来指定 GRUB 启动时的背景图像的保存位置。记得 CentOS 6.x 启动时后台的蓝色图像吧,就是这个文件的作用。不过这个文件具体在哪里呢?我们已经说过,hd(0,0) 代表第一块硬盘的第一个分区,而系统在安装时 /boot 分区就是第一个分区,所以这个背景图像的实际位置就是 /boot/gmb/splash.xpm.gz。
    • hiddenmenu:隐藏菜单。启动时默认只能看到读秒,而不能看到菜单。如果想要看到菜单,则需要按任意键。如果注释了这句话,那么启动时就能直接看到菜单了。
  • 再来介绍 CentOS 系统的具体配置:

    1. title CentOS(2.6.32-279.d6.i686):title 就是标题的意思,也就是说,在 title 后面写入的是什么,系统启动时在 GRUB 的启动菜单中看到的就是什么。
    2. root(hd0,0):是指启动程序的保存分区。这里要注意,这个 root 并不是管理员。在系统中,/boot 分区是独立划分的,而且设备文件名为 /dev/sda1,所以在 GRUB 中就被描述为 hd(0,0)。
    3. kernel /vmlinuz-2.6.32-279.el6.i686 ro root=UUID=b9a7a1a8-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。其中:
      • /vmlinuz-2.6.32-279.el6.i686:指定了内核文件的位置,这里的 / 是指 boot 分区。
      • ro:启动时以只读方式挂载根文件系统,这是为了不让启动过程影响磁盘内的文件系统。
      • root=UUID=b9a7a1 a8-767f-4a87-8a2b-a535edb362c9:指定根文件系统的所在位置。这里和以前的Linux版本不太一样了,不再通过分区的设备文件名或卷标号来指定,而是通过分区的 UUID 来指定的。
  • 査询分区的 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 后的”/“,在”/"后是有空格的。

  • 以下禁用都只是在启动过程中禁用,是为了加速系统启动的:

    1. rd_NO_LUKS:禁用 LUKS,LUKS 用于给磁盘加密。
    2. rd_NO_MD:禁用软 RAID。
    3. rd_NO_DM:禁用硬 RAID。
    4. rd_NO_LVM:禁用 LVM。
  • 除了以上这样,命令输出信息中还包含以下内容:

    1. KEYBOARDTYPE=pc KEYTABLE=us:键盘类型。
    2. crashkernel=auto:自动为crashkernel预留内存。
    3. LANG=zh_CN.UTF-8:语言环境。
    4. rhgb:(redhatgraphics boot)用图片来代替启动过程中的文字信息。启动完成之后可以使用dmesg命令来查看这些文字信息。
    5. quiet:隐藏启动信息,只显示重要信息。
    6. initrd/initramfs-2.6.32-279.el6.i686.img:指定了initramfs虚拟文件系统镜像文件的所在位置。
  • GRUB的配置文件的内容就是这样的,主要是 kernel 行较为复杂。不过,在这个 /boot/gmb/grub.conf 配置文件中,只启动了一个 Linux 系统。如果在 Linux 服务器中 既安装了 Linux 系统,又安装了 Windows 系统,那么 GRUB 的配置文件又是什么样子的呢?

16.12 多系统并存的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
  • 配置文件的变化主要是多了 WinXP 这一段。rootnoverify(hd0,0) 字段说明这个分区不检测,同时标称了 Windows 系统的启动分区在第一块硬盘的第一个分区中。也就是 Windows 系统的 C: 盘在第一块硬盘的第一个分区中。chainloader+1 的意思是,GRUB 会把启动过程转交到位于这个分区的第一个扇区(启动扇区)中的引导程序中。
  • 为了实现多系统启动,除 MBR 中可以安装启动引导程序外,每个分区的第一个扇区也可以安装启动引导程序。在这个例子中,Windows 系统的启动引导程序就被安装到了 C: 盘所在分区的启动扇区中,chainloader+1 就是 GRUB 把启动过程交给了 Windows 系统的启动引导程序,所以可以启动 Windows 系统。

参考文献:
Linux启动引导程序(GRUB)加载内核的过程

下一篇:Linux学习-71-GRUB手动安装方法
  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值