3

我正在尝试将 Cortex-M4 固件与 clang + lld 链接。gcc 构建工作正常。我正在使用仅调整 RAM 和 ROM 大小的库存 CMSIS链接器脚本(基数相同)。脚本的开头(没有注释):

__ROM_BASE = 0x00000000;
__ROM_SIZE = 0x00040000; /* 256 KB */
__RAM_BASE = 0x20000000;
__RAM_SIZE = 0x00010000; /* 64 KB */
__STACK_SIZE = 0x00000400;
__HEAP_SIZE  = 0x00000C00;
MEMORY
{
  FLASH (rx)  : ORIGIN = __ROM_BASE, LENGTH = __ROM_SIZE
  RAM   (rwx) : ORIGIN = __RAM_BASE, LENGTH = __RAM_SIZE
}

ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack")在脚本末尾的断言上链接失败。如果我删除断言二进制链接很好,但堆栈位于错误的地址。它以闪存结束(堆也在错误的位置)。输出nm

200018a8 B __bss_end__
200000d8 B __bss_start__
00004568 R __copy_table_end__
0000455c R __copy_table_start__
200000d4 D __data_end__
20000000 D __data_start__
00000000 ? __end__
00004570 A __etext
0000455c R __exidx_end
0000454c T __exidx_start
00000c00 A __HEAP_SIZE
00000c00 ? __HeapLimit
200000d4 d __init_array_end
200000d0 d __init_array_start
         w __libc_fini_array
00000445 T __libc_init_array
200000d0 d __preinit_array_end
200000d0 d __preinit_array_start
20000000 A __RAM_BASE
00010000 A __RAM_SIZE
00000000 A __ROM_BASE
00040000 A __ROM_SIZE
00000400 ? __stack
00000400 A __STACK_SIZE
00000000 ? __StackLimit
00000400 ? __StackTop

尝试在 Cortex-M 上运行时,代码当然会崩溃。我找到了这张票。如果我将我的.stack部分更改为:

.stack (COPY) :
  {
    . = ORIGIN(RAM) + LENGTH(RAM) - __STACK_SIZE;
    __StackLimit = .;
    . = . + __STACK_SIZE;
    . = ALIGN(8);
    __StackTop = .;
  } > RAM
  PROVIDE(__stack = __StackTop);

然后我收到溢出错误:

ld.lld: error: section '.stack' will not fit in region 'RAM': overflowed by 536879272 bytes

这个巨大的数字是 0x200020A8 所以lld可能正确地获得了结束地址,但不是原点。

如何修复链接器脚本以将堆栈正确放置在 RAM 顶部?感谢帮助

4

1 回答 1

0

我通过删除COPY并添加NOLOAD到堆栈部分来修复它。它可以使用 gcc 和 clang 构建和运行良好。

 .stack (ORIGIN(RAM) + LENGTH(RAM) - __STACK_SIZE) (NOLOAD) :
   {
    . = ALIGN(8);
    __StackLimit = .;
    . = . + __STACK_SIZE;
    . = ALIGN(8);
    __StackTop = .;
   } > RAM
   PROVIDE(__stack = __StackTop);
于 2022-02-08T09:57:09.297 回答