一、基礎知識
我們編寫的源文件(.c 或.s)經過ARM 編譯器的編譯生成ELF 格式的目標文件(後綴名為.o),目標文件經過ARM 連接器連接以後生成ELF 格式的映像文件(後綴名為.axf),此時的映像文件還包含一些調試信息,我們還需要通過fromelf 工具將其轉換成適合在ROM 或RAM 中運行的二進制代碼(後綴名為.bin),這時生成的二進制映像文件就可以被燒寫入目標板的ROM 或FLASH 中,當目標板上
電後可以通過各種方式在ROM 或RAM 中運行。
一個可執行程序的映像文件由一個或多個域組成,域分為兩種:一種是映像文件在存儲器中存放的地址,稱為加載域;另一種是映像文件運行時的地址,稱為運行域。每個域由一個或3 個輸出段組成,每個輸出段則由一個或多個輸入段組成。輸入段包含程序代碼、已經初始化的數據、未經初始化的存儲區、被初始化為0 的存儲區,輸入段據此可分為三種屬性:RO(只讀,包括代碼和常量)、RW(可讀可寫,包括已經初始化的全局變量和靜態變量)、ZI(未初始化的變量,需初始化為0), 連接器根據屬性將輸入段分組,組成不同的輸出段。一個輸出段是有具有相同屬性的輸入段組成的,輸出段的屬性與其中輸入段的屬性相同,因而輸出段也分為三種。域由不同屬性的輸出段組成,輸出段在域中的排列順序為RO 輸出段排在最前,然後是RW 輸出段,RW 輸出段和RO 輸出段可以不連續,最後是ZI 輸出段,ZI 輸出段是緊接著RW 輸出段的(加載域只包含RO、RW 輸出段,原因見後述)。
可執行鏡像一開始一般是存儲在系統的ROM 或FLASH 中,RO 段是只讀的,在運行的時候我們不能改變它,所以RO 段在運行的時候可以駐留在ROM 或FLASH 中,也可以拷貝到運行速度更快的RAM 中;RW 段在運行的時候,我們需要對其讀寫,在運行前這一段必須被拷貝至RAM 中;ZI 段為未初始化的全局變量段,只需要在程序運行之前建立ZI 並將其所在區域全部清零即可,因此鏡像裝載域不必包含ZI 輸出段,但在運行域需要包含ZI,並且ZI 必須處於RAM。
通過以上說明,我們知道如果某個鏡像只有RO 段的話,程序可以不必拷貝至RAM,但是如果程序包含RW 段的話,RW 段是必需要拷貝至RAM 中的,如果有必要的話還需在RAM 中創建ZI 段,並將其清零。為保證程序的正確執行,而進行必要的數據拷貝和清零,就是應用程序執行環境的初始化。
二、S3C2440啟動的基本原理
Nand Flash啟動
當S3C2440 開發板采用的是Nand Flash 啟動,鏡像一開始是存儲在Nand Flash 中,而Nand Flash只能作為存儲程序和數據之用,無法在其中運行程序,所以S3C2440 開發板啟動代碼中應用環境初始化這一步和上述步驟稍有不同。S3C2440 鏡像文件加載和運行時的地址映射關系如下圖所示:
S3C2440 沒有上電之前映像文件存儲在Nand Flash 中,Nand Flash 由專門的控制器控制,不占用存儲器BANK。當開發板上電時,Nand Flash 的前4K 被復制到S3C2440 芯片內部的一塊容量為4K 的SRAM(被稱為“Steppingstone”),然後這塊SRAM 被映射到地址0x00000000 處,程序從此處開始運行。因為Nand Flash 中不能運行程序,所以在這4K 的代碼中必須包含一段代碼將Nand Flash 中的程序拷貝至S3C2440 的SDRAM 中(0x30000000 開始)。應用環境初始化應該包含這段代碼。
Nand Flash 中的映像文件被拷貝至從0x30000000 開始的SDRAM,這時候映像文件還沒有真正被執行,此時是加載狀態,加載域如上圖所示,包括所有RO 屬性的輸出段和RW 屬性的輸出段,ZI 屬性的輸出段此時還不存在。在映像文件運行時,會生成3 個運行域,如上圖所示,RO 和RW 屬性的運行域的起始地址和加載時是相同的,所以在應用程序執行環境初始化中不需要對其進行拷貝,ZI 運行域則需要在映像開始被執行前建立並被初始化為0,所以應用程序執行環境初始化中也要包含這類代碼。
Nor Flash啟動
當S3C2440采用Nor Flash啟動時,代碼可以在上面直接運行。但為了運行的效率,還是把程序拷貝到SDRRAM中運行。加載時地址關系和運行時地址關系和Nand Flash的基本相似。Nand Flash啟動時,會將RO段和RW段同時拷貝到SDRAM中,然後再建立ZI段。從Nor Flash啟動時是先拷貝RO段,然後再拷貝RW段,最後建立ZI段。