【问题标题】:GCC BareMetal Linker Issue - Cortex M3GCC BareMetal 链接器问题 - Cortex M3
【发布时间】:2020-02-19 12:02:33
【问题描述】:

在我的项目链接过程中遇到问题。我使用制造商提供的 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 的可用空间。

只要二进制代码大小

谁能解释我为什么不呢?我看不到链接告诉我我的代码太大的原因,因为它不是!

链接脚本

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 应该是文本(代码)使用的实际大小,.data 应该为零

【问题讨论】:

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

标签: gcc cortex-m3


【解决方案1】:

谁能解释我为什么不呢?

只需查看链接器脚本:

CODE (rx ) : ORIGIN = 0x0000B000, LENGTH = 0x00074000 /* 116 page(s) */

0x74000 十六进制是 475136 十进制,即 464KB。

__etext 应该是文本(代码)使用的实际大小,.data 应该为零

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

换句话说,您的最后一个 ASSERT() 编码错误并且过早退出 0xB000 字节。并且 0x74000-0xB000 = 0x69000(或十进制的 430080)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-04-05
    • 1970-01-01
    • 1970-01-01
    • 2010-09-17
    • 1970-01-01
    • 2011-06-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多