没志青年
发布于 2026-01-26 / 8 阅读
0

Linux 内核 printk 函数

printk 是内核提供的日志打印函数,和C语言的 printf 差不多,但是不支持浮点数据。

日志级别:

printk的用法和printf类似,printf用于用户空间,printk用于内核空间。

用printk函数时,内核会根据打印的日志级别,决定是否把打印的信息输出到控制台上。

消息正常输出的前提是: 日志输出级别小于console_loglevel(在内核中数字越小优先级越高)。

日志级别一共有8个级别,printk的日志级别定义如下(在include/linux/kern_levels.h中);

没有指定日志级别的printk语句默认采用的级别是DEFAULT_MESSAGE_LOGLEVEL(这个默认级别一般为<4>,即与KERN_WARNING在一个级别上)。

我们可以通过cat /proc/sys/kernel/printk这个文件,查看系统默认的日志级别

linux@ubuntu:~/imx6ull-iot-smart-car/kernel/linux-imx-driver$ cat /proc/sys/kernel/printk
4        4        1        7
​
结果显示了 current, default, minimum 和 boot-time-default 日志级别
​
第一个数字:控制台的日志级别(printk输出的信息优先级高于它才会打印到控制台)
第二个数字:默认的日志级别(如果printk没有指定优先级,默认的优先级就是它)
第三个数字:最低的控制台日志级别(控制台日志级别可被设置的最小值:最高优先级)
第四个数字:默认的控制台日志级别(控制台日志级别的缺省值)
printk(KERN_INFO "Serial: 21285 driver\n");
printk(KERN_WARNING "3w-xxxx: scsi add host failed");
printk(KERN_ERR "53c700: Failed to allocate memory for driver, detatching\n");
printk(KERN_DEBUG "io_callback[cpu %d]: lba = %llu, t = %ld.\n",
                  smp_processor_id(), (unsigned long long)lba, jiffies);

//日志级别
#define KERN_EMERG  "<0>"   /* system is unusable           */
#define KERN_ALERT  "<1>"   /* action must be taken immediately */
#define KERN_CRIT   "<2>"   /* critical conditions          */
#define KERN_ERR    "<3>"   /* error conditions         */
​
#define KERN_WARNING    "<4>"   /* warning conditions           */
​
#define KERN_NOTICE "<5>"   /* normal but significant condition */
#define KERN_INFO   "<6>"   /* informational            */
#define KERN_DEBUG  "<7>"   /* debug-level messages         */
​
用法:printk(KERN_INFO"....",....)
    
    printk(KERN_INFO"Hello World"); =====> printk("<6>""Hello World") ====> printk("<6>Hello World")
  

dmesg --level=emerg,alert,crit,err,warn,notice,info,debug

为了方便使用,定义宏:

#define HELLO_DEBUG
#undef PDEBUG
#ifdef HELLO_DEBUG
#define PDEBUG(fmt, args...) printk(KERN_DEBUG fmt, ##args)
#else
#define PDEBUG(fmt, args...)
#endif