(arm-none-eabi-gcc) 从引导加载程序 + 2 x 固件映像创建 .elf 二进制文件

Posted

技术标签:

【中文标题】(arm-none-eabi-gcc) 从引导加载程序 + 2 x 固件映像创建 .elf 二进制文件【英文标题】:(arm-none-eabi-gcc) creating .elf binary from bootloader + 2 x firmware image 【发布时间】:2020-07-13 11:45:07 【问题描述】:

我正在使用 CLion 开发 STM32F429,并尝试从三个 .elf 文件创建合并的 .elf 文件。 合并后的 .elf 文件的布局应如下所示:

Bootloader.elf(最大 256K,但大小可能不同) FirmwareImage.elf(始终为 384K,填满第一个固件映像的分配空间) FirmwareImage.elf(始终为 384K,为第二个固件映像填满分配的空间)

总共正好是 100 万。

我尝试将 .elf 文件转换为 .bin(使用 arm-none-eabi-objcopy)并使用我编写的自定义工具创建 1M .bin 文件。我可以确认创建的 .bin 的布局是正确的。 然后我将生成的 .bin 文件转换回 .elf :

arm-none-eabi-objcopy -I binary -O elf32-little --change-section-address .data=0x08000000 in.bin out.elf

数据段地址变化是为了反映STM32F429中闪存的开始。

当我尝试使用 openocd 刷新此文件时,它失败了:

Error: invalid ELF file, no program headers

有没有办法跳过 .elfs -> .bin -> .elf 转换并直接从 .elfs -> .elf 转换?或者,插入程序标题?我怀疑这些实际上是在闪烁期间使用的。

我知道我可以通过指定闪存地址直接告诉 openocd 使用生成的 .bin 文件。但是 CLion 不会让 openocd 从其 arm-embedded 插件中刷新 .bin 文件,只有 .elf 文件。

编辑: 目前我正在使用these 链接器脚本,改编自ST 的官方脚本。他们有很多事情发生。 我可能只能使用单个链接器脚本来实现这一点。我可以有以下代码:

extern "C" __attribute__((__section__(".bootloader"))) void runBootloader()

    Platform platform;
    DFUBootloader bootloader(platform);


extern "C" __attribute__((__section__(".image1"))) void runApplication1()

    Platform platform;
    Application application(platform);


extern "C" __attribute__((__section__(".image2"))) void runApplication2()

    Platform platform;
    Application application(platform);

如果这些链接器将这些符号放置在正确的位置,它们使用的符号最终也会放置在正确的位置吗?必须复制固件映像以填满两个固件页面,因此应用程序使用的所有符号也必须复制。

【问题讨论】:

这些对象还是链接器的输出?为什么不按设计使用链接器 @old_timer,这就是你所说的“按设计”的意思吗? 链接器的工作是把东西放在输出二进制文件中的指定地址,你能不能在链接时不这样做,而不是在链接单独的项目之后将它们重新组合在一起以尝试再次链接它们.还有为什么结果需要elf这是一个MCU。 已发布答案并更新了问题,以更清楚地表明 CLion 是问题的一部分 【参考方案1】:

看起来以我描述的方式合并多个 .elf 文件是不可能的,或者至少不是很简单。

我找到了解决问题的方法。尽管 CLion 无法让 openocd 刷新 .bin 文件(其内置的 openocd 启动命令使用 .elf),但使用以下命令可以轻松创建自定义 CMake 目标来刷新合并的 .bin:

openocd -f board/stm32f429discovery.cfg -c "program merged_image.bin exit 0x08000000"

【讨论】:

以上是关于(arm-none-eabi-gcc) 从引导加载程序 + 2 x 固件映像创建 .elf 二进制文件的主要内容,如果未能解决你的问题,请参考以下文章

STM32 从外部闪存引导,QUADSPI 引导加载程序

Django:引导 CDN 或从本地服务器加载引导文件?

通过应用程序跳转到 STM32 中的引导加载程序,即在引导模式下从用户闪存使用引导 0 和引导 1 引脚

如何使用从 iframe 加载的点击事件关闭引导模式

从汇编语言引导加载程序检查软盘是不是可用

创建“update.zip”以从恢复模式(引导加载程序)安装 APK?