-
printk簡介
內核原始碼中用來記錄日志資訊的函式,只能在內核原始碼范圍內使用,用法和printf非常相似 -
printf 和 printk 對比
printf:glibc實作的列印函式,作業于用戶空間
printk:內核模塊無法使用glibc庫函式,內核自身實作的一個類printf函式,但是需要指定列印等級(若不指定就是用默認的列印等級), -
printk函式使用
在使用printk時我們會將列印等級/日志級別放到最開始的位置,如
printk(KERN_EMERG "EMERG\n");
我們沒有設定日志級別時,會為他設一個默認的日志級別:default_message_loglevel,
只有當 printk() 中的訊息日志級別小于當前控制臺日志級別(console_printk[0])時,printk 的資訊就會在控制臺上顯示, -
printk列印等級相關定義如下
// include/linux/kern_levels.h
#define KERN_SOH "\001" /* ASCII Start Of Header */
...
#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 */
- 查看當前系統printk列印等級:
cat /proc/sys/kernel/printk(不手動去修改的話就是依次列印原始碼中這四個陣列成員的值)
只有 prink 指定的列印等級比 console 小 才能列印到console,等于都不行,
//kernel/printk/printk.c
int console_printk[4] = {
CONSOLE_LOGLEVEL_DEFAULT, /* console_loglevel 當前控制臺日志級別*/
MESSAGE_LOGLEVEL_DEFAULT, /* default_message_loglevel 默認訊息日志級別*/
CONSOLE_LOGLEVEL_MIN, /* minimum_console_loglevel 最小的控制臺級別*/
CONSOLE_LOGLEVEL_DEFAULT, /* default_console_loglevel 默認控制臺日志級別*/
};
/ #
/ #
/ #
/ # cat /proc/sys/kernel/printk
7 4 1 7
/ #
/ #
/ #
- 若要修改上述默認優先級設定:
1、修改原始碼
2、修改/proc/sys/kernel/printk檔案
將要設定的值寫入到/proc/sys/kernel/printk中,我們要先cat /proc/sys/kernel/printk來看一下這個檔案中都有什么值,然后我們再寫入,其中這里的格式為:控制臺的日志級別、默認訊息日志級別、最小控制臺日志級別和默認控制臺日志級別,而我們要設定的就是第一個控制臺的日志級別,我們通過echo “W X Y Z” > /proc/sys/kernel/printk 將我們想要設定的四個值寫入到/proc/sys/kernel/printk中,
通過 dmesg 可以查看 printk 的所有列印資訊
-
內核log緩沖區大小有限制,緩沖區資料可能被沖掉
-
例程
#include <linux/module.h>
#include <linux/init.h>
#include <linux/kernel.h>
// __init 是把該函式放到統一的段里,所有內核模塊的入口函式都存到這個指定的段里,
// 等到內核呼叫了就釋放這個段,一次節約記憶體空間
// __exit 同理
static int __init hello_init(void)
{
printk(KERN_EMERG"%s(%d):[KERN_EMERG]\r\n", __FILE__, __LINE__);
// 也可以手動替換上面的宏如下,效果是一樣的
// printk("\001" "1""[ KERN_EMERG ] Hello World Module Init\n");
printk("\001" "7""%s(%d):[\"<7>\"]\r\n", __FILE__, __LINE__);
printk("\001" "6""%s(%d):[\"<7>\"]\r\n", __FILE__, __LINE__);
printk(KERN_DEBUG"\n\n%s(%d):[\"<7>\"]\r\n", __FILE__, __LINE__);
return 0;
}
static void __exit hello_exit(void)
{
printk("[ default ] goodbye\n");
}
module_init(hello_init);
module_exit(hello_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("author");
MODULE_DESCRIPTION("hello world module");
MODULE_ALIAS("test_module");
- 編譯測驗
/ #
/ #
/ #
/ # cat /proc/sys/kernel/printk
7 4 1 7
/ #
/ #
/ # modprobe test.ko
/home/jl/linux/imx6ull/linux_driver/z_exercise/test.c(7):[KERN_EMERG]
/home/jl/linux/imx6ull/linux_driver/z_exercise/test.c(11):["<7>"]
/ #
/ #
/ #
- 補充
內核模塊實驗
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/282325.html
標籤:其他
上一篇:基于百度地圖sdk的地圖app開發(五)——poi檢索
下一篇:2021-05-01
