13.4代码重定位_拷贝代码和链接脚本的改进
本节进行拷贝代码的改进和链接脚本的改进。
前面重定位时,需要ldrb命令从的Nor Flash读取1字节数据,再用strb命令将1字节数据写到SDRAM里面。

JZ2440上的Nor Flash是16位,SDRAM是32位。 假设现在需要复制16byte数据, 采用ldrb命令每次只能加载1byte,因此CPU需要发出16次命令,内存控制器每次收到命令后,访问硬件Nor Flash,因此需要访问硬件16次; 同理,访问SDRAM时,CPU需要执行strb 16次,内存控制器每次收到命令后,访问硬件SDRAM,也要16次,这样总共访问32次。
现在对其进行改进,使用ldr从Nor Flash中读,ldr命令每次加载4字节数据,因此CPU只需执行4次,但由于Nor Flash是16位的,内存控制器每次收到CPU命令后,需要拆分成两次访问,因此需要访问硬件8次;
使用str写SDRAM,CPU只需执行4次,内存控制器每次收到命令后,直接硬件访问32位的SDRAM,因此这里只需要4次,这样总共访问只需要12次。
在整个操作中,花费时间最长的就是硬件访问,改进后代码,减少了硬件访问的次数,极大的提高了效率。

根据上面原理修改代码,修改start.S:

然后编译烧写,发现启动后没有输出字符。修改主程序,尝试以整数格式输出字符,发现输出的数从0开始,应该是 全局变量被破坏了。
屏蔽掉start.S里面的清理命令,测试是否是清除bss段是清除了全局变量。

屏蔽后,正常输出,锁定了问题大致位置。查看反汇编文件,原来是没有向4取整。 修改链接脚本让bss段,使用ALIGN(4)向4取整。

现在重新编译烧写,测试结果正常。 再次查看反汇编文件,发现现在bss段以4字节对齐,清理bss段也是正常的。

同样的问题也会出在代码重定位这里,如何保证data段起始地址也是向4对齐呢? 也是使用ALIGN(4)向4取整。

Uboot是裸机的集大成者,可以参考uboot链接脚本也是类似的。