2、GRUB 配置基础:GRUB 的作用、配置文件位置与命令行模式

说实话,很多刚入行的朋友觉得 GRUB 就是个「选系统的菜单」。嗯,这么理解也没错,但太浅了。我做了这么多年系统底层,GRUB 其实是操作系统启动的「总开关」。你想想看,从按下电源键到内核跑起来,中间这段路全靠 GRUB 撑着。

2.1 GRUB 到底在干什么?

GRUB(GRand Unified Bootloader)的核心任务就三件:

  • 加载内核 —— 把 vmlinuz 从磁盘读到内存
  • 传递参数 —— 告诉内核怎么初始化硬件、挂载根文件系统
  • 提供交互 —— 让你在启动前临时改参数、选内核版本

我个人习惯把 GRUB 比作「机场的登机桥」—— 你(内核)得先通过它才能登上飞机(硬件系统)。没有它,操作系统根本跑不起来。

关键认知: GRUB 是 BIOS/UEFI 之后、内核之前唯一能干预启动流程的环节。一旦内核开始初始化,你再想改启动参数就晚了。

2.2 配置文件在哪?长什么样?

主配置文件只有一个:/etc/default/grub。注意,不是 /boot/grub/grub.cfg!那个是自动生成的,你直接改它会被覆盖掉。

我见过不少新手直接去改 grub.cfg,结果下次 update-grub 一跑,改的东西全没了。嗯,这里要记住:永远只改 /etc/default/grub。

一个典型的配置文件长这样:

# /etc/default/grub 示例
GRUB_DEFAULT=0
GRUB_TIMEOUT=5
GRUB_DISTRIBUTOR=`lsb_release -i -s 2> /dev/null || echo Debian`
GRUB_CMDLINE_LINUX_DEFAULT="quiet splash"
GRUB_CMDLINE_LINUX=""

我来拆开讲讲每个参数是干嘛的:

参数 含义 我常用的值
GRUB_DEFAULT 默认启动项(0 表示第一个) 0 或 "Advanced options for Ubuntu>Ubuntu, with Linux 5.15.0-91-generic"
GRUB_TIMEOUT 菜单等待秒数 5(生产环境我设 2)
GRUB_CMDLINE_LINUX_DEFAULT 正常启动时传给内核的参数 "quiet splash" 或 "console=tty0 console=ttyS0,115200"
GRUB_CMDLINE_LINUX 所有模式(含恢复模式)都传的参数 "net.ifnames=0 biosdevname=0"

我的小技巧: 调试内核崩溃时,把 GRUB_CMDLINE_LINUX_DEFAULT 里的 quiet splash 去掉,改成 "earlyprintk debug ignore_loglevel"。这样启动时内核会往控制台吐大量调试信息,定位问题快得多。

2.3 改完配置怎么生效?

改完 /etc/default/grub 后,必须跑一条命令:

# 在 Debian/Ubuntu 上
sudo update-grub

# 在 RHEL/CentOS 上
sudo grub2-mkconfig -o /boot/grub2/grub.cfg

这条命令会读取 /etc/default/grub,扫描 /boot 下的内核文件,然后生成最终的 grub.cfg。我曾经在升级内核后忘了跑这条命令,结果重启后还是旧内核…… 嗯,从那以后我每次改完配置都条件反射地敲一遍 update-grub。

2.4 GRUB 命令行模式 —— 最后的救命稻草

系统起不来的时候,GRUB 命令行就是你的急救箱。在 GRUB 菜单界面按 c 键就能进去。

说白了,这就是一个微型 shell,支持文件浏览、内核加载、内存操作。常用的命令就这几个:

  • ls —— 列出所有磁盘分区(比如 (hd0,msdos1)、(hd0,gpt2))
  • ls (hd0,1)/ —— 查看分区根目录
  • set root=(hd0,1) —— 设置根分区
  • linux /vmlinuz-xxx root=/dev/sda1 —— 手动加载内核并传参
  • initrd /initrd.img-xxx —— 加载初始内存盘
  • boot —— 启动

我遇到过最典型的场景:升级内核后新内核有 bug,系统启动到一半就 panic。这时候在 GRUB 菜单按 c,手动指定旧内核启动:

grub> set root=(hd0,1)
grub> linux /vmlinuz-5.15.0-91-generic root=/dev/sda1 ro
grub> initrd /initrd.img-5.15.0-91-generic
grub> boot

系统就起来了。然后你再用包管理器把有问题的内核删掉,重新 update-grub 就行。

注意: GRUB 命令行里没有 Tab 补全(至少老版本没有),路径必须手敲。分区编号从 1 开始,不是 0。比如第一块硬盘的第一个分区是 (hd0,1),不是 (hd0,0)。

2.5 知识体系总览

下面这张图把 GRUB 配置的核心脉络串起来了,你可以对照着看:

GRUB 配置核心知识体系 GRUB 配置核心知识体系 GRUB 核心作用 加载内核与 initrd 传递启动参数 提供交互菜单 配置文件 /etc/default/grub 生成 grub.cfg(update-grub) GRUB 命令行模式(按 c 进入) ls / set root linux / initrd boot(手动启动内核) 避坑提醒 只改 /etc/default/grub 不要直接编辑 grub.cfg

从这张图能看出来,GRUB 的配置链路其实很清晰:作用 → 配置文件 → 生成引导菜单 / 进入命令行。你只要把这三个环节搞明白,GRUB 这块就算拿下了。

2.6 几个实战经验

  • 双系统用户注意: GRUB_DEFAULT=saved 可以记住你上次选的是哪个系统,下次自动选中。我笔记本上就这么配的,省得每次都要手动切。
  • 调试内核参数: 在 GRUB 菜单选中条目后按 e 键,可以临时编辑启动参数,按 Ctrl+X 或 F10 启动。这个只对当前这次启动有效,适合测试新参数。
  • 隐藏菜单: 生产环境服务器我一般设 GRUB_TIMEOUT=0 并注释掉 GRUB_HIDDEN_TIMEOUT,这样启动时直接进系统,不显示菜单。需要改参数时按住 Shift 键就能强制显示。

嗯,GRUB 配置这块其实不难,但细节多。你只要记住「配置文件只有一个、改完要跑命令、命令行是救命稻草」这三条,基本不会出大问题。