kernel hacking

linux標準的打印函數是printk。

#define KERN_EMERG "<0>"
#define KERN_ALERT "<1>"
#define KERN_CRIT "<2>"
#define KERN_ERR "<3>"
#define KERN_WARNING "<4>"
#define KERN_NOTICE "<5>"
#define KERN_INFO "<6>"
#define KERN_DEBUG "<7>"

通過proc文件系統,可以動態調整printk的打印級別。

#cat /proc/sys/kernel/printk
4 4 1 7

分別是
current log level,當前打印級別,如果優先級高於此級別,就打印出去。通常設置爲4.等於或者低於4級,不會被打印。
default log level,默認的printk的打印級別,如果調用printk時,沒有指定消息前導字符串,那麼就添加默認的等級前導字符串。通常設置爲4.
min log level value,可以被設置的最小值,一般爲1。
default console log level,默認的console log的打印級別,如果沒有通過proc文件系統修改打印級別,那麼默認的打印級別就從這個參數項中提取。通常設置爲7。

#echo 8 > /proc/sys/kernel/printk

將使得current log level 被設置爲8 ,即,高於8的消息都可以被打印,DEBUG是7,所以這時候可以被打印出來。

在驅動開發時,通常使用了封裝了printk的宏。

#define dev_printk(level, dev, format, arg...) \
		printk(level "%s %s:" format, dev_driver_string(dev), (dev)->bus_id, ##arg)

#define dev_dbg(dev, format, arg...) \
		dev_printk(KERN_DEBUG, dev, format, ##arg)
#define dev_err(dev, format, arg...) \
		dev_printk(KERN_ERR, dev, format, ##arg)
#define dev_info(dev, format, arg...) \
		dev_printk(KERN_INFO, dev, format, ##arg)
#define dev_warn(dev, format, arg...) \
		dev_printk(KERN_WARNING, dev, format, ##arg)
#define dev_notice(dev, format, arg...) \
		dev_printk(KERN_NOTICE, dev, format, ##arg)

printk不是直接向console發送數據,而是把數據先寫入buffer。等到console被初始化之後,再發送給console。
所以,通常要選擇earlyprintk。然後在bootargs中添加earlyprintk參數項。

oops消息,是確定錯誤的可能原因的重要依據。
oops消息,是機器指令,所以需要轉換成更友好的形式。
ksymoops工具用來完成這個工作。

#ksysoops -m System.map < myoops.txt

這個命令將oops信息轉換成人類語言格式,並將處理結果輸出重定向到txt文件中。
當然,在開發階段,也可以選擇kallsyms選項,讓內核可以追溯函數名稱,不再打印機器碼。但是代價是,符號表被編譯到內核中,而且常駐內存。

strace是一個有效的跟蹤工具,用來監控Process中調用的SYSCALL。
將strace綁定到一個PID上,就可以監控這個process的SYSCALL行爲。
輸出的結果,是一系列字符串行,
等式左邊表示執行的語句,等式右邊表示SYSCALL的返回值。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章