1. 启动日志基础:什么是启动日志、存储位置与查看方法

各位好,我是老周。做嵌入式安全这些年,我见过太多工程师一上来就追着 Bug 跑,却忽略了最基础的线索——启动日志。说白了,启动日志就是设备从通电到系统就绪这段时间里,芯片自己写下的「日记」。你想想看,如果连设备是怎么醒过来的都不清楚,后面做安全加固、做漏洞分析,那不就是盲人摸象吗?

这一章,咱们就把启动日志的底裤扒干净。我会从三个角度来讲:它到底是什么、藏在哪儿、怎么把它揪出来看。

1.1 什么是启动日志

启动日志,英文叫 Boot Log 或者 Boot Trace。它是 BootROM、Bootloader(比如 U-Boot、CoreBoot)、以及早期内核在初始化过程中,通过串口或内存缓冲区输出的诊断信息。

我习惯把它分成三个阶段:

  • ROM 阶段:芯片上电后,固化在 ROM 里的第一段代码开始执行。这个阶段的日志通常最短,可能只有几个字符,比如「OK」或者一个版本号。很多芯片在这个阶段甚至不输出日志,除非你拉高了某个调试引脚。
  • Bootloader 阶段:这是日志最丰富的阶段。U-Boot 会打印板子信息、DDR 初始化参数、时钟频率、分区表、环境变量等等。我曾在项目里靠 U-Boot 日志里的一行 DDR 时序警告,提前发现了 PCB 走线问题——嗯,省了一版改板费用。
  • 内核阶段:Linux 内核启动时,会通过 printk 输出大量信息,包括设备树解析、驱动加载、文件系统挂载等。这部分日志通常会被 kmsg 或 dmesg 捕获。

核心要点:启动日志是固件安全分析的第一手证据。它能告诉你:

  • 芯片是否进入了安全启动模式
  • Bootloader 是否被篡改
  • 哪些外设被初始化了
  • 是否有异常重启或看门狗复位

举个例子,我曾经接手过一个设备频繁死机的案子。客户怀疑是固件有漏洞,结果我一看启动日志,发现每次死机前都有一条「WDT reset due to timeout」——说白了,是看门狗没喂饱,跟安全漏洞半毛钱关系没有。

1.2 启动日志的存储位置

启动日志不是凭空产生的,它得有地方待着。根据硬件平台和固件设计的不同,存储位置主要有以下几种:

存储位置 特点 典型场景
串口(UART) 实时输出,掉电即失 开发调试阶段
内存缓冲区(RAM) 速度快,但掉电丢失 U-Boot 的 bdinfo、内核的 dmesg
专用存储区域 掉电保留,可回读 eMMC 的 boot partition、SPI Flash 的保留块
硬件寄存器 极少,仅存关键状态 复位原因寄存器、安全状态寄存器

我个人最常用的是串口和内存缓冲区。串口适合实时看,内存缓冲区适合事后分析。但要注意一点:生产环境下的设备,串口通常是关闭的。这时候你就得靠内存缓冲区或者专用存储区域来捞日志了。

避坑指南:我曾经遇到过一台设备,启动日志被写到了 SPI Flash 的某个保留扇区。结果固件升级时,那个扇区被擦掉了——所有历史日志全没了。后来我建议团队把日志缓冲区放到一个独立的、不会被升级脚本覆盖的分区里。这个坑,你们别踩。

1.3 启动日志的查看方法

知道了日志在哪儿,接下来就是怎么把它弄出来看。我按不同场景来介绍:

1.3.1 串口查看(最直接)

这是嵌入式开发最常用的方式。你需要一根 USB 转串口线,连上设备的 UART 引脚(通常是 TX、RX、GND)。然后打开终端软件:

# 使用 screen(Linux/macOS)
screen /dev/ttyUSB0 115200

# 使用 minicom
minicom -D /dev/ttyUSB0 -b 115200

# 使用 PuTTY(Windows)
# 选择 Serial,填写 COM 口和波特率

设备上电后,你就能看到启动日志一行一行地滚出来了。我习惯把日志同时保存到文件:

screen -L /dev/ttyUSB0 115200
# 日志会自动保存到 screenlog.0 文件中

1.3.2 内核日志查看(系统已启动)

如果设备已经跑起来了,你可以通过以下命令查看内核的启动日志:

# 查看完整内核日志
dmesg

# 查看最近 50 条
dmesg | tail -50

# 实时监控新日志
dmesg -w

# 查看特定关键词
dmesg | grep -i error

这里有个小技巧:dmesg 读取的是内核环形缓冲区的内容。如果系统运行时间长了,早期的启动日志会被新日志覆盖掉。所以,我建议在系统启动后尽快把 dmesg 保存下来:

dmesg > /tmp/boot_log_$(date +%Y%m%d_%H%M%S).txt

1.3.3 Bootloader 日志查看

U-Boot 的日志通常也是通过串口输出的。但如果你想在 U-Boot 命令行下查看一些信息,可以用这些命令:

# 查看板子信息
bdinfo

# 查看内存信息
md 0x80000000 10

# 查看环境变量
printenv

# 查看分区表
mmc part

我遇到过一种情况:U-Boot 启动太快,日志一闪而过,根本来不及看。这时候可以在 U-Boot 里设置一个启动延迟:

setenv bootdelay 5
saveenv

这样 U-Boot 会在启动前等你 5 秒,按任意键就能进入命令行。

1.3.4 从 Flash 中回读日志

有些设备会把启动日志写到 Flash 的特定区域。你可以通过以下方式回读:

# 假设日志存储在 /dev/mtdblock3
dd if=/dev/mtdblock3 of=/tmp/boot_log.bin bs=1024 count=64

# 查看内容(通常是文本,但可能有二进制头)
strings /tmp/boot_log.bin

经验之谈:我在分析一款 IoT 设备时,发现它的启动日志被加密后存储在 Flash 里。解密密钥藏在 BootROM 的某个固定偏移处。这种设计看似安全,但只要你拿到了芯片的 datasheet 和参考代码,密钥基本就是透明的。所以,别把日志加密当成安全护身符——它只能防住最懒的对手。

1.4 启动日志知识体系总览

为了让你对整个启动日志体系有个直观的认识,我画了一张图:

启动日志知识体系总览 启动日志知识体系总览 启动日志 (Boot Log) 1. 什么是启动日志 2. 存储位置 3. 查看方法 ROM 阶段 Bootloader 阶段 内核阶段 串口 (UART) 内存缓冲区 专用存储区域 串口查看 dmesg Bootloader 命令 💡 启动日志是固件安全分析的第一手证据 掌握它,你就能在设备启动阶段发现潜在的安全风险

这张图把启动日志的三个核心维度串在了一起。你从「什么是启动日志」出发,理解它的三个阶段;然后知道它存在哪儿;最后学会怎么把它捞出来看。这三步走通了,后续做安全分析就有了地基。

1.5 小结

这一章我们聊了启动日志的基础。说白了,它就是设备启动过程的「黑匣子」。我个人的经验是:拿到一块新板子,第一件事就是抓一份完整的启动日志。把它存好、标好日期、写上备注。等后面出了问题,这份日志就是你最可靠的参照物。