为 ARM M4 编译和链接位置无关代码 (PIC)

Dre*_*ter 2 c arm position pic bootloader

我正在制作一个引导加载程序并赋予它自我更新的能力。此过程包括将二进制文件复制到新位置,跳转到该位置,然后使用它在原始位置刷新新的引导加载程序。这一切都是使用 ARM GCC 工具链在 Eclipse 中为 M4 处理器开发的。

为此,我认为需要将其编译为位置无关代码(PIC)。

我四处搜索并发现这篇优秀的文章,因此当我将“-fPIC”添加到 ARM GCC 编译器调用时,我预计会看到有关 GOT 和 PLT 丢失的链接器错误 https://eli.thegreenplace.net/2011/11 /03/共享库中的位置无关代码图片/

在我的链接器脚本中,我将这些位置添加到 .data 部分,如下所示:

.data : AT(__DATA_ROM)
{
. = ALIGN(4);
__DATA_RAM = .;
__data_start__ = .; /* Create a global symbol at data start. */
*(.got*) /* .got and .plt for position independent code */
*(.data) /* .data sections */
*(.data*) /* .data* sections */
KEEP(*(.jcr*))
. = ALIGN(4);
__data_end__ = .; /* Define a global symbol at data end. */
} > m_data
Run Code Online (Sandbox Code Playgroud)

但是,此代码无法从 ROM 复制到 RAM。

我的下一个想法是,也许我的链接器需要知道它正在链接 PIC 可执行文件。为了找到答案,我在 LD 链接器脚本调用中添加了“--pic-executable”。然而,链接器现在生成了“interp”、“dyn”、“rel.dyn”和“hash”部分。我也尝试将它们放入数据部分,但出现以下错误:

gcc-arm-none-eabi-4_9/bin/../lib/gcc/arm-none-eabi/4.9.3/../../../../arm-none-eabi/bin/ld .exe:找不到输出节.hash

gcc-arm-none-eabi-4_9/bin/../lib/gcc/arm-none-eabi/4.9.3/../../../../arm-none-eabi/bin/ld .exe:最终链接失败:输出中不可表示的部分

我认为这意味着编译器实际上没有用任何内容填充“.hash”部分,因此链接失败。

我的做法正确吗?我还需要添加其他内容才能让编译器执行此操作吗?任何帮助将不胜感激。

Jan*_*rvi 7

最近,我广泛研究了 Cortex-M4 引导加载 PIC 固件映像。

有几件事需要:

一个非常简单的引导加载程序。它只需要从固件映像的闪存位置读取 2 个 4 字节字。第一个是堆栈指针地址,第二个是 Reset_Handler 地址。Bootloader需要跳转到Reset_Handler。但随着固件在闪存中重新定位得更远,Reset_Handler 实际上也更远一些。请参阅此图片以进行澄清:

因此,引导加载程序在跳转到固件映像的 Reset_Handler 之前添加正确的偏移量。没有进行其他修补,但引导加载程序(至少在我的解决方案中)存储固件映像的位置和偏移量,计算校验和并将此信息传递到寄存器中以供固件映像使用。

然后我们需要修改固件链接器文件以强制 ISR 向量表位于 RAM 的开头。对于 Cortex-M4 和 VTOR(向量偏移表寄存器),ISR 向量表需要与 512 边界对齐。在 RAM 的开头,它自然就在那里。在链接描述文件中,我们还在 RAM 中为全局偏移表 (GOT) 指定了一个位置,以便于操作。地址范围也应该通过链接描述文件符号导出。

我们还需要 C 编译器选项。基本上是这些:

-fpic

-mpic-寄存器=r9

-ms单图片库

-mno-pic-data-is-text-relative

它们只适用于 C 编译器!这将创建全局偏移表 (GOT) 核算。

最后,我们需要在固件映像项目中使用专用且繁琐的汇编引导例程。这些例程执行设置 C 运行时环境的正常启动任务,但它们还从闪存读取 ISR 和 GOT 并将它们复制到 RAM。在 RAM 中,那些指向闪存的表的地址会根据固件映像在引导加载程序之外运行的数量进行偏移。示例图片:

我花了 6 个月的时间研究这个主题,并在这里写了一篇关于它的深入文章:

https://techblog.paalijarvi.fi/2022/01/16/portable-position-independent-code-pic-bootloader-and-firmware-for-arm-cortex-m0-and-cortex-m4/

通过提供链接,我希望能为 StackOverflow 做出贡献,我将其作为我研究的起点。我希望这可以帮助一些人学习内在原理。