1

我正在尝试使用 Atmel Studio 7 中包含的 ARM GNU 工具链(arm-none-eabi ?)为 Cortex-M0+ 创建与位置无关的二进制文件。我已经在很多地方寻找有关如何执行此操作的信息,但没有成功。这将有助于在低高闪存区域中为 OTA 更新创建 ping-pong 映像,而无需知道或关心更新是该单元的 ping 映像还是 pong 映像。

我有一个位于 0x0000 的 8 kB 引导加载程序,我可以通过 UART 与它通信,如果它在此处检测到二进制文件(即不是 0xFFFF 擦除闪存),它将在重置后跳转到 0x6000(24 kB)。这个 SAM-BA 引导加载程序允许我在指定地址转储内存并使用 .bin 文件擦除和编程闪存。

在应用程序项目中(简单的 LED 闪烁),除了在链接器命令行中添加 -section-start=.text=0x6000 之外什么都不做会导致 LED 闪烁代码在引导加载程序在 0x6000 处编程后工作。我还在十六进制文件中看到它从 0x6000 开始。

在我尝试创建与位置无关的二进制文件时,我删除了上述链接器项,并将 -fPIC 标志添加到编译器、链接器和汇编器的命令行中。但是,我想我仍然在反汇编中看到绝对分支地址,例如:

28e: d001 beq.n 294

结果是我在 0x6000 加载的 LED 闪烁二进制文件不会执行,除非我明确告诉链接器将它放在 0x6000,这违背了目的。请注意,我也确实看到了反汇编其他部分中的相对分支:

21c:4b03 ldr r3,[pc,#12];(22c)

21e: 58d3 ldr r3, [r2, r3]

220:9301 str r3,[sp,#4]

222: 4798 blx r3

SRAM 总是在同一个地址(0x20000000),我只需要能够重新定位可执行文件。我没有修改链接器命令文件,并且它没有 .got 部分(例如(.got)或类似文件)。

谁能向我解释我需要对编译器/汇编器/链接器标志进行的具体更改以在此设置中创建与位置无关的二进制文件?提前谢谢了。

4

1 回答 1

0

您需要更仔细地查看您的拆卸。对于 0xd001,我得到这个:

 0x00000000:    d001        ..      BEQ      {pc}+0x6 ; 0x6

就您而言,工具链已尝试提供帮助。显然,16 位操作码不能用 32 位地址空间编码绝对地址。因此,您比您想象的更接近解决方案。

于 2019-03-21T16:52:50.237 回答