Linux 启动流程全解析:从 BIOS 到 systemd

19次阅读

linux启动是分阶段移交过程,bios/UEFI→MBR/gpt→GRUB→内核+initramfs→systemd;initramfs必须精确匹配硬件与根设备形态,缺失或不兼容会导致“VFS: Unable to mount root fs”等错误。

Linux 启动流程全解析:从 BIOS 到 systemd

Linux 启动不是一条线性路径,而是一系列依赖明确、阶段清晰的移交过程;跳过任一环节(比如绕过 initramfs 直接挂载根文件系统),系统大概率卡死在“VFS: Unable to mount root fs”。

BIOS/UEFI 到 MBR/GPT 的控制权移交关键点

传统 BIOS 读取磁盘第一个扇区(512 字节)的 MBR,执行其中的引导代码;UEFI 则查找 EFI 系统分区(ESP)中 /EFI/boot/bootx64.efi(x86_64)这类可执行镜像。两者根本区别在于:BIOS 是 16 位实模式,无文件系统概念;UEFI 原生支持 FAT32,能直接按路径加载 EFI 应用。

常见错误现象:

  • UEFI 模式下硬盘为 MBR 分区表 → 启动失败,提示 “Invalid partition table” 或直接进固件界面
  • BIOS 模式下硬盘为 GPT 分区表 → 可能成功启动(部分兼容),但 grub 安装到 core.img 时会报错 “embedding is not possible”

实操建议:

  • lsblk -f 查看分区类型和挂载点,确认 ESP 是否存在且格式为 vfat
  • efibootmgr -v(需在 UEFI 环境下运行)验证当前启动项指向的 EFI 路径是否真实存在
  • 安装系统前,根据固件类型明确选择 MBR+BIOS 或 GPT+UEFI 组合,不要混用

GRUB2 加载内核与 initramfs 的实际行为

grub.cfg 中的 linux 行指定内核镜像(如 vmlinuz-6.1.0-xx-amd64),initrd 行指定对应的 initramfs.img。注意:这不是“加载两个文件后一起运行”,而是 GRUB 将内核解压到内存,再把 initramfs 作为初始 RAM 文件系统一并载入——内核启动后第一件事就是解包并切换到这个临时根环境。

容易踩的坑:

  • initramfs 缺失或损坏 → 内核 panic,停在 “Kernel panic – not syncing: VFS: Unable to mount root fs on unknown-block(0,0)”
  • initramfs 不含对应硬件驱动(如 NVMe 控制器、LVM 模块、加密模块 dm-crypt)→ 找不到根设备,卡在 “Waiting for root device…”
  • 手动更新内核后未重建 initramfsupdate-initramfs -u 必须执行,否则新内核无法识别旧 initramfs 中的驱动

验证方式:

  • 启动时按 e 进入 GRUB 编辑模式,检查 linuxinitrd 行路径是否指向真实存在的文件(用 ls (hd0,gpt2)/boot/ 测试)
  • 从 Live 系统挂载原系统,运行 lsinitramfs /boot/initrd.img-xxx | grep -E "(nvme|lvm|crypt)" 确认关键模块已打包

systemd 接管后如何判定“启动完成”

systemd 并不等待所有服务就绪才宣告启动完成;它以 default.target(通常是 graphical.targetmulti-user.target)的激活状态为标志。只要该 target 下所有 Wants/Requires 的 unit 进入 active(running)状态,systemctl is-system-running 就返回 running

这意味着:

  • 后台仍在启动的服务(如 docker.service 设置了 After=network.target 但网络尚未 ready)不会阻塞系统就绪判断
  • systemctl list-jobs 可看到 pending 的 unit,它们可能因依赖未满足而排队
  • 某些服务(如 getty@tty1.service)在 graphical.target 下是被 WantedBy 的,但若桌面环境崩溃,它仍可能处于 running 状态,系统仍算“已启动”

调试建议:

  • systemd-analyze blame 查看哪些 unit 启动耗时最长
  • systemd-analyze critical-chain 追踪从 default.target 到最慢 unit 的依赖链
  • 若服务始终 failed,检查其 Wants=After= 的上游 unit 是否 active,而非只看自身日志

整个流程里最容易被忽略的是 initramfs 的内容适配性——它不像内核那样“向下兼容”,而是必须精确匹配当前硬件抽象层和根设备形态;换一块 NVMe 硬盘、加一层 LUKS 加密、甚至启用 Intel RST RAID,都可能让旧 initramfs 失效,且错误信息极其简略。

text=ZqhQzanResources