Skip to content

[Bug] STM32的gcc链接脚本存在问题,会导致编译后的固件大小可以超出flash允许范围 #11124

@wdfk-prog

Description

@wdfk-prog

RT-Thread Version

master

Hardware Type/Architectures

STM32

Develop Toolchain

GCC

Describe the bug

  • stm32 自带的链接脚本如下
  /* Used by the startup to initialize data */
  _sidata = LOADADDR(.data);

  /* Initialized data sections into "RAM" Ram type memory */
  .data :
  {
    . = ALIGN(4);
    _sdata = .;        /* create a global symbol at data start */
    *(.data)           /* .data sections */
    *(.data*)          /* .data* sections */
    *(.RamFunc)        /* .RamFunc sections */
    *(.RamFunc*)       /* .RamFunc* sections */

    . = ALIGN(4);
    _edata = .;        /* define a global symbol at data end */

  } >RAM AT> FLASH
  • RTT的链接脚本如下,没有将.data绑定到flash 区域,导致编译器并不会识别到这一块实际上是放入flash存储的空间,进而对超过的固件大小进行报错

__exidx_start = .;
.ARM.exidx :
{
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
/* This is used by the startup in order to initialize the .data secion */
_sidata = .;
} > ROM
__exidx_end = .;
/* .data section which is used for initialized data */
.data : AT (_sidata)
{
. = ALIGN(4);
/* This is used by the startup in order to initialize the .data secion */
_sdata = . ;
*(.data)
*(.data.*)
*(.gnu.linkonce.d*)
PROVIDE(__dtors_start__ = .);
KEEP(*(SORT(.dtors.*)))
KEEP(*(.dtors))
PROVIDE(__dtors_end__ = .);
. = ALIGN(4);
/* This is used by the startup in order to initialize the .data secion */
_edata = . ;
} >RAM

MEMORY
{
    CODE (rx) : ORIGIN = 0x08000000, LENGTH = 128k /* 128k boot flash */
    RAM1 (rw) : ORIGIN = 0x20000000, LENGTH =  128k /* 128K sram */
    CCM  (rw) : ORIGIN = 0x10000000, LENGTH =   64k /* 64K ccm ram */
}

arm-none-eabi-objcopy -O binary "f407_boot.elf"  "f407_boot.bin"
arm-none-eabi-size --format=berkeley "f407_boot.elf"
make --no-print-directory post-build
   text	   data	    bss	    dec	    hex	filename
 130752	   1900	  16820	 149472	  247e0	f407_boot.elf

              Used Size(B)           Used Size(KB)
Flash:         132652 B              129.54 KB
RAM:            18720 B               18.28 KB
arm-none-eabi-objcopy -O ihex "f407_boot.elf" "f407_boot.hex"
  • 进行如下修改后可以超过大小将会提醒
  • 原因:
    • “.data 链接到 RAM1”指的是它的 VMA(运行时地址)在 RAM;但它的 LMA(镜像存放位置)默认还是紧跟前一段(通常是 Flash 的 .text)排布在输出镜像里,开机时由启动代码把 LMA 处的初始化数据拷到 RAM 的 _sdata。

所以即使 > RAM1,如果没写 AT> CODE,ld 会把 .data 的 LMA 放到前一段后面(仍在 Flash 地址空间),并且不会对 Flash 区域做越界检查,这就是为什么 .data 的内容占用 Flash 容量却不报错。

若想让 Flash 溢出被检查,就把 .data 写成 > RAM1 AT> CODE 并用 LOADADDR(.data) 作为 _sidata;.bss/.stack 没有初始化镜像,不占 Flash,不需要 AT> CODE

    /* .ARM.exidx is sorted, so has to go in its own output section.  */
    __exidx_start = .;
    .ARM.exidx :
    {
        *(.ARM.exidx* .gnu.linkonce.armexidx.*)
    } > CODE
    __exidx_end = .;

    /* .data section which is used for initialized data */
    _sidata = LOADADDR(.data);

    .data :
    {
        . = ALIGN(4);
        /* This is used by the startup in order to initialize the .data secion */
        _sdata = . ;

        *(.data)
        *(.data.*)
        *(.gnu.linkonce.d*)

        . = ALIGN(4);
        /* This is used by the startup in order to initialize the .data secion */
        _edata = . ;
    } > RAM1 AT> CODE
linking...
D:/arm_gnu_Toos/arm-gnu-toolchain-14.3.rel1-mingw-w64-i686-arm-none-eabi/bin/../lib/gcc/arm-none-eabi/14.3.1/../../../../arm-none-eabi/bin/ld.exe:E:\f407_boot\cubemx\linker_scripts\link.lds:90: section has both a load address and a load region
D:/arm_gnu_Toos/arm-gnu-toolchain-14.3.rel1-mingw-w64-i686-arm-none-eabi/bin/../lib/gcc/arm-none-eabi/14.3.1/../../../../arm-none-eabi/bin/ld.exe: f407_boot.elf section `.data' will not fit in region `CODE'
D:/arm_gnu_Toos/arm-gnu-toolchain-14.3.rel1-mingw-w64-i686-arm-none-eabi/bin/../lib/gcc/arm-none-eabi/14.3.1/../../../../arm-none-eabi/bin/ld.exe: region `CODE' overflowed by 1580 bytes
collect2.exe: error: ld returned 1 exit status
make[1]: *** [makefile:81: f407_boot.elf] Error 1
make: *** [makefile:74: all] Error 2
"make -j16 all" terminated with exit code 2. Build might be incomplete

Other additional context

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions