在開始之前請先確認(rèn)你的電腦有并口,如果是筆記本就算了,買個(gè)PCMIA轉(zhuǎn)并口的卡的錢夠買個(gè)盜版U-Link了;要是肯下血本買盜版J-Link,那就看我以后寫的文章。
GDB使用GDB工具鏈,調(diào)試解決方案的結(jié)構(gòu)是
GDB前端<--->GDB<--->GDB服務(wù)程序<--->JTAG協(xié)議轉(zhuǎn)換器(仿真器)<--->目標(biāo)CPU(ARM CPU)
|
控制接口
GDB有一個(gè)很大的缺點(diǎn)——文本界面,使用非常不方便。但幸運(yùn)的是,有很多熱心的開發(fā)者為GDB寫了一些圖形“外殼”——GDB前端,大大方便了GDB的使用。因?yàn)槲覀冏龅氖墙徊骈_發(fā)(即在x86結(jié)構(gòu)的電腦上開發(fā)ARM等非x86結(jié)構(gòu)的CPU程序),所以GDB無法直接調(diào)試編譯出來的程序,這就需要一個(gè)服務(wù)程序。這個(gè)服務(wù)程序可以是一個(gè)可以控制目標(biāo)CPU的程序(可能運(yùn)行于計(jì)算機(jī)上;也可能運(yùn)行于某些仿真器上,例如如BDI2000就是這樣),也可以是一個(gè)運(yùn)行于目標(biāo)CPU上的服務(wù)程序,由它來裝載被調(diào)試的程序。但是后者一般需要目標(biāo)CPU上已經(jīng)運(yùn)行起了Linux內(nèi)核;調(diào)試Bootloader和Linux內(nèi)核本身,需要前一種服務(wù)程序。GDB和GDB服務(wù)程序之間的連接方式可以是以太網(wǎng)或者串口,而且GDB服務(wù)程序一般還有別的控制接口,例如Telnet接口,可以實(shí)現(xiàn)對目標(biāo)CPU的控制,如初始化和程序文件下載等。比較復(fù)雜哦,一會兒說到軟件的時(shí)候就會用上這些知識。
你需要的東西和裸奔代碼一樣
你需要的軟件有:
● 一個(gè)可以運(yùn)行的Linux
● 本機(jī)GCC編譯器
Open Suse自己帶的就可以
● 交叉GCC編譯器
● OpenOCD源碼
● Insight源碼
Insight是一個(gè)GDB的圖形前端,我感覺它比DDD更適合嵌入式系統(tǒng)程序的調(diào)試。
● 隨便什么程序的源碼,例如U-Boot
U-Boot就不用介紹了,如果不知道可以Google下。
下面開始編譯,先是OpenOCD,假設(shè)源代碼已經(jīng)解壓縮到了/home/lxz/build-openocd,先設(shè)定權(quán)限
# cd /home/lxz/build-openocd
# chmod 755 ./bootstrap
# ./bootstrap
等一會兒,輸入
# ./configure --prefix=/usr/local/arm/openocd --enable-parport
這里--prefix指定的是安裝的路徑,--enable-parport使能并口,然后
# make
# sudo make install
輸入root密碼,等一會兒,安裝就完成了
然后是insight,假設(shè)源碼已經(jīng)解壓縮到了/home/lxz/insight-6.8,然后
# cd /home/lxz/insight-6.8
# ./configure --prefix=/usr/local/arm/arm-linux-insight --target=arm-linux
這里--prefix指定的是安裝的路徑,--target指的是為ARM編譯GDB,等一會兒,輸入
# make
等一會兒,輸入
# sudo make install
輸入root密碼,等一會兒,安裝就完成了
然后編譯一個(gè)U-Boot用于測試,假設(shè)源碼已經(jīng)解壓縮到了/home/lxz/at91rm9200/u-boot-1.2.0,假設(shè)已經(jīng)修改完了Makefile中的交叉編譯器的選項(xiàng),假設(shè)我為AT91RM9200DK開發(fā)板編譯,然后
# cd /home/lxz/at91rm9200/u-boot-1.2.0
# make at91rm9200dk_config
# make
于是得到了/home/lxz/at91rm9200/u-boot-1.2.0/u-boot這個(gè)映像
# Daemon configuration
telnet_port 23
gdb_port 2331
daemon_startup reset
# JTAG interface configuration
interface parport
jtag_speed 0
reset_config trst_and_srst
jtag_device 4 0x1 0xf 0xe
# parport options
parport_port 0x378
parport_cable wiggler
# Target configuration
target arm920t little run_and_init 0 arm920t
run_and_halt_time 0 1000
target_script 0 reset at91rm9200_init.script
working_area 0 0x00200000 0x1000 backup
我還是提一下,上面這段配置信息中的target_script 0 reset at91rm9200_init.script這句就是指定第二個(gè)腳本的,而且讓OpenOCD在當(dāng)前目錄下搜索這個(gè)腳本。也就是說,如果at91rm9200.cfg在/home/lxz/at91rm9200下,那么你在/home/lxz/at91rm9200下啟動OpenOCD服務(wù)程序,OpenOCD就會在/home/lxz/at91rm9200下搜索at91rm9200_init.script這個(gè)腳本;如果在與at91rm9200.cfg所在路徑不同的路徑下啟動OpenOCD服務(wù)程序,OpenOCD就無法找到at91rm9200_init.script,此時(shí),target_script 0 reset at91rm9200_init.script這句就應(yīng)該寫成target_script 0 reset /home/lxz/at91rm9200/at91rm9200_init.script。
第二個(gè)腳本的作用是初始化ARM CPU,因?yàn)閁-Boot往往是在SDRAM里運(yùn)行的,其連接位置也都在SDRAM里。用GDB或GDB前端下載程序的時(shí)候,必須保證SDRAM是可用的。AT91RM9200這個(gè)CPU上電的時(shí)候如果從片內(nèi)Boot ROM啟動(不推薦從外部啟動,因?yàn)槿绻麤]有啟動程序,AT91RM9200將運(yùn)行于慢時(shí)鐘,這樣JTAG仿真器可能工作不正常),需要進(jìn)一步配置PLL,PIO,SDRMC之類的外設(shè)之后,SDRAM才可以使用。第二個(gè)腳本就是一系列寄存器讀寫和延時(shí)命令的集合,如何編寫請看OpenOCD的手冊
http://openfacts.berlios.de/index-en.phtml?title=OpenOCD_commands,給出我的at91rm9200_init.script。
mww 0xfffffc28 0x00000000
mww 0xfffffc2c 0x00000000
mww 0xfffffc20 0x0000ff01
sleep 20
mww 0xfffffc28 0x20263e04
sleep 20
mww 0xfffffc2c 0x10483e0e
sleep 20
mww 0xfffffc30 0x00000000
sleep 20
mww 0xfffffc30 0x00000202
sleep 20
mww 0xfffff870 0xffff0000
mww 0xfffff804 0xffff0000
mww 0xffffff60 0x00000002
mww 0xffffff64 0x00000000
mww 0xffffff98 0x2188c159
mww 0xffffff90 0x00000002
mww 0x20000000 0x00000000
mww 0xffffff90 0x00000004
mww 0x20000000 0x00000000
mww 0x20000000 0x00000000
mww 0x20000000 0x00000000
mww 0x20000000 0x00000000
mww 0x20000000 0x00000000
mww 0x20000000 0x00000000
mww 0x20000000 0x00000000
mww 0x20000000 0x00000000
mww 0xffffff90 0x00000003
mww 0x20000200 0x00000000
mww 0xffffff94 0x000002e0
mww 0x20000000 0x00000000
mww 0xffffff90 0x00000000
mww 0x20000000 0x00000000
arm7_9 sw_bkpts enable
這個(gè)腳本寫起來很復(fù)雜,建議從一些樣例代碼上把寄存器的數(shù)值扒過來。另外,有些CPU,例如S3C2410,它上電的時(shí)候,SDRAM是默認(rèn)可以用的,就不需要這個(gè)腳本了。還有一個(gè)值得注意的是,由于我們用的是Wiggler這種簡單的JTAG協(xié)議轉(zhuǎn)換器,初始化腳本里必須加上arm7_9 sw_bkpts enable這句,F(xiàn)在終于可以開始調(diào)試了,假設(shè)把OpenOCD安裝在了/usr/local/arm/openocd,把Insight安裝在了/usr/local/arm/arm-linux-insight,兩個(gè)初始化腳本都放在了/home/lxz/at91rm9200;你已經(jīng)正確連接了Wiggler,開發(fā)板已經(jīng)上電。接下來還是用命令來說明
# cd /home/lxz/at91rm9200
# sudo /usr/local/arm/openocd/bin/openocd -f at91rm9200.cfg
root's password:
Open On-Chip Debugger 1.0 (2008-07-21-20:15) svn:
$URL: http://svn.berlios.de/svnroot/repos/openocd/trunk/src/openocd.c $
Info: jtag.c:1329 jtag_examine_chain(): JTAG device found: 0x05b0203f (Manufacturer: 0x01f, Part: 0x5b02, Version: 0x0)
Info: target.c:240 target_init_handler(): executing reset script 'at91rm9200_init.script'
Info: options.c:50 configuration_output_handler(): software breakpoints enabled
這就說明OpenOCD已經(jīng)開始工作了。然后啟動Insight
# cd /home/lxz/at91rm9200/u-boot-1.2.0/
# /usr/local/arm/arm-linux-insight/bin/arm-linux-insight
出現(xiàn)下面的窗口
然后選擇菜單File>Target Settings...,在出現(xiàn)的窗口中進(jìn)行如下設(shè)置,然后點(diǎn)OK。
選擇菜單File>Open,打開/home/lxz/at91rm9200/u-boot-1.2.0/u-boot這個(gè)映像;然后選擇菜單Run>Download,將U-Boot程序下載到目標(biāo)CPU。然后在程序運(yùn)行的必經(jīng)之路設(shè)定一個(gè)斷點(diǎn),如下圖所示。
選擇菜單Control>Continure,程序就會從頭開始執(zhí)行,并停在斷點(diǎn)處了。Insight還有很多不錯的功能,并且很容易上手,大家研究下就好。補(bǔ)充一點(diǎn),如果你對你的初始化腳本是否起作用沒有信心,可以在啟動Insight之后只選擇菜單Run>Connect to target,然后選擇菜單View>Memory查看各個(gè)寄存器和內(nèi)存。最后給出一張我用Insight調(diào)試U-Boot的截圖。
在使用的過程中就會發(fā)現(xiàn),用Wiggler下載的速度實(shí)在不怎么樣,U-Boot的可執(zhí)行映像至多只有200KB,所以還是可以忍受的。
用同樣的方法也可以調(diào)試其他Boot Loader,甚至是Linux內(nèi)核;但是Linux內(nèi)核的可執(zhí)行映像一般有2MB之大,用Wiggler調(diào)試也是不現(xiàn)實(shí)的。我之前已經(jīng)做了廣告了,內(nèi)核的調(diào)試要用J-Link來搞,敬請期待EE小站的后續(xù)文章。