ubuntu 在 R40e 上 還有 Debian 在 Sempron 2600 上

2010年11月9日 星期二

device print in kernel

kernel, driver 有一堆 DBG( ...)。\
實際上是: #define DRIVER_NAME "mydriver" #define DBG(f, x...) \ pr_debug(DRIVER_NAME " [%s()]: " f, __func__, ## x)
呼叫 pr_debug。

pr_debug 又定義在: include/linux/kernel.h
#if defined(DEBUG)
#define pr_debug(fmt, ...) \
printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__)
#elif defined(CONFIG_DYNAMIC_DEBUG)
/* dynamic_pr_debug() uses pr_fmt() internally so we don't need it here */
#define pr_debug(fmt, ...) do { \
dynamic_pr_debug(fmt, ##__VA_ARGS__); \
} while (0)
#else
#define pr_debug(fmt, ...) \
({ if (0) printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__); 0; })
#endif
也就是說,要有 define DEBUG 或是 CONFIG_DYNAMIC_DEBUG 才會有效果。
還有 pr_debug 好像要 loglevel 設 8 才會直接 output 到 console.
device driver 都用 dev_err, dev_dbg 作 print 輸出。
定義在 include/linux/device.h
#if defined(DEBUG) #define dev_dbg(dev, format, arg...) \ dev_printk(KERN_DEBUG , dev , format , ## arg) #elif defined(CONFIG_DYNAMIC_DEBUG) #define dev_dbg(dev, format, ...) do { \ dynamic_dev_dbg(dev, format, ##__VA_ARGS__); \ } while (0) #else ...
其中 dev_dbg 定義是:
#define dev_printk(level, dev, format, arg...) \ printk(level "%s %s: " format , dev_driver_string(dev) , \ dev_name(dev) , ## arg)
所以只要 有 define DEBUG,dev_dbg 就是 printk 加一堆 device driver name..

但是好像不是所有的 driver Makefile 都有 DEBUG option,沒有的可能要自己加..
在對應driver 的 Makefile 最後,加上:
EXTRA_CFLAGS += -DDEBUG
但是 Makefile 好像沒有在 master Makefile 的 dependentenct check 裡,所以要自己 touch source code 再 make

這樣所有 dev_XXX 的 message 都會log起來,可以用 dmesg 印出來,但ˋ是只有 level 小於 loglevel 的 message 才會realtime印出console。

一般 (android) loglevel 是 3,設為 8 好像就可以把所有 message 都 realtime印出來。
ref : Enable log print out
kerenl 定義這些 run level 和 KERN_INFO, KERN_DEBUG 的地方是: linux/kernel.h
#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 */
決定 要不要從console 輸出是在 kernel/printk.c
/* 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 7 /* anything MORE serious than KERN_DEBUG */ DECLARE_WAIT_QUEUE_HEAD(log_wait); 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 */ }; 系統起來後,可以在
proc/sys/kernel/printk 裡看到這四個值 (cat 出來就可以)



好像有些 driver 用 DBG, 有些用 pr_debug,有些又用 dev_dbg..沒有統一。
kernel developer 好像有定一個rule,並且加入了 dynamic_debug 的功能:
http://lwn.net/Articles/286191/ 好像是說,follow rule使用 pr_debug, dev_dbg 印 message 的 module,只要 define support dynamic_message,在 load module 時就會被 list 在 /sys/kernel/debug 這樣就可以動態 enable/disable 這些 module print message

沒有留言:

標籤

網誌存檔