1. Linux 启动流程概览:BIOS/UEFI → Bootloader → Kernel → init → systemd

Linux 系统的启动是一个多阶段、高度结构化的过程,从按下电源键到用户获得完整的交互式 shell 环境,经历了固件初始化、引导加载、内核解压、根文件系统挂载以及系统服务启动等关键步骤。理解这一流程是掌握内核参数解析与 systemd 调试的基础。

1.1 启动阶段总览

整个启动流程可划分为五个核心阶段,每个阶段都有明确的职责与输出产物:

阶段 执行主体 主要任务 输出/产物
1. 固件阶段 BIOS / UEFI 硬件自检(POST)、枚举启动设备、加载引导程序 启动设备选择、Bootloader 入口地址
2. 引导加载阶段 GRUB2 / systemd-boot 加载内核映像与 initramfs,传递内核参数 内核 vmlinuz + initramfs 到内存
3. 内核初始化阶段 Linux Kernel 解压内核、初始化子系统、挂载根文件系统 用户空间 PID 1 进程(init)
4. 早期用户空间 initramfs / init 加载必要驱动、检测硬件、挂载真实根文件系统 切换到真实根文件系统
5. 系统服务阶段 systemd (PID 1) 并行启动系统服务、管理单元依赖、提供用户界面 多用户目标 / 图形界面
关键概念: 内核参数(kernel command-line parameters)主要在阶段 2 由 Bootloader 传递给内核,并在阶段 3 和阶段 4 被解析。systemd 在阶段 5 也会读取部分内核参数来调整自身行为(如 systemd.unit=、systemd.log_level=)。

1.2 启动流程 SVG 架构图

下图展示了从固件到 systemd 的完整启动链路,包含各阶段之间的数据流与控制流:

Linux 启动流程架构图 Linux 启动流程:BIOS/UEFI → systemd BIOS / UEFI 硬件自检 · 启动设备枚举 Bootloader GRUB2 / systemd-boot Linux Kernel 解压 · 子系统初始化 initramfs 早期用户空间 systemd (PID 1) 并行启动服务 加载 Bootloader 传递内核参数 挂载 initramfs 切换到真实根 内核参数传递路径 • Bootloader 解析 grub.cfg • 拼接内核参数到命令行 • 内核 / init / systemd 读取

1.3 各阶段详细说明

1.3.1 固件阶段:BIOS 与 UEFI

  • BIOS(Legacy):读取主引导记录(MBR,位于磁盘第一个扇区),执行 16 位实模式代码,加载 Bootloader 的第一阶段。
  • UEFI(现代):读取 EFI 系统分区(ESP)中的引导管理器(如 grubx64.efi),支持安全启动(Secure Boot)和更丰富的启动配置。
  • 关键差异:UEFI 支持 GPT 分区表、更大的磁盘容量、更快的启动速度,且不再依赖 MBR 的 512 字节限制。
调试提示: 如果系统无法启动,首先检查固件设置中的启动顺序。UEFI 系统可使用 efibootmgr 命令查看当前启动条目。

1.3.2 引导加载阶段:Bootloader

Bootloader 负责将内核映像(vmlinuz)和初始 RAM 磁盘(initramfs)加载到内存,并传递内核参数。以 GRUB2 为例,其工作流程如下:

  1. 第一阶段(boot.img):从 MBR 或 GPT 的 BIOS 启动分区加载,定位第二阶段。
  2. 第二阶段(core.img):加载文件系统驱动,读取 /boot/grub/grub.cfg 配置文件。
  3. 菜单显示:呈现内核选择菜单,等待用户选择或超时自动启动。
  4. 加载内核与 initramfs:将 vmlinuz 和 initramfs 放入内存,设置内核命令行参数。
  5. 跳转到内核入口:执行 start_kernel(),控制权移交给内核。
# GRUB2 配置文件示例 (/boot/grub/grub.cfg)
menuentry 'Linux' {
  linux   /vmlinuz-6.1.0 root=/dev/sda2 ro quiet splash
  initrd  /initramfs-6.1.0.img
}

1.3.3 内核初始化阶段

内核获得控制权后,执行以下关键步骤:

  • 解压内核:自解压代码将压缩的内核映像解压到内存中。
  • 架构初始化:设置页表、中断描述符表(IDT)、内存管理单元(MMU)。
  • 子系统初始化:按顺序初始化调度器、内存管理、VFS、网络协议栈等核心子系统。
  • 挂载 initramfs:将 initramfs 作为临时根文件系统挂载,执行其中的 /init 脚本。
注意: 内核参数中的 root= 指定真实根设备,但内核在挂载 initramfs 之前不会直接使用它。initramfs 负责加载存储控制器驱动,然后挂载真实根。

1.3.4 早期用户空间:initramfs

initramfs 是一个小型根文件系统,包含必要的内核模块、设备驱动和启动脚本。其典型工作流程:

步骤 操作 说明
1 执行 /init 通常是 shell 脚本或 BusyBox 二进制
2 加载内核模块 如存储控制器、文件系统驱动
3 检测硬件 创建设备节点,运行 udev
4 挂载真实根文件系统 根据 root= 参数挂载
5 切换到真实根 执行 switch_root 或 pivot_root

1.3.5 系统服务阶段:systemd

当 initramfs 完成切换后,真实根文件系统中的 systemd 作为 PID 1 启动。systemd 的初始化流程:

  • 读取内核参数:解析 systemd.unit=、systemd.log_target= 等参数。
  • 加载默认目标:根据 default.target 符号链接确定启动目标(如 multi-user.target 或 graphical.target)。
  • 并行启动服务:基于单元依赖图,并行激活 socket、service、mount 等单元。
  • 达到目标状态:所有依赖单元启动完成后,系统进入可用状态。
# 查看当前默认启动目标
systemctl get-default

# 临时切换到救援模式(通过内核参数)
# 在 GRUB 菜单编辑内核命令行,添加:
systemd.unit=rescue.target

1.4 启动流程中的关键内核参数

以下参数在启动流程的不同阶段被解析,对调试至关重要:

参数 解析阶段 作用
root= Kernel / initramfs 指定真实根文件系统设备
ro / rw Kernel 以只读或读写方式挂载根文件系统
quiet Kernel / systemd 减少内核日志输出
systemd.unit= systemd 覆盖默认启动目标
systemd.log_level= systemd 设置 systemd 日志级别(debug/info/err)
init= Kernel 指定 PID 1 程序(覆盖 systemd)
调试技巧: 在 GRUB 菜单按 e 键编辑启动项,删除 quiet 并添加 systemd.log_level=debug,可以获取详细的启动日志,帮助定位服务启动失败的原因。

1.5 启动流程总结

Linux 启动流程是一个精心设计的接力过程:

  • 固件 负责硬件初始化和 Bootloader 加载。
  • Bootloader 负责内核加载和参数传递。
  • 内核 负责硬件抽象和核心子系统初始化。
  • initramfs 负责驱动加载和真实根挂载。
  • systemd 负责服务管理和用户空间初始化。