内核调试函数printk()

来源:互联网 发布:coremail知乎 编辑:程序博客网 时间:2024/05/22 08:16

内核模式下系统信息输出函数printk() 与用户模式下printf()函数在输出内容上是有区别的,第一:内核在切换模式时不保存处理器的浮点状态,因此printk()并不支持浮点数运算;第二:printk()可以指定一个记录级别,内核根据这个级别来判断是否在终端上打印消息,而printf()则不要。

内核通过 printk() 输出的信息具有日志级别,日志级别是通过在 printk() 输出的字符串前加一个带尖括号的整数来控制的,如 printk("<6>Hello, world!\n");。内核中共提供了八种不同的日志级别,在 include/linux/kernel.h 中有相应的宏对应。

#define KERN_EMERG "<0>" /* system is unusable */    //是最高优先输出的紧急事件消息,OS崩溃前输出提示消息
#define KERN_ALERT "<1>" /* action must be taken immediately */  //输出警告消息,通知需要采取措施
#define KERN_CRIT "<2>" /* critical conditions */   //发生严重的软件或者硬件操作失败时,进行输出提示
#define KERN_ERR "<3>" /* error conditions */   //设备驱动程序常常用KERN_ERR来报告硬件错误信息
#define KERN_WARNING "<4>" /* warning conditions */   //提示信息,一般用于提醒
#define KERN_NOTICE "<5>" /* normal but significant */   //普通提示,系统输出时需要注意的情况信息
#define KERN_INFO "<6>" /* informational */           //飞正式消息,例如驱动程序进行挂载时,一般打印硬件信息
#define KERN_DEBUG "<7>" /* debug-level messages */  //用于程序开发与调试的信息,完成编码后要删除

所以 printk() 可以这样用:printk(KERN_INFO "Hello, world!\n");。

未指定日志级别的 printk() 采用的默认级别是 DEFAULT_MESSAGE_LOGLEVEL,这个宏在 kernel/printk.c 中被定义为整数 4,即对应KERN_WARNING。

在 /proc/sys/kernel/printk 会显示4个数值(可由 echo 修改),分别表示当前控制台日志级别、未明确指定日志级别的默认消息日志级别、最小(最高)允许设置的控制台日志级别、引导时默认的日志级别。当 printk() 中的消息日志级别小于当前控制台日志级别时,printk 的信息(要有/n符)就会在控制台上显示。但无论当前控制台日志级别是何值,通过 /proc/kmsg (或使用dmesg)总能查看。另外如果配置好并运行了 syslogd 或 klogd,没有在控制台上显示的 printk 的信息也会追加到 /var/log/messages.log 中。

char myname[] = "chinacodec\n";
printk(KERN_INFO "Hello, world %s!\n", myname);

0 0