4. 内核启动流程概览:BIOS/UEFI → Bootloader → Kernel → init 进程,dmesg 在各阶段的输出特征
Linux 系统的启动是一个多阶段、高度结构化的过程。从按下电源键到出现登录提示符,系统依次经历固件初始化、引导加载、内核解压与初始化、以及用户空间初始化四个核心阶段。理解每个阶段的职责与边界,是精准解读 dmesg 日志、快速定位启动故障的基础。
本章将拆解启动流程的四个主要阶段,并重点分析每个阶段在 dmesg 环形缓冲区中留下的“指纹”特征。掌握这些特征,你就能在数百行启动日志中迅速判断故障发生在哪个环节。
4.1 启动流程四阶段总览
下表总结了四个阶段的核心任务、时间窗口及 dmesg 输出特征:
| 阶段 | 核心任务 | 时间窗口 | dmesg 输出特征 |
|---|---|---|---|
| BIOS/UEFI | 硬件自检 (POST)、选择启动设备、加载 Bootloader | 按下电源键 ~ 数秒 | 无输出(dmesg 缓冲区尚未初始化) |
| Bootloader | 加载内核映像与 initramfs 到内存,传递启动参数 | BIOS/UEFI 完成后 ~ 1-2 秒 | 无输出(内核未运行,dmesg 不可用) |
| Kernel | 解压内核、初始化子系统、驱动、挂载根文件系统 | Bootloader 跳转后 ~ 5-30 秒 | 大量输出:时间戳从 [ 0.000000] 开始,包含 CPU、内存、设备枚举、驱动加载等 |
| init 进程 | 启动 systemd/init 服务、挂载文件系统、启动用户态服务 | 内核初始化完成后 ~ 持续 | 持续输出:时间戳延续内核阶段,包含服务启动、挂载、网络配置等用户态日志 |
4.2 阶段一:BIOS/UEFI 固件初始化
这是系统启动的第一阶段。固件(BIOS 或 UEFI)负责最基本的硬件初始化和自检(Power-On Self-Test, POST)。
- BIOS(传统):使用 16 位实模式,读取主引导记录(MBR),寻找活动分区并加载 Bootloader 的第一阶段代码。
- UEFI(现代):使用 32/64 位模式,读取 GPT 分区表上的 EFI 系统分区(ESP),直接加载
.efi格式的 Bootloader(如 GRUB、systemd-boot)。
dmesg 特征:无输出。 此阶段完全在 CPU 实模式或 UEFI 固件环境中运行,内核尚未接管硬件,printk 机制不存在。
4.3 阶段二:Bootloader 引导加载
Bootloader(如 GRUB 2)被固件加载后,负责定位并加载 Linux 内核映像(vmlinuz)和初始内存盘(initramfs)到内存,然后跳转到内核入口点。
Bootloader 的主要工作:
- 从磁盘或网络加载内核与 initramfs。
- 解析并设置内核启动参数(如
root=、quiet、console=)。 - 切换到保护模式或长模式(64 位)。
- 调用内核的启动协议入口。
dmesg 特征:无输出。 内核尚未执行,dmesg 缓冲区不存在。不过,GRUB 本身可以通过 grub.cfg 中的 serial 或 console 设置输出文本到屏幕或串口,但这些信息不属于 dmesg。
1. 内核映像损坏或配置错误。
2. 启动参数错误(如指定了不存在的根设备)。
3. 硬件兼容性问题(如 ACPI 表解析失败)。
此时,可以在 GRUB 菜单按
e 编辑启动项,移除 quiet 和 splash 参数,添加 earlyprintk=vga,keep 来获取早期内核输出。
4.4 阶段三:内核初始化
这是 dmesg 输出的核心阶段。内核从入口点 start_kernel() 开始,执行一系列复杂的初始化过程。dmesg 日志的时间戳从 [ 0.000000] 开始,精确到微秒。
内核初始化的关键子阶段及其 dmesg 特征:
| 子阶段 | 典型 dmesg 输出示例 | 说明 |
|---|---|---|
| CPU 与架构检测 | [ 0.000000] Linux version 6.1.0 ...[ 0.000000] DMI: ...[ 0.000000] smpboot: CPU0: Intel(R) ... |
显示内核版本、编译信息、主板型号、CPU 拓扑。 |
| 内存初始化 | [ 0.000000] e820: [mem 0x0000000000000000-0x000000000009ffff] usable[ 0.000000] Memory: 16285712K/... |
e820 映射显示物理内存布局,最后一行报告总内存。 |
| 中断控制器与时钟 | [ 0.000000] APIC: ...[ 0.000000] clocksource: tsc: ... |
初始化本地 APIC、IO-APIC 和系统时钟源。 |
| 设备枚举与驱动加载 | [ 0.123456] pci 0000:00:00.0: [8086:...] ...[ 0.234567] ahci 0000:00:1f.2: AHCI 0001.0301 ... |
PCI 总线扫描、设备发现、驱动绑定。这是日志最密集的部分。 |
| 文件系统与根设备 | [ 1.234567] EXT4-fs (sda1): mounted filesystem with ordered data mode |
挂载根文件系统,准备切换到用户空间。 |
| 启动 init 进程 | [ 1.345678] Run /sbin/init as init process |
内核初始化完成,创建第一个用户态进程。 |
下面这张 SVG 图展示了内核初始化阶段的主要组件调用关系与数据流:
4.5 阶段四:init 进程与用户空间初始化
内核挂载根文件系统后,在用户空间启动第一个进程——init。在现代 Linux 发行版中,init 通常是 systemd,但也可能是 SysV init 或 OpenRC。
此阶段的 dmesg 特征:
- 时间戳连续:内核阶段的时间戳会自然延续到用户空间阶段。
- 日志来源变化:除了内核自身的 printk 输出,用户空间守护进程(如
systemd-journald、udevd)也会通过/dev/kmsg或syslog系统调用向内核日志缓冲区写入信息。 - 典型输出:服务启动状态、文件系统挂载(如
/home、/var)、网络接口配置、模块加载等。
示例 dmesg 输出片段:
[ 1.345678] Run /sbin/init as init process
[ 1.456789] systemd[1]: systemd 252 running in system mode (+PAM +AUDIT +SELINUX +APPARMOR +IMA)
[ 1.567890] systemd[1]: Detected virtualization kvm
[ 1.678901] systemd[1]: Detected architecture x86-64
[ 1.789012] systemd[1]: Set hostname to <server01>
[ 2.123456] systemd[1]: Started Journal Service.
[ 2.234567] systemd[1]: Started udev Kernel Device Manager.
[ 3.456789] systemd[1]: Mounting /home...
[ 4.567890] systemd[1]: Started Network Manager.
systemd[1]: 前缀表示日志来自 systemd 进程。如果系统在此阶段挂起,应检查:1. 关键服务(如
systemd-journald)是否启动失败。2. 文件系统挂载是否超时(如 NFS 挂载不可达)。
3. udev 设备管理器是否卡在某个设备探测上。
使用
systemctl status 或 journalctl -xb 可以获取更详细的用户空间故障信息。
4.6 各阶段故障与 dmesg 的对应关系
下表总结了常见启动故障与 dmesg 输出阶段的对应关系,帮助你快速定位问题范围:
| 故障现象 | 可能原因 | dmesg 检查点 | 阶段归属 |
|---|---|---|---|
| 黑屏,无任何输出 | 硬件故障、BIOS/UEFI 损坏、Bootloader 损坏 | dmesg 无输出 | BIOS/UEFI 或 Bootloader |
| GRUB 菜单后卡死,无内核日志 | 内核映像损坏、启动参数错误、早期 ACPI 错误 | dmesg 无输出或只有 [ 0.000000] 开头几行 |
Bootloader → 内核早期 |
| 内核日志开始,但中途停止 | 驱动崩溃、硬件不兼容、内存错误 | 检查最后一条日志,通常在设备探测或驱动加载处 | 内核初始化 |
| 内核日志完整,但无法进入登录界面 | 根文件系统损坏、init 进程缺失、关键服务失败 | 检查 Run /sbin/init 之后的服务启动日志 |
init 进程 |
| 系统启动缓慢 | 设备超时、服务依赖等待、udev 规则执行慢 | 检查时间戳间隔,寻找长时间停顿点 | 内核或 init 进程 |
4.7 实战:从 dmesg 时间戳判断当前阶段
在分析 dmesg 输出时,时间戳是判断当前处于哪个阶段的最直接依据。以下是一个快速判断指南:
- 时间戳 < 0.5 秒:通常处于 CPU/内存/中断等核心子系统初始化阶段。如果在此区间出现错误,往往是硬件兼容性或 ACPI 问题。
- 时间戳 0.5 ~ 5 秒:设备枚举与驱动加载阶段。大量 PCI、USB、SATA 设备日志出现。此阶段的错误通常指向特定硬件或驱动。
- 时间戳 5 ~ 30 秒:文件系统挂载与 init 启动阶段。如果在此区间出现长时间停顿,应检查根设备识别、文件系统完整性或 initramfs 内容。
- 时间戳 > 30 秒:用户空间初始化阶段。服务启动、网络配置、挂载远程文件系统等。此阶段的延迟通常与 systemd 服务配置有关。
dmesg -T 可以将内核时间戳转换为人类可读的日期时间,便于与系统日志 /var/log/messages 或 journalctl 进行交叉比对。例如:dmesg -T | grep -E "error|fail|warning" 可以快速筛选出带有时间信息的异常日志。
通过本章的学习,你应该能够根据 dmesg 日志的时间戳和内容特征,准确判断系统启动到了哪个阶段,从而将故障定位的范围从“整个启动过程”缩小到“某个具体阶段”,为后续的深入分析打下坚实基础。