最近遇到了内核模块printk输出的信息无法在终端显示。
解决办法:
原因1:printk()有一个控制日志级别的字段,如果该字段的日记级别高于console默认的日志级别那么才会打印出来(数值越小日志级别越高,分为从0-7共计8个日志级别)。有一种简单的改变当前终端的日志级别的方法,echo 8 > /proc/sys/kernel/printk。理论上这样printk就能输出到终端了。但是我的没有。
cat /proc/sys/kernel/printk
8 4 1 7
四个数字含义
/proc/sys/kernel/printk
The four values in this file are console_loglevel, default_mes-
sage_loglevel, minimum_console_level and default_con-
sole_loglevel. These values influence printk() behavior when
printing or logging error messages. See syslog(2) for more info
on the different loglevels. Messages with a higher priority
than console_loglevel will be printed to the console. Messages
without an explicit priority will be printed with priority
default_message_level. minimum_console_loglevel is the minimum
(highest) value to which console_loglevel can be set.
default_console_loglevel is the default value for con-
sole_loglevel.
原因2:syslogd守护进程的规则有问题,/etc/syslog.conf中定义了一些列规则,其中就包含数内核消息的处理规则,Fedora中的syslogd守护进程叫做rsyslogd,相应它的规则配置文件叫rsyslog.conf,其中有一行”#kern.* /dev/console“它的意思是把所有日志级别的内核log都输出到/dev/console即我们的终端。我们只需要把该行的'#'去掉,重启,理论上那么内核log (printk()输出也是内核log)就会输出到终端了。但是我的没找到大哥所说的文件。
原因3:系统中同时有klogd和syslogd守护进程那么不管日志级别是什么都不能输出到终端。
如果不能在终端上看到printk的输出,那么可以通过查看/var/log/messages文件,或运行dmesg命令查看,或查看/proc/kmsg文件获得信息,或是通过ctrl+alt+f2~f6进入系统文本模式装载模块,这样也可以看到prink()输出的信息,当然这里就准确对应原因1中所讲的规则。感觉这方法还算靠谱。
附一位大仙说的原因:
printk () 打出来的东西不是打到 stdout 或者 stderr 上,所以你没法直接看到。
你可以通过 dmesg 来查看。
附 printk() 作用的解释, 取自 linux kernel primer:
printk()
One of the most basic kernel messaging systems is the printk() function. The kernel uses printk() as opposed to printf() because the standard C library is not linked to the kernel. printk() uses the same interface as printf() does and displays up to 1,024 characters to the console. The printk() function operates by trying to grab the console semaphore, place the output into the console's log buffer, and then call the console driver to flush the buffer. If printk() cannot grab the console semaphore, it places the output into the log buffer and relies on the process that has the console semaphore to flush the buffer. The log-buffer lock is taken before printk() places any data into the log buffer, so concurrent calls to printk() do not trample each other. If the console semaphore is being held, numerous calls to printk() can occur before the log buffer is flushed. So, do not rely on printk() statements to indicate any program timing.
printk() 将输出打倒了内核提供的 console buffer 里面,再由这个 console 的驱动将其打印出来。