13 固件内存布局与段

一句话记忆:Flash 主要放代码、只读数据;RAM 主要放可写数据、堆和栈。 以下为常见 MCU 布局,不是所有芯片的固定规则。

1. 一张图记住六个区域

Flash 和 RAM 的六个常见区域

区域中文记忆典型位置
.text代码区:存机器指令Flash
.rodata只读区:Read-Only DataFlash
.data初值区:可写,有非零初始数据RAM
.bss清零区:可写,初始为零RAM
Heap(堆)malloc() 等动态分配RAM
Stack(栈)函数调用、部分局部变量、任务栈RAM

注意: 这是 4 个常见段 + 堆 + 栈 的记忆模型,不表示芯片只有六个物理区域,也不表示所有固件都一定使用堆。

2. 最容易混淆:.data 与 .bss

data 与 bss 的启动过程

  • .data:例如 int a = 10;,通常要在 Flash 保存初始数据,开机时复制到 RAM。
  • .bss:例如 int b = 0;,通常在开机时清零;无须在固件映像中保存大量零,但仍占 RAM。
int count = 10;          // 通常 .data
int flags = 0;           // 通常 .bss
const int version = 2;   // 通常 .rodata

int add(int a, int b)    // 机器指令通常位于 .text
{
    return a + b;
}

3. 嵌入式开发记住的三个关键点

容易误解实际情况
.bss 不保存一堆零,所以不占内存错:它通常仍占运行时 RAM
const 一定放 Flash错:只读语义不等于存储位置,取决于编译与链接
.text 就是字符串文本错:通常是机器指令;字符串常量常在 .rodata

例如,被保留的全局 uint8_t buffer[1024] = {0}; 通常放在 .bss,会占用 1024 字节 RAM。

最终以 MAP 文件和链接脚本为准。 .data 初始映像也可能占 Flash;RTOS 任务栈、自定义段、RAM 执行函数等会让实际布局比这张图更复杂。