调整内核printk打印级别--减少启动时的打印信息

本文介绍 Linux 内核 printk 函数的使用方法及其日志级别的控制方式。通过修改 /proc/sys/kernel/printk 文件内容,可以实现对内核模块调试信息的精确控制。此外,还介绍了如何在 I2C 驱动开发中利用 printk 进行调试。

有时调试内核模块,打印信息太多了,可以通过修改/proc/sys/kernel/printk文件内容来控制。默认设置是6   4   1   7

# cat /proc/sys/kernel/printk

7       4       1      7

该文件有四个数字值,它们根据日志记录消息的重要性,定义将其发送到何处。关于不同日志级别的更多信息,请查阅syslog(2)联机帮助。上面显示的4个数据分别对应:

控制台日志级别:优先级高于该值的消息将被打印至控制台

默认的消息日志级别:将用该优先级来打印没有优先级的消息

最低的控制台日志级别:控制台日志级别可被设置的最小值(最高优先级)

默认的控制台日志级别:控制台日志级别的缺省值

 

数值越小,优先级越高

                其实这四个值是在kernel/printk.c 中被定义的,如下:

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 */

};

 内核通过printk() 输出的信息具有日志级别,日志级别是通过在printk() 输出的字符串前加一个带尖括号的整数来控制的,如printk("<6>Hello, world!\n");。内核中共提供了八种不同的日志级别,在 linux/kernel.h 中有相应的宏对应。

#define KERN_EMERG  "<0>"   /* systemis unusable */

#define KERN_ALERT  "<1>"   /* actionmust be taken immediately */

#define KERN_CRIT    "<2>"   /*critical conditions */

#define KERN_ERR     "<3>"   /* errorconditions */

#define KERN_WARNING "<4>"   /* warning conditions */

#define KERN_NOTICE  "<5>"   /* normalbut significant */

#define KERN_INFO    "<6>"   /*informational */

#define KERN_DEBUG   "<7>"   /*debug-level messages */

所以printk() 可以这样用:printk(KERN_INFO"Hello, world!\n");。

未指定日志级别的printk() 采用的默认级别是DEFAULT_MESSAGE_LOGLEVEL,这个宏在kernel/printk.c 中被定义为整数4,即对应KERN_WARNING。

如果要想在内核启动过程中打印少的信息,就可以根据自己的需要在kernel/printk.c中修改以上数值,重新编译即可!

/* printk's without a loglevel use this.. */

#define DEFAULT_MESSAGE_LOGLEVEL 4 /* KERN_WARNING */

 

了解了上面的这些知识后,我们就应该知道如何手动控制printk打印了。例如,我想屏蔽掉所有的内核printk打印,那么我只需要把第一个数值调到最小值1或者0。

# echo 1       4       1      7 > /proc/sys/kernel/printk

或者

# echo 0       4       0      7 > /proc/sys/kernel/printk



Linux 内核配置以打印设备驱动调试信息  

注: 转载请注明出处, 来自chenhui的博客:http://blog.163.com/whpt_chenhui/blog/static/1665966902011111113710540/
最近学习Linux内核下IIC驱动编程,想打印调试消息,弄了半天才弄出来,和大家一起分享以下:
在网上搜了一下帖子,说得不甚清楚,我结合我的应用整理了一下.
内核在IIC驱动( ./drivers/i2c/ )的makefile有如下代码:
ifeq ($(CONFIG_I2C_DEBUG_CORE),y)
EXTRA_CFLAGS += -DDEBUG
endif

Kconfig里面当然也有对应的:
config I2C_DEBUG_CORE bool "I2C Core debugging messages"
    help Say Y here if you want the I2C core to produce a bunch of debug
      messages to the system log.  Select this if you are having a
      problem with I2C support and want to see more of what is going on.

在配置内核时, 设置IIC对应的debug项目:
Device Drivers --->
    <*> I2C support -->
        <*> I2C Core debugging messages
        
<*> I2C Algorithm debugging messages
        
<*> I2C Bus debugging messages
        
<*> I2C Chip debugging messages

重新编译内核然. 烧写启动后更该printk的缺省值:
#echo 8 > /proc/sys/kernel/printk
后运行 ./i2c_test, 会看见如下的调试信息:
注: IIC测试程序代码:http://blog.youkuaiyun.com/hongtao_liu/article/details/4964244

i2c-adapter i2c-0: ioctl, cmd=0x702, arg=0x01

i2c-adapter i2c-0: ioctl, cmd=0x701, arg=0x02

i2c-adapter i2c-0: ioctl, cmd=0x707, arg=0xbeb95d28

i2c-adapter i2c-0: master_xfer[0] W, addr=0x50, len=2

s3c2440-i2c s3c2440-i2c: START: 000000d0 to IICSTAT, a0 to DS

s3c2440-i2c s3c2440-i2c: iiccon, 000000e0

s3c2440-i2c s3c2440-i2c: STOP

s3c2440-i2c s3c2440-i2c: master_complete 0

i2c-adapter i2c-0: ioctl, cmd=0x707, arg=0xbeb95d28

i2c-adapter i2c-0: master_xfer[0] W, addr=0x50, len=1

i2c-adapter i2c-0: master_xfer[1] R, addr=0x50, len=1

s3c2440-i2c s3c2440-i2c: START: 000000d0 to IICSTAT, a0 to DS

s3c2440-i2c s3c2440-i2c: iiccon, 000000e0

s3c2440-i2c s3c2440-i2c: WRITE: Next Message

s3c2440-i2c s3c2440-i2c: START: 00000090 to IICSTAT, a1 to DS

s3c2440-i2c s3c2440-i2c: iiccon, 000000f0

s3c2440-i2c s3c2440-i2c: READ: Send Stop

s3c2440-i2c s3c2440-i2c: STOP

s3c2440-i2c s3c2440-i2c: master_complete 0

buff[0]=58


网上也有方法,直接在IIC的i2c-core.c, i2c-dev.c, i2c-s3c2410.c中第一行直接加入

#define DEBUG    1 

运行后的调试信息和上面的一样. 具体如下:


注: 以下文章来自网络:
lsf0129的空间:
http://hi.baidu.com/lsf0129/blog/item/3e242d88d7315603c8fc7a08.html

  linux设备驱动调试,我们在内核中看到内核使用dev_dbg来控制输出信息,这个函数的实质是调用printk(KERN_DEBUG )来输出打印信息。要打开这个开关需要下面两步。
     1、打开调试开关:你调试的文件中必然包含了<linux/device.h>,或者《linux/paltforam_device.h》,后者包含了前者,在包含此头文件之前,使用#define DEBUG 1 来打开调试开关:例如
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/clk.h>
#include <linux/module.h>
#define DEBUG    1    /*添加在驱动的程序中,而非头文件*/
#include <linux/platform_device.h>

     在linux/device.h文件中:
#define dev_printk(level, dev, format, arg...)    \
    printk(level "%s %s: " format , dev_driver_string(dev) , (dev)->bus_id , ## arg)

#ifdef DEBUG
#define dev_dbg(dev, format, arg...)        \
    dev_printk(KERN_DEBUG , dev , format , ## arg)
#else
static inline int __attribute__ ((format (printf, 2, 3)))
dev_dbg(struct device * dev, const char * fmt, ...)
{
    return 0;
}
#endif
但是这个打开了之后,也不能顺利的输出信息,原因是printk有默认的信息级别。
    linux/kernel文件中
#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            */
可以看到KERN_DEBUG是级别最低的。


2、修改文件kernel/printk文件
/* 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 8 /* anything MORE serious than KERN_DEBUG */
   其中DEFAULT_CONSOLE_LOGLEVEL为终端console输出的最低级别,比这严重的都将输出。原来该值为7,则调试信息无法输出,修改为8则全部有输出。

3, 用echo命令
#echo 8 > /proc/sys/kernel/printk
#cat /proc/sys/kernel/printk
    
8       4       1       7
四个数字的含义:当前的loglevel、默认loglevel、最小允许的loglevel、引导时的默认loglevel。


去掉linux内核打印信息的一种方法
在使用嵌入式linux系统开发产品的过程中,有时会使用console作为用户操作界面,这时就没必要看到linux系统的启动信息,需要将它去掉,现有方法如下:

  在linux内核中的/kernel目录下printk.c文件中有一个函数:
CODE:
static void __call_console_drivers(unsigned long start, unsigned long end)
{
struct console *con;
for (con = console_drivers; con; con = con->next) {
if ((con->flags & CON_ENABLED) && con->write)
con->write(con, &LOG_BUF(start), end - start);
}
}

  去掉如下两行重新编译内核即可:
CODE:
if ((con->flags & CON_ENABLED) && con->write)
con->write(con, &LOG_BUF(start), end - start);


Linux内核用函数printk打印调试信息,该函数的用法与C库打印函数printf格式类似,但在内核使用。用户可在内核代码


中的某位置加入函数printk,直接把所关心的信息打打印到屏幕上或日志文件中。


函数printk根据日志级别(loglevel)对调试信息进行分类。日志级别用宏定义,展开为一个字符串,在编译时由预处理


器将它和消息文本拼接成一个字符串,因此函数printk中的日志级别和格式字符串间不能有逗号。


下面两个 printk 的例子,一个是调试信息,一个是临界信息:
printk(KERN_DEBUG "Here I am: %s:%i\n", _ _FILE_ _, _ _LINE_ _); 
printk(KERN_CRIT "I'm trashed; giving up>\n", ptr);


样例:在用户空间或内核中开启及关闭打印调试消息 用户还可以在内核或用户空间应用程序定义统一的函数打印调试信


息,可在Makefile文件中打开或关闭调试函数。定义方法列出如下:
/*debug_on_off.h*/
#undef PDEBUG             /* undef it, just in case */ 
#ifdef SCULL_DEBUG 
#ifdef _ _KERNEL_ _ 
    /* This>#define PDEBUG(fmt,args...) printk(KERN_DEBUG "scull: " fmt, ## args)
#else 
    /* This>#define PDEBUG(fmt, args...) fprintf(stderr, fmt, ## args) 
#endif 
#else 
#define PDEBUG(fmt, args...) /* not debugging: nothing */ 
#endif


在文件Makefile加上下面几行:
# Comment/uncomment the following line to disable/enable debugging 
DEBUG = y 
 
# Add your debugging flag (or not) to CFLAGS 
ifeq ($(DEBUG),y) 
 DEBFLAGS = -O -g -DSCULL_DEBUG # "-O" 
else 
 DEBFLAGS = -O2 
endif 
 
CFLAGS += $(DEBFLAGS)


更改makefile中的DEBUG值,需要调试信息时,DEBUG = y,不需要时,DEBUG赋其它值。再用make编译即可。


<think>嗯,用户想了解Linux内核日志打印等级的设置和作用。我之前学过一些Linux系统管理的知识,但得仔细回忆一下相关的细节。首先,内核日志是通过printk函数输出的,和用户空间的printf不同,printk需要指定日志级别。记得日志级别数字越小优先级越高,比如0是紧急情况,7是调试信息。 用户提供的引用里提到,控制台日志级别由/proc/sys/kernel/printk文件控制,这个文件有四个参数,但第一个参数最重要,决定了哪些信息能显示到控制台。例如,如果设置为4,那么只有级别0到3的信息会被显示。用户可能想知道如何查看和修改这个参数,比如用echo命令临时修改,或者通过dmesg命令调整。 另外,引用里还提到了通过启动参数loglevel来永久设置,这需要修改grub配置然后重启。可能用户有持久设置的需求,这时候就得用这种方法。不过临时修改的话,直接写入/proc/sys/kernel/printk或者用dmesg -n比较方便。 需要注意的是,不同发行版的设置方法可能略有不同,比如文件路径或工具的使用。用户可能需要根据实际环境调整步骤。另外,日志级别的作用是过滤信息,确保关键问题能被及时看到,而调试信息在需要时开启,避免控制台信息过载。 用户的问题可能还涉及到如何查看当前的日志级别,可以用cat /proc/sys/kernel/printk来查看四个参数的值。每个参数的含义需要解释清楚,比如第一个是控制台日志级别,第二个是默认消息级别,第三个是允许设置的最低级别,第四个是默认的控制台级别。 可能用户在实际操作中遇到问题,比如修改后不生效,这时候需要检查是否有权限,或者是否修改了正确的文件。此外,使用dmesg -n调整的是控制台的输出级别,但dmesg命令本身输出的日志可能还是按照默认级别,这点需要区分清楚。 总结一下,回答应该包括日志级别的定义、查看方法、临时和永久修改的方法,以及不同级别的应用场景。同时,结合用户提供的引用内容,正确引用来源,比如修改printk文件的方法来自引用2和5,启动参数来自引用5等。确保步骤清晰,命令准确,避免用户操作时出错。</think>### Linux 内核日志打印等级的设置与作用 #### 1. **日志等级定义** Linux 内核通过 `printk` 函数输出日志,其优先级由 **日志级别** 控制,级别数值越小优先级越高。具体级别如下: - **0 (KERN_EMERG)**: 系统不可用(最高优先级- **1 (KERN_ALERT)**: 需立即处理 - **2 (KERN_CRIT)**: 严重错误 - **3 (KERN_ERR)**: 错误 - **4 (KERN_WARNING)**: 警告 - **5 (KERN_NOTICE)**: 正常但需注意 - **6 (KERN_INFO)**: 普通信息 - **7 (KERN_DEBUG)**: 调试信息(最低优先级) 只有 **优先级高于控制台当前级别** 的日志才会输出到控制台[^3][^5]。 --- #### 2. **查看当前日志等级** 通过 `/proc/sys/kernel/printk` 文件查看当前设置: ```bash cat /proc/sys/kernel/printk ``` 输出结果为四个参数: `<控制台日志级别> <默认消息级别> <最低控制台级别> <默认控制台级别>` 例如 `4 4 1 7` 表示控制台仅显示优先级小于等于4的日志[^2][^5]。 --- #### 3. **设置日志等级** ##### **临时修改** - **修改控制台日志级别**(立即生效): ```bash echo <新级别> > /proc/sys/kernel/printk ``` 例如 `echo 7 > /proc/sys/kernel/printk` 允许所有日志输出到控制台[^1][^4]。 - **通过 `dmesg` 调整**(仅影响控制台输出): ```bash dmesg -n <级别> # 例如 dmesg -n 5 ``` ##### **永久修改** - **修改内核启动参数**: 在 GRUB 配置中(如 `/etc/default/grub`)添加 `loglevel=<级别>`,更新配置后重启生效。 例如: ```bash GRUB_CMDLINE_LINUX_DEFAULT="loglevel=4" ``` --- #### 4. **作用与场景** - **调试场景**:设置为 `7` 可查看详细调试信息。 - **生产环境**:设置为 `4` 或更低,减少冗余日志干扰。 - **关键问题排查**:临时调整为 `3` 以捕获错误级别以上的日志。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值