You need to enable JavaScript to run this app. GCC链接脚本如何实现.bss段自动拆分到两块不连续SRAM区域
优惠活动
大模型
产品
解决方案
定价
更多

GCC链接脚本如何实现.bss段自动拆分到两块不连续SRAM区域

GCC链接器自动拆分BSS段到多SRAM区域实现方案

核心实现原理

GNU Binutils 2.36及以上版本新增了非连续内存区域段分配支持,允许链接器自动将单个逻辑段的内容优先分配到指定内存区域,容量不足时自动溢出到其他指定内存区域,无需人工拆分变量或目标文件。

步骤1:配置链接脚本MEMORY区域

首先在链接脚本中按优先级顺序定义两块SRAM内存区域,优先分配的小容量SRAM放在前面:

MEMORY
{
  /* 16KB SRAM 放前面,优先分配BSS内容 */
  SRAM1 (rw!x) : ORIGIN = 0x20000000, LENGTH = 16K
  /* 96KB SRAM 作为溢出存储区域 */
  SRAM2 (rw!x) : ORIGIN = 0x20040000, LENGTH = 96K
}

步骤2:编写自动溢出的BSS段定义

在链接脚本的段定义部分,按如下方式配置BSS段:

SECTIONS
{
  /* 其他段(.text、.data等)定义保持不变 */

  .bss (NOLOAD) ALIGN(4) :
  {
    __bss_sram1_start = .;
    /* 匹配所有BSS类型变量 */
    *(.bss .bss.* .gnu.linkonce.b.*)
    *(COMMON)
    . = ALIGN(4);
    __bss_sram1_end = .;
  } > SRAM1

  .bss (NOLOAD) ALIGN(4) :
  {
    __bss_sram2_start = .;
    /* 自动匹配SRAM1放不下的剩余BSS变量 */
    *(.bss .bss.* .gnu.linkonce.b.*)
    *(COMMON)
    . = ALIGN(4);
    __bss_sram2_end = .;
  } > SRAM2

  /* 其他段定义保持不变 */
}

步骤3:添加必要链接参数

在编译链接选项中添加以下参数,开启非连续段分配支持:
-Wl,--enable-non-contiguous-regions -Wl,--sort-section=alignment

  • --enable-non-contiguous-regions:允许单个逻辑段分布在多个不连续的内存区域
  • --sort-section=alignment:按变量对齐值从小到大排序分配,最大化内存利用率,减少碎片

步骤4:修改启动代码BSS清零逻辑

由于BSS段现在分布在两个不连续的内存区域,需要修改启动代码中的BSS清零逻辑,分别清零两个区域的BSS内容:

#include <stdint.h>

/* 链接脚本导出的符号 */
extern uint8_t __bss_sram1_start[];
extern uint8_t __bss_sram1_end[];
extern uint8_t __bss_sram2_start[];
extern uint8_t __bss_sram2_end[];

void bss_init(void)
{
  /* 清零SRAM1区域的BSS */
  for (uint8_t *p = __bss_sram1_start; p < __bss_sram1_end; p++) {
    *p = 0;
  }
  /* 清零SRAM2区域的BSS */
  for (uint8_t *p = __bss_sram2_start; p < __bss_sram2_end; p++) {
    *p = 0;
  }
}

兼容性说明

如果使用的Binutils版本低于2.36,原生不支持自动溢出分配,建议升级Binutils到2.36或以上版本即可直接使用上述方案。

内容的提问来源于stack exchange,提问作者ckain

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.20 07:15:02