如果正常配置了输入输出终端,则内核启动过程中会将很多信息输出到控制台上。这些信息中有些表示严重错误,有些只是一般的提示信息。
在平台成熟后,继续保留这些信息既不美观,也会影响启动速度(串口的波特率很低)。因此要尽量屏蔽不重要的信息。这需要对内核进行一些改造。
内核打印分析
内核启动过程中的打印都是通过printk()输出的,按照重要程度,内核把这些打印分类为8个级别:
============== include/linux/printk.h 7 14 ===================
#define KERN_EMERG "<0>" /* system is unusable */
#define KERN_ALERT "<1>" /* action must be taken immediately */
#define KERN_CRIT "<2>" /* critical conditions */
#define KERN_ERR "<3>" /* error conditions */
#define KERN_WARNING "<4>" /* warning conditions */
#define KERN_NOTICE "<5>" /* normal but significant condition */
#define KERN_INFO "<6>" /* informational */
#define KERN_DEBUG "<7>" /* debug-level messages */
此外,内核还定义了一些宏来表示要输出到控制台上的级别、printk函数的默认级别等,在一个数组中描述:
=============== kernel/printk.c 60 74 =====================
/* printk's without a loglevel use this.. */
#define DEFAULT_MESSAGE_LOGLEVEL 4 /* KERN_WARNING */
/* We show everything that is MORE important than this.. */
#define MINIMUM_CONSOLE_LOGLEVEL 1 /* Minimum loglevel we let people use */
#define DEFAULT_CONSOLE_LOGLEVEL 7 /* anything MORE serious than KERN_DEBUG */
DECLARE_WAIT_QUEUE_HEAD(log_wait);
int console_printk[4] = {
DEFAULT_CONSOLE_LOGLEVEL, /* console_loglevel */
DEFAULT_MESSAGE_LOGLEVEL, /* default_message_loglevel */
MINIMUM_CONSOLE_LOGLEVEL, /* minimum_console_loglevel */
DEFAULT_CONSOLE_LOGLEVEL, /* default_console_loglevel */
};
浏览内核代码可以看到,基本上启动过程中的打印都是以默认级别KERN_WARNING及以下级别输出,因此要控制这些信息,只需要修改上面几个宏即可,尤其是将DEFAULT_CONSOLE_LOGLEVEL修改为4即可屏蔽大部分信息。
重新编译内核后尝试启动,可见大部分输出都被屏蔽了。
恢复打印
启动完成后恢复打印
改造后大部分的打印信息消失,但是启动后一些模块的正常printk也会被屏蔽,这会漏失掉很多重要信息,为此在启动完成后要恢复打印,方法是在启动脚本中执行一句:
echo 7 4 1 7 > /proc/sys/kernel/printk
就能恢复默认打印级别。
找回启动过程中的打印
如果启动过程异常,是不是打印就找不回来呢?当然不是,内核的printk除了向控制台输出外,还将一些信息输出到了/proc/kmsg中,可以在启动后通过dmsg命令全部找回。
恢复启动时打印
如果需要临时恢复打印,并不需要重新编译内核。在启动参数中配置一项ignore_loglevel即可:
=============== kernel/printk.c 471 479 ==================
static int __init ignore_loglevel_setup(char *str)
{
ignore_loglevel = 1;
printk(KERN_INFO "debug: ignoring loglevel setting.\n");
return 0;
}
early_param("ignore_loglevel", ignore_loglevel_setup);
在输出时会判断ignore_loglevel变量,如果为真则无论如何都会将信息输出到控制台上。
本文介绍了如何控制Linux内核启动时的打印信息,通过调整内核宏 DEFAULT_CONSOLE_LOGLEVEL 屏蔽不必要的输出,然后在启动完成后通过设置 `/proc/sys/kernel/printk` 恢复打印。当启动异常时,可以利用/proc/kmsg和dmesg命令找回启动过程中的打印记录。若临时恢复启动时打印,可在启动参数中添加 `ignore_loglevel`。

被折叠的 条评论
为什么被折叠?



