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的返回值。

你可能感兴趣的:(driver)