在开始之前请先确认你的电脑有并口,如果是笔记本就算了,买个PCMIA转并口的卡的钱够买个盗版U-Link了;要是肯下血本买盗版J-Link,那就看我以后写的文章。
如果你对Linux下ARM的开发没有概念,先看我还是菜菜鸟的时候写的这篇文章 http://xianzilu.spaces.live.com/blog/cns!4201FDC93932DDAF!121.entry 。
GDB使用GDB工具链,调试解决方案的结构是
GDB前端<--->GDB<--->GDB服务程序<--->JTAG协议转换器(仿真器)<--->目标CPU(ARM CPU)
|
控制接口
GDB有一个很大的缺点——文本界面,使用非常不方便。但幸运的是,有很多热心的开发者为GDB写了一些图形“外壳”—— GDB前端,大大方便了GDB的使用。因为我们做的是交叉开发(即在x86结构的电脑上开发ARM等非x86结构的CPU程序),所以GDB无法直接调试 编译出来的程序,这就需要一个服务程序。这个服务程序可以是一个可以控制目标CPU的程序(可能运行于计算机上;也可能运行于某些仿真器上,例如如 BDI2000就是这样),也可以是一个运行于目标CPU上的服务程序,由它来装载被调试的程序。但是后者一般需要目标CPU上已经运行起了Linux内 核;调试Bootloader和Linux内核本身,需要前一种服务程序。GDB和GDB服务程序之间的连接方式可以是以太网或者串口,而且GDB服务程 序一般还有别的控制接口,例如Telnet接口,可以实现对目标CPU的控制,如初始化和程序文件下载等。比较复杂哦,一会儿说到软件的时候就会用上这些 知识。
你需要的东西和裸奔代码一样
你需要的软件有:
● 一个可以运行的Linux
虚拟机里的、真实的都可以,推荐使用Open Suse 10.3,下载地址 http://software.opensuse.org/
● 本机GCC编译器
Open Suse自己带的就可以
● 交叉GCC编译器
可以去下载一个,随便给个地址把 http://www.linux4sam.org/twiki/bin/view/Linux4SAM/SoftwareTools#Cross_Toolchain 值得注意的是U-Boot 1.2.0之后需要使用支持软浮点的交叉编译器,如果没有,可以用Crosstool制作一个,可以看我之前的这篇文章 http://xianzilu.spaces.live.com/blog/cns!4201FDC93932DDAF!274.entry
● OpenOCD源码
OpenOCD的主页是 http://openocd.berlios.de/web/ 。OpenOCD是一个运行于PC上的程序,它可以控制包括Wiggler之内的很多JTAG硬件;我们可以将它理解为一种GDB服务程序。OpenOCD的源码只能通过SVN下载,地址是svn://svn.berlios.de/openocd/trunk
,在写这篇文章的时候OpenOCD已经是R818版本了,这个版本对Wiggler的支持有问题,我编译的是r520版本的,如果没有SVN Client,这个版本只能通过曲线的方式获得:先到下载 http://www.yagarto.de/download/oldver/openocd-r520-20080322.exe 这个由YAGARTO提供的OpenOCD For Cygwin的版本,安装它,在安装目录例如C:/Program Files/openocd-r520/source里找到源码压缩包。
● Insight源码
Insight是一个GDB的图形前端,我感觉它比DDD更适合嵌入式系统程序的调试。
Insight的下载地址 http://sourceware.org/insight/downloads.php 。
● 随便什么程序的源码,例如U-Boot
U-Boot就不用介绍了,如果不知道可以Google下。
U-Boot的下载地址是 http://www.denx.de/wiki/UBoot/SourceCode 。
下面开始编译,先是OpenOCD,假设源代码已经解压缩到了/home/lxz/build-openocd,先设定权限
# 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,假设源码已经解压缩到了/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密码,等一会儿,安装就完成了
然后编译一个U-Boot用于测试,假设源码已经解压缩到了/home/lxz/at91rm9200/u-boot-1.2.0,假设已经修改完了Makefile中的交叉编译器的选项,假设我为AT91RM9200DK开发板编译,然后
# cd /home/lxz/at91rm9200/u-boot-1.2.0
# make at91rm9200dk_config
# make
于是得到了/home/lxz/at91rm9200/u-boot-1.2.0/u-boot这个映像
为了能让OpenOCD正常使用,我们还需要2个脚本,第一个是OpenOCD的配置脚本,这个脚本的作用是配置GDB服务程序、JTAG仿真器。写这个脚本可以看OpenOCD的文档 http://openfacts.berlios.de/index-en.phtml?title=OpenOCD_configuration 。我给出我的AT91RM9200DK开发板的配置文件at91rm9200.cfg,每一条配置信息的作用我就不解释了,请仔细阅读OpenOCD的文档。
# 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这句就是指定第二个脚本的,而且让OpenOCD在当前目录下搜索这个脚本。也就是说,如果 at91rm9200.cfg在/home/lxz/at91rm9200下,那么你在/home/lxz/at91rm9200下启动OpenOCD服 务程序,OpenOCD就会在/home/lxz/at91rm9200下搜索at91rm9200_init.script这个脚本;如果在与 at91rm9200.cfg所在路径不同的路径下启动OpenOCD服务程序,OpenOCD就无法找到 at91rm9200_init.script,此时,target_script 0 reset at91rm9200_init.script这句就应该写成target_script 0 reset /home/lxz/at91rm9200/at91rm9200_init.script。
第二个脚本的作用是初始化ARM CPU,因为U-Boot往往是在SDRAM里运行的,其连接位置也都在SDRAM里。用GDB或GDB前端下载程序的时候,必须保证SDRAM是可用 的。AT91RM9200这个CPU上电的时候如果从片内Boot ROM启动(不推荐从外部启动,因为如果没有启动程序,AT91RM9200将运行于慢时钟,这样JTAG仿真器可能工作不正常),需要进一步配置 PLL,PIO,SDRMC之类的外设之后,SDRAM才可以使用。第二个脚本就是一系列寄存器读写和延时命令的集合,如何编写请看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
这个脚本写起来很复杂,建议从一些样例代码上把寄存器的数值扒过来。另外,有些CPU,例如S3C2410,它上电的时 候,SDRAM是默认可以用的,就不需要这个脚本了。还有一个值得注意的是,由于我们用的是Wiggler这种简单的JTAG协议转换器,初始化脚本里必 须加上arm7_9 sw_bkpts enable这句。现在终于可以开始调试了,假设把OpenOCD安装在了/usr/local/arm/openocd,把Insight安装在了 /usr/local/arm/arm-linux-insight,两个初始化脚本都放在了/home/lxz/at91rm9200;你已经正确连接 了Wiggler,开发板已经上电。接下来还是用命令来说明
# 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已经开始工作了。然后启动Insight
# cd /home/lxz/at91rm9200/u-boot-1.2.0/
# /usr/local/arm/arm-linux-insight/bin/arm-linux-insight
出现下面的窗口
然后选择菜单File>Target Settings...,在出现的窗口中进行如下设置,然后点OK。
选择菜单File>Open,打开/home/lxz/at91rm9200/u-boot-1.2.0/u- boot这个映像;然后选择菜单Run>Download,将U-Boot程序下载到目标CPU。然后在程序运行的必经之路设定一个断点,如下图所 示。
选择菜单Control>Continure,程序就会从头开始执行,并停在断点处了。Insight还有很多不错 的功能,并且很容易上手,大家研究下就好。补充一点,如果你对你的初始化脚本是否起作用没有信心,可以在启动Insight之后只选择菜单 Run>Connect to target,然后选择菜单View>Memory查看各个寄存器和内存。最后给出一张我用Insight调试U-Boot的截图。
在使用的过程中就会发现,用Wiggler下载的速度实在不怎么样,U-Boot的可执行映像至多只有200KB,所以还是可以忍受的。
用同样的方法也可以调试其他Boot Loader,甚至是Linux内核;但是Linux内核的可执行映像一般有2MB之大,用Wiggler调试也是不现实的。我之前已经做了广告了,内核的调试要用J-Link来搞,敬请期待EE小站的后续文章。
我对ARM CPU的在线Flash Download这件事情不是很感冒,所以H-JTAG和OpenOCD的这部分功能EE小站是不会涉及了,请见谅。今天就到这里。