天天看點

打開dev_dbg()調試開關開啟DEBUG調整printk日志級别寫在最後

打開dev_dbg開關,使其日志輸出到控制台

核心驅動中(大多數是子系統中)有大量使用dev_dbg列印日志資訊,但是這些資訊預設是不會輸出到控制台的。調試過程中,我們如何打開DEBUG,擷取這些dev_dbg日志呢?

打開dev_dbg需要滿足兩個條件:

  • 開啟DEBUG
  • 調整printk日志級别

下面介紹為什麼需要這兩個條件以及如何修改。

開啟DEBUG

首先看下dev_dbg的定義:

#if defined(CONFIG_DYNAMIC_DEBUG)
#define dev_dbg(dev, format, ...)            \
do {                             \
    dynamic_dev_dbg(dev, format, ##__VA_ARGS__); \
} while ()
#elif defined(DEBUG)
#define dev_dbg(dev, format, arg...)        \
    dev_printk(KERN_DEBUG, dev, format, ##arg)
#else
#define dev_dbg(dev, format, arg...)                \
({                              \
    if ()                          \
        dev_printk(KERN_DEBUG, dev, format, ##arg); \
    ;                          \
})
#endif
           

動态調試dev_dbg過程繁瑣,且需要核心打開CONFIG_DYNAMIC_DEBUG選項才可以,這裡暫不讨論。

首先需要定義DEBUG,即

#define dev_dbg(dev, format, arg...)        \
    dev_printk(KERN_DEBUG, dev, format, ##arg)
           

在需要打開dev_dbg的驅動檔案子產品開頭:

#define DEBUG           /* Enable dev_dbg */

#include xxx
...

<xxx.c>
           

根據dev_dbg的定義,隻有打開DEBUG,才能滿足打開dev_dbg調試開關的第一個條件。

調整printk日志級别

打開DEBUG開關後,dev_dbg日志也是不會輸出到控制台的。因為預設的printk日志級别是7,隻有高于該級别的printk日志才會輸出到控制台,printk日志級别如下:

#define KERN_EMERG  KERN_SOH "0"    /* system is unusable */
#define KERN_ALERT  KERN_SOH "1"    /* action must be taken immediately */
#define KERN_CRIT   KERN_SOH "2"    /* critical conditions */
#define KERN_ERR    KERN_SOH "3"    /* error conditions */
#define KERN_WARNING    KERN_SOH "4"    /* warning conditions */
#define KERN_NOTICE KERN_SOH "5"    /* normal but significant condition */
#define KERN_INFO   KERN_SOH "6"    /* informational */
#define KERN_DEBUG  KERN_SOH "7"    /* debug-level messages */
           

而dev_dbg的日志級别也是7,如下:

#define dev_dbg(dev, format, arg...)        \
    dev_printk(KERN_DEBUG, dev, format, ##arg)
           

是以,預設不會輸出到控制台。

需要修改printk預設日志級别低于dev_dbg的日志級别,dev_dbg日志資訊才能輸出到控制台。修改printk預設日志級别的方法有很多種,這裡提供兩種:

  • 修改DEFAULT_CONSOLE_LOGLEVEL
  • Rockchip平台修改方式

修改DEFAULT_CONSOLE_LOGLEVEL

DEFAULT_CONSOLE_LOGLEVEL表示控制台輸出的最低級别,預設的DEFAULT_CONSOLE_LOGLEVEL在核心檔案kernel/printk.c中定義:

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

修改這裡的DEFAULT_CONSOLE_LOGLEVEL為8,這樣KERN_DEBUG就可以輸出到控制台了。

Rockchip平台修改方式

Rockchip也可以通過第一種方式實作,但是這種方式略顯粗暴,這裡我們提供另外一種方式,即通過指令行參數傳遞的方式傳遞loglevel來修改printk預設日志級别。

RK指令行參數傳遞是通過parameter實作的,有關parameter詳細資訊可自行查閱資料。這裡給出修改方式,parameter修改如下:

...

CMDLINE:console=ttyFIQ0 loglevel= androidboot.selinux=permissive 
androidboot.hardware=rk30board androidboot.console=ttyFIQ0 ...

...
           

添加loglevel=8設定kernel printk的預設日志級别為8,這樣KERN_DEBUG就可以輸出到控制台了。

注:CMDLINE指令行參數傳遞是如何修改printk預設日志級别有待研究。

寫在最後

需要滿足兩個條件才能打開dev_dbg調試開關,開啟DEBUG的方法也有缺陷,就是必須在驅動檔案定義#define DEBUG,如果需要調試的檔案很多,或者調試初期無法确定問題是在哪個檔案時,如何處理?這裡提供一個參考,kernel頂層Makefile中KBUILD_CFLAGS+=DDEBUG可實作,但又會引入更多問題,比如DVFS的大量日志等等。

參考蝸窩Linux kernel debug技巧

繼續閱讀