在 ARM 嵌入式開發中,RO(Read-Only)、RW(Read-Write)、ZI(Zero-Init) 是程式執行映像的三大核心區段。許多開發者對散佈載入檔、連結器符號(如 Image$$RW$$ZI$$Limit)感到困惑。本文從 ARM 程式組成、映像檔結構、啟動流程三個維度,系統釐清概念,並深入解析關鍵符號含義與應用場景。
| 區段 | 全稱 | 內容 | 特性 |
|---|---|---|---|
| RO | Read-Only | 程式碼(指令)、常數、字面常量池 | 唯讀,可燒錄於 ROM/Flash,執行時可直接在 ROM 運作 (XIP) |
| RW | Read-Write | 已初始化的全域/靜態變數(非零初值) | 需可寫入,必須從 ROM 複製到 RAM 才能執行 |
| ZI | Zero-Init | 未初始化或初值為 0 的全域/靜態變數 | 不佔映像檔空間,啟動時由啟動碼清零 RAM 區域 |
關鍵區別: 「ARM 程式」= 執行時在記憶體中的完整映像(含 RO+RW+ZI);「ARM 映像檔」= 燒錄在 ROM 的二進位檔(僅含 RO+RW,不含 ZI)。
ZI 區塊全為 0,若包含在映像檔會白白浪費儲存空間。啟動流程只需:
__main / 散佈載入機制自動處理)典型啟動序列(以 ARMCC/KEIL 為例):
; 散佈載入檔片段
LR_IROM1 0x00000000 0x00100000 { ; 載入區域:ROM
ER_IROM1 0x00000000 0x00100000 { ; 執行區域:ROM
*.o (RESET, +First)
*(InRoot$$Sections)
.ANY (+RO)
}
RW_IRAM1 0x20000000 0x00040000 { ; 執行區域:RAM
.ANY (+RW +ZI)
}
}
連結器會自動產生下列符號供啟動碼/應用程式使用:
Image$$RO$$Base、Image$$RO$$LimitImage$$RW$$Base、Image$$RW$$Limit(RW 在 RAM 的起始/結束)Image$$ZI$$Base、Image$$ZI$$Limit(ZI 在 RAM 的起始/結束)extern int Image$$RW_IRAM1$$ZI$$Limit;
此符號代表 ZI 區段在 RAM 中的結束位址(即 RW+ZI 總區域的結束)。具體含義:
RW_IRAM1:散佈載入檔中定義的 RAM 執行區域名稱ZI$$Limit:ZI 區段結束位址(開區間結尾,即第一個未使用的位址)&Image$$RW_IRAM1$$ZI$$Limit:取得該位址值,常用於堆疊/堆積初始化rt_system_heap_init((void*)&Image$$RW_IRAM1$$ZI$$Limit, (void*)STM32_SRAM_END);
將 ZI 結束位址作為堆疊起始,STM32_SRAM_END 作為結束,劃分動態記憶體池。
objcopy -O binary 產生的 bin 檔大小 = RO + RW,不含 ZI。Image$$ZI$$Limit ≠ 映像檔大小 → 它是 RAM 位址,而非檔案偏移。RW_IRAM1 區域大小 = RW + ZI,連結器會自動計算並檢查是否超出 RAM 容量。掌握 RO/RW/ZI 三區段與連結器符號的對應關係,是編寫啟動碼、配置散佈載入、除錯記憶體佈局的基礎。Image$$RW$$ZI$$Limit 等符號是連結器與執行期程式溝通的橋樑,善用它們可精準控制記憶體配置,避免堆疊溢出、變數未初始化等隱蔽 Bug。