内核打印
printk 说明
在开发Linux device Driver
或者跟踪调试内核行为的时候经常要通过Log API
来trace
整个过程,Kernel API printk()
是整个Kernel Log
机制的基础API
,几乎所有的Log
方式都是基于printk
来实现的。
当然,利用printk
还有一些需要注意的地方,在详细讲述之前先分析一下printk()
实现,大致流程如下图所示:
从上图可以看出,printk
的流程大致可以分为两步:
将所有
Log
输出到内核的Log Buffer
,该Log Buffer
是一个循环缓冲区,其地址可以在内核中用log_buf
变量访问根据设定的
Log
级别决定是否将Log
输出到Console
基于以上内容,我们打印的Log
最终会走向两个位置:
Log Buffer
:该Buffer
里面的内容可以存储在/proc/kmsg
Console
:Console
的实现可以有很多,目前我们用到的有UART Console
(串口)和RAM Console
。通向UART Console
的Log
会在对应的UART
端口打印出来。
对于Console Log
,不可避免的对系统性能有影响。所以对于Console Log
设置了两道关卡
第一个是对
Log
级别进行过滤,只能输出高优先级的Log
;第二个是为
UART
设置单独的开关,在不必要的时候可以将其关闭以提高系统性能。这里提到了Log
优先级,那什么是Log
优先级呢?
printk 日志等级设置
Linux 内核为printk定义了8个打印等级,KERN_EMERG
等级最高,KERN_DEBUG
等级最低。在内核配置时,有一个宏来设定系统默认的打印等级 CONFIG_MESSAGE_LOGLEVEL_DEFAULT
,通常该值设置为4
,那么只有打印等级高于4
时才会打印到终端或者串口。kern_levels.h
4个值的含义依次如下:
console_loglevel
:当前console
的log
级别,只有更高优先级的log
才被允许打印到console
;default_message_loglevel
:当不指定log
级别时,printk
默认使用的log
级别;minimum_console_loglevel
:console
能设定的最高log
级别;default_console_loglevel
:默认的console
的log
级别。
另外,关于printk
格式化字符串形式,参考printk-formats.txt
使用dmesg
命令,可以显示之前所有的打印信息,常配合grep
来查找历史纪录。
屏蔽等级日志控制机制
屏蔽如下代码片段:
文件目录:kernel\kernel\printk\printk.c
printk打印常用方式
打印对应函数名(func
)及对应行数(LINE
)
最后编辑:SteveChen 更新时间:2025-03-30 18:07