调试内核感觉很麻烦,在网上搜到的帖子倒是多,大多数都是复制粘贴过来,一搜一大堆,浪费大把的时间,简直就是在坑害人。其实我自己在这方面也不是很懂的。但是解决自己的这个问题,还是有点收获的。
在这之前要先谈一下printf和printk之间的区别:
printf 很容易理解,用户层函数,将字符打印到控制台上。
printk,内核层函数,内核会根据日志级别,可能把消息打印到当前控制台上,这个控制台通常是一个字符模式的终端、一个串口打印机或是一个并口打印机。这些消息正常输出的前提是──日志输出级别小于console_loglevel(在内核中数字越小优先级越高)。
没有指定日志级别的printk语句默认采用的级别是 DEFAULT_ MESSAGE_LOGLEVEL(这个默认级别一般为<4>,即与KERN_WARNING在一个级别上),其定义在linux26/kernel/printk.c中可以找到
日志级别一共有8个级别,printk的日志级别定义如下(在include/linux/kernel.h中):
#define KERN_EMERG 0/*紧急事件消息,系统崩溃之前提示,表示系统不可用*/
#define KERN_ALERT 1/*报告消息,表示必须立即采取措施*/
#define KERN_CRIT 2/*临界条件,通常涉及严重的硬件或软件操作失败*/
#define KERN_ERR 3/*错误条件,驱动程序常用KERN_ERR来报告硬件的错误*/
#define KERN_WARNING 4/*警告条件,对可能出现问题的情况进行警告*/
#define KERN_NOTICE 5/*正常但又重要的条件,用于提醒*/
#define KERN_INFO 6/*提示信息,如驱动程序启动时,打印硬件信息*/
#define KERN_DEBUG 7/*调试级别的消息*/
在程序中可以添加调试语句(终端打印调试)
printk(KERN_NOTICE "DevilBios hahahhahahahhahahahahahahah\n");
先改一下控制台级别:
通过读写/proc/sys/kernel/printk文件可读取和修改控制台的日志级别。查看这个文件的方法如下:
#cat /proc/sys/kernel/printk 6 4 1 7
上面显示的4个数据分别对应控制台日志级别、默认的消息日志级别、最低的控制台日志级别和默认的控制台日志级别。
可用下面的命令设置当前日志级别:
# echo 8 > /proc/sys/kernel/printk
这样理论什么都是可以打印到控制台上面去了。
但是当我们 insmod XXX.ko 的时候并没有什么现象产生:
接下来再学一个Linux命令:dmesg
dmesg用来显示开机信息,将kernel里的信息显示到控制台上,同理,我改变Linux里kernel内容,添加调试语句,那么调试语句也会打印到控制台 上。
dmesg用法:
-c
当完成打印显示后清除环缓冲内的内容。
-s 缓冲区大小
定义一个大小为"缓冲区大小"的缓冲区用于查询内核环缓冲区。默认大小为 8196(此大小与 2.0.33 和 2.1.103 内核的默认syslog 缓冲区大小一致),如果你设置了一个大于默认值的环缓冲区,那你就可以用这个选项定义一个相当的缓冲区来查看完整的环缓冲区内容。
-n级别
设置级别为记录控制台启动信息的级别。比如,-n 1指的就是将此级别设为最低级,除了内核恐慌信息之外不会向控制台显示信息。所有级别的启动信息还将记录到/proc/kmsg,文件中,因此,syslogd(8)同样可以用来对信息的输出进行控制。当使用-n选项时,dmesg将不会 清除内核环缓冲区中的内容。当同时使用以上两个选项时,只有最后一个选项才会产生效果
所以,在模块执行的时候,我们在终端里敲下命令dmesg,就可以看到调试语句了。