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的菜单选择过程是一个典型的“倒计时+用户干预”模型。理解其内部状态转换对排查“无法进入系统”或“自动进入救援模式”等问题至关重要。

Grub2 菜单选择与内核加载流程 BIOS/UEFI 阶段 Grub2 核心加载 读取 grub.cfg 用户按键? 是 显示交互菜单 等待用户选择 否(倒计时结束) 加载 vmlinuz + initramfs 到内存指定位置 说明:按 e 键编辑启动参数;按 c 键进入命令行;按 Esc 键返回上级菜单

3.3 内核与initramfs加载机制

当用户选择(或倒计时默认选中)一个菜单项后,Grub2会执行以下关键步骤:

  1. 解析菜单项配置: 从 grub.cfg 中提取 linux 和 initrd 指令对应的文件路径及参数。
  2. 加载内核(vmlinuz): 将压缩后的内核映像从磁盘(/boot 分区)读取到内存中。Grub2支持从 ext2/3/4、xfs、btrfs、lvm 等文件系统读取。
  3. 加载initramfs: 将初始内存文件系统(initramfs)加载到内存中。initramfs是一个压缩的cpio归档,包含必要的内核模块和启动脚本。
  4. 传递控制权: 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命令行。

3.5 本章小结