1. 背景

我们进行驱动和内核开发时,最常用的调试手段就是 printk()。该函数支持多个等级的日志级别,不同的内核配置会修改相应的日志级别,最终影响终端显示的日志信息。因此我们很有必要知道如何修改日志级别,以达到显示屏蔽显示日志的目的。

1.1 测试环境:

Kernel version:5.10.0(Xilinx petalinux-2021.2)

1.2 内核模块:

这里使用上篇文章中的 hello 驱动。该驱动中使用 KERN_DEBUG 模式持续输出调试信息。通过修改系统中对应文件的内容达到影响 printk() 的目的,最终可看到 hello 驱动中调试信息的有无。

2. 日志等级说明

Linux 内核中,日志等级定义在 include/linux/kern_levels.h 文件中。数值越小等级越高。

级别

对应内核日志级别

说明

0

KERN_EMERG

紧急消息。系统崩溃之前提示,表示系统已不可用。

1

KERN_ALERT

报告消息。表示必须立即采取措施。

2

KERN_CRIT

临界消息。通常涉及严重的硬件或软件操作失败。

3

KERN_ERR

错误消息。串口日志的默认级别。驱动程序常用 KERN_ERR 来报告硬件的错误。

4

KERN_WARNING

警告消息。对可能出现问题的情况进行警告。

5

KERN_NOTICE

正常但又重要的消息。用于提醒,常用于与安全相关的消息。

6

KERN_INFO

提示消息。如驱动程序启动时,打印硬件消息。

7

KERN_DEBUG

调试消息。设置此级别会打印所有日志消息。

3. 查看系统使用的日志等级信息

通常情况下,上述命令会输出 7 4 1 7

。这四个数字依次对应 console_logleveldefault_message_loglevelminimum_console_logleveldefault_console_loglevel

console_loglevel:控制台使用的日志级别;

default_message_loglevel:调用 printk() 未指定日志级别时使用的日志级别;

minimum_console_loglevel:允许设置的控制台日志级别(console_loglevel)最小值;

default_console_loglevel:系统启动时使用的日志级别。

4. 修改日志等级

通常情况下,为了加速系统启动,系统的启动信息会非常少。比如 default_console_loglevel 和 console_loglevel 为 4 的情况下,只能显示 err、crit、alert 和 emerg 等调式信息。这给内核模块的调式带来极大的不便。系统启动后,为了能够自如的控制调试信息的显示,我们有必要学习如何修改内核日志等级,以达到显示调试信息的目的。主要有以下几种实现方式。

4.1 proc/sys/kernel/printk

cat proc/sys/kernel/printk

可以显示当前内核日志等级信息。同时,使用 echo 命令能够控制对应的日志等级。

比如,编译内核前,设置了 default_console_loglevel4。系统启动后,我们想要显示 debug 级别的信息,那么我们可以使用如下命令:

为什么是 8 呢,KERNEL_DEBUG 的值不是 7 么?因为控制台(console)只会显示大于所设置等级的信息。比如只显示 alert 和 emerg 级别的信息,那么 console_loglevel 应该设置为 2。同样的,想要显示 debug 信息,console_loglevel 应设置为**大于 7 **的值。

系统重启后上述修改会丢失。

4.2 dmesg

dmesg -n <value>

和 echo x > proc/sys/kernel/printk

能够达到同样的效果。同样,系统重启后修改会丢失。

4.3 sysctl
4.3.1 临时修改

sysctl -w kernel.printk=xx

。该种方式和前面的两种方式达到的效果相同。同样的,系统重启后修改会丢失。

4.3.2 永久修改

sysctl 依据 etc/sysctl.conf 文件配置内核,比如可以通过配置该文件修改 socket 接收缓冲区大小。如果向该文件中加入 kernel.printk = 3 4 1 7,那么系统启动后串口终端只会显示 crit、alert、emerg 这三个等级的日志信息。

由于修改的系统配置文件,因此,系统重启后修改会保留并生效。

4.4 menuconfig

生成内核 image 之前,可以使用 make menuconfig

配置 default_console_loglevel 选项。比如配置为显示 debug 级别的信息,可以修改为如下设置。

通过内核中如下源码可知,console_loglevel 和 default_console_loglevel 值相同。因此内核启动后,使用 cat proc/sys/kernel/printk

可以得到 8 4 1 8

4.5 kernel parameter
4.5.1 loglevel

通过在内核启动参数 bootargs 中添加 loglevel=xx

也可以达到修改日志级别的功能。

比如,我们在内核中将 console_loglevel 设置为 4,然后在 bootargs 中添加 loglevel=8

。启动系统并登录后,在串口同样可以看到 hkm thread run 的信息。需要注意的是,这种方式设置的 loglevel

只会设置 console_loglevel 的值,不会设置 default_console_loglevel。

4.5.2 ignore_loglevel

也可以在内核启动参数中标明 ignore_loglevel

,也能达到 loglevel=8

的效果。

5. 总结

  1. 不管设置的日志级别为何值,dmesg
    命令总是能显示所有日志信息;

  1. 如果要修改系统启动时的日志显示,那么只能通过修改内核选项(make menuconfig) 或修改启动参数(bootargs)达到此目的;

  1. 系统启动后,可通过 echo x > /proc/sys/kernel/printkdmesg -n xsysctl -w kernel.printk=x临时修改日志显示级别。如果要永久修改,可以将 kernel.printk = x x x x 写入 /etc/sysctl.conf 文件中。

转载自:

https://www.modb.pro/db/407111

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐