1. 启动日志概述

各位同学,咱们今天聊聊启动日志。说实话,这玩意儿在嵌入式开发里经常被忽略,但真出了问题,它就是你的救命稻草。我做了这么多年安全启动和固件开发,可以负责任地告诉你——看懂启动日志,是排查启动故障的第一步。

什么是启动日志

启动日志,说白了就是设备从上电到操作系统跑起来这段时间,各个阶段输出的记录信息。你想想看,一个嵌入式设备从按下电源键到进入系统,中间要经历多少环节?Boot ROM、Bootloader、UEFI、Kernel……每个环节都可能出问题。

启动日志就是把这些环节的关键信息记录下来。比如:

  • 哪个阶段初始化成功了
  • 哪个外设没响应
  • 镜像校验是否通过
  • 内存地址映射是否正确

我记得有一次,客户反馈设备批量启动失败。我远程拿到日志一看,Bootloader 阶段报了个 HASH mismatch,直接定位到是镜像签名校验出了问题。如果没有日志,这种问题排查起来就像大海捞针。

核心观点:启动日志是设备启动过程的"黑匣子"。它记录了从硬件复位到系统就绪的完整轨迹,是诊断启动故障的第一手资料。

启动日志的作用

启动日志到底能帮我们干什么?我归纳了四个核心作用:

  1. 故障定位——启动到哪一步崩了,日志里清清楚楚。是 Bootloader 挂了还是 Kernel panic,一眼就能看出来。
  2. 安全校验验证——镜像签名校验、哈希比对、证书链验证,这些安全启动的关键步骤,日志里都会留下记录。我在项目中遇到过,有人篡改了固件,但日志里校验失败的信息直接暴露了问题。
  3. 性能分析——每个阶段的耗时、初始化顺序、资源分配,日志都能反映出来。优化启动速度的时候,这些数据特别有用。
  4. 调试与开发——开发阶段,日志是调试的"眼睛"。尤其是早期硬件还没稳定的时候,串口日志几乎是唯一的交互手段。

我的习惯:在产品开发阶段,我会把日志级别调到最详细(DEBUG级别)。量产阶段再降到INFO或WARNING。这样既能保留关键信息,又不会拖慢启动速度。

常见的启动日志类型

启动日志不是铁板一块。不同阶段、不同组件输出的日志,格式和内容差异很大。我把它分成三类:

日志类型 输出阶段 典型内容 获取方式
Bootloader Log Boot ROM → Bootloader 硬件初始化、内存检测、镜像加载、签名校验 串口(UART)、JTAG
UEFI Log UEFI 固件阶段 PEI/DXE 事件、驱动加载、Secure Boot 状态 UEFI 控制台、串口、BMC
Kernel Log 操作系统内核启动 驱动注册、文件系统挂载、服务启动 dmesg、/var/log/

1. Bootloader Log

Bootloader 日志是最底层的。它通常在硬件刚上电、CPU 还在跑汇编代码的时候就开始了。我见过很多工程师忽略这个阶段的日志,觉得太底层、看不懂。但恰恰是这里,最容易暴露硬件问题和安全漏洞。

举个例子,一个典型的 Bootloader 日志片段:

U-Boot 2023.04 (Apr 12 2024 - 10:23:45 +0800)

DRAM:  512 MiB
NAND:  256 MiB
MMC:   mmc@ff0f0000: 0
Loading image from MMC...
Verifying hash... OK
Jumping to kernel at 0x42000000...

你看,这里包含了内存大小、存储设备、镜像加载路径、哈希校验结果。如果校验失败,这里会直接报 FAILED,而不是 OK。

注意:Bootloader 日志的输出依赖于串口或调试接口。量产设备可能会关闭这些接口。我建议在产品设计阶段就预留日志输出通道,哪怕只是一个测试点。否则出了问题,你连日志都拿不到。

2. UEFI Log

UEFI 日志比 Bootloader 日志更结构化。它分为多个阶段:PEI(Pre-EFI Initialization)、DXE(Driver Execution Environment)、BDS(Boot Device Selection)。每个阶段都有独立的事件记录。

UEFI 日志里我最关注的是 Secure Boot 相关的信息:

Secure Boot: Enabled
Image 0x7A3F0000: signature verification succeeded
Variable: SetupMode=0, SecureBoot=1

这里 SecureBoot=1 表示安全启动已开启,signature verification succeeded 表示镜像签名校验通过。如果校验失败,UEFI 会直接阻止启动,并在日志里记录失败原因。

我曾经调试过一个 UEFI 安全启动的问题,客户说设备无法启动。我拿到日志一看,SetupMode=1,说明设备处于设置模式,没有加载自定义证书。这就是典型的配置问题,日志里一目了然。

3. Kernel Log

Kernel 日志是最常见的。Linux 下用 dmesg 命令就能看到。它记录了内核启动过程中的所有事件:

[    0.000000] Booting Linux on physical CPU 0x0
[    0.000123] Memory: 512MB available
[    0.456789] mmc0: new high speed SD card at address 0x1234
[    1.234567] EXT4-fs (mmcblk0p2): mounted filesystem with ordered data mode
[    2.345678] systemd[1]: Starting System Initialization

Kernel 日志的时间戳非常精确(单位是秒,精确到微秒级别)。这对于分析启动性能特别有用。比如,你可以算出从内核启动到文件系统挂载花了多少时间。

嗯,这里要注意:Kernel 日志只有在内核成功解压并开始执行后才会出现。如果设备在 Bootloader 阶段就崩了,你是看不到 Kernel 日志的。所以排查问题的时候,要按阶段逐级查看。

知识体系总览

为了让大家更直观地理解启动日志的整体结构,我画了一张图:

启动日志知识体系总览 设备上电 → 系统就绪 Bootloader Log UEFI Log Kernel Log 关键内容 • 硬件初始化状态 • 内存/存储检测 • 镜像加载路径 • 签名/哈希校验 关键内容 • PEI/DXE 事件 • Secure Boot 状态 • 驱动加载记录 • 变量/配置信息 关键内容 • 内核解压信息 • 驱动注册/初始化 • 文件系统挂载 • 服务启动顺序 核心作用:故障定位 · 安全校验 · 性能分析 · 调试开发 启动日志覆盖从硬件复位到系统就绪的完整链路 不同阶段的日志相互补充,共同构成完整的启动证据链 💡 排查问题时,建议按 Bootloader → UEFI → Kernel 顺序逐级查看

这张图把启动日志的脉络理清楚了。从上电到系统就绪,Bootloader、UEFI、Kernel 三个阶段各有各的日志,各有各的关注点。它们不是孤立的,而是相互衔接、层层递进的。

我个人习惯在排查启动问题时,先看 Bootloader 日志,确认硬件初始化和镜像校验是否通过。如果没问题,再看 UEFI 日志,检查 Secure Boot 状态和驱动加载。最后看 Kernel 日志,分析系统启动的详细过程。这样逐级排查,效率最高。

一个小技巧:如果你手头没有串口工具,但设备能进系统,可以试试 journalctl -k 或者 cat /var/log/kern.log。有些系统会把启动日志保存到文件系统里,方便事后分析。