第一章:系统启动流程详解
大家好,我是老张。做系统救援这行十几年了,每次遇到服务器起不来,我第一反应就是——先搞清楚它卡在哪一步。启动流程就像一条流水线,哪个环节出问题,机器就趴窝。今天咱们就把这条流水线从头到尾捋一遍。
核心观点:系统启动不是黑盒操作。你越了解每个阶段在干什么,救援时就越能精准定位问题。
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 的工作流程:
- Stage 1:从 MBR 或 ESP 分区加载 boot.img(446 字节)
- Stage 1.5:加载 core.img,识别文件系统(比如 ext4、xfs)
- 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 的启动流程:
- 执行
/sbin/init(软链接到 systemd) - 读取默认 target(通常是 graphical.target 或 multi-user.target)
- 按依赖关系并行启动服务单元(.service 文件)
- 执行 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。记住:先诊断,后治疗。
知识体系总览
下面这张图把整个启动流程和救援介入点串起来了。建议你保存下来,以后排查问题时对照着看。
这张图把四个阶段和对应的介入点放在一起了。你救援时,先看现象属于哪个阶段,然后找对应的介入点下手。比如,如果机器卡在 "Loading initial ramdisk...",那就是内核加载阶段的问题,直接走介入点 3 的路线。
最后说一句:启动流程这东西,光看文档记不住。我建议你找台虚拟机,故意搞坏几个环节——比如删掉 /boot 下的内核文件、改错 grub.cfg、破坏 initramfs——然后自己动手修复。踩过坑,才能真正记住。嗯,我就是这么过来的。