调整内核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.csdn.net/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编译即可。

猜你喜欢

转载自blog.csdn.net/xingqingly/article/details/76592778