GCC ld Bootloader链接Cortex M3 / M4

时间:2014-06-18 08:39:42

标签: c gcc linker bootloader cortex-m3

我无法找到有关我想要实现的信息。我正在使用ARM GCC工具链为Cortex M4微控制器开发固件。该固件的一个功能是引导加载程序,它位于闪存的第一个地址,用于检查是否需要闪存,然后闪存其余内存。

为此,我确保引导加载程序功能都包含在一个部分中,因此永远不会调用闪存的固件端。问题是,我在引导程序中有一些功能,我想从固件中使用它。这在开发中非常有效,因为我每次都在编译和链接所有内容,但是我担心将来gcc / ld会改变引导加载程序的布局,使得从固件调用到不同的地址并破坏旧的ulpdated系统

具体来说,我有:

.pretext : AT(ORIGIN(FLASH_1_uncached))
{
    KEEP(*(.false.vector));
    *(.Xmc4200.falsepostreset);
    *aes*.o (.text .text.* .gnu.linkonce.t.* .rodata .rodata.* .gnu.linkonce.r.*);
    *crc32*.o (.text .text.* .gnu.linkonce.t.* .rodata .rodata.* .gnu.linkonce.r.*);
    *bootloader.o (.text .text.* .gnu.linkonce.t.* .rodata .rodata.* .gnu.linkonce.r.*);
    *BootCLK*.o (.text .text.* .gnu.linkonce.t.* .rodata .rodata.* .gnu.linkonce.r.*);
    *BootIO001*.o (.text .text.* .gnu.linkonce.t.* .rodata .rodata.* .gnu.linkonce.r.*);
    *BootIO004*.o (.text .text.* .gnu.linkonce.t.* .rodata .rodata.* .gnu.linkonce.r.*);
    *BootRESET001*.o (.text .text.* .gnu.linkonce.t.* .rodata .rodata.* .gnu.linkonce.r.*);
    *BootSPI001*.o (.text .text.* .gnu.linkonce.t.* .rodata .rodata.* .gnu.linkonce.r.*);
    *bslld*.o (.text .text.* .gnu.linkonce.t.* .rodata .rodata.* .gnu.linkonce.r.*);
    __pretext_end = .;
} > FLASH_1_cached

.text ABSOLUTE(0x08008000): AT(0x0C008000)
{
    sText = .;
    *(.Xmc4200.reset);
    KEEP(*(.version));
    *(.Xmc4200.postreset);
    *(.XmcStartup);
    *(EXCLUDE_FILE (*boot_ram.o *FLASH002*.o *aes*.o *bootloader.o *BootCLK*.o *BootIO001*.o *BootIO004*.o *BootRESET001*.o *BootSPI001*.o *bslld*.o *crc32*.o) .text);
    *(EXCLUDE_FILE (*boot_ram.o *FLASH002*.o *aes*.o *bootloader.o *BootCLK*.o *BootIO001*.o *BootIO004*.o *BootRESET001*.o *BootSPI001*.o *bslld*.o *crc32*.o) .text.*);
    *(EXCLUDE_FILE (*boot_ram.o *FLASH002*.o *aes*.o *bootloader.o *BootCLK*.o *BootIO001*.o *BootIO004*.o *BootRESET001*.o *BootSPI001*.o *bslld*.o *crc32*.o) .gnu.linkonce.t.*);
...

请注意以下事项:

  • 有一些Boot *目标文件是我在引导加载程序中需要的固件代码的复制品,具有不同的命名方案,因此不会发生任何冲突。
  • 我在那里有aes和crc,以及我从固件端使用的一些常量
  • 我没有在RAM中包含与引导加载程序部分相关的链接描述文件的其他部分,因为它起作用,我认为与问题无关。

我希望实现的目的是确保将来每个符号的引导加载程序在地址方面保持完全相同,因此新固件将始终使用这些地址。

我认为只使用始终相同的.o文件作为引导加载程序并不能保证任何内容,因为如果将来使用另一个gcc版本,链接器可能会优化或执行不同的操作,我是对的吗?

此外,没有选项只将每个符号放在链接器脚本上,或者至少,我找不到它。函数相对容易,因为我用-ffunction-sections编译,但是其他符号如常量和变量呢?解决方案是掩盖函数下的所有内容并将它们排序在链接描述文件中吗?那会有用吗?对于这种情况,我还缺少其他任何典型的解决方案吗?

感谢您的帮助

0 个答案:

没有答案