2011年(2)
分类: LINUX
2011-08-20 00:02:32
测试目的:
实现U-Boot的源码级调试,便于启动部分代码的学习和移植
测试项目:
u-boot-1.1.6-FA24x0(mini2440光盘自带的已移植版本)
u-boot-2010.03-tekkaman,下载页面:
PS:增加了一个比较新的版本的测试:u-boot-2010.03-tekkaman,功能很全。
测试环境:
主机:Window XP SP2 + Ubuntu 10.10(VMware)
开发板:mini2440
仿真器:J-Link V8, 驱动程序 J-Link ARM V4.10i
编译器:
MDK V4.14.40
arm-linux-gcc-3.4.1(mini2440早期光盘自带)
arm-linux-gcc-4.3.2(mini2440光盘自带)
参考:
zzm24,以u-boot为例介绍如何在MDK下调试elf格式文件
http://www.ourdev.cn/bbs/bbs_content.jsp?bbs_sn=4579114
一、配置Samba服务
配置Samba,便于在Windows与Ubuntu下共享代码。
也可以先在Ubuntu下编译,然后将整个目录拷到Windows下进行调试。
二、编译U-Boot
编译时要加上调试选项 -g(这里默认是有的,不需要修改),并且降低优化级别:改为-O0(不优化)或-O1。
在config.mk中修改调试和优化选项:
DBGFLAGS= -g # -DDEBUG
OPTFLAGS= -O1 # -Os #-fomit-frame-pointer
在U-Boot目录中执行如下命令:
u-boot-1.1.6-FA24x0的编译过程(使用arm-linux-gcc-3.4.1编译):
make distclean # 清除编译的文件,第一次编译时不用执行
make open24x0_config #配置
make
u-boot-2010.03-tekkaman的编译过程(使用arm-linux-gcc-4.3.2编译):
在Makefile文件中修改编译器:CROSS_COMPILE = arm-linux-
make distclean # 清除编译的文件,第一次编译时不用执行
make mini2440_config #配置
make
三、配置MDK工程
配置一个可以在MDK调试s3c2440的工程。
可以直接从MDK官网下载s3c2440的Led示例工程
解压缩后将led.Uv2,led.Opt,Ext_RAM.ini三个文件复制到U-Boot目录下打开工程文件led.Uv2,删除所有源文件
添加以下文件(启动代码所在的文件)
\cpu\arm920t\start.S
\lib_arm\board.c
配置工程选项
1、配置Debug为J-Link
2、配置J-Link选项:适当修改下速度可加快下载时间
3、修改Ext_RAM.ini
从u-boot.map中查找.text和.bss的信息
.text 0x33f80000 0x21d78
.bss 0x33fabcf4 0x6868
修改内容为:(修改的部分已标红)
FUNC void Init (void) {
_WDWORD(0x4A000008, 0xFFFFFFFF); // Disable All Interrupts
……
_WDWORD(0x56000000, 0x000007FF); // GPACON: Enable Address lines for SDRAM
}……
Init(); // Initialize memory
LOAD u-boot INCREMENTAL // Download program
PC = 0x33F80000; // Setup for Running
//g, main // Goto Main
如果文件中还有引用到.text位置的地方,一并修改。
现在就可以调试了。
PS:Ext_RAM.ini中写入GAPCON的值是0x000003FF,需要改成0x000007FF,因为Mini2440用了两片32MB的SDRAM,用到了地址线ADDR25,因此要把GPA10设置为1。不修改内在访问会有问题,程序就会跑飞。
四、运行结果
进入start.S,汇编代码显示正常
进入board.c,C代码显示正常
如果要调试某个文件,先把这个文件加到工程中,就可以调试了(真麻烦)。
五、结束语
以前有文章写了使用J-Link在AXD下的调试过程,考虑到当下MDK比较常用,先整理了这篇文章,后续再整理AXD下调试的文章。
感谢zzm24的文章,在我的测试中,发现参考文章中有些步骤可以省略(如修改u-boot为u-boot.axf,修改输出文件及修改RO/RW等),目前没有发现有什么问题,如有问题请大家加上并告知。
目前有几个问题:
1、上面提到的调试时要手动添加源文件(使用AXD时只需在第一次指定文件,以后就可正常调试了)。不能自动加载,这个很烦人,哪位兄台如果有可行的办法望告知。
2、我用这个方法调试最新的u-boot-2011.06,使用了arm-linux-gcc-4.3.2和arm-linux-gcc-4.4.3(根据网上资料gcc加了-gdwarf-2选项)编译通过,只能进行二进制(汇编)调试。无法进行C语言级调试,猜想MDK不能解析新版的gcc生成的调试信息,或者需要加一些什么编译选项,如有知道也请告知,不胜感激。
PS:以后等再使用新的4.5.X再试试
PS:编译u-boot-2010.03-tekkaman时使用的是arm-linux-gcc-4.3.2,可以进行源码调试。
3、开始时使用arm-linux-gcc-4.3.2编译u-boot 1.1.6,出现以下错误
arm-linux-ld: ERROR: Source object /usr/local/arm/4.3.2/bin/../lib/gcc/arm-none-linux-gnueabi/4.3.2/armv4t/libgcc.a(_udivdi3.o) has EABI version 5, but target u-boot has EABI version 0
arm-linux-ld: failed to merge target specific data of file /usr/local/arm/4.3.2/bin/../lib/gcc/arm-none-linux-gnueabi/4.3.2/armv4t/libgcc.a(_udivdi3.o)
arm-linux-ld: ERROR: Source object /usr/local/arm/4.3.2/bin/../lib/gcc/arm-none-linux-gnueabi/4.3.2/armv4t/libgcc.a(_udivsi3.o) has EABI version 5, but target u-boot has EABI version 0
arm-linux-ld: failed to merge target specific data of file /usr/local/arm/4.3.2/bin/../lib/gcc/arm-none-linux-gnueabi/4.3.2/armv4t/libgcc.a(_udivsi3.o)
arm-linux-ld: ERROR: Source object /usr/local/arm/4.3.2/bin/../lib/gcc/arm-none-linux-gnueabi/4.3.2/armv4t/libgcc.a(_dvmd_lnx.o) has EABI version 5, but target u-boot has EABI version 0
arm-linux-ld: failed to merge target specific data of file /usr/local/arm/4.3.2/bin/../lib/gcc/arm-none-linux-gnueabi/4.3.2/armv4t/libgcc.a(_dvmd_lnx.o)
arm-linux-ld: ERROR: Source object /usr/local/arm/4.3.2/bin/../lib/gcc/arm-none-linux-gnueabi/4.3.2/armv4t/libgcc.a(_clz.o) has EABI version 5, but target u-boot has EABI version 0
arm-linux-ld: failed to merge target specific data of file /usr/local/arm/4.3.2/bin/../lib/gcc/arm-none-linux-gnueabi/4.3.2/armv4t/libgcc.a(_clz.o)
/usr/local/arm/4.3.2/bin/../lib/gcc/arm-none-linux-gnueabi/4.3.2/armv4t/libgcc.a(_dvmd_lnx.o): In function `__aeabi_ldiv0':
(.text+0x8): undefined reference to `raise'
make: *** [u-boot] 错误 1
在以下页面中给出一些解释:
U-Boot is not a GNU/Linux application. However, you're using the
GNU/Linux toolchain to compile it -- so the libraries assume the
presence of a GNU/Linux C library. In this case, the division routine
wants to call "raise" to signal a division-by-zero exception.
People often try to abuse the GNU/Linux toolchain to build U-Boot
because they want to use the same toolchain that they use to build the
Linux kernel and GNU/Linux applications. But, U-Boot is really a
bare-metal application, and, as such, should be built with a bare-metal
toolchain, like our "ARM EABI" toolchains. There are often these kinds
of problems with U-Boot when moving between different architectures or
toolchain versions because the U-Boot source code has tricks to try to
make the GNU/Linux toolchain work, and those tricks only work with
particular toolchains.
That's the long story.
The short story is that you can probably provide an __aeabi_ldiv0
routine that just returns zero, overriding the default implementation.看来,友善给的u-boot是太旧了。