方法产生的原因:
公司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调试工具.
文章内容为原创,转载请注明出处,若有火星之处请见谅,本身也是第一次调试U-boot
马桶吸盘
于2010年7月26日arm11 u-boot调试手札