標籤:
偵錯項目為公司一塊使用s3c2440的板子,調試器為基於ft2232d的openjtag,pc作業系統為ubunut14.04.2 x64,jtag->gdb橋為openocd 0.9.0。
1.準備核心源碼
拷貝出兩份完全一樣的核心源碼,不加調試資訊的一份燒寫/下載到板子上,加調試資訊的一份用於調試。這裡用uboot+nfs的方式下載核心。
~/buildspacce/linux-2.6.32.2_debug
~/buildspacce/linux-2.6.32.2_release
debug版源碼做如下配置
Kernel hacking ---> [*] Kernel debugging
[*] Compile the kernel with debug info
需要調試的驅動,編譯時間指定的核心源碼路徑,應當是debug版核心源碼。
【一】從頭開始調試核心
1.配置openocd
2.上電
串連arm板與openjtag
串連openjtag與pc
給arm板上電
3.開啟一個終端,啟動openocd
sudo /opt/openocd/bin/openocd -f ~/.openocd/openjtag.cfg -f /opt/openocd/share/openocd/scripts/target/samsung_s3c2440.cfg
4.開啟一個終端,通過telnet訪問openocd
telnet 127.0.0.1:4444
在telnet中輸入如下指令,複位ARM並停止運行,以便在核心啟動前加斷點。
jtag的原因,你的系統可能不會自己啟動起來,reset後才會啟動uboot。
> reset halt
5.另開啟一個終端,切換到核心源碼根目錄(需要先配置並編譯),啟動gdb。
PATH=$PATH:/opt/arm-linux-gcc/s3c2440_4.4.3/bincd ~/buildspacce/linux-2.6.32.2_debugarm-none-linux-gnueabi-gdb ./vmlinux -d .
在gdb中串連openocd,並設定核心進入地址為斷點
(gdb) target remote 127.0.0.1:3333
Remote debugging using :3333
0x000000ac in ?? ()
(gdb) b *0x30008040
(gdb) c
Continuing.
Breakpoint 1, 0x30008040 in ?? ()
0x30008040這個地址來源於uboot的列印(更早的時候開了minicom)
Entry Point: 30008040
接下來你就可以從頭開始調試核心了。
【二】調試正在運行中的核心。
1.串連arm、openjtag、pc,啟動openocd。
2.使用uboot下載核心,或從nand/nor啟動載入核心,讓arm系統正常運行起來(shell可用)。
3.telnet到openocd,使用
halt
指令停止arm處理器。
4.啟動gdb
PATH=$PATH:/opt/arm-linux-gcc/s3c2440_4.4.3/bincd ~/buildspacce/linux-2.6.32.2_debugarm-none-linux-gnueabi-gdb ./vmlinux -d .
在gdb中串連openocd,核心停止在休眠狀態。
(gdb) target remote :3333
Remote debugging using :3333s3c24xx_default_idle () at arch/arm/mach-s3c2410/include/mach/system.h:4040 for (i = 0; i < 50; i++) {
5.核心是你的了……
【三】調試核心模組
1.串連arm、openjtag、pc,啟動openocd,讓系統正常運行起來。
2.通過arm的串口、telnet、ssh等方式載入目標驅動,這裡被調試的核心模組為spi_slave.ko
3.查看核心模組的載入地址(虛擬位址)
# lsmodspi_slave 3055 0 - Live 0xbf000000# cat /sys/module/spi_slave/sections/.data0xbf000730# cat /sys/module/spi_slave/sections/.bss0xbf00091c
4.將arm系統halt掉,啟動gdb,gdb中串連openocd,載入核心模組的符號表
(gdb) target remote :3333Remote debugging using :3333s3c24xx_default_idle () at arch/arm/mach-s3c2410/include/mach/system.h:4040 for (i = 0; i < 50; i++) {(gdb) add-symbol-file ~/buildspace/spi_slave/spi_slave.o 0xbf000000 -s .data 0xbf000730 -s .bss 0xbf00091c add symbol table from file "/home/cjh/buildspace/spi_slave/spi_slave.o" at .text_addr = 0xbf000000 .data_addr = 0xbf000730 .bss_addr = 0xbf00091c(y or n) yReading symbols from /home/cjh/buildspace/spi_slave/spi_slave.o...done.
目前經常無法將驅動中的變數列印出來、無法加斷點,原因都是虛擬位址到物理地址的轉換有問題。解決方案還不明確
使用jtag+gdb調試arm上的linux核心和驅動