日志收集工具:dmesg、journalctl 与串口捕获

做嵌入式安全启动,第一步不是看代码,而是学会“听”系统说话。日志就是系统的语言。你听不懂,出了问题就只能干瞪眼。

这一章,我带你搞定三个最常用的日志收集工具。它们分别是:dmesg(内核日志)、journalctl(系统日志)和串口捕获(硬件级日志)。这三板斧用熟了,大部分启动问题你都能定位个七七八八。

核心观点:日志收集不是“看输出”,而是“有目的地抓取”。不同阶段用不同工具,才能拿到最关键的线索。

日志收集工具知识体系 日志收集工具知识体系 dmesg 内核环形缓冲区日志 journalctl systemd 日志系统 串口捕获 硬件级调试日志 dmesg -T 时间戳 dmesg -l 级别过滤 journalctl -u 服务过滤 journalctl -k 内核日志 minicom / screen 波特率 115200 💡 实战建议:启动阶段用 dmesg,服务阶段用 journalctl,死机阶段用串口 三者互补,覆盖从 BootROM 到用户态的全链路日志

1. dmesg:内核的“黑匣子”

dmesg 读取的是内核环形缓冲区。说白了,就是内核在启动过程中打印的所有信息。从 BootROM 交棒给内核,到驱动加载、文件系统挂载,全在这里。

我个人习惯,拿到一块新板子,第一件事就是跑 dmesg | head -50。为什么?因为我要确认内核版本、编译时间、以及早期有没有致命错误。

常用命令速查

命令 作用 我的经验
dmesg 打印所有内核日志 信息太多,建议配合 grep
dmesg -T 显示人类可读时间戳 必加!否则你看不懂时间
dmesg -l err 只显示错误级别日志 排查问题第一步
dmesg -w 实时监控新日志 类似 tail -f,调试驱动时很爽
dmesg -c 清空缓冲区 慎用!清完就没了

我的小技巧:在安全启动调试中,我经常用 dmesg -T | grep -i "secure\|trust\|verified\|dm-verity" 来快速定位与安全相关的日志。这样能一眼看出签名校验是否通过。

日志级别过滤

内核日志有 8 个级别,从 KERN_EMERG(0)到 KERN_DEBUG(7)。你想想看,如果启动时系统直接挂了,你还在看 debug 信息,那不是浪费时间吗?

我建议这样用:

# 只看错误和警告
dmesg -l err,warn

# 只看关键信息
dmesg -l crit,alert,emerg

# 查看某个模块的日志(比如 USB)
dmesg -T | grep -i usb

嗯,这里要注意:-l 参数后面可以跟多个级别,用逗号隔开就行。

2. journalctl:systemd 时代的日志瑞士军刀

如果你的系统用了 systemd(现在大部分嵌入式 Linux 都用了),那 journalctl 就是你的主力工具。它比 dmesg 更强大,因为它能记录用户态服务的日志,而不仅仅是内核的。

我记得第一次用 journalctl 时,被它的参数数量吓到了。但别慌,常用的其实就那几个。

核心用法

命令 作用 实战场景
journalctl -u sshd 查看某个服务的日志 SSH 连不上?看这个
journalctl -k 查看内核日志(类似 dmesg) 比 dmesg 多了索引
journalctl -p err 按优先级过滤 只看错误,省眼睛
journalctl --since "1 hour ago" 按时间过滤 出问题后回头看
journalctl -f 实时跟踪日志 调试时开着,像 tail -f

我曾经踩过的坑:journalctl 默认只保留最近的日志。如果系统重启了,之前的日志可能就丢了。解决办法是配置 /etc/systemd/journald.conf 中的 Storage=persistent,并设置 SystemMaxUse=500M。否则你重启后查不到上一轮的日志,那叫一个抓狂。

实战:排查安全启动服务

假设你的安全启动由一个叫 secure-boot-check 的服务负责。你可以这样查:

# 查看该服务的所有日志
journalctl -u secure-boot-check

# 只看最近的 20 条
journalctl -u secure-boot-check -n 20

# 加上时间戳和输出格式
journalctl -u secure-boot-check -o short-precise

# 实时监控
journalctl -u secure-boot-check -f

为什么我喜欢用 -o short-precise?因为它会显示微秒级的时间戳。在分析启动时序问题时,这个精度能帮你判断哪个服务先报错。

3. 串口日志捕获:最后的救命稻草

当系统连网络都没有,或者内核还没起来时,dmesg 和 journalctl 都救不了你。这时候,串口就是你的“上帝视角”。

说白了,串口日志是硬件级别的。只要 CPU 的 UART 引脚有输出,你就能看到从 BootROM 开始的所有信息。包括安全启动的签名校验、密钥加载、以及早期初始化失败的原因。

常用工具对比

工具 特点 适用场景
minicom 经典,功能全 日常调试,支持文件传输
screen 轻量,系统自带 快速连接,不想装软件
picocom 极简,无依赖 嵌入式环境,资源受限
putty (Windows) 图形化,支持串口 Windows 开发机

我的串口配置模板

我个人习惯用 screen,因为它几乎每个 Linux 发行版都自带。配置如下:

# 连接串口(波特率 115200,8 数据位,1 停止位,无校验)
screen /dev/ttyUSB0 115200

# 退出:Ctrl+A,然后按 :quit

# 如果想记录日志到文件
screen -L -Logfile boot_log.txt /dev/ttyUSB0 115200

避坑指南:我曾经在调试一块 RK3588 开发板时,串口死活没输出。折腾了半天,发现是 USB 转串口模块的 TX/RX 接反了。嗯,这种低级错误最容易让人怀疑人生。记住:TX 接 RX,RX 接 TX,GND 接 GND。

波特率的选择

大部分嵌入式设备默认用 115200。但有些老旧的 bootloader 可能用 57600 甚至 9600。如果你看到乱码,先别慌,试试切换波特率。

我建议这样排查:

  1. 先试 115200,这是最常用的
  2. 如果乱码,试 57600
  3. 还不行?试 38400、19200、9600
  4. 如果所有波特率都是乱码,检查硬件连接

实战:一次安全启动的日志捕获流程

好了,理论说完了。我带你走一遍实际流程。假设我们要调试一块新板子的安全启动:

# 第一步:打开串口,捕获从 BootROM 开始的日志
screen -L -Logfile secure_boot_log.txt /dev/ttyUSB0 115200

# 第二步:给板子上电,观察输出
# 你会看到类似这样的信息:
#   BootROM start
#   Loader from eMMC
#   Verify signature... OK
#   Jump to kernel...

# 第三步:系统启动后,用 dmesg 看内核日志
dmesg -T | grep -i "secure\|trust"

# 第四步:用 journalctl 看安全服务日志
journalctl -u secure-boot-check -o short-precise

关键点:串口日志能捕获到 BootROM 阶段的签名校验信息,这是 dmesg 和 journalctl 做不到的。所以,做安全启动调试,串口是必备的。

总结一下

这三个工具各有分工:

  • dmesg:看内核启动过程,适合驱动和内核模块调试
  • journalctl:看系统服务日志,适合用户态服务排查
  • 串口:看从 BootROM 开始的完整启动链,适合底层和安全启动调试

我个人建议,平时开发时三个工具都开着。串口一直录着,dmesg 和 journalctl 按需查询。这样一旦出问题,你手里有完整的日志链,定位起来会快很多。