Linux 系统启动流程详解:从按下电源到登录界面

说实话,搞运维这么多年,我见过太多启动失败的案例。有一次线上服务器突然起不来,排查了半天,最后发现是 GRUB 配置被误改了。从那以后,我就养成了一个习惯——每次改启动参数前,先备份一份。

要理解启动参数备份为什么重要,你得先搞懂 Linux 是怎么启动的。今天我就带你走一遍完整的启动流程,把每个阶段掰开揉碎了讲清楚。

第一阶段:BIOS 还是 UEFI?

按下电源键后,CPU 会去执行固件里的第一条指令。这个固件,要么是传统的 BIOS,要么是现代的 UEFI。

特性 BIOS UEFI
启动模式 16位实模式 32/64位保护模式
磁盘分区 MBR(主引导记录) GPT(GUID分区表)
最大磁盘 2TB 9.4ZB
启动速度 较慢 较快
安全启动 不支持 支持 Secure Boot

我个人习惯用 UEFI + GPT 的组合。为什么?因为现在服务器磁盘动不动就上 TB,BIOS 的 2TB 限制太难受了。而且 UEFI 的启动管理器更灵活,你可以在 NVRAM 里直接指定启动项,不用像 BIOS 那样去 MBR 里找引导代码。

小提示: 如果你在旧服务器上看到 /boot 分区是单独的,而且用的是 MBR 分区表,那基本就是 BIOS 模式。新机器用 UEFI 的话,会有一个 EFI 系统分区(ESP),挂载在 /boot/efi 下。

第二阶段:GRUB 阶段——启动参数的战场

BIOS/UEFI 加载完引导程序后,控制权就交给了 GRUB。GRUB 分两个阶段:

  1. 第一阶段(boot.img): 写在 MBR 或 GPT 的专用分区里,很小,就 446 字节。它的任务只有一个——加载第二阶段的 core.img。
  2. 第二阶段(core.img + grub.cfg): core.img 里包含了文件系统驱动,能读取 /boot/grub/grub.cfg。这个配置文件里定义了内核路径、initramfs 路径,还有最重要的——内核启动参数。

嗯,这里要注意。grub.cfg 里的启动参数,就是我们做回滚保护要备份的核心对象。比如 quiet splash、root=UUID=xxx、ro 这些,一旦写错,系统就起不来了。

避坑指南: 我曾经手滑把 grub.cfg 里的 root 参数写成了错误的 UUID,重启后直接进了 emergency mode。还好之前备份了 /boot/grub/grub.cfg,用 U 盘进救援模式恢复了一下。从那以后,我每次改 grub.cfg 之前都会 cp 一份到 /root/backup/ 目录下。

第三阶段:内核初始化

GRUB 加载完内核和 initramfs 后,内核就开始干活了。这个过程大致分几步:

  • 解压内核: 内核镜像通常是压缩的,先自解压到内存里。
  • 初始化硬件: 内核会枚举 CPU、内存、PCI 设备、磁盘控制器等。这时候会打印一堆 dmesg 信息。
  • 挂载根文件系统: 内核根据启动参数里的 root= 找到根分区,尝试挂载。如果找不到,就 panic 了。
  • 启动 init 进程: 内核在根文件系统里找 /sbin/init 或 /lib/systemd/systemd,然后启动它。

你想想看,如果启动参数里的 root 指向了错误的设备,或者文件系统损坏,内核在这一步就卡死了。所以备份启动参数,本质上就是在保护内核能找到正确的根文件系统。

第四阶段:init 进程与 systemd 的崛起

传统上,init 进程是 SysV 风格的,按顺序执行 /etc/rc.d/rc.sysinit 和各个运行级别的脚本。但现在,绝大多数 Linux 发行版都换成了 systemd。

systemd 和传统 init 最大的区别是什么?

  • 并行启动: systemd 能同时启动多个服务,速度比串行的 SysV 快得多。
  • 依赖管理: 通过 unit 文件定义依赖关系,比如 network.target 必须在网络服务之前启动。
  • 日志统一: journald 接管了所有日志,用 journalctl 就能查。
  • 快照功能: systemd 支持创建和恢复系统快照,这个在回滚场景下很有用。
核心要点: systemd 的 PID 永远是 1。它是所有用户进程的祖先。如果 systemd 挂了,整个系统就挂了。所以我们在做启动参数备份时,也要考虑 systemd 的配置,比如 /etc/systemd/system/ 下的自定义 unit 文件。

完整启动流程图

下面这张图把整个流程串起来了,建议你保存下来对照着看。

Linux 启动流程总览 Linux 系统启动流程总览 按下电源键 BIOS / UEFI 固件 GRUB 引导程序 加载 grub.cfg 解析启动参数 内核初始化 + initramfs systemd (PID 1) 关键备份点 • /boot/grub/grub.cfg • /etc/default/grub • /etc/systemd/system/

启动参数到底在哪?

搞清楚了流程,咱们得知道启动参数具体存在哪里。我整理了一下:

配置文件 路径 说明
GRUB 主配置 /boot/grub/grub.cfg 自动生成,不要手动编辑
GRUB 用户配置 /etc/default/grub 你真正要改的地方,改完执行 update-grub
内核命令行 /proc/cmdline 当前系统实际使用的参数,只读
systemd 配置 /etc/systemd/system/ 自定义服务单元文件
我的习惯: 每次改 /etc/default/grub 之前,我都会执行 cp /etc/default/grub /etc/default/grub.bak.$(date +%Y%m%d)。然后改完执行 update-grub 生成新的 grub.cfg。这样万一新配置起不来,还能从 GRUB 菜单里手动指定旧内核和旧参数。

总结一下

Linux 启动流程,说白了就是一条链:固件 → 引导程序 → 内核 → init 进程。每个环节都有配置文件,每个配置文件都可能成为故障点。

我们做启动参数备份,核心就是保护 /etc/default/grub 和 /boot/grub/grub.cfg 这两个文件。后面的章节我会详细讲怎么自动化备份、怎么在系统挂了之后恢复,以及怎么用 systemd 的快照功能做更高级的回滚。