一個不同是 printk 允許你根據消息的嚴重程度對其分類, 通過附加不同的記錄級別或者 優先級在消息上. 你常常用一個宏定義來指示記錄級別. 例如, KERN_INFO, 我們之前曾 在一些打印語句的前面看到過, 是消息記錄級別的一種可能值. 記錄宏定義擴展成一個字 串, 在編譯時與消息文本連接在一起; 這就是為什么下面的在優先級和格式串之間沒有逗 號的原因. 這里有 2 個 printk 命令的例子, 一個調試消息, 一個緊急消息:
printk(KERN_DEBUG "Here I am: %s:%i\n", FILE , LINE ); printk(KERN_CRIT "I'm trashed; giving up on %p\n", ptr);
有 8 種可能的記錄字串, 在頭文件 <linux/kernel.h> 里定義; 我們按照嚴重性遞減的 順序列出它們:
KERN_EMERG
用於緊急消息, 常常是那些崩潰前的消息.
KERN_ALERT
需要立刻動作的情形.
KERN_CRIT
嚴重情況, 常常與嚴重的硬件或者軟件失效有關.
KERN_ERR
用來報告錯誤情況; 設備驅動常常使用 KERN_ERR 來報告硬件故障.
KERN_WARNING
有問題的情況的警告, 這些情況自己不會引起系統的嚴重問題.
KERN_NOTICE
正常情況, 但是仍然值得注意. 在這個級別一些安全相關的情況會報告.
KERN_INFO
信息型消息. 在這個級別, 很多驅動在啟動時打印它們發現的硬件的信息.
KERN_DEBUG
用作調試消息.
每個字串( 在宏定義擴展里 )代表一個在角括號中的整數. 整數的范圍從 0 到 7, 越小 的數表示越大的優先級.
一條沒有指定優先級的 printk 語句缺省是 DEFAULT_MESSAGE_LOGLEVEL, 在 kernel/printk.c 里指定作為一個整數. 在 2.6.10 內核中, DEFAULT_MESSAGE_LOGLEVEL 是 KERN_WARNING, 但是在過去已知是改變的.
基於記錄級別, 內核可能打印消息到當前控制台, 可能是一個文本模式終端, 串口, 或者 是一台並口打印機. 如果優先級小於整型值 console_loglevel, 消息被遞交給控制台, 一次一行( 除非提供一個新行結尾, 否則什么都不發送 ). 如果 klogd 和 syslogd 都在 系統中運行, 內核消息被追加到 /var/log/messages (或者另外根據你的 syslogd 配置 處理), 獨立於 console_loglevel. 如果 klogd 沒有運行, 你只有讀 /proc/kmsg ( 用 dmsg 命令最易做到 )將消息取到用戶空間. 當使用 klogd 時, 你應當記住, 它不會保存 連續的同樣的行; 它只保留第一個這樣的行, 隨后是, 它收到的重復行數.
變量 console_loglevel 初始化成 DEFAULT_CONSOLE_LOGLEVEL, 並且可通過 sys_syslog 系統調用修改. 一種修改它的方法是在調用 klogd 時指定 -c 開關, 在 klogd 的 manpage 里有指定. 注意要改變當前值, 你必須先殺掉 klogd, 接着使用 -c 選項重啟它. 另外, 你可寫一個程序來改變控制台記錄級別. 你會發現這樣一個程序的版本在由 O' Reilly 提供的 FTP 站點上的 miscprogs/setlevel.c. 新的級別指定未一個整數, 在 1 和 8 之前, 包含 1 和 8. 如果它設為 1, 只有 0 級消息( KERN_EMERG )到達控制台; 如果它設為 8, 所有消息, 包括調試消息, 都顯示.
61
也可以通過文本文件 /proc/sys/kernel/printk 讀寫控制台記錄級別. 這個文件有 4 個 整型值: 當前記錄級別, 適用沒有明確記錄級別的消息的缺省級別, 允許的最小記錄級別, 以及啟動時缺省記錄級別. 寫一個單個值到這個文件就改變當前記錄級別成這個值; 因此, 例如, 你可以使所有內核消息出現在控制台, 通過簡單地輸入:
# echo 8 > /proc/sys/kernel/printk
現在應當清楚了為什么 hello.c 例子使用 KERN_ALERT 標志; 它們是要確保消息會出現 在控制台上.