Linux内核打印-----printk
本文将展开介绍内核打印函数printk
printk
函数是Linux内核中常用的记录消息的函数之一。能在任何上下文中使用,并提供灵活的格式化输出功能。通过使用
printk
函数,开发者可以在内核代码中记录关键消息,进行调试以及了解系统的运行状况。
函数原型
/**
* printk - print a kernel message
* @fmt: format string
*
* This is printk(). It can be called from any context. We want it to work.
*
* We try to grab the console_lock. If we succeed, it's easy - we log the
* output and call the console drivers. If we fail to get the semaphore, we
* place the output into the log buffer and return. The current holder of
* the console_sem will notice the new output in console_unlock(); and will
* send it to the consoles before releasing the lock.
*
* One effect of this deferred printing is that code which calls printk() and
* then changes console_loglevel may break. This is because console_loglevel
* is inspected when the actual printing occurs.
*
* See also:
* printf(3)
*
* See the vsnprintf() documentation for format string extensions over C99.
*/
asmlinkage __visible int printk(const char *fmt, ...)
{
printk_func_t vprintk_func;
va_list args;
int r;
va_start(args, fmt);
/*
* If a caller overrides the per_cpu printk_func, then it needs
* to disable preemption when calling printk(). Otherwise
* the printk_func should be set to the default. No need to
* disable preemption here.
*/
vprintk_func = this_cpu_read(printk_func);
r = vprintk_func(fmt, args);
va_end(args);
return r;
}
EXPORT_SYMBOL(printk);
printk
函数使用asmlinkage
和__visible
修饰符,表示这是一个可见的内联函数,并可以在任意上下文中调用。
EXPORT_SYMBOL(printk)
表示将printk
函数导出为符号,使得其他模块能够使用该函数。
打印级别
共有如下8个级别,这些宏通常与printk函数一起使用,用于在内核中输出不同级别的消息到系统日志。
#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 */
#define KERN_DEFAULT KERN_SOH "d" /* the default kernel loglevel */
默认打印级别
console_printk数组
Linux内核源代码中,console_printk
是一个名为console_printk
的整型数组。该数组的定义如下所示:
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 */
};
其中,数组console_printk
的四个元素依次表示以下意义的值:
console_loglevel
:控制台(console)输出日志的级别。default_message_loglevel
:默认消息日志级别。minimum_console_loglevel
:最小控制台日志级别。default_console_loglevel
:默认控制台日志级别。
这些值在内核的初始化阶段被用于设定控制台输出日志的级别。这些级别控制了内核消息何时会被输出到系统的控制台上。
在这个数组中,CONSOLE_LOGLEVEL_DEFAULT
和MESSAGE_LOGLEVEL_DEFAULT
分别代表控制台和消息的默认日志级别,而CONSOLE_LOGLEVEL_MIN
代表最小的控制台日志级别。
这些值是Linux内核中用于控制内核消息输出的重要参数,在调试系统问题和进行日志记录时起着关键作用。
查看当前控制台的打印级别
cat /proc/sys/kernel/printk
输出的内容通常是一个由空格分隔的四个整数,分别表示以下意义的值:
- 控制台(console)输出日志的最小级别
- 默认消息日志级别
- 控制台输出日志的最小级别
- 默认控制台日志级别
输出可能是类似这样的信息:
4 4 1 7
与上面的console_printk数组对应