GCC裸金属连接器问题-Cortex M3

GCC裸金属连接器问题-Cortex M3,gcc,cortex-m3,Gcc,Cortex M3,在我的项目链接过程中,我遇到了一个问题。我使用制造商提供的GCC链接器脚本 在这里,我对代码部分的定义如下: MEMORY { // .. deleted other sections CODE (rx ) : ORIGIN = 0x0000B000, LENGTH = 0x00074000 /* 116 page(s) */ // .. deleted other sections } 因此,代码段的开头位于0xB000,长度为0x74000。长度为116 x 4096字节

在我的项目链接过程中,我遇到了一个问题。我使用制造商提供的GCC链接器脚本

在这里,我对代码部分的定义如下:

MEMORY
{
  // .. deleted other sections
  CODE  (rx ) : ORIGIN = 0x0000B000, LENGTH = 0x00074000   /* 116 page(s) */
  // .. deleted other sections
}
因此,代码段的开头位于0xB000,长度为0x74000。长度为116 x 4096字节=>475136字节代码大小

我的二进制生成具有以下大小:

   text    data     bss     dec     hex filename
 432372       0  112048  522420   7f8b4 project.elf
因此,它应该链接OK,因为使用的大小432372(文本+数据)远小于可用空间475136

只要二进制代码大小<~422kBytes,它就可以链接,一旦它变大,链接器就会告诉我代码段溢出,无法链接

有人能解释一下为什么不行吗?我看不出链接告诉我我的代码太大的原因,因为它不是

链接器脚本

MEMORY
{
  // ... removed sections here .. irelevant for discussion ...
  CODE  (rx ) : ORIGIN = 0x0000B000, LENGTH = 0x00074000   /* 116 page(s) */
  // ... removed sections here .. irelevant for discussion ...
  RAM                    (xrw) : ORIGIN = 0x20000040, LENGTH = 20000
  MEMORY_B1              (rx ) : ORIGIN = 0x60000000, LENGTH = 0K
}

/* The '__stack' definition is required by crt0, do not remove it            */
__stack = ORIGIN(RAM) + LENGTH(RAM);
_estack = __stack; 

__Main_Stack_Size = 2048 ;

PROVIDE ( _Main_Stack_Size = __Main_Stack_Size ) ;

__Main_Stack_Limit = __stack  - __Main_Stack_Size ;

/*"PROVIDE" allows to easily override these values from an object file or the command line. */
PROVIDE ( _Main_Stack_Limit = __Main_Stack_Limit ) ;

/*
 * There will be a link error if there is not this amount of 
 * RAM free at the end. 
 */
_Minimum_Stack_Size = 2048 ;

/*
 * Default heap definitions.
 * The heap start immediately after the last statically allocated 
 * .sbss/.noinit section, and extends up to the main stack limit.
 */
/*PROVIDE ( _Heap_Begin = _end_noinit ) ;  */
/*PROVIDE ( _Heap_Limit = _end_noinit ) ;   */

_Min_Heap_Size  = 0x100; /* required amount of heap  (256 bytes) */
_Min_Stack_Size = 0x400; /* required amount of stack (1kByte)    */

ENTRY(Reset_Handler)

SECTIONS
{
  .text :
  {
    KEEP(*(.vectors))
    __Vectors_End = .;
    __Vectors_Size = __Vectors_End - __Vectors;
    __end__ = .;

    *(.text*)

    KEEP(*(.init))
    KEEP(*(.fini))

    /* .ctors */
    *crtbegin.o(.ctors)
    *crtbegin?.o(.ctors)
    *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors)
    *(SORT(.ctors.*))
    *(.ctors)

    /* .dtors */
    *crtbegin.o(.dtors)
    *crtbegin?.o(.dtors)
    *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors)
    *(SORT(.dtors.*))
    *(.dtors)

    *(.rodata*)

    KEEP(*(.eh_frame*))
  } > CODE

  .ARM.extab :
  {
    *(.ARM.extab* .gnu.linkonce.armextab.*)
  } > CODE

  __exidx_start = .;
  .ARM.exidx :
  {
    *(.ARM.exidx* .gnu.linkonce.armexidx.*)
  } > CODE
  __exidx_end = .;

  /* To copy multiple ROM to RAM sections,
   * uncomment .copy.table section and,
   * define __STARTUP_COPY_MULTIPLE in startup_ARMCMx.S */
  /*
  .copy.table :
  {
    . = ALIGN(4);
    __copy_table_start__ = .;
    LONG (__etext)
    LONG (__data_start__)
    LONG (__data_end__ - __data_start__)
    LONG (__etext2)
    LONG (__data2_start__)
    LONG (__data2_end__ - __data2_start__)
    __copy_table_end__ = .;
  } > CODE
  */

  /* To clear multiple BSS sections,
   * uncomment .zero.table section and,
   * define __STARTUP_CLEAR_BSS_MULTIPLE in startup_ARMCMx.S */
  /*
  .zero.table :
  {
    . = ALIGN(4);
    __zero_table_start__ = .;
    LONG (__bss_start__)
    LONG (__bss_end__ - __bss_start__)
    LONG (__bss2_start__)
    LONG (__bss2_end__ - __bss2_start__)
    __zero_table_end__ = .;
  } > CODE
  */

  __etext = .;

  .data : AT (__etext)
  {
    __data_start__ = .;
    *(vtable)
    *(.data*)
    . = ALIGN (4);
    *(.ram)

    . = ALIGN(4);
    /* preinit data */
    PROVIDE_HIDDEN (__preinit_array_start = .);
    KEEP(*(.preinit_array))
    PROVIDE_HIDDEN (__preinit_array_end = .);

    . = ALIGN(4);
    /* init data */
    PROVIDE_HIDDEN (__init_array_start = .);
    KEEP(*(SORT(.init_array.*)))
    KEEP(*(.init_array))
    PROVIDE_HIDDEN (__init_array_end = .);

    . = ALIGN(4);
    /* finit data */
    PROVIDE_HIDDEN (__fini_array_start = .);
    KEEP(*(SORT(.fini_array.*)))
    KEEP(*(.fini_array))
    PROVIDE_HIDDEN (__fini_array_end = .);

    KEEP(*(.jcr*))
    . = ALIGN(4);
    /* All data end */
    __data_end__ = .;

  } > RAM

  .bss :
  {
    . = ALIGN(4);
    __bss_start__ = .;
    *(.bss*)
    *(COMMON)
    . = ALIGN(4);
    __bss_end__ = .;
  } > RAM

  .heap (COPY):
  {
    __HeapBase = .;
    __end__ = .;
    end = __end__;
    _end = __end__;
    KEEP(*(.heap*))
    __HeapLimit = .;
  } > RAM

  /* .stack_dummy section doesn't contains any symbols. It is only
   * used for linker to calculate size of stack sections, and assign
   * values to stack symbols later */
  .stack_dummy (COPY):
  {
    KEEP(*(.stack*))
  } > RAM

  /* Set stack top to end of RAM, and stack limit move down by
   * size of stack_dummy section */
  __StackTop = ORIGIN(RAM) + LENGTH(RAM);
  __StackLimit = __StackTop - SIZEOF(.stack_dummy);
  PROVIDE(__stack = __StackTop);

  /* Check if data + heap + stack exceeds RAM limit */
  ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack")

  /* Check if CODE usage exceeds CODE size */
  ASSERT( LENGTH(CODE) >= (__etext + SIZEOF(.data)), "CODE memory overflowed !")
}
在最后几行,我断言代码大小:

  /* Check if CODE usage exceeds CODE size */
  ASSERT( LENGTH(CODE) >= (__etext + SIZEOF(.data)), "CODE memory overflowed !")
__etext应该是文本(代码)使用的实际大小。数据应该为零

有人能解释一下为什么不行吗

只需查看链接器脚本:

code(rx):原点=0x0000B000,长度=0x00074000/*116页)*/

0x74000十六进制为‭475136‬ 十进制,或464KB

__etext应该是文本(代码)使用的实际大小。数据应该为零

不是根据链接器脚本。在发布的脚本中,uu etext是代码段的结束地址。或者只是代码段的大小加上它的起始地址(非零)

换句话说,您的最后一个ASSERT()编码错误,过早地释放0xB000字节。和0x74000-0xB000=0x69000(或‭430080‬ 十进制)

有人能解释一下为什么不行吗

只需查看链接器脚本:

code(rx):原点=0x0000B000,长度=0x00074000/*116页)*/

0x74000十六进制为‭475136‬ 十进制,或464KB

__etext应该是文本(代码)使用的实际大小。数据应该为零

不是根据链接器脚本。在发布的脚本中,uu etext是代码段的结束地址。或者只是代码段的大小加上它的起始地址(非零)


换句话说,您的最后一个ASSERT()编码错误,过早地释放0xB000字节。和0x74000-0xB000=0x69000(或‭430080‬ 小数)。

如果显示的不够多,二进制文件中的.bss是如何显示的?正在使用的整个链接器脚本是什么样子的?当你把它缩小到能说明问题的范围时会发生什么?@old_timer(A).bss是零初始化的ram部分。因此,我有闪存区域(文本+数据)和ram部分(bss+数据)。数据是由ram初始化的值。(B) 你需要什么样的证明?正如我所说,问题发生在我添加新代码时,因此代码大小增加了约422kBytes,然后链接器“表示”代码部分不适合flash部分并中止链接。(C) 链接器脚本,请参阅上面编辑的帖子当我写评论时,你的链接器脚本没有数据,也没有bss定义,只有代码,但问题超出了前面提到的范围。如果您有工具/链接器脚本问题,您可以将其设置为10或100字节的部分,并对问题中可见的所有示例代码/数据进行相同的演示。如果您的演示不够,那么二进制文件中如何有.bss?正在使用的整个链接器脚本是什么样子的?当你把它缩小到能说明问题的范围时会发生什么?@old_timer(A).bss是零初始化的ram部分。因此,我有闪存区域(文本+数据)和ram部分(bss+数据)。数据是由ram初始化的值。(B) 你需要什么样的证明?正如我所说,问题发生在我添加新代码时,因此代码大小增加了约422kBytes,然后链接器“表示”代码部分不适合flash部分并中止链接。(C) 链接器脚本,请参阅上面编辑的帖子当我写评论时,你的链接器脚本没有数据,也没有bss定义,只有代码,但问题超出了前面提到的范围。如果您有工具/链接器脚本问题,可以将其设置为10或100字节的部分,并对问题中可见的所有示例代码/数据进行相同的演示。