驱动调试之printk的使用

来源:互联网 发布:战地1玩家数据 编辑:程序博客网 时间:2024/06/05 07:49

用printk来调试驱动程序

先引进错误(不用虚拟地址,直接用物理地址)


编译驱动程序和测试程序并拷贝到网络文件系统里面去


装载驱动程序,运行测试程序


无法卸载驱动,因为程序崩溃,一直占用驱动,智能通过reboot重启


重启后安装驱动看打印


运行测试程序,打印出了26行,就知道是在后面的行死了


原因是访问了非法地址


查看gpfcon



应用程序调用open函数进而调用内核的open函数,进行打印调试(可以折半加打印,不用每行都加)

方法一:

我们可以再内核中使用如下打印语句:
#define DEG_PRINTK printk
//#define DEG_PRINTK(x...)  //不想用时定义为空的宏
DEG_PRINTK("%s %s %d\n",_FILE_,_FUNCTION_,_LINE_);
这行打印语句的意思就是讲本行代码所在的文件的名(包括路径)、所在的函数、所在的行打印出来
当我们需要调试的时候,就使用#define DEG_PRINTK printk这个宏,当不需要调试的时候,就使用#define DEG_PRINTK(x...)这个宏。其中#define DEG_PRINTK(x...)里面的"..."的意思是DEG_PRINTK的参数是可变的!,
当代码比较少的时候,我们可以在每一行都加上这个打印语句,这样很容易就会发现错误的位置!
当代码比较多的时候,我们可以采用对半查找的方法先在代码中间加上打印语句!然后判断出错位置在打印语句之前还是之后,如果出现在之前,就在之前的代码代码里面再次采用对半查找!


方法二:(系统运行中修改打印级别,从而减少或不打印内核信息,节省时间)

打印级别

printk加上打印级别

如果消息的打印级别msg_log_level(KERN_DEBUG)小于console_loglevel就打印,调整console_loglevel,要打印debug信息,需要把console_loglevel设置为8,因为msg_log_level(KERN_DEBUG)为7




loglevel

当uboot传入的参数有loglevel这个前缀时,后面带的字符串是str会作为参数调用函数loglevel把字符串转化成1个整数赋给值console_loglevel,console_loglevel在里面用到。把console_loglevel这个值改为0 就能把所有打印信息去掉。但可以用dmesg命令打印内核信息

重启后所有的打印信息都没有了

设置成debug级别,console_loglevel为10

会打印所有信息


方法三:,
上面我们说到过,要打印的信息会存放在log_buf中,通过文件/proc/kmsg可以来访问这个buf,然后将信息打印出来。由此我们就想了,我们是否可以构造这样一个mylog_buf,里面存放我们所需要的打印信息,通过一个/proc/kmsg文件可以访问该buf,然后打印出来?答案是肯定的!下面我们就一步步来完成!

0 0
原创粉丝点击