活动地址:CSDN21天学习挑战赛
一、printk
作用:
printk 函数主要做两件事情:
将信息记录到 log 中;
调用控制台驱动来将信息输出。
运用
- printk 在内核源码中用来记录日志信息的函数,只能在内核源码范围内使用,功能类似 printf 函数。
- printk 将内核信息输出到内核信息缓冲区中,内核缓冲区在
kernel/printk/printk.c
中定义:
static char __log_buf[__LOG_BUF_LEN] __aligned(LOG_ALIGN);
内核信息缓冲区是一个环形缓冲区(Ring Buffer),因此,如果塞入的消息过多,则就会将之前的消息冲刷掉。
二、消息级别(printk 8个级别)
Linux 内核共提供了八种不同的消息级别,分为级别 0~7。数值越大,表示级别越低,对应的消息越不重要。相应的宏定义在 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 */
三、内核 printk 文件
可以修改printk的级别,以及查看它的级别:
[root@RV1126_RV1109:/]# cat /proc/sys/kernel/printk
7 4 1 7
[root@RV1126_RV1109:/]#
[root@RV1126_RV1109:/]#
[root@RV1126_RV1109:/]#
[root@RV1126_RV1109:/]#
[root@RV1126_RV1109:/]# echo 8 > /proc/sys/kernel/printk
[root@RV1126_RV1109:/]#
[root@RV1126_RV1109:/]# cat /proc/sys/kernel/printk
8 4 1 7
四个数值的含义如下:
- 控制台日志级别:优先级高于该值的消息将被打印至控制台;
- 默认的消息日志级别:将用该优先级来打印没有优先级的消息;
- 最低的控制台日志级别:控制台日志级别可被设置的最小值(最高优先级);
- 默认的控制台日志级别:控制台日志级别的缺省值。
这四个值是在 kernel/printk/printk.c 中被定义的:
int console_printk[4] = {
CONSOLE_LOGLEVEL_DEFAULT, /* console_loglevel */
MESSAGE_LOGLEVEL_DEFAULT, /* default_message_loglevel */
CONSOLE_LOGLEVEL_MIN, /* minimum_console_loglevel */
CONSOLE_LOGLEVEL_DEFAULT, /* default_console_loglevel */
};
EXPORT_SYMBOL_GPL(console_printk);
示例:
printk(KERN_EMERG "GetIot: KERN_EMERG\n");
printk(KERN_ALERT "GetIot: KERN_ALERT\n");
printk(KERN_CRIT "GetIot: KERN_CRIT\n");
printk(KERN_ERR "GetIot: KERN_ERR\n");
printk(KERN_WARNING "GetIot: KERN_WARNING\n");
printk(KERN_NOTICE "GetIot: KERN_NOTICE\n");
printk(KERN_INFO "GetIot: KERN_INFO\n");
printk(KERN_DEBUG "GetIot: KERN_DEBUG\n");
如果没有设置消息的日志级别,默认使用 default_message_loglevel 级别