1. 程式人生 > >(轉)載域和運行域的理解(ARM程序是怎麽運行的)

(轉)載域和運行域的理解(ARM程序是怎麽運行的)

重新 運行速度 訪問 readonly 狀態 集成 hex 並不是 否則

對ARM加載域和運行域的理解

一般而言,一個程序包括只讀的代碼段和可讀寫的數據段。在ARM的集成開發環境中,只讀的代碼段和常量被稱作RO段(ReadOnly);可讀寫的全局變量和靜態變量被稱作RW段(ReadWrite);RW段中要被初始化為零的變量被稱為ZI段(ZeroInit)對於嵌入式系統而言,程序映象都是存儲在Flash存儲器等一些非易失性器件中的,而在運行時,程序中的RW段必須重新裝載到可讀寫的RAM中。這就涉及到程序的加載時域和運行時域。簡單來說,程序的加載時域就是指程序燒入Flash中的狀態,運行時域是指程序執行時的狀態。對於比較簡單的情況,可以在ADS集成開發環境的ARM LINKER選項中指定RO BASE和RW BASE,告知連接器RO和RW的連接基地址。對於復雜情況,如RO段被分成幾部分並映射到存儲空間的多個地方時,需要創建一個稱為"分布裝載描述文件"的文本文件,通知連接器把程序的某一部分連接在存儲器的某個地址空間。需要指出的是,分布裝載描述文件中的定義要按照系統重定向後的存儲器分布情況進行。在引導程序完成初始化的任務後,應該把主程序轉移到RAM中去運行,以加快系統的運行速度。

什麽是arm的映像文件,arm映像文件其實就是可執行文件,包括bin或hex兩種格式,可以直接燒到rom裏執行。在axd調試過程中,我們調試的是axf文件,其實這也是一種映像文件,它只是在bin文件中加了一個文件頭和一些調試信息。映像文件一般由域組成,域最多由三個輸出段組成(RO,RW,ZI)組成,輸出段又由輸入段組成。所謂域,指的就是整個bin映像文件所處在的區域,它又分為加載域和運行域。加載域就是映像文件被靜態存放的工作區域,一般來說Flash裏的 整個bin文件所在的地址空間就是加載域,當然在程序一般都不會放在 Flash裏執行,一般都會搬到SDRAM裏運行工作,它們在被搬到SDRAM裏工作所處的地址空間就是運行域

。我們輸入的代碼,一般有代碼部分和數據部分,這就是所謂的輸入段,經過編譯後就變成了bin文件中RO段和RW段,還有所謂的ZI段,這就是輸出段。對於加載域中的輸出段,一般來說RO段後面緊跟著RW段,RW段後面緊跟著ZI段。在運行域中這些輸出段並不連續,但RW和ZI一定是連著的。ZI段和RW段中的數據其實可以是RW屬性。

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那樣"無中生有"的。

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程序才能正常訪問變量。

否則只能運行不含變量的代碼。

註意:如果一個變量被初始化為0,則該變量的處理方法與未初始化華變量一樣放在ZI區域。即:ARM C程序中,所有的未初始化變量都會

被自動初始化為0。RO包含了 Code和RO Data兩類數據。

總結:

1; C中的指令以及常量被編譯後是RO類型數據。

2; C中的未被初始化或初始化為0的變量編譯後是ZI類型數據。

3; C中的已被初始化成非0值的變量編譯後是RW類型數據。

(轉)載域和運行域的理解(ARM程序是怎麽運行的)