轉載自http://huenlil.pixnet.net/blog/post/23271426-printk()-%E4%BD%BF%E7%94%A8%E8%AA%AA%E6%98%8E
轉載自http://rritw.com/a/bianchengyuyan/C__/20121124/259446.html
核心通過 printk() 輸出的訊息具有日誌級別,日誌級別是通過在 printk() 輸出的字符串前加一個帶尖括號的整數來控制的,如 printk("<7>Hi, world!\n");。內核中共提供了八種不同的日誌級別,在 linux/kernel.h 中有相應的macro對應。
#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 */
#define KERN_INFO "<6>" /* informational */
#define KERN_DEBUG "<7>" /* debug-level messages */
所以 printk() 可以這樣用:
printk(KERN_DEBUG "Hello, world!\n");
printk(KERN_DEBUG "Here I am: %s:%i\n", _ _FILE_ _, _ _LINE_ _);
printk(KERN_CRIT "I'm trashed; giving up on %p\n", ptr);
/*没有定義日誌级别的printk使用下面的默認级别*/
#define DEFAULT_MESSAGE_LOGLEVEL 4 /* KERN_WARNING*/
为了更好地控制不同级别的信息顯示在控制台上,内核设置了控制台的日誌级别console_loglevel。printk日誌级别的作用是打印一定级别的消息,與之類似,控制台只顯示一定级别的消息。
/* 显示比这个级别更重发的消息*/
#define MINIMUM_CONSOLE_LOGLEVEL 1 /*可以使用的最小日志级别*/
#define DEFAULT_CONSOLE_LOGLEVEL 7 /*比KERN_DEBUG 更重要的消息都被打印*/
int console_printk[4] = {
DEFAULT_CONSOLE_LOGLEVEL,/*控制台日志级别,优先级高于该值的消息将在控制台显示*/
/*默认消息日志级别,printk没定义优先级时,打印这个优先级以上的消息*/
DEFAULT_MESSAGE_LOGLEVEL,
/*最小控制台日志级别,控制台日志级别可被设置的最小值(最高优先级)*/
MINIMUM_CONSOLE_LOGLEVEL,
DEFAULT_CONSOLE_LOGLEVEL,/* 默认的控制台日志级别*/
};
如果系统运行了klogd和syslogd,则无论console_loglevel为何值,内核消息都将追加到/var/log/messages中。如果klogd没有运行,消息不会传递到用户空间,只能查看/proc/kmsg。
变量console_loglevel的初始值是DEFAULT_CONSOLE_LOGLEVEL,可以通过sys_syslog系统调用进行修改。调用klogd时可以指定-c开关选项来修改这个变量。如果要修改它的当前值,必须先杀掉klogd,再加-c选项重新启动它。
通过读写/proc/sys/kernel/printk文件可读取和修改控制台的日志级别。查看这个文件的方法如下:
#cat /proc/sys/kernel/printk
6 4 1 7
上面显示的4个数据分别对应控制台日志级别、默认的消息日志级别、最低的控制台日志级别和默认的控制台日志级别。
可用下面的命令设置当前日志级别:
# echo 8 > /proc/sys/kernel/printk
另外為了防止 printk() 瞬時被呼叫次數過多,可以通過 printk_ratelimit() 來控制速度。printk_ratelimit() 通過跟蹤發送到控制台的消息數量工作,當輸出速度超過一個臨界值,就返回零。可通過修改 /proc/sys/kernel/{printk_ratelimit, printk_ratelimit_burst} 來調節 printk_ratelimit() 的計算。
printk_ratelimit() 的典型用法如下:
if (printk_ratelimit())
printk(KERN_INFO "Hello, world!\n");
參考http://www.makelinux.net/books/lkd2/ch18lev1sec3
If variable is of Type, use printk format specifier:
———————————————————
int %d or %x
unsigned int %u or %x
long %ld or %lx
unsigned long %lu or %lx
long long %lld or %llx
unsigned long long %llu or %llx
size_t %zu or %zx
ssize_t %zd or %zx
Raw pointer value SHOULD be printed with %p.
u64 SHOULD be printed with %llu/%llx, (unsigned long long):
printk(“%llu", (unsigned long long)u64_var);
s64 SHOULD be printed with %lld/%llx, (long long):
printk(“%lld", (long long)s64_var);
%pM : 印出 MAC Address