4. GRUB2 基础配置语法:核心命令与启动流程

GRUB2 的配置核心位于 /boot/grub/grub.cfg 文件(或由 grub-mkconfig 生成的类似文件)。本章将深入剖析构成该文件的五个基础语法元素:set、menuentry、insmod、linux/initrd 以及 boot。掌握这些命令是定制启动菜单和调试内核加载的基石。

💡 核心认知:GRUB2 的配置文件本质上是一个脚本。set 用于定义变量,menuentry 定义菜单项,insmod 动态加载驱动,linux/initrd 指定内核与内存盘,boot 则启动所选条目。理解它们的执行顺序至关重要。

4.1 set 命令:配置变量与环境

set 命令用于在 GRUB2 运行时环境中设置变量。这些变量控制着从默认启动项到图形分辨率的所有行为。

变量名 作用 典型值示例
default 设置默认启动的菜单项索引(从 0 开始)或名称 0 或 "Ubuntu"
timeout 自动启动前的等待秒数(-1 为无限等待) 5
gfxmode 设置图形模式下的分辨率 1920x1080
root 指定根设备(通常为包含内核的分区) (hd0,msdos1)
prefix 指定 GRUB2 自身文件(如模块)的路径 (hd0,msdos1)/boot/grub
# 设置默认启动项为第一个菜单项
set default=0

# 设置超时时间为 10 秒
set timeout=10

# 设置图形分辨率为 1920x1080
set gfxmode=1920x1080

# 设置根分区为第一块硬盘的第一个 MBR 分区
set root=(hd0,msdos1)
⚠️ 避坑指南:变量名是大小写敏感的。set Timeout=5 不会生效,必须使用小写的 timeout。此外,set 命令在 menuentry 块内外均可使用,但作用域不同(全局 vs 局部)。
set 命令变量作用域 全局作用域 (grub.cfg 顶层) set default=0 set timeout=5 局部作用域 (menuentry 块内) set root=(hd0,gpt2) set gfxpayload=keep 说明:局部变量会覆盖全局变量,仅在当前 menuentry 块内生效。

4.2 menuentry 块:定义启动菜单项

menuentry 是 GRUB2 配置的核心结构,用于定义一个在启动菜单中可见的条目。其基本语法如下:

menuentry '条目名称' [--class 类别] [--id 标识符] {
    # 在此块内编写启动命令
    ...
}
  • 条目名称:在菜单中显示给用户的文本,必须用单引号包裹。
  • --class:用于指定条目的类别(如 linux、windows),主要用于主题图标匹配。
  • --id:为条目设置一个唯一标识符,便于通过 grub-set-default 等工具引用。
menuentry 'Ubuntu 22.04 LTS (Kernel 5.15)' --class ubuntu --class gnu-linux --class os --id 'ubuntu-5.15' {
    # 内部命令序列
    set root=(hd0,msdos1)
    linux /vmlinuz-5.15.0-91-generic root=/dev/sda1 ro quiet splash
    initrd /initrd.img-5.15.0-91-generic
    boot
}
📌 关键点:一个 menuentry 块内部通常包含 set、linux、initrd 和 boot 命令。块内的 set 命令仅影响该条目,不会污染全局环境。

4.3 insmod 命令:动态加载模块

GRUB2 采用模块化设计,核心功能(如文件系统支持、视频驱动、分区表解析)都通过模块实现。insmod 命令用于在运行时加载这些模块。

模块名 功能 使用场景
ext2 支持 ext2/ext3/ext4 文件系统 从 Linux 根分区读取内核
ntfs 支持 NTFS 文件系统 从 Windows 分区读取文件
part_gpt 支持 GPT 分区表 识别 GPT 分区的硬盘
all_video 加载所有视频驱动 确保图形界面正常显示
lvm 支持 LVM 逻辑卷 从 LVM 卷启动系统
# 加载必要的模块
insmod part_gpt          # 支持 GPT 分区表
insmod ext2              # 支持 ext4 文件系统
insmod all_video         # 加载所有视频驱动,确保图形界面正常
insmod font              # 加载字体模块,用于显示中文
⚠️ 常见错误:如果忘记加载 ext2 模块,GRUB2 将无法读取 ext4 分区上的内核文件,导致 file not found 错误。通常,insmod 命令应放在 menuentry 块的开头或全局配置中。
insmod 模块加载流程 GRUB2 启动 insmod part_gpt 识别 GPT 分区表 成功读取 /vmlinuz 说明:模块加载顺序至关重要,必须先加载分区模块,才能识别分区并读取文件。

4.4 linux / initrd 命令:指定内核与内存盘

这两个命令是启动 Linux 系统的核心:

  • linux:指定内核映像文件的路径,并传递内核启动参数。
  • initrd:指定初始内存盘(initramfs)的路径,该文件包含早期启动所需的驱动和脚本。
# 指定内核文件路径,并传递参数
linux /boot/vmlinuz-5.15.0-91-generic root=/dev/sda1 ro quiet splash

# 指定 initrd 文件路径
initrd /boot/initrd.img-5.15.0-91-generic
参数 含义 说明
root=/dev/sda1 指定根文件系统设备 内核挂载根分区的位置
ro 以只读方式挂载根文件系统 启动初期进行文件系统检查
quiet 减少内核启动时的输出信息 使启动界面更简洁
splash 显示启动画面(splash screen) 配合 Plymouth 使用
💡 进阶技巧:可以使用 linux 命令传递 single 参数进入单用户模式(救援模式),或传递 nomodeset 参数解决显卡驱动问题。

4.5 boot 命令:启动执行

boot 命令是 menuentry 块的最后一步。它告诉 GRUB2 开始执行之前由 linux 和 initrd 命令加载的内核与内存盘。如果没有 boot 命令,GRUB2 将停留在菜单界面,不会实际启动系统。

menuentry 'My Custom Linux' {
    insmod ext2
    set root=(hd0,msdos1)
    linux /vmlinuz root=/dev/sda1 ro
    initrd /initrd.img
    boot   # 必须存在,否则不会启动
}
⚠️ 常见错误:初学者经常忘记在 menuentry 块末尾添加 boot 命令。如果菜单项配置正确但选择后无反应,请检查是否遗漏了 boot。

4.6 完整示例:一个典型的启动条目

将上述所有命令组合起来,形成一个完整的、可工作的启动条目:

menuentry 'Ubuntu 22.04 (Kernel 5.15)' --class ubuntu --id 'ubuntu-main' {
    # 1. 加载必要模块
    insmod part_gpt
    insmod ext2
    insmod all_video

    # 2. 设置根设备
    set root=(hd0,gpt2)

    # 3. 指定内核与参数
    linux /vmlinuz-5.15.0-91-generic root=/dev/nvme0n1p2 ro quiet splash

    # 4. 指定 initrd
    initrd /initrd.img-5.15.0-91-generic

    # 5. 启动
    boot
}
GRUB2 启动条目完整流程 menuentry 块开始 insmod 加载模块 set root 设置根设备 linux 指定内核与参数 initrd 指定内存盘 boot 启动执行 说明:此流程展示了从菜单项定义到内核启动的完整命令执行顺序。
📌 本章小结:set 命令配置环境变量,menuentry 定义菜单项,insmod 动态加载模块,linux/initrd 指定内核与内存盘,boot 启动系统。这五个命令构成了 GRUB2 配置的基石,熟练掌握它们将为你后续进行主题定制和高级启动配置打下坚实基础。