Linux驱动(基础):21---调试技术之(printk、DEFAULT_MESSAGE_LOGLEVEL、console_loglevel、klogd、syslogd)

一、printk介绍

  • printk是打印内核消息的函数
  • printk通过附加不同日志级别(loglevel)或者说消息优先级,让printk对消息进行分类
  • 在编译时,日志级别宏会被展开为一个字符串,然后与消息本文拼接在一起,因此printk中优先级和格式字符串之间没有逗号
  • 例如:下面一个是调试信息,一个是临界信息

二、日志级别宏

  • 在头文件中定义了8中可用的日志级别字符串,下面以严重程序的降序方式排列
    • KERN_EMEGR:用于紧急事件消息,一般是系统崩溃之前提示的消息
    • KERN_ALERT:用于需要立即采取动作的情况
    • KERN_CRIT:临界状态,通常设计严重的硬件或软件操作失败
    • KERN_ERR:用于报告错误状态。设备驱动程序会经常使用该宏来报告来自硬件的问题
    • KERN_WARNING:对可能出现问题的情况进行警告,但这类情况通常不会对系统造成严重问题
    • KERN_NOTICE:有必要进行提示的正常情形。许多与安全相关的状态用这个级别进行汇报
    • KERN_INFO:提示性信息。很多驱动程序在启动的时候以这个级别来打印出它们找到的硬件信息
    • KERN_DEBUG:用于调试信息
  • 上面每个字符串表示一个尖括号中的整数。范围分别为0~7。数值越小,优先级越高

三、/proc/sys/kernel/printk文件

  • 该文件指定了在不用场景下所使用的日志消息级别,文件中分别有4个数值字段,从左到右分别为:
    • 当前的日志级别
    • 未明确指定日志记别时的默认消息级别的默认消息界别
    • 最小允许的日志级别
    • 引导时的默认日志级别
  • 例如下面是本人系统中的文件:

四、DEFAULT_MESSAGE_LOGLEVEL宏

  • 未指定优先级的printk语句采用的默认级别是DEFAULT_MESSAGE_LOGLEVEL,该宏在kernel/printk.c中被指定为一个整数
  • 在Linux 2.6.10内核中,DEFAULT_MESSAGE_LOGLEVEL就是KERN_WARNGIN(从上面的/proc/sys/kernel/printk文件中可以看出,其第二个数字为4,说明为KERN_WARNING)

五、消息打印到何处(console_loglevel变量、klogd、syslogd服务)

  • 消息打印到何处与console_loglevel变量和klogd、syslogd服务有关

打印到控制台:

  • 有时候我们想把消息打印到控制台当中,控制台可以是:一个字符模式的终端、一个串口打印机、一个并口打印机
  • 打印到控制台时,消息是每次输出一行,并且只有以newline(换行)字符结尾,消息才会打印。否则不会打印

console_loglevel整数变量

  • 只有printk中指定的优先级值小于console_loglevel变量的时候消息才会打印到控制台中
  • 变量console_loglevel的初始值是DEFAULT_MESSAGE_LOGLEVEL,而DEFAULT_MESSAGE_LOGLEVEL就是KERN_WARNGIN,因此默认情况“KERN_EMEGR”~“KERN_ERR”才会打印到控制台

klogd和syslogd服务

Linux驱动(基础):21---调试技术之(printk、DEFAULT_MESSAGE_LOGLEVEL、console_loglevel、klogd、syslogd)_第1张图片

  • 如果系统同时运行了klogd和syslogd,则无论console_loglevel取何值,内核消息都讲追加到/var/log/message文件中(否则按照syslogd配置进行处理)
  • 如果klogd没有运行,消息就不会传递到用户空间,这种情况下,只能查看/proc/kmsg文件(使用dmesg命令也可以查看)
  • 如果使用klogd,则应该了解它不会保存连续相同的信息行;它只会保存连续相同的第一行,并在最后打印这一行的重复次数

修改console_loglevel变量

  • console_loglevel变量默认值为DEFAULT_MESSAGE_LOGLEVEL,如果我们想要修改console_loglevel变量的值从而来控制哪些消息显示在控制台
  • 可以通过下面一些方法:
    • ①通过sys_syslog系统调用
    • ②在启动klogd服务时指定-c选项(见klogd手册)。如果klogd服务已经启动,需要将其关闭
    • ③通过编写程序来改变控制台的日志级别:入力O'Reilly的FTP站点提供的源文件misc-progs/setlevel.c
    • ④通过修改/proc/sys/kernel/printk文件。例如下面修改文件第一个字段的数值为8,这样所有内核消息都会显示到控制固态上

六、重定向控制台消息

  • 对于控制台日志策略,Linux允许有某些灵活性:内核可以将消息发送到一个指定的虚拟控制台(假设控制台是文本屏幕的话)
  • 默认情况下,“控制台”就是当前的虚拟终端。可以在任何一个控制台设备上调用ioctl(TIOCLINUX)来指定接收消息的其他虚拟终端

演示案例

  • 下面的setconsole程序,可选择专门用来接收内核消息的控制台,这个程序必须由超级用户进行,在misc-progs目录可以找到它

Linux驱动(基础):21---调试技术之(printk、DEFAULT_MESSAGE_LOGLEVEL、console_loglevel、klogd、syslogd)_第2张图片

代码解析:

  • ioctl()使用TIOCLINUX时,需要传给它一个指向字节数组的指针参数。数组的第一个字节指定所请求子命令的编号,随后的字节所具有的的功能则有这个子命令来决定
  • 在setconsole中,使用的子命令是11,后面那个字节(保存在bytes[1]中)则用来表示虚拟控制台
  • 关于TIOCLINUX的完整描述可以在内核源代码中的frivers/char/tty_io.c文件中得到

你可能感兴趣的:(Linux驱动(基础),printk,klogd,syslogd)