29、常见故障排除:启动失败修复、驱动冲突解决、内存泄漏定位、日志分析技巧

说实话,做 Jetson 开发最头疼的不是写代码,而是系统突然起不来了。我见过太多同事,板子一黑屏就慌了,直接重刷系统。其实很多问题,咱们冷静分析一下,完全能救回来。

这一章,我就把这几年来踩过的坑、修过的板子,总结成一套实战方法。从启动失败到内存泄漏,咱们一个一个来。

核心思路: 遇到问题别急着重刷。先看日志,再定位根因,最后修复。这套流程走下来,你解决问题的能力会上一个台阶。

29.1 启动失败修复:三板斧

启动失败,说白了就是系统在开机过程中卡住了。我遇到过最夸张的一次,客户说板子点不亮,结果只是 HDMI 线松了。嗯,先排除这种低级问题。

29.1.1 第一板斧:检查电源和指示灯

Jetson 板子通电后,LED 灯会按特定模式闪烁。比如 Orin NX 正常启动时,绿色 LED 会先快闪,然后慢闪。如果灯不亮,或者一直快闪不停,那就是有问题。

  • LED 不亮: 检查电源适配器,至少 15V/3A 以上。我见过有人用手机充电器去带 Orin,那肯定不行。
  • LED 快闪不停: 通常是 bootloader 损坏,或者 SD 卡/SSD 接触不良。
  • LED 常亮但无显示: 可能是显示驱动问题,或者系统卡在了内核加载阶段。

29.1.2 第二板斧:进入恢复模式

如果系统完全起不来,可以试试强制进入恢复模式(Force Recovery Mode, FRM)。

# 以 Jetson Orin NX 为例
# 1. 按住 FORCE RECOVERY 按钮
# 2. 按住 RESET 按钮
# 3. 松开 RESET,保持 FORCE RECOVERY 2秒后松开
# 4. 连接主机,检查是否识别到设备
lsusb | grep NVIDIA
# 应该看到:ID 0955:7023 NVIDIA Corp.

进入恢复模式后,就可以用 flash.sh 重新烧录系统了。但别急着烧,先试试能不能救活。

29.1.3 第三板斧:修复 bootloader

很多时候,启动失败是因为 bootloader 的配置文件坏了。比如你改了 extlinux.conf,结果语法写错了。

# 进入恢复模式后,挂载 SD 卡或 eMMC
sudo ./flash.sh -r -k APP jetson-orin-nano-devkit mmcblk0p1

# 或者只更新 bootloader 分区
sudo ./flash.sh -r -k kernel-dtb jetson-orin-nano-devkit mmcblk0p1
我的习惯: 每次修改系统关键文件前,先备份。比如 /boot/extlinux/extlinux.conf,我会 cp 一份成 .bak。这样出了问题,在恢复模式下挂载分区,把备份拷回去就行。

29.2 驱动冲突解决:谁动了我的内核?

驱动冲突,是 Jetson 上最常见的问题之一。尤其是当你装了多个版本的 JetPack,或者自己编译了内核模块。

我记得有一次,客户在 Orin NX 上同时装了 JetPack 5.1 和 6.0 的库,结果摄像头驱动死活加载不了。查了半天,发现是 libcuda.so 的版本冲突了。

29.2.1 如何检测驱动冲突

最简单的方法,看 dmesg 日志。驱动加载失败时,内核会告诉你原因。

# 查看内核日志,过滤驱动相关
dmesg | grep -i "failed\|error\|conflict"

# 查看已加载的模块
lsmod | sort

# 检查模块依赖
modinfo nvgpu | grep depends

如果看到类似 nvgpu: disagrees about version of symbol module_layout 这样的错误,那就是内核版本不匹配。

29.2.2 解决冲突的步骤

  1. 确认内核版本: uname -r,看看当前跑的内核是哪个。
  2. 检查模块路径: /lib/modules/$(uname -r)/ 下有没有对应的 .ko 文件。
  3. 手动加载模块: sudo insmod /path/to/module.ko,看报错信息。
  4. 卸载冲突模块: sudo modprobe -r nvgpu,再重新加载。
注意: 千万不要在运行的系统上直接替换内核模块。我曾经这么干过,结果系统直接 panic 了。正确的做法是,在开发机上编译好模块,然后通过恢复模式刷进去。

29.3 内存泄漏定位:谁吃了我的内存?

内存泄漏,是嵌入式开发的老大难问题。Jetson 上跑 AI 模型,动不动就几百 MB 显存,泄漏起来特别快。

我遇到过最离谱的一次,一个客户写的推理程序,每跑一次就泄漏 50MB 显存。跑了 100 次后,系统直接 OOM,连 SSH 都连不上了。

29.3.1 用工具定位泄漏

我个人最常用的工具是 valgrindnvidia-smi 配合使用。

# 查看显存使用情况
watch -n 1 nvidia-smi

# 用 valgrind 检测内存泄漏
valgrind --leak-check=full --show-leak-kinds=all ./your_program

# 如果是 Python 程序,用 tracemalloc
python -m tracemalloc your_script.py

但 valgrind 在 Jetson 上跑起来很慢,尤其是跑神经网络的时候。所以我一般先用 nvidia-smi 看显存趋势,确认有泄漏后,再用 valgrind 去定位具体代码。

29.3.2 手动排查技巧

有时候工具不好使,就得靠经验了。我总结了一套手动排查流程:

  1. 看 /proc/meminfo: cat /proc/meminfo | grep -E "MemTotal|MemFree|Cached"
  2. 看进程内存: top -o %MEM 或者 htop
  3. 看 slab 缓存: cat /proc/slabinfo,有时候是内核模块泄漏了。
  4. 用 smem 看 USS/PSS: smem -t -p,这个能看出进程实际占用的物理内存。
避坑指南: 我曾经在调试一个视频解码程序时,发现内存只增不减。查了三天,最后发现是 av_frame_free() 没调用。说白了,就是申请了资源忘了释放。所以写代码时,一定要养成「谁申请,谁释放」的习惯。

29.4 日志分析技巧:从日志里读出真相

日志是系统给你的「遗言」。学会看日志,你就成功了一半。

29.4.1 关键日志文件

日志文件 用途 我的经验
/var/log/syslog 系统通用日志 启动失败先看这个,关键词搜 "error"
/var/log/kern.log 内核日志 驱动问题、硬件错误都在这里
/var/log/nv.log NVIDIA 驱动日志 CUDA、多媒体 API 的报错信息
/var/log/daemon.log 后台服务日志 比如 nvargus-daemon 的启动情况

29.4.2 高效分析日志的方法

别用 cat 看整个日志,那会累死你。用 grepjournalctl 配合。

# 只看最近 10 分钟的内核日志
journalctl -k --since "10 minutes ago"

# 按优先级过滤:只显示错误和警告
journalctl -p err -p warning

# 实时跟踪日志
tail -f /var/log/syslog | grep -E "error|failed|oom"

# 用 awk 统计错误出现次数
grep "error" /var/log/syslog | awk '{print $5}' | sort | uniq -c | sort -nr

嗯,这里有个小技巧。如果日志刷得特别快,比如摄像头驱动每秒报一堆错误,你可以先重定向到文件,再慢慢分析。

# 把日志抓下来,离线分析
journalctl -k -o short-precise > kernel_log.txt
# 然后用 vim 或者 less 慢慢看

29.4.3 常见日志模式解读

  • "Out of memory: Killed process":OOM killer 出手了。说明内存不够,或者有泄漏。
  • "NVRM: failed to register":NVIDIA 驱动注册失败。通常是内核版本不匹配。
  • "tegra-i2c: timeout":I2C 总线超时。可能是硬件连接问题,或者设备地址冲突。
  • "nvargus-daemon: Failed to open camera":摄像头初始化失败。检查 CSI 线缆和驱动。
注意: 有些日志看起来是 error,但其实不是致命问题。比如 "nvpmodel: WARNING: fan speed is 0",这只是风扇没转,不影响系统运行。要学会区分「真错误」和「假警告」。

29.5 知识体系总览

下面这张图,是我自己总结的故障排除流程。每次遇到问题,我就按这个思路走一遍,基本都能找到根因。

Jetson 故障排除流程 系统出现异常 第一步:查看日志(dmesg / journalctl) 启动失败?→ 检查电源/恢复模式 驱动冲突?→ 检查 lsmod / modinfo 内存泄漏?→ 检查 nvidia-smi / valgrind 定位根因,制定修复方案 修复并验证

说白了,故障排除就是「看日志 → 定位 → 修复」的循环。别怕出问题,出一次问题,你就长一次经验。我刚开始做 Jetson 开发时,也是天天重刷系统。后来慢慢学会了看日志、分析问题,现在遇到问题反而有点兴奋——又能学新东西了。

嗯,这一章的内容就到这里。记住,工具是死的,思路是活的。把上面这些方法练熟了,你也能成为别人眼中的「Jetson 救火队员」。


公众号:蓝海资料掘金营,微信deep3321