MIPS uboot移植
网上 有很多ARM的uboot分析文章,看了 之后发现受益良多,但是对mips的uboot移植这块欠缺,但是都大同小异,原理相差 不大。
背景思路:
由于采用RTL8382L 芯片,该芯片外围 并没有DDR,所以我们想做一款没有DDR的基于RTL8382L芯片的SWITCH。由于技术文档的缺失, 经过一段时间分析原先的UBOOT代码,该uboot运行如下:
首先uboot的入口地址 为0XBFC00000,该链接地址一般是由 uboot.lds 链接脚本 指定的。或者 是在编译的时候 使用指定,这 两者网上分析也比较多了。uboot.lds 主要需要理解加载地址 以及 其链接地址(运行地址),这些其实应该都是虚拟地址。
uboot执行 一部分汇编代码后,会从flash将sram的代码拷贝到cpu内部sram中,sram的代码段、数据 段也是由uboot.lds 文件指定的。之后设置 栈地址后,便跳转到内部sram中运行了。进行cpu的初始化,涉及到icache的初始化。为何需要 enable cache呢,因为 虚拟地址中的 OX9F000000以及0x9FC00000地址的使用是通过cache的。所以 刚开始我们的入口地址为 0xBFC00000地址无需cache,直接可以使用。具体哪一段地址是cache才能使用的请自行百度。
之后sram中会搬运uboot的其他代码到DDR中,然后就 跳转到DDR运行了。所以我们需要在第一阶段做文章了。
运行 方案:
1、Flash使用的是SPI的,所以代码是可以再flash上运行的。 由于内部只有128K的sram,远远 不够我们的使用,所以我们需要考虑将代码段以及只读数据段 放入到 flash进行 存储,这个由uboot.lds文件指定。
验证后 发现可以将代码 段以及只读数据段放入flash中,但是当调试flash识别以及读写的时候发现在flash上运行的代码无法识别该flash,定位发现是 寄存器的状态没有到 ready的状态。然后我们考虑到,会不会由于是在flash 上运行的,所以无法识别该flash啊。然后我们还是先讲代码 段以及数据段放入sram中,发现是可以进行识别flash 的。所以我们确定了这样的运行方案:
uboot阶段还是 放在内部sram中运行,因为uboot需要 支持升级,然后再跳转到flash中继续运行app程序(指定app程序的入口地址,仿照uboot进行编译即可。)这样就能够解决该问题了。
2、跳转验证生效后,便进行了uboot升级app的功能,uboot升级使用串口进行 xmodem进行升级的。移植xmodem代码,发现可以升级成功, 但是在调试的时候出现一个奇怪的 问题,就是加入一些调试打印后,有些时候无法 正常跳转到app执行,app没有 一点打印。刚开始定位的思路都是在怀疑运行环境是否异常。虚拟地址是否使用正确,发现一直 没有进展,没有定位的 思路。然后到了昨天, 我将整个由uboot和app合成的img烧写到flash,发现是可以 正常启动的。感觉发现了新大陆,瞬间定位思路就变了,于是怀疑是升级导致img文件异常了。结果一对比,果然升级后和原先由makefile 生成的img 差异很大。然后变对 xmodem升级进行 定位问题了。最后发现原因是这样的,由于xmodem升级的最后一包数据,如果不满128字节的话,便以0x1a进行填充,所以我们需要进行将最后一包的0x1a数据给抹去,但是没有想到的是,中间的数据片段的末尾也会出现0x1a情况,所以该升级代码存在bug,导致升级到img的数据报文错误或者异常了。这样启动app就失败了。修改升级代码后正常执行。
这个问题定位后,对之后app阶段驱动、应用层、配置等的移植有很大帮助。
经过这次boot的移植,对栈、虚拟地址、数据存储以及程序运行有了更加深入的了解了。还是挺好的。