Linux 内核启动流程深度实战:从加电到用户空间的完全工程指南
Linux 内核的启动是一台计算机从硬件加电到用户空间应用程序运行的完整旅程。本文以 x86_64 架构和 Linux 6.x 内核为蓝本,逐阶段剖析从固件到 init 的全过程。
1. x86 重置向量与实模式
CPU 加电后从物理地址 0xFFFFFFF0(reset vector)开始执行,此时处于实模式(Real Mode),仅能访问 1MB 内存。处理器自动跳转到 BIOS/UEFI 固件入口。
2. UEFI 固件初始化
UEFI 固件分为多个阶段:SEC(安全验证)→ PEI(内存初始化)→ DXE(驱动执行,初始化 PCIe/SATA/USB 等)→ BDS(启动设备选择)。UEFI 通过 ESP 分区中的 efi 引导程序(如 grubx64.efi)加载 bootloader。
3. GRUB2 多阶段加载
GRUB2 引导分三步:boot.img(512B,MBR 中)加载 core.img(~32KB),core.img 读取 /boot 分区并加载所有模块和 grub.cfg,最后加载 bzImage 和 initrd。
4. 内核自解压与入口
bzImage 由 bootsect + setup + compressed_kernel(vmlinux.gz) 组成。实模式 setup 代码切换至保护模式(32位),解压缩内核至高端内存,然后切换至长模式(64位)并跳转到 startup_64。
5. start_kernel 初始化链
start_kernel()(init/main.c)是 C 入口。初始化顺序:
| 顺序 | 函数 | 作用 |
|---|---|---|
| 1 | setup_arch() | 平台相关初始化,内存布局 |
| 2 | mm_init() | 内存管理初始化 |
| 3 | sched_init() | 调度器初始化 |
| 4 | init_IRQ() | 中断控制器初始化 |
| 5 | timekeeping_init() | 时钟源初始化 |
| 6 | console_init() | 控制台启用 |
| 7 | mem_init() | 伙伴系统初始化 |
| 8 | rest_init() | 启动 init 进程 |
6. SMP 启动
BSP 已运行,AP 处于实模式循环。BSP 发送 INIT-SIPI-SIPI 唤醒 AP。AP 经历:实模式 → 保护模式 → 长模式 → cpu_startup_entry → idle执行。
7. ACPI 与设备枚举
ACPI 表(DSDT/SSDT)描述设备电源管理和中断路由。内核初始化 APIC 中断控制器、PCI 根复合体、IOMMU 等。
8. initramfs 与根文件系统切换
initramfs 是压缩的 cpio 镜像,/sbin/init 在临时根文件系统中执行,加载驱动、挂载真实根目录并 switch_root。
// initramfs 流程
mount -t proc proc /proc
mount -t sysfs sysfs /sys
modprobe ext4
mount /dev/sda1 /mnt
switch_root /mnt /sbin/init
9. systemd init 阶段
PID 1 = systemd,并行启动服务 targets:Default.target → multi-user.target → 各服务单元。通过 cgroups v2 跟踪资源。
10. 启动优化与故障排查
使用 systemd-analyze blame 定位慢服务、EFI Stub 跳过 bootloader、内核参数 initcall_debug 显示各 init 阶段耗时。故障排查包括 initramfs 修复、内核参数编辑和 fsck 文件系统检查。
11. 总结
从重置向量到 PID 1,Linux 内核的启动是精心编排的初始化链。EFI Stub、initramfs 和 systemd 是现代 Linux 启动的三大核心组件。

发表评论 取消回复