1. 程式人生 > >調整核心printk列印級別--減少啟動時的列印資訊

調整核心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編譯即可。