反汇编u-boot与重定向(正点原子笔记)

重定位就是 uboot 将自身拷贝到 DRAM 的另一个地放去继续运行(DRAM 的高地址处)。
我们知道,一个可执行的 bin 文件,其链接地址和运行地址要相等,也就是链接到哪个地址,
在运行之前就要拷贝到哪个地址去。现在我们重定位以后,运行地址就和链接地址不同了,这
样寻址的时候不会出问题吗?为了分析这个问题,需要在 mx6ull_alientek_emmc.c 中输入
如下所示内容。

static int rel_a = 0;

void rel_test(void)
{
 rel_a = 100;
 printf("rel_test\r\n");
}

最后还需要在 mx6ullevk.c 文件中的 board_init 函数里面调用 rel_test 函数,否则 rel_reset 不
会被编译进 uboot。

 board_init 函数会调用 rel_testrel_test 会调用全局变量 rel_a,使用如下命令编译 uboot

./mx6ull_alientek_emmc.sh

编译完成以后,使用 arm-linux-gnueabihf-objdump 将 u-boot 进行反汇编,得到 u-boot.dis 这
个汇编文件,命令如下:

arm-linux-gnueabihf-objdump -D -m arm u-boot > u-boot.dis

在 u-boot.dis 文件中找到 rel_a、rel_rest 和 board_init,相关内容如下所示:

1 87804184 <rel_test>:
2 87804184: e59f300c ldr r3, [pc, #12] ; 87804198 <rel_test+0x14>
3 87804188: e3a02064 mov r2, #100 ; 0x64
4 8780418c: e59f0008 ldr r0, [pc, #8] ; 8780419c <rel_test+0x18>
5 87804190: e5832000 str r2, [r3]
6 87804194: ea00d668 b 87839b3c <printf>
7 87804198: 8785da50 ; <UNDEFINED> instruction: 0x8785da50
8 8780419c: 878426a2 strhi r2, [r4, r2, lsr #13]
9 
10 878041a0 <board_init>:
11 878041a0: e92d4010 push {r4, lr}
12 878041a4: ebfffff6 bl 87804184 <rel_test>
13
14 ......
15
16 8785da50 <rel_a>:
17 8785da50: 00000000 andeq r0, r0, r0

第 12 行是 borad_init 调用 rel_test 函数,用到了 bl 指令,而 bl 指令时位置无关指令,bl 指
令是相对寻址的(pc+offset),因此 uboot 中函数调用是与绝对位置无关的。
再来看一下函数 rel_test 对于全局变量 rel_a 的调用,第 2 行设置 r3 的值为 pc+12 地址处的
值,因为ARM流水线的原因,pc寄存器的值为当前地址+8,因此pc=0X87804184+8=0X8780418C,
r3=0X8780418C+12=0X87804198,第 7 行就是 0X87804198 这个地址,0X87804198 处的值为
0X8785DA50。根据第 17 行可知,0X8785DA50 正是变量 rel_a 的地址,最终 r3=0X8785DA50。

第 3 行,r2=100。
第 5 行,将 r2 内的值写到 r3 地址处,也就是设置地址 0X8785DA50 的值为 100,这不就
是示例代码代码 32.2.6.2 中的第 5 行:rel_a = 100。

总结:

①、在函数 rel_test 末尾处有一个地址为 0X87804198 的内存空间(示例代码 32.2.6.3 第 7
行),此内存空间保存着变量 rel_a 的地址。
②、函数 rel_test 要想访问变量 rel_a,首先访问末尾的 0X87804198 来获取变量 rel_a 的地
址,而访问 0X87804198 是通过偏移来访问的,很明显是个位置无关的操作。
③、通过 0X87804198 获取到变量 rel_a 的地址,对变量 rel_a 进行操作。
④、可以看出,函数 rel_test 对变量 rel_a 的访问没有直接进行,而是使用了一个第三方偏
移地址 0X87804198,专业术语叫做 Label。这个第三方偏移地址就是实现重定位后运行不会出
错的重要原因!

uboot 重 定 位 后 偏 移 为 0X18747000 , 那 么 重 定 位 后 函 数 rel_test 的 首 地 址 就 是
0X87804184+0X18747000=0X9FF4B184 。 保 存 变 量 rel_a 地 址 的 Label 就 是
0X9FF4B184+8+12=0X9FF4B198( 既 : 0X87804198+0X18747000) , 变 量 rel_a 的 地 址 就 为0X8785DA50+0X18747000=0X9FFA4A50。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值