再提代码重定位

最近在做uboot的一些移植工作,在过程中遇到了很多的问题,有的问题是由于概念不清楚而引发的,其中就包括代码重定位,也不全是代码重定位,牵扯到程序执行的一些地址,关于代码重定位的问题,我在另一篇文章中也做了简单的介绍,这次遇到的问题我也花了一些时间进行了总结,在此把自己的感想做以记录,不对的地方还请指出
1、两个地址
加载地址:存储地址
运行地址:链接地址,运行时所处的地址
区别:加载地址简单的说就是程序的存储地址,运行地址就是程序运行起来所处的地址,一般在链接脚本中会指定程序的链接地址
例如:second 0x30000000 :AT(4096) {main.o}
main.o的存储地址是4096(0x1000),用"AT"指定程序的存储地址,但是它的运行地址是0x30000000,运行之前需要把程序从0x1000的地址复制到0x30000000的地方去,此过程需要读取flash,把程序拷贝到相应的位置才能运行
2、在移植uboot的时候有一个重要的地方就是代码的拷贝,uboot一般会定义一个宏_TEXT_BASE来表示呈现当前的运行地址,那么需要注意的是,如果程序一开始存储在flash中,从flash中开始运行,那么这个时候得到_TEXT_BASE的值就是程序的存储地址,一般是0,当执行完代码重定位,跳转到SDRAM中去运行的时候,这个时候使用_TEXT_BASE得到的值就是程序的运行地址。
3、由第二点引发出来一个问题,就是汇编指令的问题,位置无关指令和位置有关指令
位置无关指令:
bl xxx,指令所执行的操作是pc = pc + 偏移量,这个偏移量是到xxx这个地址标号处的,不管程序是在片内SRAM中运行还是在 SDRAM中,程序内部的各种偏移是不变的,所以,PC会跳转到正确的地方去执行,这和程序所处的位置无关
位置有关指令:
ldr pc,=xxx,这个指令所进行的操作也是跳转,不过它是直接给PC赋值为xxx地址标号的地址,这个地址标号是从程序的运行地址处开始计算的,是基于链接脚本中的链接地址的,所以执行ldr指令就会从片内SRAM跳转到SDRAM中去。

发布了33 篇原创文章 · 获赞 2 · 访问量 1011

猜你喜欢

转载自blog.csdn.net/weixin_41791581/article/details/105421666