接上文《Linux內核驅動開發之KGDB單步調試內核(kgdboc方式) http://www.linuxidc.com/Linux/2013-06/86233.htm 》。上篇文章中,僅簡單介紹使用串口的Kgbd的流程(kgdboc方式),本文將重點介紹KGDB調試Linux內核的原理。內核版本在2.6.26以前的Linux,kgdb是通過補丁安裝的,過程非常復雜,而且問題比較多.Linux內核從 2.6.26開始已經在內部集成kgdb,只需要配置kgdb並重新編譯2.6.26(或更高)內核即可.使用kgdb調試需要兩台機器,即主機和目標機(一般為開發板),兩者通過串口線相連。要調試的內核編譯需要配置支持kgbd,它跑在目標機上,主機上使用gdb通過串口線進行遠程調試目標機上的內核。另外kgdb還支持網絡方式(即kgdboe方式)進行遠程調試內核,見本文第三部分。
一、KGDB原理:
Kgdb相關源碼主要實現了主機上gdb遠程調試所需的功能,包括命令處理、陷阱處理以及串口通信3個主要部分。Kgdb會在Linux內核中添加一個調試stub,調試stub是Linux內核中的一小段代碼,是運行gdb的開發機和目標機內核之間的媒介。gdb和調試stub之間通過gdb串行協議進行通信。Gdb串行協議是一種基於消息的ASCII碼協議,包含了各種調試命令。當設置斷點時,kgdb將斷點的指令替換為一條trap指令,當執行到斷點時控制權就轉移到調試stub中去。此時,調試stub的任務就是使用遠程串行通信協議將當前內核環境傳送給gdb,然後從gdb處接收命令。gdb命令告訴調試stub下一步該做什麼,當調試stub收到繼續執行的命令時,將恢復內核的運行環境,把對cpu的控制權重新交還給內核。
二、KGDB功能部件:
(1)GDB stub。
Gdb stub被稱為調試插樁(簡稱為stub),是kgdb調試器的核心。它是Linux內核中的一小段代碼,用來處理主機上gdb發來的各種請求;並且在內核處於被調試狀態時,控制目標機上的處理器。
(2)陷阱處理。
當設置斷點時,kgdb會提供一個異常處理函數,將斷點位置的指令替換成一條異常指令。執行到該斷點時該異常會發生,內核則將cpu控制權交給kgdb調試器,程序進入kgdb的提供異常處理函數中。在該異常處理函數中,可以分析內核代碼的各種情況。
(3)串口通信。
Gdb和調試stub之間通過gdb串行協議進行通信。它是一種基於消息的ASCII碼協議,包含了各種調試命令。
三、KGDBOE方式配置:(參閱Linux內核驅動開發之KGDB單步調試內核(kgdboc方式) )
最後要說的是除了使用串口外,也可以使用網卡進行通信,也就是kgdboe方式。kgdboe方式要比kgdboc方式優越,上篇kgdboc使用流程中也提到,當u-boot加載內核執行到 kgdb: Waiting for connection from remote gdb... 要手動關閉該串口,因為gdb遠程連接時也需要此串口。那麼帶來的影響就是我們無法看到調試過程中內核的輸出信息,而網卡(kgdboe)方式剛可以避免這一缺陷。下面簡單介紹下網卡方式(kgdboe)的配置流程:
(1)配置內核:
a) CONFIG_NETCONSOLE (Networking support -> Network console logging support)
b) CONFIG_DEBUG_KERNEL (Kernel hacking -> Kernel Debugging)
c) CONFIG_KGDB (Kernel hacking -> KGDB)
d) CONFIG_KGDB_ETH (Kernel hacking -> KGDB -> Method of KGDB communication -> Ethernet)
(2)修改u-boot的啟動參數bootargs以支持kgdb調試(與kgdboc類似):
setenv bootargs 'console=…kgdboe=[target-port]@<target-ip>/[dev][target-macaddr],[host-port]@<host-ip>/[dev] kgdbwait … nfsroot=…
舉例:[email protected]/,@192.168.1.3/
主要增加以上紅色字體部分,解釋下參數的意義:
■ target-port (optional): GDB port (default 6443)
■ target-ip: target ip address (i.e DVEVM ip address)
■ dev (optional): network interface (default eth0)
■ host-port (optional): Host port use to send/recieve UDP packets (default 6442)
■ host-ip: Host IP address