uboot启动流程-uboot代码重定位说明二
一. uboot启动流程
本文学习 uboot 的启动流程中涉及的 uboot 代码重定位部分。
_main 函数中会调用 relocate_code 函数。
relocate_code 函数分两个部分:
1. 拷贝 uboot 代码部分
2. 有关 " 重定位后有关函数调用或全局变量地址的问题"的解决方法。
本文继上一篇文章的学习,地址如下:
uboot启动流程-uboot代码重定位说明一_凌肖战的博客-CSDN博客
这里学习 uboot 重定位的第二部分内容:重定位后有关函数调用或全局变量地址的问题。
二. uboot代码重定位
1. 重定位后函数调用或全局变量使用问题
具体问题描述:
重定位 就是 uboot 将自身拷贝到 DRAM 的另一个地放去继续运行(DRAM 的高地址处)。
我们知道,一个可执行的 bin 文件,其链接地址和运行地址要相等,也就是链接到哪个地址, 在运行之前,就要拷贝到哪个地址去。现在我们重定位以后,运行地址就和链接地址不同了,这 样寻址的时候不会出问题吗?
当简单粗暴的将uboot从0X87800000拷贝到其他地方以后,关于函数调用、全局变量引用就会出问题。Uboot对于这个的处理方法就是采用位置无关码,这个就需要借助于 .rel.dyn段。
接下来,relocate_code 函数 的第 94 行~109 行,是重定位.rel.dyn 段,.rel.dyn 段是存放.text 段中需要重定位地址的集合。
uboot重定位后的函数调用或全局变量地址问题处理如下:
94 ldr r2, =__rel_dyn_start /* r2 <- SRC &__rel_dyn_start */
95 ldr r3, =__rel_dyn_end /* r3 <- SRC &__rel_dyn_end */
96 fixloop:
97 ldmia r2!, {r0-r1} /* (r0,r1) <- (SRC location,fixup) */
98 and r1, r1, #0xff
99 cmp r1, #23 /* relative fixup? */
100 bne fixnext
101
102 /* relative fix: increase location by offset */
103 add r0, r0, r4
104 ldr r1, [r0]
105 add r1, r1, r4
106 str r1, [r0]
107 fixnext:
108 cmp r2, r3
109 blo fixloop