我这里的设备上,一般都是在NOR-Flash上跑U-boot,但有时候为了调试等的方便,要让u-boot在内存中跑。 Flash版本的u-boot是不能直接在内存中跑的(至少我这里的情况是这样)。
下面,主要按照我这的情况,简单说说内存版u-boot的制作。制作出来的u-boot,可以:
1)用仿真器下载到内存中运行;
2)通过设备中已经有的u-boot,用tftp下载到内存中,再用go 0xxxx运行。
内存版u-boot的制作简单地说,就是注释掉不需要运行的相关代码,主要是:
1)内存,flash的初始化
2)ARM的内存重映射
3)相关时钟初始化
这里,我是这样做的:
修改u-boot-1.0.2/cpu/arm940t/start.S,注释相关代码:
。。。。。。
reset:
//bl platformsetup
/*这里的platformsetup是具体设备的内存、Flash相关初始化;注释掉这个步骤,因为内存版u-boot运行时,内存、Flash已初始化好。*/
。。。。。。
。。。。。。
clbss_l:
str r2, [r0]
add r0, r0, #4
cmp r0, r1
bne clbss_l
ldr pc, _start_armboot
_start_armboot: .word start_armboot //跳到C程序start_armboot执行
。。。。。。
再注释board_init函数中调用的时钟初始化函数init_clk:
void init_clk(void)
{
icache_disable();
#if 0
PMUSetFCS(PLL_331776000);
PMUSetTurboMode(1); // 1: On, 0: Off
PMUSetPLL3();
#endif
icache_enable();
}
【转】u-boot 内存中调试的实现方法
方法产生的原因:
公司ARM11的板子需要移植yaffs2文件系统,linux驱动已移植完成,现需要移植u-boot的yaffs2文件系统烧写
u-boot版本1.1.6 linux版本2.6.22 flash AM29LV040B nand flash 三星256MB
方法产生的经过:
在网上找了几个u-boot移植代码,使用flash烧写器烧进去后都起不来,串口无输出,而且该产品板并没有买JATG调试器,flash烧写器 是生产部门的,u-boot挂了,总是要打断烧写MM的正常工作,十分不好意思.在尝试危险的热插拔后,决定寻找更方便的方法去调试(热插拔:公司的 flash芯片并不是直接焊在板子上,而是使用插座.所以我使用两片flash,总是保留一片正常的flash,在另一片flash挂掉后,使用正常的 flash启动,然后上电状态下换上坏的flash用u-boot直接烧写,这个和电脑主板的BIOS修复类似,实际上该操作十分危险,而且成功率不 高,u-boot总是死机)
方法产生的思路:
既然linux内核可以在内存中启动,为什么u- boot不可以呢,回顾一下u-boot的启动顺序和工作原理,发现理论上是可行的,u-boot本身就是复制到内存中运行的,所以改变u-boot在内 存中运行的地址,就可以用一个u-boot启动另外一个u-boot.
方法:
首先将内存u- boot的TEXT_BASE改为和flash u-boot不一样的地址,然后使用tftp将内存u-boot下载到其对应的地址,go TEXT_BASE,这里我发现死机了,第一次尝试失败,回顾u-boot的启动过程,前期有flash to ram的过程,而内存的uboot并不需要复制(虽然代码有判断uboot自身是否在内存中运行).所以我这里参考了编译好的内存u-boot的map, 找到 start_armboot所在内存的地址(*.map文件中可以找到),然后go start_armboot,启动成功,但是nand flash识别错误,之后我也没分析其原因,我直接换了go的地址,使用了内存搬移后的动作---堆栈初始化stack_setup这个地址,go之后一 切正常,因为是在内存中启动,环境变量使用了默认值,但不影响我的调试,之后的调试,我发现是yaffs2的mkyaffs2image这个程序有 BUG,他没有生成坏块标志0xff,修bug后,在内存中运行的u-boot可以正常烧写yaffs2文件系统.
结束语:
本文为抛砖引玉,该方法在arm系列平台应该都适用,u-boot内存调试,不仅仅是为了解决移植yaffs2烧写问题,是提供了开发u-boot驱动时的新方法,既减少了芯片的烧写次数,而且省去了jtag调试工具.
http://www.360doc.com/content/13/0130/04/7775902_263163496.shtml