附录:
1.在u-boot-1.3.2前(不含u-boot-1.3.2)nand_init函数的调用关系,它的调用是被“CONFIG_COMMANDS&
CFG_CMD_NAND”和“CFG_NAND_LEGACY”控制的,1:表示该值为真,0:表示该值为假
CONFIG_COMMANDS&
CFG_CMD_NAND
CFG_NAND_LEGACY
/drivers/mtd/nand/nand.c中的
nand_init()函数
/board/qljt/qljt2440/qljt2440.c中的nand_init()函数
0
0
0
0
0
1
0
0
1
0
1
1
1
1
0
1
2.在u-boot-1.3.2后(含u-boot-1.3.2)nand_init函数的调用关系,它的调用是被“CONFIG_CMD_NAND”和“CFG_NAND_LEGACY”控制的,1:表示该值为真,0:表示该值为假
CONFIG_CMD_NAND
CFG_NAND_LEGACY
/drivers/mtd/nand/nand.c中的
nand_init()函数
/board/qljt/qljt2440/qljt2440.c中的nand_init()函数
0
0
0
0
0
1
0
0
1
0
1
1
1
1
0
1
三、调试uboot
调试uboot有很多方法,其中主要分两大类,一是用jlink或者jtag然后使用调试工具,如GDB,AXD以及RVD之类的,二是直接下载到内存中去运行
两种方法应该场合不一样,后一种是推荐使用,但是前提是要有网络,而前一种方法因为可以实现单步源码级调试,有很多场合也非常有用,下面介绍一下
1、 使用jlink和AXD
首先,打开AXD后,按Alt+L打开命令窗
对于命令窗,说明:
如果板子没有网口,在调试U-Boot和uclinux时就没法用gdb调试。
这时只能利用串口和JTAG口进行调试,linux下可以用BDI这个玩意调试,可是BDI非常昂贵,不适合大众需求。
我总结了下,根据我的调试经验,可以用ADS调试linux的程序。
打开AXD,按下 Alt + L ;或者点SystemViews下Command Line Interface,就可以打开一个命令行:
输入help查看帮助文件。
比较有用的命令如:
LoadBinary = 将一个文件导入RAM
LoadSymbols = 导入符号表
SetPC = 设置PC寄存器
Run = 开始运行
OB + 文件名 = 按照批处理文件运行
所有的命令在GUI里面也是有的,可以利用批处理文件(OB命令)来免去敲命令和点菜单的麻烦,
以调试u-boot为例,写一个批处理文件放在D盘,文件名为u-boot.txt,内容如下:
loadbinary Y:\u-boot-1.1.4\u-boot.bin 0x33f80000
loadsymbols Y:\u-boot-1.1.4\u-boot
setpc 0x33f80000
run
打开AXD,按下ALT+L,键盘输入:obd:\u-boot.txt
那么AXD会自动运行批处理文件内的命令,自动载入u-boot的二进制代码,自动载入符号表,设置指针为0x00100000,并开始运行。
在调试时,最后自己一步步输入命令做
loadbinary简写lb,只能将二进制文件加载到ram中,不能将地址指定到flash中
在loadsymbols之后,等待进度条显示加载完成,将setpc (pc)指到u-boot.bin的加载位置,即可单步调试。
这时ads会提示寻找u-boot的入口文件start.s地址,此时需要手动指定start.s的位置,通常这时可以在linux下建立smaba服务共享,将整个u-boot的文件夹映射成windows下一个盘符,这样就可以指定目录地址了。
在进入C语言代码中后,ads还可能出现提示指定board.c、string.c等其他文件的地址,这都需要手动做。
此后就可以用ads进行c语言级的u-boot源码调试了!
这种方法应该没问题的,因为我实验了很多次了,都成功了,这可是偶找了近一个月才弄清楚的方法..........
同样,这种方法不知道是否可以用在uclinux上调试,正在进行试验。
按照上面说的,就可以调试到,其中软件会叫你指定一些文件,指定完就可以持到源文件,在源文件上调试
二、出现的问题
****************************************
在nor flashs模式下调试
************************************
1、调试前如果没加上Init script,会出现raise an exption,cause:The processor was reset.
所以参考开发板的配套资料
在命令行打入(我的GT2440是)
setmem 0x53000000,0x00000000,32
setmem 0x4a000008,0xffffffff,32
setmem 0x4a00001c,0x000007ff,32
setmem 0x53000000,0x00000000,32
setmem 0x56000050,0x000055aa,32
setmem 0x4c000014,0x00000007,32
setmem 0x4c000000,0x00ffffff,32
setmem 0x4c000004,0x00061012,32
setmem 0x4c000008,0x00040042,32
setmem 0x48000000,0x22111120,32
setmem 0x48000004,0x00002f50,32
setmem 0x48000008,0x00000700,32
setmem 0x4800000c,0x00000700,32
setmem 0x48000010,0x00000700,32
setmem 0x48000014,0x00000700,32
setmem 0x48000018,0x0007fffc,32
setmem 0x4800001c,0x00018005,32
setmem 0x48000020,0x00018005,32
setmem 0x48000024,0x008e0459,32
setmem 0x48000028,0x00000032,32
setmem 0x4800002c,0x00000030,32
setmem 0x48000030,0x00000030,32
——————————
用于初始化内存
——————————
后面我把它写到一个startrun.ini里,然后用ob ...就行了
运行到bl lowlevel_init运行不下去,有两种可能
第一种是lowlevel_init 没有运行在前4K内存中
解决办法
方法一:
顶层Makefile文件中:
#__LIBS := $(subst $(obj),,$(LIBS)) $(subst$(obj),,$(LIBBOARD))
__LIBS := $(subst $(obj),,$(LIBBOARD)) $(subst $(obj),,$(LIBS))
这样修改之后查看map文件可以发现,lowlevel_init函数链接到了前面.
方法二:
在不修改Makefile的情况下,可以通过修改目标板下的链接文件u-boot.lds来使lowlevel_init放在4K之内: cpu/arm920t/start.o (.text)board/net2410e/lowlevel_init.o (.text) 把之放到start.o的后面.
这相当于修改链接脚本,未做验证,我使用第一种方法!
第二种问题是解决第一种后,还出现
这个问题解决办法:暂未研究
--------------------------------------------------------------------
为方便使用,同时,也是方便u-boot的调试。因此,我要将此u-boot代码再做一修改,使其可以在内存中运行。这样,可以用
开发板自带的vivi将其下载到内存中,再在内存中运行u-boot。要想它在内存中运行,方法很简单,将/root/u-boot-
1.3.1/cpu/arm920t中的start.s中
#ifndef CONFIG_SKIP_LOWLEVEL_INIT
bl cpu_init_crit
#endif
此段代码中的bl cpu_init_crit注释掉,即不进行CPU的初始化工作(此工作,当前在板子上运行的vivi已完成,故不能再次进行)
,即改为
#ifndef CONFIG_SKIP_LOWLEVEL_INIT
@bl cpu_init_crit
#endif
修改/board/hugerat/rat2440/config.mk中text_base 值为0x33000000
使用vivi命令load ram 0x33000000 0x17ea8 x将u-boot.bin装入内存。再用go 0x33000000命令,即可。
******************************************************
直接在nand flash模式下调试
---------------------------------------------------------
uboot直接加载到SDRAM是不能运行的,必须屏蔽掉uboot中的CPU及RAM初始化代码才行,
因为从Norflash启动时已经初始化过了。
**********************************
其实最简单的方法就是在你创建的头文件中定义 CONFIG_SKIP_LOWLEVEL_INIT
其实就是跳过底层初始化
因为执行lowlevel_init会初始化SDRAM,但是这工作在NORflash上已经执行,如果又执行,则将清空
内存版u-boot的制作简单地说,就是注释掉不需要运行的相关代码,主要是:
1)内存,flash的初始化
2)ARM的内存重映射
3)相关时钟初始化
***********************************
2、 用tftp下载在内存里调试
首先,手头上要有的软硬件:
1、移植好的uboot(具有tftp和go功能),可选用开发板配套的,这里我使用的是自己移植的(比较有成功感)
2、tftp就要有网线,这里这调试局限,要有网络,如果没有,可以使用AXD调试,详情请看另一文章
3、串口线当然要,超级终端也是必须
开始:
1、下载移植好的uboot(不是调试的,是成功的)
可下载到nor也可以nand
2、下载要调试的uboot到内存中,需要了解几个信息
(1)内存的大小:SDRAM:64M(开发板不同而不同)
了解到内存是从30000000开始的,那64M就是3000,0000~3400,0000,这里有个问题,你uboot从nor或者nand运行时,再经过一系列拷贝之类,就在内存中运行,在哪里运行?就是_TEXT_BASE=33f80000的位置后512K中运行,所以移植如果超过512就要注意,这时可以修改board\开发板文件\config.mk那时指定,当然现在不是这问题。现在是什么问题呢?现在的问题是如果我还是把uboot用tftp下载到33f80000里可不可以,解决这问题前,还有一个问题,我为什么下载到33f80000?我们先看一段代码start.S里:
***************** CHECK_CODE_POSITION******************************************/
adr r0, _start /* r0 <- current position of code */
ldr r1, _TEXT_BASE /* test if we run from flash or RAM */
cmp r0, r1 /* don't reloc duringdebug */
beq stack_setup
/***************** CHECK_CODE_POSITION******************************************/
这段代码是检测你现在是否运行在RAM中,它怎么知道?就是看你开始的代码是不是为text_base的值,如果你移植的不是,那当然会再执行下面的nor或者flash拷贝了
解决上面这问题,重新回到为什么不下载到33f80000?我们知道,它现在运行在33f80000,如果你再tftp进去,那不是把现在的执行中的代码都清除了?有什么后果?死机!!!
所以不能下载到33f80000里,那么应该下载到哪里?我应该是要下载到TEXT_BASE指定的地址里的,所以我们要执行这样的操作:修改TEXT_BASE的值!!!
修改\board\开发板目录\config.mk
将TEXT_BASE改成33000000这个虽然顺便改,但是不能改到别的什么堆啊什么栈空间里,这样程序也执行不下去,最好的就是修改到后面,面不影响原来的就可以。
(2)还有一个问题,就是底层初始化,底层初始化会将内存清空一次的,所以不应该让它执行,所以在开发板头文件中应该定义:CONFIG_SKIP_LOWLEVEL_INIT或者在start.S中定义也可以
要解决的问题解决了,现在是下载
先打开开发板,执行移植好的uboot,然后不tftp下载uboot到指定内存中33000000,然后执行
go 33000000
就可以运行了!!!
Uboot移植到此结束,希望对大家有帮助。