因为在Linux内核中没有printf
这个函数,所以在进行驱动开发要打印信息时需要用到printk
。printk
相当于printf
的孪生兄妹,printf
运行在用户态,printk
运行在内核态。在内核中想要向控制台输出或显示一些内,必须使用printk这个函数。不同之处在于,printk
可以根据日志级别对消息进行分类,一共有8个消息级别,这 8个消息级别定义在文件include/linux/kern_levels.h里面,定义如下:
#define KERN_SOH "\001" /* ASCII Start Of Header */
#define KERN_SOH_ASCII '\001'
#define KERN_EMERG KERN_SOH "0" /* system is unusable */
#define KERN_ALERT KERN_SOH "1" /* action must be taken immediately */
#define KERN_CRIT KERN_SOH "2" /* critical conditions */
#define KERN_ERR KERN_SOH "3" /* error conditions */
#define KERN_WARNING KERN_SOH "4" /* warning conditions */
#define KERN_NOTICE KERN_SOH "5" /* normal but significant condition */
#define KERN_INFO KERN_SOH "6" /* informational */
#define KERN_DEBUG KERN_SOH "7" /* debug-level messages */
一共定义了8个级别,其中 0的优先级最高,7的优先级最低。如果要设置消息级别,参考如下示例:
printk(KERN_EMERG "gsmi: Log Shutdown Reason\n");
上述代码就是设置“gsmi: Log Shutdown Reason\n”这行消息的级别为KERN_EMERG。在具体的消息前面加上KERN_EMERG就可以将这条消息的级别设置为KERN_EMERG。如果使用printk的时候不显式的设置消息级别,那么printk将会采用默认级别CONFIG_MESSAGE_LOGLEVEL_DEFAULT,CONFIG_MESSAGE_LOGLEVEL_DEFAULT默认为4。
在include/linux/printk.h中有个宏CONSOLE_LOGLEVEL_DEFAULT,定义如下:
/*
* Default used to be hard-coded at 7, we're now allowing it to be set from
* kernel config.
*/
#define CONSOLE_LOGLEVEL_DEFAULT CONFIG_CONSOLE_LOGLEVEL_DEFAULT
CONSOLE_LOGLEVEL_DEFAULT
控制着哪些级别的消息可以显示在控制台上,从注释可知此宏默认为7,意味着只有优先级高于7的消息才能显示在控制台上。
这个就是printk
和printf
的最大区别,可以通过消息级别来决定哪些消息可以显示在控制台上。默认消息级别为4,4的级别比 7 高,所示直接使用printk输出的信息是可以显示在控制台上的。