底软驱动 | uboot 与 代码重定位

1、为什么需要重定位?

大部分的程序是不需要重定位的,但是有时候需要。

最常见的例子就是我们的UBOOT,因为我们的UBOOT有200多KB,但是我们开始BL0的地方只有96KB。

所以我们需要在96KB之前进行重定位,使开发板能够进行重定位。如果代码不是位置无关码,代码必须放在链接地址开始的地方,程序才可以正常运行,否则的话当PC去访问、执行某个变量名、函数名对应地址上的代码时就会找不到,接着程序无疑就是跑飞。

2、什么是重定位?

  • 重定位:把代码搬移到你想要的地址,本来程序是运行在运行地址处的,你可以通过重定位搬移到链接地址处。

  • 链接地址: 编译器对代码中的变量名、函数名等东西进行一个地址的编排,赋予这些抽象的东西一个地址,然后在程序中访问这些变量名、函数名就是在访问一些地址,这些地址我们称之为编译地址。

  • 运行地址:是指程序指令真正运行的地址,是由用户指定的,用户将运行地址烧录到哪里,也就是PC当前执行指令所在的实际地址,就是运行的地址。也就是真实在程序中运行的地址。

3、重定位的基础知识

(1)大部分指令是位置有关编码。

  • 位置无关码(PIC, position independent code):

汇编源文件被编码成二进制可执行程序后与位置无关。有些特别的指令,可以跟地址没有关系。也就是说这些代码实际运行时,不管放在哪里都能正常运行。

  • 位置有关码:

汇编编码成二进制可执行程序后和内存地址是有关的。

PS:
我们在设计一个程序时,会给这个程序指定一个运行地址。就是说我们在写程序时,其实我们是知道我们程序将来被运行的地址的。
必须给编译器和链接器指定这个地址才行,最后得到二进制程序。
理论上和你指定的运行地址是有关的,这就叫做位置有关代码。

(2) 对于位置有关码来说:最终执行时的运行地址和编译链接时给定的链接地址必须相同,否则一定会出错。

如果编译时 使用-Ttext 0x0来指定链接地址是0x0,这意味着我们认为这个程序将来会放在这个内存地址中运行。但是实际上我们运行的地址是下载在开发板的地址0xd0020010。因为是位置无关码,所以运行程序来是没有什么问题的。而且我们开发板对这些程序进行了映射,所以说这是一个偶然的情况。

(3)我们再来分析一下S5PV210的启动过程。

官方建议的启动过程(假定你的Bootloader为80KB)

  • 开机启动,执行BL0,BL0会加载外部启动设备中的bootloader的前16KB到SRAM,

(BL0是厂家事先固化好的程序)就是BootRom

  • 校验BL1,运行BL1

  • BL1在运行时,初始化外部DDR,加载剩余的64kb代码到 BL2中 ( 64 = 80 - 16)

  • 运行BL2,初始化DDR,并且将OS搬运到DDR

  • 执行OS,启动完成。

UBOOT实际上的启动的方法:

(由于 BL2 的空间也太小了,使用起来非常有局限,所以uboot的设计者干脆在BL1以后,连同BL2与OS有关的直接放到DDR上运行了)

  • 先开机上电,BL0运行,BL0会加载外部启动设备中的UBOOT的前16KB(BL1)到SRAM中去运行,

  • BL1运行会初始化DDR。然后将整个UBOOT,搬运到我们的DDR中。

  • 从SRAM中直接长跳转到DDR中继续执行我们的UBOOT。直到UBOOT完全启动。

  • 长跳转的意思就是从SRAM中跳转到DDR中。UBOOT启动后在命令行中去执行OS。

4、从源码到可执行程序的步骤:预编译、编译,链接、[strip]

  • 预编译: 比如C中的宏定义就是由预编译器处理的,注释等也是由预编译器处理的。

  • 编译: 编译器来执行,把源码中的.c/.s文件转换为.o文件。

  • 链接: 链接器来执行,把.o文件中的各种函数(段)按照一定的规则(即使不用用链接脚本指定,链接器也有默认的固定的顺序)链接到一起,形成可执行程序。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

TrustZone_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值