蓝盟IT小贴士,来喽!
一、为什么需要位置无关代码?
首先,你需要知道ARM板的启动过程。
1. exynos 4412启动过程
首先让我们看看exynos 4412 memory map。
iROM源地址是0x00000000 iRAM源地址是0x02020000
这两个内存在SOC上。
显示exy nos 4412引导顺序:
在第五章。
上图是exynos4412通电复位时的启动流程,大致如下。
小于1的是执行内部只读存储器的iROM的代码(制造商在内部固化),该代码主要是初始化几个系统的基本结构,例如初始时钟结构、堆栈、启动模式(与图中的标志对应)
小于2的iROM代码根据在第1阶段获取的启动模式(OM_STAT寄存器),从相应的存储介质将BL1镜像到内部静态随机存储器SRAM。 BL1主要具备系统时钟的初始化动作、存储器控制器的几个定时的配置。 这些作业结束后,将OS镜像复制到存储器中(对应图中的标记)。
小于3时,跳至操作系统执行。
SRAM只有256KB,但uboot镜像通常超过了这个大小。 也就是说,不能将完整的uboot镜像复制到SRAM。 因此,这里的复制方法是“BL1复制只是UBOT的一部分”,估计这部分除了基本的硬件操作环境之外,还可以“完全复制uboot镜像本身”。
通常,两者的地址不同,程序在DRAM中的地址重新定位过程必须由程序员执行。
这是一种名为“位置无关代码”的概念,是指代码即使不是连接时指定的执行地址空间也可以执行,可以加载到任意地址空间中执行的特殊代码。
如果uboot移动到DRAM,跳转到DRAM,继续运行uboot的其馀代码,移动前的代码无论位置如何,都将无法使用绝对寻址命令。 否则,寻址将出错。
二、如何实现位置无关代码?
什么是《编译地址》? 什么是《运行地址》? “编译到:”
32位处理器,每个指令为4字节,以4字节的存储顺序依次执行,CPU依次执行,除非发生任何跳跃,否则依次执行,编译器为每个指令分配编译地址。 这是编译器分配的、在编译过程中分配的地址,称为编译地址。执行地址:
程序指令实际执行的地址,是用户指定的,是用户将执行地址写入哪里,执行哪里的地址。 例如,一个指令的编译地址是0x40008000,实际执行的地址是0x40008000,用户在0x6000000上烧指令时,该指令的执行地址是0x6000000。
如果编译目标和执行目标不同会怎么样? 结果无法跳转,编译后发生跳转目标,实际地址和编译后发生的地址不相等的话就无法跳转。
“c语言编译目标:”
我想把编译地址和实际执行地址放在一起,但是汇编代码不需要从c语言转换为汇编,所以可以直接写地址。 所以直接写他的执行地址。 这是bootloader首先具有程序集代码的原因。 因为开始代码的编译地址和实际地址不相等,所以无论程序集如何,该代码都是跳转的执行地址。
文/上海蓝盟 IT外包专家