uboot代码重定位: 拷贝代码

一.  uboot启动流程

本文学习 uboot 的启动流程中涉及的 uboot 代码重定位部分。

_main 函数中会调用 relocate_code 函数,本文继续简单分析一下 relocate_code 函数。

relocate_code 函数分两个部分:

1.  拷贝 uboot 代码部分

2.  有关 " 重定位后有关函数调用或全局变量地址的问题"的解决方法。

二.  uboot代码重定位

1.  uboot一些变量的地址

要分析 uboot 的启动流程,首先要找到“入口”,找到第一行程序在哪里。

程序的链接是由链接脚本来决定的,所以通过链接脚本可以找到程序的入口。连接脚本在uboot的根目录下u-boot.lds文件。

在 u-boot.lds 中有一些跟地址有关的“变量”,我所编译后的uboot源码涉及的变量的值如下:

变量数值描述
__image_copy_start0X87800000uboot拷贝的首地址
__image_copy_end0X8786B03Cuboot拷贝的结束地址

__rel_dyn_start

0X8786B03C

.rel.dyn 段起始地址

__rel_dyn_end

0X8787459C

.rel.dyn 段结束地址

_image_binary_end

0X8787459C

镜像结束地址

__bss_start

0X8786B03C

.bss 段起始地址

__bss_end

0X878B7314

.bss 段结束地址

2.   _main函数

_main 函数中会调用 relocate_code 函数,调用的地方如下:

	ldr	r0, [r9, #GD_RELOCADDR]		/* r0 = gd->relocaddr */
	b	relocate_code

可以看出,relocate_code函数有一个参数,r0=gd->relocaddr=0X8FF38000uboot重定位后的首地址。

3.  relocate_code 函数:拷贝代码部分

relocate_code 函数是用于代码拷贝的,此函数定义在文件 arch/arm/lib/relocate.S 中。relocate_code 函数的前半部分代码如下:

79 ENTRY(relocate_code)
80 ldr r1, =__image_copy_start /* r1 <- SRC &__image_copy_start */
81 subs r4, r0, r1 /* r4 <- relocation offset */
82 beq relocate_done /* skip relocation */
83 ldr r2, =__image_copy_end /* r2 <- SRC &__image_copy_end */
84 
85 copy_loop:
86 ldmia r1!, {r10-r11} /* copy from source address [r1] */
87 stmia r0!, {r10-r11} /* copy to target address [r0] */
88 cmp r1, r2 /* until source end address [r2] */
89 blo copy_loop

80 行, r1=__image_copy_start ,也就是 r1 寄存器保存源地址,获取到镜像起始地址,
__image_copy_start=0X87800000
81 行,r0= 0X8FF38000 ,这个地址就是 uboot 拷贝的目标首地址
r4 = r0-r1 = 0X8FF38000 - 0X87800000=0X18747000 ,因此, r4寄存器 保存偏移量。
82 行,如果在第 81 中, r0-r1 等于 0 ,说明 r0 r1 相等,也就是源地址和目的地址是 一样的,那肯定就不需要拷贝了!即执行 relocate_done 函数。
83 行, r2 = __image_copy_end 保存拷贝之前的代码结束地址由之前的
__image_copy_end = 0X8786B03C
84 行,函数 copy_loop 完成代码拷贝工作!从 r1 ,也就是 __image_copy_start 开始,读 uboot 代码保存到 r10 r11 中,一次就只拷贝这 2 32 位的数据。拷贝完成以后 r1 的值会 更新,保存下一个要拷贝的数据地址。
87 行,将 r10 r11 的数据写到 r0 开始的地方,也就是目的地址。写完以后 r0 的值会 更新,更新为下一个要写入的数据地址。
88 行,比较 r1 是否和 r2 相等,也就是检查是否拷贝完成,如果不相等的话说明没有拷 贝完成,则跳转到 copy_loop 接着拷贝,直至拷贝完成。
下一篇文章继续学习 uboot重定位部分。具体学习 relocate_code 函数 的第二部分:
有关 " 重定位后有关函数调用或全局变量地址的问题"的解决方法。

我们知道,一个可执行的 bin 文件,其链接地址和运行地址要相等,也就是链接到哪个地址, 在运行之前,就要拷贝到哪个地址去。现在我们重定位以后,运行地址就和链接地址不同了,这 样寻址的时候不会出问题吗?

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值