按照Linux系统从打开电源到进入系统的顺序,整个启动过程可分为以下阶段。
- BIOS阶段,Ubuntu的启动过程-CSDN博客
- 引导程序阶段,本文讲解这一阶段
- 内核阶段
- 进入系统
在介绍引导程序之前,首先简单地了解一下硬盘的构造。硬盘的构造比较复杂,但是存储数据的部分是由多个类似于CD的盘片堆叠而成的,盘片正反两面都可以记录数据。每个盘片被分成许多扇形的区域,称为扇区。通常情况下,一个扇区的大小为512字节。盘片以中心为圆心,不同半径的同心圆称为磁道。不同盘片相同半径的磁道所组成的圆柱称为柱面。
启动设备的0磁道0柱面1扇区称为引导扇区。引导扇区中包含两个部分:第1部分为主引导记录,即通常所说的MBR,大小为446字节;第2部分为磁盘分区表,即通常所说的DPT,大小为64字节。DPT中每个磁盘分区项需要占用16字节来描述,所以最多可以描述4个分区,这就是一个磁盘最多包含4个基本分区的原因。最后2字节为十六进制的55AA,这2字节是结束标志。如果某个磁盘该位置的值不为55AA,则表示该磁盘不含有MBR,即不可以从该磁盘启动计算机。
引导程序是指用来加载操作系统的程序。引导程序通常分为两部分,第一部分就是前面所讲的主引导记录。主引导记录不是直接跟操作系统打交道,而是用来加载第二部分的引导程序。第二部分的引导程序可以位于磁盘上的其他分区,常见的有NTLDR、BOOTMGR以及GNU GRUB等。
注意:BIOS位于主板上的EEPROM或者闪存内。而引导程序包括MBR、NTLDR以及GRUB,位于磁盘上。
GNU GRUB是目前绝大部分Linux发行版的引导程序。在启动的时候,GRUB会显示一个菜单列表以供用户选项,对于Ubuntu 22.04版本,需要在启动时按Esc键和Shift键才能进入。不同版本的Linux有不同的按键进入方式,如图7-1所示。
用户可以通过上下箭头键来选择需要的菜单项,按Enter键即可引导操作系统。
此外,用户可以在图7-1所示的界面中按c键,进入GRUB的命令行界面,如图7-2所示。
GRUB提供了非常多的命令,用户可以通过help命令查看,在此只介绍以下几个命令。
- search:通过文件或者卷标搜索设备。通过--set选项可以把搜索到的第一个设备赋给指定的环境变量,--file选项可以指定搜索条件为文件,--label选项可以指定搜索条件为文件系统卷标,--fs-uuid选项可以指定搜索条件为文件系统的UUID。
- linux:加载指定的Linux内核。该命令只接受一个文件名参数,其他的参数将作为内核参数。
- initrd:加载initrd镜像文件。initrd镜像文件一般被用来临时引导系统到实际内核vmlinuz能够接管并继续引导的状态。
- boot:引导通过Linux命令加载的系统内核。
为了能够使读者深入理解Linux的引导过程,下面介绍通过命令行手动引导Ubuntu。
注意:参数root会因系统硬盘分区的不同而有差异。
(1)设置root环境变量,指定根设备,命令如下:
grub> ls /boot/vmlinuz*
在上面的命令中,vmlinuz为压缩后的Linux系统内核。在引导过程中,该内核会自动解压并引导。root为GRUB的环境变量,用来指定根设备。
(2)加载Linux系统内核,命令如下:
grub> linux /vmlinuz root=/dev/sda3
在上面的命令中,/vmlinuz为内核的绝对路径,root=/dev/sda3为传递给内核的参数,用来指定根分区。
实际上,Linux内核位于/boot目录中,而且同时存在多个内核文件,如下所示:
liu@ubuntu:~$ ls -l /boot/vm*
-rw-r--r-- 1 root root 7567136 6月 17 08:41 /boot/vmlinuz-4.10.0-19-generic
-rw------- 1 root root 7575312 6月 8 18:12 /boot/vmlinuz-4.10.0-24-generic
-rw------- 1 root root 7575312 6月 27 00:09 /boot/vmlinuz-4.10.0-26-generic
…
在上面的输出结果中,存在3个不同版本的内核。而/vmlinuz是一个符号链接,指向/boot目录中的一个内核文件,例如下面的/vmlinuz指向/boot/vmlinuz-4.10.0-26-generic:
liu@ubuntu:~$ ls -l /boot/vmlinuz
lrwxrwxrwx 1 root root 30 7月 1 09:05 /vmlinuz -> boot/vmlinuz-4.10.0-26-generic
用户可以通过linux命令直接加载/boot目录中的某个特定的内核,而不是通过/vmlinuz这个符号链接。
(3)加载initrd镜像文件,命令如下:
grub> initrd /boot/initrd.img
其中,/initrd为initrd镜像文件的绝对路径,其文件的扩展名为.img。该步骤是可选的,如果当前操作系统不使用initrd镜像文件,则省略该步骤。在某些情况下,不使用initrd镜像文件会无法找到根分区。
同样,initrd镜像文件也位于/boot目录中,一个系统中也可以存在多个不同版本的initrd镜像文件,如下所示:
liu@ubuntu:~$ ls -l /boot/ini*
-rw-r--r-- 1 root root 42978621 7月 12 22:36 /boot/initrd.img-4.10.0-19-generic
-rw-r--r-- 1 root root 42977623 7月 12 22:36 /boot/initrd.img-4.10.0-24-generic
-rw-r--r-- 1 root root 42998349 7月 12 22:36 /boot/initrd.img-4.10.0-26-generic
initrd镜像文件的版本必须与vmlinuz内核文件的版本相匹配,否则会引导失败。/initrd也是一个指向/boot目录中的某个镜像文件的符号链接,如下所示:
liu@ubuntu:~$ ls -l /initrd.img
lrwxrwxrwx 1 root root 33 7月 1 09:05 /initrd.img -> boot/initrd.img-4.10.0-26-generic
(4)引导内核。命令如下:
grub> boot
注意:initrd镜像文件必须在内核加载完成之后加载,即上面的步骤(2)和(3)不可以颠倒。
本文节选自《Ubuntu Linux系统管理与运维实战》,获出版社和作者授权发布。
《Ubuntu Linux系统管理与运维实战(Linux技术丛书)》(张春晓,肖志健)【摘要 书评 试读】- 京东图书 (jd.com)