關鍵詞: 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. |
調試工具
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