1. 程式人生 > 實用技巧 >在s3c2440上用GDB除錯linux核心

在s3c2440上用GDB除錯linux核心

前面的文章介紹瞭如何用ADS除錯uboot,把uboot調通以後,引導linux,卻發現怎麼都沒有列印log輸出。ADS在開啟mmu做過頁面對映以後就無法追蹤除錯下去了,所以得用其他的方法進行追蹤除錯。網上有好多說可以用openocd來進行除錯,也嘗試了下這個方法,發現不好配置,連不上除錯板,最終使用Jlink gdb成功除錯,不過網上的資料都比較分散,這邊做個筆記方便日後翻看。

我這邊是在ubuntu上面進行除錯的,所以需要先在ubuntu中安裝jlink 驅動,找到一種感覺最小白的方法來安裝jlink驅動:

https://blog.csdn.net/chile19/article/details/78980665

防止連結失效,把網址內容也貼下:

關於在Ubuntu安裝JLink驅動的最簡便方法

1、在JLink官網下載deb字尾,https://www.segger.com/downloads/jlink/#J-LinkSoftwareAndDocumentationPack


2、下載好後,複製到vmware的共享目錄中

3、在ubuntu中,複製到家目錄

4、直接開啟“Files”圖示,找到複製過來的deb檔案,雙擊,然後選 install,就ok了

安裝好jlink驅動以後,預設是安裝在/opt/SEGGER/Jlink下面

在虛擬機器上面,把jlink連線到虛擬機器裡面:

然後執行JLinkExe程式,如果看到cpu的相關資訊,說明安裝驅動成功:

對於2440的處理器,device要選擇arm9,否則無法識別,其他的選項直接回車用預設值就好。

確認安裝ok,就可以開始進行除錯了,首先執行JLinkGDBServer -device arm9 命令,需要帶上device引數,2440是arm9,不然無法工作:

Gdb server 起來以後,我們用arm-none-linux-gnueabi-gdb程式連上gdbserver,命令如下:

arm-none-linux-gnueabi-gdb vmlinux

不知道為什麼,使用arm-linux-gdb無法開啟連線,登入進gdb控制檯以後,使用如下命令

target remote localhost:2331

連線上JlinkGdb server

然後使用 break start_kernel 命令打斷點,其中start_kernel 是linux程式起來時執行的第一個c函式入口點,這時已經開啟mmu了,使用的是段式對映,然後使用 continue 指令,讓2440 程式繼續執行下去。因為gdb剛連上時,2440 cpu會被停止住,需要執行contine 指令,才能在串列埠控制檯上控制2440 download linux 核心,並引導核心,啟動gdb的流程如下:

一切準備就緒,這個時候在 串列埠控制檯下下載linux核心,並啟動核心:

因為我在uboot 中設定tftpboot 的載入記憶體地址為0x31000000,所以執行bootm 0x31000000讓uboot 去0x31000000去載入linux:

可以看到在booting the kernel 以後就沒有列印資訊了,booting the kernel 是在 自解壓程式中打印出來的,還沒有進入到 linux真正的kernel初始化部分,這個時候去看gdb介面,可以看到程式已經進入start_kernel的斷點:

這個時候說明利用gdb除錯 linux kernel是可行的,當然我也利用gdb偵錯程式成功讓kernel 打印出來資訊,使得系統移植可以繼續進行下去,3.10的kernel 對2440 處理器是有個坑的,唉,下面把gdb除錯時一些比較實用的命令列出來(目前我用到的):

step c語言級別的單步除錯,進入函式

next c語言級別的單步除錯,不進入函式

si 彙編級別的單步除錯,除錯進入printascii 函式以後(其實這是用匯編寫的),發現裡面有些彙編用的是巨集定義,使用si 只能看到停在某個巨集定義外面,看不到在巨集定義裡面執行到哪句了,可以使用如下命令看到具體的彙編執行過程:

disassemble 顯示當前的彙編程式

display /i $pc在每次執行下一條彙編語句時,都會顯示出當前執行的語句

還可以使用 info registers 檢視暫存器的值

monitor reset 可以讓cpu reset ,從0地址開始重新執行

具體使用就記錄這些,等移植完linux 以後再做一些筆記