ARM程式的RO段 RW段和ZI段 Image

2022-03-16 20:58:13 字數 1943 閱讀 2246

limit 含義

了解ro,rw和zi需要首先了解以下知識:

arm程式的組成

此處所說的「arm程式」是指在arm系統中正在執行的程式,而非儲存在rom中的bin映像(image)檔案,這一點清注意區別。

乙個arm程式包含3部分:ro,rw和zi

ro是程式中的指令和常量

rw是程式中的已初始化變數

zi是程式中的未初始化的變數

由以上3點說明可以理解為:

ro就是readonly,

rw就是read/write,

zi就是zero

arm映像檔案的組成

所謂arm映像檔案就是指燒錄到rom中的bin檔案,也成為image檔案。以下用image檔案來稱呼它。

image檔案包含了ro和rw資料。

之所以image檔案不包含zi資料,是因為zi資料都是0,沒必要包含,只要程式執行之前將zi資料所在的區域一律清零即可。包含進去反而浪費儲存空間。

q:為什麼image中必須包含ro和rw?

a:因為ro中的指令和常量以及rw中初始化過的變數是不能像zi那樣「無中生有」的。

注意:如果乙個變數被初始化為0,則該變數的處理方法與未初始化華變數一樣放在zi區域。

即:arm c程式中,所有的未初始化變數都會被自動初始化為0。

總結:1; c中的指令以及常量被編譯後是ro型別資料。

2; c中的未被初始化或初始化為0的變數編譯後是zi型別資料。

3; c中的已被初始化成非0值的變數編譯後市rw型別資料。

arm程式的執行過程

從以上兩點可以知道,燒錄到rom中的image檔案與實際執行時的arm程式之間並不是完全一樣的。因此就有必要了解arm程式是如何從rom中的image到達實際執行狀態的。

實際上,rom中的指令至少應該有這樣的功能:

1. 將rw從rom中搬到ram中,因為rw是變數,變數不能存在rom中。

2. 將zi所在的ram區域全部清零,因為zi區域並不在image中,所以需要程式根據編譯器給出的zi位址及大小來將相應得ram區域清零。zi中也是變數,同理:變數不能存在rom中

在程式執行的最初階段,ro中的指令完成了這兩項工作後c程式才能正常訪問變數。否則只能執行不含變數的**。

rt_system_heap_init((void*)&image$$rw_iram1$$zi$$limit, (void*)stm32_sram_end);

用於初始化rt-thread系統的堆區域。

image$$rw_iram1$$zi$$limit

是乙個鏈結器匯出的符號,代表zi段的結束,也就是程式執行區的ram結束後的(注意這個『的』,有點i++和++i的意思)位址,

反過來也就是我們執行區的ram未使用的區域的起始位址(其實這裡有點牽強,因為這樣理解往往只是乙個準尋的標準,以為在ram的使用上zi區往往是整個程式的最末尾,也許這裡我理解錯了)。

&image$$rw_iram1$$zi$$limit

取位址。

例如:

image$$ro$$limit

image$$rw$$base

image$$zi$$base

image$$zi$$limit

程式先把rom裡(image$$ro$$limt)開始的rw初始資料拷貝到ram裡面

(image$$rw$$base)開始的位址,當ram這邊的目標位址到達(image$$zi&&base)後就表示rw區的結束和zi區的開始,接下去就對這片zi區進行清零操作,直到遇到結束位址。

RO和RW還有ZI代表什麼?

一般而言,乙個程式包括唯讀的 段和可讀寫的資料段。在arm 的整合開發環境中,唯讀的 段和常量被稱作ro 段 readonly 可讀寫的全域性變數和靜態變數被稱作rw 段 readwrite rw段中要被初始化為零的變數被稱為zi 段 zeroinit 對於嵌入式系統而言,程式映象都是儲存在flas...

程式的各個段

section 結構 sections region phdr fill secname 段名 contents 決定哪些內容存放在此段 start 本段的連線位址 實際執行位址 at ldadr 儲存位址 載入的位址 例子u boot.lds 根據上面的section的介紹,雖能大體看懂,但是還是...

bss段和 data段的區別

在採用段式記憶體管理的架構中 比如intel的80x86系統 bss段 block started by symbol segment 通常是指用來存放程式中未初始化的全域性變數的一塊記憶體區域,一般在初始化時bss 段部分將會清零。bss段屬於靜態記憶體分配,即程式一開始就將其清零了。比如,在c語...