第一章:系统启动流程详解

大家好,我是老张。做系统救援这行十几年了,每次遇到服务器起不来,我第一反应就是——先搞清楚它卡在哪一步。启动流程就像一条流水线,哪个环节出问题,机器就趴窝。今天咱们就把这条流水线从头到尾捋一遍。

核心观点:系统启动不是黑盒操作。你越了解每个阶段在干什么,救援时就越能精准定位问题。

1.1 BIOS/UEFI 阶段:硬件自检与引导选择

按下电源键,CPU 第一个执行的是固化在主板 ROM 里的代码。这就是 BIOS 或 UEFI 的活儿。

BIOS(传统模式):

  • 执行 POST(加电自检),检查内存、CPU、显卡等关键硬件
  • 读取 MBR(主引导记录),位于磁盘第 0 扇区
  • MBR 只有 512 字节,里面放着引导代码和分区表

UEFI(现代模式):

  • 不依赖 MBR,而是读取 EFI 系统分区(ESP)
  • ESP 分区格式为 FAT32,里面存放 .efi 引导文件
  • 支持安全启动(Secure Boot),防止未签名代码运行

我的经验:我个人习惯在装机时直接选 UEFI + GPT 方案。为什么?因为 MBR 分区表最大只支持 2TB 磁盘,而且 BIOS 模式启动速度慢。有一次客户服务器换了块 4TB 硬盘,BIOS 死活认不全,折腾半天才发现是分区表问题。

这里有个关键区别——BIOS 是 16 位实模式,UEFI 是 32/64 位保护模式。说白了,UEFI 更像一个小型操作系统,能直接加载驱动、显示图形界面。

1.2 Bootloader 阶段:GRUB 的使命

BIOS/UEFI 把接力棒交给 Bootloader。Linux 世界里,GRUB 是绝对的主角。

GRUB 2 的工作流程:

  1. Stage 1:从 MBR 或 ESP 分区加载 boot.img(446 字节)
  2. Stage 1.5:加载 core.img,识别文件系统(比如 ext4、xfs)
  3. Stage 2:读取 /boot/grub/grub.cfg,显示菜单

你想想看,GRUB 其实是个微型系统。它得理解文件系统,才能找到内核文件。如果 /boot 分区坏了,GRUB 就卡在 Stage 1.5,菜单都出不来。

避坑指南:我曾经遇到过一台机器,升级内核后重启直接黑屏。后来发现是 grub.cfg 里内核路径写错了。救援时用 Live CD 进去,手动挂载 /boot,重新生成 grub.cfg 就解决了。记住:grub2-mkconfig -o /boot/grub2/grub.cfg 这条命令要刻在脑子里。

GRUB 还有一个隐藏技能——编辑模式。启动时按 e 键,可以临时修改内核启动参数。比如加 single 进入单用户模式,或者加 rd.break 进入 dracut 紧急 shell。这是救援时最常用的手段之一。

1.3 内核加载阶段:从压缩镜像到根文件系统

GRUB 把内核和 initramfs 加载到内存,然后跳转到内核入口。内核开始自解压、初始化硬件、挂载根文件系统。

内核加载的关键步骤:

  • 解压内核镜像(vmlinuz)到内存
  • 初始化 CPU、内存管理、中断控制器
  • 加载驱动(磁盘控制器、文件系统驱动等)
  • 挂载 initramfs(临时根文件系统)
  • 执行 initramfs 中的 init 程序

这里有个容易忽略的点——initramfs。它是个微型根文件系统,里面包含了必要的驱动和工具。为什么需要它?因为真正的根文件系统可能在 LVM 逻辑卷上、在加密分区里、或者在网络存储上。内核一开始挂载不了,得靠 initramfs 先加载驱动、解锁设备,然后再 pivot_root 切换到真正的根。

实战案例:我记得有一次,服务器换了新的 RAID 卡,内核没有对应驱动。启动时卡在 "Waiting for root device" 报错。解决方案是重建 initramfs,把新驱动打包进去:dracut --force --add-drivers "megaraid_sas"。嗯,这个坑我踩过两次,后来学乖了,换硬件前先检查内核模块列表。

1.4 Init 进程与 Systemd 阶段:用户空间的起点

内核完成初始化后,启动第一个用户空间进程——PID 为 1 的 init 程序。传统 Linux 用 SysV init,现代发行版基本都换成了 Systemd。

Systemd 的启动流程:

  1. 执行 /sbin/init(软链接到 systemd)
  2. 读取默认 target(通常是 graphical.target 或 multi-user.target)
  3. 按依赖关系并行启动服务单元(.service 文件)
  4. 执行 rc-local、getty 等收尾工作

Systemd 最大的特点是并行启动。传统 SysV 是一个接一个跑脚本,Systemd 能同时启动多个不相关的服务。你想想看,如果系统有 50 个服务,串行启动可能要 2 分钟,并行可能 30 秒就搞定了。

我的习惯:排查启动慢的问题时,我第一件事就是跑 systemd-analyze blame。这条命令会列出每个服务的启动耗时,按从大到小排序。有一次发现某个服务占了 45 秒,查了半天是 NFS 挂载超时。去掉那个挂载点,启动时间从 1 分半降到了 20 秒。

Systemd 的 target 机制也很重要。常见的 target 有:

Target 名称 说明 救援用途
poweroff.target 关机 —
rescue.target 单用户模式,只挂载基本文件系统 修复 fstab、重置密码
emergency.target 紧急 shell,只挂载根文件系统为只读 修复严重损坏的系统
multi-user.target 多用户文本模式 正常启动
graphical.target 图形界面模式 桌面环境

1.5 救援模式介入点分析

了解了整个启动流程,我们就能画出救援的「作战地图」。每个阶段都有对应的介入点:

介入点 1:BIOS/UEFI 阶段

  • 现象:开机黑屏、无 POST 蜂鸣声
  • 救援:检查硬件连接、重置 CMOS、更换主板电池
  • 工具:主板诊断卡、IPMI/BMC 远程控制台

介入点 2:GRUB 阶段

  • 现象:显示 "GRUB" 后卡住、菜单不出现、文件未找到错误
  • 救援:使用 GRUB 命令行手动引导、从 Live CD 重装 GRUB
  • 工具:grub2-install、grub2-mkconfig

介入点 3:内核加载阶段

  • 现象:内核 panic、挂载根文件系统失败、驱动加载失败
  • 救援:编辑 GRUB 启动参数(加 single、rd.break)、重建 initramfs
  • 工具:dracut、mkinitrd

介入点 4:Systemd 阶段

  • 现象:服务启动失败、登录循环、图形界面卡死
  • 救援:进入 rescue.target 或 emergency.target、禁用故障服务
  • 工具:systemctl、journalctl

重要提醒:救援时不要慌。先判断机器卡在哪个阶段,再对症下药。我曾经见过新手一上来就重装系统,结果只是 /etc/fstab 里写错了一个 UUID。记住:先诊断,后治疗。

知识体系总览

下面这张图把整个启动流程和救援介入点串起来了。建议你保存下来,以后排查问题时对照着看。

系统启动流程与救援介入点 BIOS/UEFI POST → 引导设备选择 GRUB Bootloader Stage 1 → Stage 1.5 → Stage 2 内核加载 解压 → 驱动 → initramfs Systemd PID 1 ↓ 救援介入点 ↓ 介入点 1 硬件自检失败 检查硬件连接 重置 CMOS 介入点 2 GRUB 无法加载 GRUB 命令行 Live CD 重装 GRUB 介入点 3 内核 panic rd.break 参数 重建 initramfs 介入点 4 服务故障 rescue.target journalctl 关键命令速查 • grub2-mkconfig -o /boot/grub2/grub.cfg — 重新生成 GRUB 配置 • dracut --force --add-drivers "xxx" — 重建 initramfs 并添加驱动 • systemd-analyze blame — 查看各服务启动耗时 • systemctl rescue — 进入救援模式 • journalctl -xb — 查看本次启动的详细日志

这张图把四个阶段和对应的介入点放在一起了。你救援时,先看现象属于哪个阶段,然后找对应的介入点下手。比如,如果机器卡在 "Loading initial ramdisk...",那就是内核加载阶段的问题,直接走介入点 3 的路线。

最后说一句:启动流程这东西,光看文档记不住。我建议你找台虚拟机,故意搞坏几个环节——比如删掉 /boot 下的内核文件、改错 grub.cfg、破坏 initramfs——然后自己动手修复。踩过坑,才能真正记住。嗯,我就是这么过来的。

可可精品资料库