3. 引导加载程序(Grub2):Grub2配置文件解析、菜单选择、内核与initramfs加载
Grub2(GRand Unified Bootloader version 2)是现代Linux发行版的标准引导加载程序。它负责在BIOS/UEFI完成硬件自检后,接管系统控制权,加载内核与initramfs到内存,并将控制权移交给内核。理解Grub2的配置文件结构、菜单选择逻辑以及内核加载过程,是排查启动故障的核心能力。
3.1 Grub2配置文件层次与解析
Grub2的配置体系采用“主配置+动态生成”的架构,主要涉及以下关键文件:
| 文件路径 | 作用 | 是否手动编辑 |
|---|---|---|
/boot/grub2/grub.cfg |
最终生成的引导菜单配置文件,包含所有菜单项和启动参数 | 禁止手动编辑(由grub2-mkconfig生成) |
/etc/default/grub |
主配置文件,定义全局默认参数(超时时间、默认菜单项、内核命令行参数等) | 是 |
/etc/grub.d/ |
脚本目录,包含00_header、10_linux、30_os-prober等片段脚本 |
通常不直接编辑,可添加自定义脚本 |
核心原则: 永远不要直接编辑
/boot/grub2/grub.cfg。正确的做法是修改 /etc/default/grub 或 /etc/grub.d/ 下的脚本,然后运行 grub2-mkconfig -o /boot/grub2/grub.cfg 重新生成。
3.1.1 /etc/default/grub 关键参数
该文件是Grub2行为的“控制面板”,以下是最常调整的参数:
# /etc/default/grub 典型内容
GRUB_TIMEOUT=5 # 菜单等待秒数,设为0则直接启动默认项
GRUB_DEFAULT=saved # 默认启动项,可以是数字索引或菜单项名称
GRUB_DISABLE_RECOVERY="true" # 是否禁用恢复模式菜单项
GRUB_CMDLINE_LINUX="rhgb quiet" # 传递给所有Linux内核的通用命令行参数
GRUB_CMDLINE_LINUX_DEFAULT="" # 仅传递给默认内核的参数
GRUB_TERMINAL_OUTPUT="console" # 输出终端类型
GRUB_DISABLE_OS_PROBER="false" # 是否禁用探测其他操作系统
故障排查要点: 如果系统无法启动,可以在Grub菜单界面按
e 键编辑当前启动项,临时修改 GRUB_CMDLINE_LINUX 行。例如,移除 rhgb quiet 可以查看详细启动日志;添加 single 或 1 可以进入单用户模式进行修复。
3.2 Grub2菜单选择与交互流程
Grub2的菜单选择过程是一个典型的“倒计时+用户干预”模型。理解其内部状态转换对排查“无法进入系统”或“自动进入救援模式”等问题至关重要。
3.3 内核与initramfs加载机制
当用户选择(或倒计时默认选中)一个菜单项后,Grub2会执行以下关键步骤:
- 解析菜单项配置: 从
grub.cfg中提取linux和initrd指令对应的文件路径及参数。 - 加载内核(vmlinuz): 将压缩后的内核映像从磁盘(
/boot分区)读取到内存中。Grub2支持从ext2/3/4、xfs、btrfs、lvm等文件系统读取。 - 加载initramfs: 将初始内存文件系统(initramfs)加载到内存中。initramfs是一个压缩的cpio归档,包含必要的内核模块和启动脚本。
- 传递控制权: Grub2设置好内核启动参数(通过
linux行传递),然后执行boot指令,将CPU控制权交给内核入口点。
3.3.1 典型的菜单项配置
以下是从 /boot/grub2/grub.cfg 中截取的一个典型菜单项:
menuentry 'CentOS Linux (5.14.0-427.el9.x86_64) 9 (Stream)' --class centos --class gnu-linux --class gnu --class os {
load_video
set gfxpayload=keep
insmod gzio
insmod part_gpt
insmod ext2
set root='hd0,gpt2'
if [ x$feature_platform_search_hint = xy ]; then
search --no-floppy --fs-uuid --set=root --hint-bios=hd0,gpt2 --hint-efi=hd0,gpt2 --hint-baremetal=ahci0,gpt2 12345678-1234-1234-1234-123456789abc
else
search --no-floppy --fs-uuid --set=root 12345678-1234-1234-1234-123456789abc
fi
linux /vmlinuz-5.14.0-427.el9.x86_64 root=/dev/mapper/rl-root ro crashkernel=auto resume=/dev/mapper/rl-swap rd.lvm.lv=rl/root rd.lvm.lv=rl/swap rhgb quiet
initrd /initramfs-5.14.0-427.el9.x86_64.img
}
关键字段解读:
set root='hd0,gpt2':指定包含/boot目录的设备为第一块硬盘的第二个GPT分区。linux行:指定内核映像路径,以及传递给内核的命令行参数(如root=指定根文件系统设备)。initrd行:指定initramfs映像路径。Grub2会将其加载到内存中,内核启动后会解压并挂载它作为临时根文件系统。
3.4 常见故障与排查方法
| 故障现象 | 可能原因 | 排查与修复 |
|---|---|---|
| Grub菜单不显示,直接进入救援模式 | GRUB_TIMEOUT=0 或 grub.cfg 损坏 |
启动时按住 Shift(BIOS)或 Esc(UEFI)强制显示菜单;使用Live CD修复 |
| 选择内核后黑屏或卡住 | 内核参数错误(如 root= 指向错误设备) |
按 e 编辑启动项,检查 linux 行参数;移除 rhgb quiet 查看详细错误 |
提示 File not found |
grub.cfg 中指定的内核或initramfs路径错误,或 /boot 分区损坏 |
进入Grub命令行,使用 ls 命令探测分区,手动指定正确的文件路径 |
| 升级内核后旧内核无法启动 | 新内核模块与initramfs不匹配 | 在Grub菜单选择旧内核启动;重新生成initramfs:dracut -f |
3.4.1 Grub2命令行救援示例
当 grub.cfg 完全损坏时,可以手动引导系统:
# 1. 在Grub提示符下,列出所有分区
grub> ls
(hd0) (hd0,gpt1) (hd0,gpt2) (hd0,gpt3)
# 2. 找到包含 /boot 的分区(通常为 ext4 或 xfs 格式)
grub> ls (hd0,gpt2)/
lost+found/ vmlinuz-5.14.0-427.el9.x86_64 initramfs-5.14.0-427.el9.x86_64.img grub2/
# 3. 设置根分区
grub> set root=(hd0,gpt2)
# 4. 加载内核(注意:路径相对于 root 分区)
grub> linux /vmlinuz-5.14.0-427.el9.x86_64 root=/dev/mapper/rl-root ro
# 5. 加载 initramfs
grub> initrd /initramfs-5.14.0-427.el9.x86_64.img
# 6. 启动
grub> boot
重要提示: 手动引导成功后,务必立即运行
grub2-mkconfig -o /boot/grub2/grub.cfg 重新生成配置文件,否则下次重启仍会进入Grub命令行。