接着上一节,我们再来完整概括一下,一个uboot程序如何从FLASH加载启动。
第一步:编译生成目标文件,并去除ELF信息,得到binary格式得文件:
- make
- arm-linux-objcopy --gap-fill=0xff -O binary uboot uboot.bin
第二步:把该binary文件转换成AIS能识的COFF格式,也就是重新加上类似于ELF的信息
- raw2coff uboot.out 0xC1080000 uboot.bin
第三步:用AisGen for D800K001工具,将uboot.out 转换成最终的Flash镜像文件uboot.ais,具体可以参考TI官方手册,设置如下:
第四步:在CCS中用DSP例程nandwrite将uboot.ais烧写到NAND Flash中。
第五步:OMAP得BOOT开关设置到NAND 8引导状态,上电后观察ARM端程序运行结果,uboot一般会在串口打印
信息。
在这个过程里面有几个需要注意的地方:
首先,对于uboot来说,它比较大,一般有200K左右,所以入口肯定要在片外RAM,而对于一般的小程序,原则上可以入口在片内RAM,比如ARM片内地址FFFF0000,但是这样有一个问题,由于AIS程序是由DSP执行的,它无法访问ARM的片内地址,所以如果要通过AIS方式自动Boot一段ARM程序,那么它的入口地址必须在Shared RAM(4K),或SDRAM;否则的话,AIS无法正常加载ARM程序到入口地址,可能会加载过去一段DSP代码,这个具体是什么原因我也没搞清楚。
其次,开发板提供的uboot1.3.3和编译工具一般是测试(DEC137的交叉编译器很诡异,rubbish!),本节中用到了开发板附带的uboot,但是编译器是另外下载的cross-4.4.3,过程中遇到了一个inline函数不能声明weak属性的错误,例如这样的代码
- inline void __func__(void);
-
inline void func __attribute((weak,alias('__func__')))__;
第二行这种weak别名,4.4.3的编译器不承认,所以我强制注释了它们,并把引用的地方直接改成了__func__.此外遇到过几个warning,最终顺利编译。按照上面的步骤烧写Flash,但是串口没有输出;考虑最可能的问题就是串口号不对,查看uboot代码,果然设置输出串口为UART2,而LNV137板上引出的是UART1,修改了一些初始化代码(学到了BIC这个指令,挺有意思的)。重新编译-转换-烧写,最后成功的在串口看到了uboot的信息。
Note:发现一个小知识,ARM程序一般通过volatile方式访问寄存器,而DSP似乎不需要这么做。下一节就要正式开始折腾uboot的功能了。试试网络是不是正常,能不能启动Linux和Vxworks.如果顺利的话
最后再换用新2010年的uboot版本。
阅读(3134) | 评论(0) | 转发(1) |