3、dmesg 高级用法:参数实战与日志过滤

在 RK3568 显示驱动调试中,基础 dmesg 命令往往输出海量信息,直接阅读效率极低。本章聚焦 dmesg 的高级参数组合与文本过滤工具(grep/awk/sed)的实战配合,帮助开发者从杂乱日志中快速定位 DRM/KMS、MIPI DSI、HDMI 等显示子系统的关键事件与错误。

3.1 核心参数实战:-c / -w / -l / -t / -x

以下参数是日常调试中使用频率最高的组合,每个参数解决一类特定场景。

参数 功能 典型调试场景
-c 读取并清除内核环形缓冲区 在驱动加载前后分别执行,只保留新产生的日志
-w 实时等待新日志(类似 tail -f) 监控热插拔、中断、时序切换时的即时输出
-l 按日志级别过滤(err/warn/info/debug) 只查看错误或警告,排除冗余 info 信息
-t 不打印时间戳 减少行宽,便于复制关键错误码
-x 显示日志级别与 facility 的原始编码 确认某条日志的优先级是否被用户态错误修改
实战建议:在 RK3568 开发板上加载显示驱动前,先执行 dmesg -c 清空缓冲区;加载后执行 dmesg -l err 只查看错误级日志,避免被大量 probe 信息淹没。

3.1.1 参数组合示例

# 清空缓冲区后,实时监控错误级日志(最常用组合)
dmesg -c && dmesg -w -l err

# 只查看最近 50 条与 DRM 相关的日志,不显示时间戳
dmesg -t | grep -i drm | tail -50

# 查看所有日志级别编码,确认某条日志的原始优先级
dmesg -x | grep "rockchip-drm"
技巧:使用 -x 参数时,输出格式为 <facility>.<level>,例如 <6> 表示内核信息(KERN_INFO),<3> 表示错误(KERN_ERR)。在显示驱动调试中,若看到本应为 error 的日志却显示为 <6>,说明驱动中 printk 级别使用错误。

3.2 日志过滤三剑客:grep / awk / sed

单独使用 dmesg 参数仍不足以应对复杂场景,必须结合文本处理工具进行二次过滤。以下是在 RK3568 显示驱动调试中的典型用法。

3.2.1 grep:关键词快速定位

# 查找所有与显示子系统相关的日志(不区分大小写)
dmesg | grep -iE "drm|hdmi|dsi|edp|lvds|vop"

# 显示匹配行及其前后各 3 行上下文(定位错误来源)
dmesg | grep -i -B3 -A3 "rockchip-drm.*fail"

# 反向过滤:排除时间戳和 CPU 调频等无关信息
dmesg | grep -vE "cpufreq|thermal|devfreq"

3.2.2 awk:结构化字段提取

当需要从日志中提取时间戳、函数名、错误码等结构化字段时,awk 是最佳选择。

# 提取所有包含 "irq" 的日志,只显示第 1 列(时间戳)和第 5 列(函数名)
dmesg | grep "irq" | awk '{print $1, $5}'

# 统计每种日志级别的出现次数
dmesg | awk '{print $4}' | sort | uniq -c | sort -rn

# 提取 DRM 子系统中所有包含数字错误码的行
dmesg | grep -i "drm" | awk '{for(i=1;i<=NF;i++) if($i ~ /-[0-9]+/) print $i}'

3.2.3 sed:日志文本清洗与格式化

# 删除所有时间戳,只保留日志正文
dmesg | sed 's/^\[.*\] //'

# 将日志中的 "rockchip-drm" 缩写为 "RKD"(减少行宽)
dmesg | sed 's/rockchip-drm/RKD/g'

# 只保留包含 "dsi" 或 "hdmi" 的行,并删除空行
dmesg | grep -iE "dsi|hdmi" | sed '/^$/d'
注意:在 RK3568 平台上,显示驱动的 probe 顺序可能影响日志输出。使用 dmesg | grep -i "drm" | awk '{print $1, $0}' 可以按时间戳排序,确认 VOP、HDMI、DSI 的初始化先后关系。

3.3 显示驱动专用过滤模式

针对 RK3568 显示子系统的常见模块,以下过滤模板可直接用于调试。

过滤目标 过滤命令 关注点
DRM 核心 dmesg | grep -i "drm\|drm_kms_helper" probe 成功/失败、connector 状态、fb 创建
VOP 显示控制器 dmesg | grep -i "vop\|vop2" 时钟使能、中断注册、图层配置
MIPI DSI dmesg | grep -i "dsi\|mipi" PHY 初始化、时序参数、LP/HS 模式切换
HDMI dmesg | grep -i "hdmi\|dw-hdmi" EDID 读取、HDCP 认证、音频时钟
eDP/LVDS dmesg | grep -i "edp\|lvds\|panel" 背光控制、链路训练、面板时序

3.4 日志过滤流程架构

以下 SVG 图展示了从原始 dmesg 输出到最终调试结论的完整过滤链路。

dmesg 日志过滤与显示驱动调试流程 原始 dmesg 输出 参数预处理 (-c/-w/-l/-t/-x) grep 关键词匹配 awk 字段提取 sed 文本清洗 按显示模块分类过滤 结构化调试结论 每个环节可循环迭代,直到定位问题

3.5 实战案例:定位 RK3568 HDMI 无显示问题

以下是一个完整的调试会话,展示如何组合使用上述工具。

# 步骤1:清空旧日志,加载驱动
dmesg -c
modprobe rockchipdrm

# 步骤2:实时监控错误,同时保存完整日志
dmesg -w -l err &
dmesg > /tmp/full_drm.log

# 步骤3:过滤 HDMI 相关错误
dmesg | grep -i "hdmi" | grep -i "fail\|error\|timeout"

# 步骤4:提取 EDID 读取状态
dmesg | grep -i "edid" | awk '{print $1, $NF}'

# 步骤5:查看中断注册情况
dmesg | grep -i "irq" | grep -i "hdmi\|dw-hdmi"
经验总结:在 RK3568 平台上,HDMI 无显示最常见的原因是 EDID 读取超时或 PHY 初始化失败。使用 dmesg | grep -i "edid" | awk '{print $1, $0}' 可以快速确认 EDID 是否在预期时间点被成功读取。

3.6 日志过滤效率对比

方法 适用场景 效率 学习成本
dmesg 原生参数 快速查看错误/警告 高 低
grep 关键词过滤 按模块/关键字搜索 高 低
awk 字段提取 结构化数据统计 中 中
sed 文本清洗 日志格式化/缩写 中 中
组合管道 复杂调试场景 极高 较高
核心原则:在 RK3568 显示驱动调试中,优先使用 dmesg -l err -w 实时监控,再通过 grep -i 按模块缩小范围,最后用 awk 提取关键字段。避免一次性使用过于复杂的管道链,应逐步迭代过滤条件。