printk
We used the printk function in earlier chapters with the simplifying assumption that it works like printf. Now it's time to introduce some of the differences. 我们在前面的章节中使用了 printk 函数,并假设它像 printf 一样工作。 现在是时候介绍一些不同之处了。
One of the differences is that printk lets you classify messages according to their severity by associating different loglevels , or priorities, with the messages. You usually indicate the loglevel with a macro. For example, KERN_INFO, which we saw prepended to some of the earlier print statements, is one of the possible loglevels of the message. The loglevel macro expands to a string, which is concatenated to the message text at compile time; that's why there is no comma between the priority and the format string in the following examples. Here are two examples of printk commands, a debug message and a critical message: 区别之一是 printk 允许您通过将不同的日志级别或优先级与消息相关联,根据消息的严重性对消息进行分类。 您通常使用宏来指示日志级别。 例如,KERN_INFO,我们看到之前的一些打印语句,是消息的可能日志级别之一。 loglevel 宏扩展为一个字符串,在编译时连接到消息文本; 这就是以下示例中优先级和格式字符串之间没有逗号的原因。 以下是 printk 命令的两个示例,一条调试消息和一条关键消息:
printk(KERN_DEBUG "Here I am: %s:%i\n", _ _FILE_ _, _ _LINE_ _);
printk(KERN_CRIT "I'm trashed; giving up on %p\n", ptr);
There are eight possible loglevel strings, defined in the header
KERN_EMERG
Used for emergency messages, usually those that precede a crash. 用于紧急消息,通常是在崩溃之前的消息。
KERN_ALERT
A situation requiring immediate action. 需要立即采取行动的情况。
KERN_CRIT
Critical conditions, often related to serious hardware or software failures. 危急情况,通常与严重的硬件或软件故障有关。
KERN_ERR
Used to report error conditions; device drivers often use KERN_ERR to report hardware difficulties. 用于报告错误情况; 设备驱动程序经常使用 KERN_ERR 来报告硬件问题。
KERN_WARNING
Warnings about problematic situations that do not, in themselves, create serious problems with the system. 关于问题情况的警告本身不会对系统造成严重问题。
KERN_NOTICE
Situations that are normal, but still worthy of note. A number of security-related conditions are reported at this level. 正常的情况,但仍然值得注意。 在此级别报告了许多与安全相关的情况。
KERN_INFO
Informational messages. Many drivers print information about the hardware they find at startup time at this level. 信息性消息。 许多驱动程序在此级别打印有关他们在启动时找到的硬件的信息。
KERN_DEBUG
Used for debugging messages. 用于调试消息。
Each string (in the macro expansion) represents an integer in angle brackets. Integers range from 0 to 7, with smaller values representing higher priorities. 每个字符串(在宏扩展中)表示尖括号中的一个整数。 整数范围从 0 到 7,较小的值代表较高的优先级。
A printk statement with no specified priority defaults to DEFAULT_MESSAGE_LOGLEVEL, specified in kernel/printk.c as an integer. In the 2.6.10 kernel, DEFAULT_MESSAGE_LOGLEVEL is KERN_WARNING, but that has been known to change in the past. 没有指定优先级的 printk 语句默认为 DEFAULT_MESSAGE_LOGLEVEL,在 kernel/printk.c 中指定为整数。 在 2.6.10 内核中,DEFAULT_MESSAGE_LOGLEVEL 是 KERN_WARNING,但过去已知会发生变化。
Based on the loglevel, the kernel may print the message to the current console, be it a text-mode terminal, a serial port, or a parallel printer. If the priority is less than the integer variable console_loglevel, the message is delivered to the console one line at a time (nothing is sent unless a trailing newline is provided). If both klogd and syslogd are running on the system, kernel messages are appended to /var/log/messages (or otherwise treated depending on your syslogd configuration), independent of console_loglevel. If klogd is not running, the message won't reach user space unless you read /proc/kmsg (which is often most easily done with the dmesg command). When using klogd, you should remember that it doesn't save consecutive identical lines; it only saves the first such line and, at a later time, the number of repetitions it received. 基于日志级别,内核可以将消息打印到当前控制台,无论是文本模式终端、串行端口还是并行打印机。 如果优先级小于整数变量console_loglevel,则消息一次传递一行到控制台(除非提供了尾随换行符,否则不会发送任何内容)。 如果 klogd 和 syslogd 都在系统上运行,内核消息将附加到 /var/log/messages(或根据您的 syslogd 配置以其他方式处理),与 console_loglevel 无关。 如果 klogd 没有运行,消息将不会到达用户空间,除非您阅读 /proc/kmsg(这通常使用 dmesg 命令最容易完成)。 使用 klogd 时,您应该记住它不会保存连续的相同行; 它只保存第一行,并在稍后保存它收到的重复次数。
The variable console_loglevel is initialized to DEFAULT_CONSOLE_LOGLEVEL and can be modified through the sys_syslog system call. One way to change it is by specifying the -c switch when invoking klogd, as specified in the klogd manpage. Note that to change the current value, you must first kill klogd and then restart it with the -c option. Alternatively, you can write a program to change the console loglevel. You'll find a version of such a program in misc-progs/setlevel.c in the source files provided on O'Reilly's FTP site. The new level is specified as an integer value between 1 and 8, inclusive. If it is set to 1, only messages of level 0 (KERN_EMERG) reach the console; if it is set to 8, all messages, including debugging ones, are displayed. 变量console_loglevel初始化为DEFAULT_CONSOLE_LOGLEVEL,可以通过sys_syslog系统调用修改。 更改它的一种方法是在调用 klogd 时指定 -c 开关,如 klogd 手册页中所述。 请注意,要更改当前值,您必须先终止 klogd,然后使用 -c 选项重新启动它。 或者,您可以编写一个程序来更改控制台日志级别。 您可以在 O'Reilly 的 FTP 站点上提供的源文件中的 misc-progs/setlevel.c 中找到此类程序的一个版本。 新级别指定为 1 到 8 之间的整数值,包括 1 和 8。 如果设置为 1,则只有级别 0 (KERN_EMERG) 的消息到达控制台; 如果设置为 8,则显示所有消息,包括调试消息。
It is also possible to read and modify the console loglevel using the text file /proc/sys/kernel/printk. The file hosts four integer values: the current loglevel, the default level for messages that lack an explicit loglevel, the minimum allowed loglevel, and the boot-time default loglevel. Writing a single value to this file changes the current loglevel to that value; thus, for example, you can cause all kernel messages to appear at the console by simply entering: 也可以使用文本文件 /proc/sys/kernel/printk 读取和修改控制台日志级别。 该文件包含四个整数值:当前日志级别、缺少显式日志级别的消息的默认级别、允许的最小日志级别和引导时默认日志级别。 将单个值写入此文件会将当前日志级别更改为该值; 因此,例如,您可以通过简单地输入以下命令使所有内核消息出现在控制台上:
# echo 8 > /proc/sys/kernel/printk
It should now be apparent why the hello.c sample had the KERN_ALERT markers; they are there to make sure that the messages appear on the console. 现在应该很清楚为什么 hello.c 样本有 KERN_ALERT标记; 他们在那里确保消息出现在控制台上。