1) CONFIG_IPC_LOGGING
/ # ls -l /sys/kernel/debug/ipc_logging/4a80000.qcom,qup_uart_tx/ total 0 -r--r--r-- 1 root root 0 Jan 1 08:00 log -r--r--r-- 1 root root 0 Jan 1 08:00 log_cont / # echo tt > /dev/ttyHS1 / # cat /sys/kernel/debug/ipc_logging/4a80000.qcom,qup_uart_tx/log [ 720.203382040/ 0x33ee71cd9] DMA Tx[0x0000000000:2] : 74 74 [ 720.205881832/ 0x33ee7d859] DMA Tx[0x0000000000:2] : 0d 0a2)CONFIG_DYNAMIC_DEBUG
mount -t debugfs none /sys/kernel/debug/ //挂载debugfs
echo -n "file xxxxxx.c +p" > /sys/kernel/debug/dynamic_debug/control //打开调试信息
参考: Linux 内核动态打印机制详解
3) printk配置
printk 是 Linux 内核里用来打印日志的核心函数,它会把消息写进内核环形缓冲区,再按日志级别和过滤条件分发到已注册的 console 设备(如串口、VGA 等)。
🔍 工作机制
- 写入阶段:printk 格式化文本后写入内核环形缓冲区(
__log_buf),这一步基本总能成功,除非缓冲区被锁住或打印速度超过 CPU 处理能力。 - 输出阶段:
console_unlock()按优先级和过滤条件,把缓冲区日志分发给所有已注册的 console 设备,由各设备的write回调真正输出到硬件。
📊 日志级别
级别数字越小越紧急,输出条件是level < console_loglevel,不是大于。
| 宏定义 | 数值 | 含义 |
|---|---|---|
| KERN_EMERG | 0 | 系统不可用 |
| KERN_ALERT | 1 | 必须立即处理 |
| KERN_CRIT | 2 | 严重错误 |
| KERN_ERR | 3 | 普通错误 |
| KERN_WARNING | 4 | 警告 |
| KERN_NOTICE | 5 | 正常但需关注 |
| KERN_INFO | 6 | 普通信息 |
| KERN_DEBUG | 7 | 调试信息 |
⚙️ 查看与调整
查看当前配置:cat /proc/sys/kernel/printk,输出 4 个值,依次是console_loglevel、default_message_loglevel、minimum_console_loglevel、default_console_loglevel。
- 打开所有内核输出:
echo 8 > /proc/sys/kernel/printk或dmesg -n 8 - 启动时调整:bootargs 加
loglevel=8,调试时可配合ignore_loglevel强制全部输出,但生产环境别长期开。
⚠️ 常见坑:
dmesg能看到但串口看不到,多半是console_loglevel过滤掉了;KERN_DEBUG(7 级)默认不会打到普通控制台,需要用ignore_loglevel或dmesg -n 8调上去。
🔧 排查思路
- dmesg 能看到、串口看不到:查
console_loglevel、console 是否注册成功、串口 console 的write是否被拖住。 - dmesg 也看不到:日志没进缓冲区、缓冲区被刷掉、级别设置异常,或环形缓冲区太小被冲掉。
- 调试挂死:先用
dmesg -n 8或引导时加loglevel=8 ignore_loglevel确保信息外吐,定位后立即去掉。
对于 pr_debug 和 dev_dbg 这类 7 级调试信息,默认不会输出,可用动态调试(/sys/kernel/debug/dynamic_debug/control)或静态调试(驱动文件头加#define DEBUG)打开