標籤:linux驅動 核心 調試
問題描述:最近這兩天再調試 platform 驅動,程式老是有點小問題,得不到自己想要的結果,突然意識到核心調試重要性,重新整理一下 printk 基本用法。核心通過 printk() 輸出相關資訊,在調用 printk() 函數時必須要指定記錄層級。
1、printk 日誌等級
在 include/linux/kernel.h 中定義了如下幾個記錄層級
<span style="font-family:Microsoft YaHei;font-size:12px;">#defineKERN_EMERG"<0>"/* 系統崩潰 */#defineKERN_ALERT"<1>"/* 必須緊急處理 */#defineKERN_CRIT"<2>"/* 臨界條件,嚴重的硬軟體錯誤 */#defineKERN_ERR "<3>" /* 報告錯誤 */#defineKERN_WARNING"<4>"/* 警告 */#defineKERN_NOTICE"<5>"/* 普通但還是須注意 */#defineKERN_INFO"<6>"/* 資訊 */#defineKERN_DEBUG"<7>"/* 調試資訊 */</span>
這裡也可以看出數值越小,其緊急和嚴重程度就越高。
接下來,我們來看 kernel/printk.c 檔案:
/* printk's without a loglevel use this.. */#define DEFAULT_MESSAGE_LOGLEVEL 4 /* KERN_WARNING *//* 因此,如果未在 printk() 中指定記錄層級,系統將預設採用4級 *//* 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 */};/* 這4組數字可以在/proc/sys/kernel/printk中更改 */
在 /proc/sys/kernel/printk 會顯示4個數值(可由 echo 修改),分別表示
當前控制台記錄層級;
未明確指定記錄層級的預設訊息記錄層級;
最小(最高)允許設定的控制台記錄層級;
引導時預設的記錄層級;
當 printk()中指定的層級 (數值上)小於 當前控制台記錄層級(前面說過,數值越小,嚴重性越高)時,printk 的資訊(要有\n符)就會在控制台上顯示。但無論當前控制台記錄層級是何值,通過 dmesg 總能查看。
系統的日誌記錄工具有兩種主要的:syslog 和 klog。
syslog 用於執行系統日誌記錄活動,系統進程顯示為 syslogd。設定檔是/etc/syslog.conf。如果在設定檔中把kern.*這一行前的#號去掉,那麼printk的資訊也會輸出到控制台。其守護進程是syslogd。syslogd 進程從一組日誌源(如 /dev/log 和 /dev/klog )中讀取資料,並按照 /etc/syslog.conf 中的說明處理這些日誌訊息。
2、printk 輸出格式符
如果變數類型是 , 使用 prink 的格式說明符 :
int %d 或者 %x( 註: %d 是十進位, %x 是十六進位 )
unsigned int %u 或者 %x
long %ld 或者 %lx
unsigned long %lu 或者 %lx
long long %lld 或者 %llx
unsigned long long %llu 或者 %llx
size_t %zu 或者 %zx
ssize_t %zd 或者 %zx
原始指標值必須用 %p 輸出。
u64,即(unsigned long log n),必須用 %llu 或者 %llx 輸出,如:
printk("%llu", (unsigned long long)u64_var);
s64,即(long long),必須用 %lld 或者 %llx 輸出,如 :
printk("%lld", (long long)s64_var);
Linux 核心調試之 printk