linux驱动--调试方法总结


关键词: linux驱动,调试,内核


 

内核编译

设备驱动程序的调试需要内核的支持,因此通常应该根据需要对内核进行重编译。

wuchao@wuchao-VirtualBox:/usr/src/linux-headers-3.2.0-23-generic-pae$sudo make menuconfig

make menuconfig 需要安装sudoapt-get insatll ncurses-dev,否则出现错误:

 

***Unable to find the ncurses libraries or the

***required header files.

*** ‘makemenuconfig’ requires the ncurses libraries.


 

 menuconfig图

调试工具

Binutils

objdump反汇编,addr2line转换地址到函数名, nm查看符号,gprof分析各个函数使用情况。

make vmlinux 表示对生成的内核镜像不压缩, 生成的内核镜像大约150M。

objdump -Dvmlinux > vmlinux.dis 内核镜像反汇编,生成的vmlinux.dis大约500M。

用内核错误处的ip指针,在vmlinux.dis中搜索,查找执行指令。

printk

printk()会将内核信息输出到内核信息缓冲区中。内核信息缓冲区是一个环形缓冲区(ring buffer),因此,如果塞入的消息过多,就会将之前的消息冲刷掉。通过/proc/sys/kernel/printk文件可以调节printk 的输出等级。

 

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


上面命令可以使得Linux内核的任何printk都被输出。

Gdb/KDB/KGDB

kgdb提供了一种使用 gdb调试 Linux 内核的机制。使用KGDB可以象调试普通的应用程序那样,在内核中进行设置断点、检查变量值、单步跟踪程序运行等操作。使用KGDB调试时需要两台机器,一台作为开发机(Development Machine),另一台作为目标机(Target Machine)。

安装kgdb调试环境需要为Linux内核应用kgdb补丁,补丁实现的gdb远程调试所需要的功能包括命令处理、陷阱处理及串口通讯3个主要的部分。kgdb补丁的主要作用是在Linux内核中添加了一个调试Stub。调试Stub是Linux内核中的一小段代码,提供了运行gdb的开发机和所调试内核之间的一个媒介。gdb和调试stub之间通过gdb串行协议进行通讯。gdb串行协议是一种基于消息的ASCII码协议,包含了各种调试命令。当设置断点时,kgdb负责在设置断点的指令前增加一条trap指令,当执行到断点时控制权就转移到调试stub中去。此时,调试stub的任务就是使用远程串行通信协议将当前环境传送给gdb,然后从gdb处接受命令。gdb命令告诉stub下一步该做什么,当stub收到继续执行的命令时,将恢复程序的运行环境,把对CPU的控制权重新交还给内核。

OOPS/PANIC

oops是内核级(特权级)的Segmentation Fault。

 

 

其他调试方法

进程跟踪工具strace

系统性能测试gprof

代码覆盖率测试gcov

core dump

内存泄漏检测工具 valgrind,  memwatch

 

 

 

2.6.18编译错误

linux内核2.6.18版本打kdb补丁后编译错误, 不建议使用kdb Kdb已经很久没更新,对i686及其他平台也没有支持了。


scripts/mod/sumversion.c: In function ‘get_src_version’:  

scripts/mod/sumversion.c:384:16: error: ‘PATH_MAX’ undeclared (first use in this function)  

scripts/mod/sumversion.c:384:16: note: each undeclared identifier is reported only once for each function it appears in  

scripts/mod/sumversion.c:384:7: warning: unused variable ‘filelist’ [-Wunused-variable]  

make[2]: *** [scripts/mod/sumversion.o] Error 1 

解决方法:# viscripts/mod/sumversion.c头文件包含中查看是否有limits.h,若没有,包含进去即可,,#inlcude <limits.h>

 

gcc: 错误: elf_i386:没有那个文件或目录

解决方法:arch/i386/kernel/Makefile文件,把"-m elf_i386" 替换为 "-m32"

 

drivers/video/sstfb.c:150:6:error: #elif with no expression

解决方法:#elif 改为#else

 

kernel/built-in.o:In function `.text.lock.mutex':

mutex.c:(.sched.text+0x17a7):undefined reference to `__mutex_lock_slowpath'

mutex.c:(.sched.text+0x17b1):undefined reference to `__mutex_unlock_slowpath'

make: ***[.tmp_vmlinux1] Error 1

解决方法:将.config文件中的CONFIG_DEBUG_MUTEXES宏值必为y即可。

                   CONFIG_DEBUG_MUTEXES=y

 





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