ARM映像文件及其地址映射
arm映像文件其實就是可執(zhí)行文件,包括bin或hex兩種格式,可以直接燒到ROM里執(zhí)行。在axd調(diào)試過程中,我們調(diào)試的是axf文件,其實這也是一種映像文件,它只是在bin文件中加了一個文件頭和一些調(diào)試信息。
本文引用地址:http://m.butianyuan.cn/article/201611/316906.htm映像文件一般由域組成,域最多由三個輸出段組成(RO,RW,ZI),輸出段又由輸入段組成。所謂域,指的就是整個bin映像文件所處在的區(qū)域,它又分為加載域和運行域。對于嵌入式系統(tǒng)而言,程序映象都是存儲在Flash存儲器等一些非易失性器件中的,而在運行時,程序中的RW段必須重新裝載到可讀寫的RAM中。簡單來說,程序的加載時域就是指程序燒入Flash中的狀態(tài),運行時域是指程序執(zhí)行時的狀態(tài)。一般來說flash里的整個bin文件所在的地址空間就是加載域,當然在程序一般都不會放在flash里執(zhí)行,一般都會搬到sdram里運行工作,它們在被搬到sdram里工作所處的地址空間就是運行域。我們輸入的代碼,一般有代碼部分和數(shù)據(jù)部分,這就是所謂的輸入段,經(jīng)過編譯后就變成了bin文件中ro段和rw段,還有所謂的zi段,這就是輸出段。在ARM的集成開發(fā)環(huán)境中,只讀的代碼段和常量被稱作RO段(ReadOnly);可讀寫的全局變量和靜態(tài)變量被稱作RW段(ReadWrite);RW段中要被初始化為零的變量被稱為ZI段(ZeroInit)。對于加載域中的輸出段,一般來說RO段后面緊跟著RW段,RW段后面緊跟著ZI段。在運行域中這些輸出段并不連續(xù),但RW和ZI一定是連著的。ZI段和RW段中的數(shù)據(jù)其實可以是RW屬性。
2、簡單地址映射
對于比較簡單的情況,可以在ADS集成開發(fā)環(huán)境的ARM LINKER選項output中指定RO Base和RW Base,即在simple模式下,告知連接器RO和RW的連接基地址。
這種模式下,ARM Linker會輸出以下符號,它們指示了在運行域中各個輸出段所處的地址空間,在使用的時候可以用IMPORT引入:
| Image$$RO$$Base|:表示RO段在運行域中的起始地址
|Image$$RO$$Limit|:表示RO區(qū)末地址后面的地址,即RW數(shù)據(jù)源的起始地址
|Image$$RW$$Base|:RW區(qū)在RAM里的執(zhí)行區(qū)起始地址,也就是編譯器選項RW_Base指定的地址
|Image$$ZI$$Base|:ZI區(qū)在RAM里面的起始地址
|Image$$ZI$$Limit|:ZI區(qū)在RAM里面的結(jié)束地址后面的一個地址
RO Base對應(yīng)的就是| Image$$RO$$Base|,RW Base對應(yīng)的是|Image$$RW$$Base|,由于ZI段是包含在RW段里的,所以|Image$$RW$$Limit|就等于|Image$$ZI$$limit|。
下面給出一個例子,假設(shè)RO Base設(shè)為0x00000000,后面的RWBase地址是0x30000000,然后在Options選項中有Image entry point,是一個初始程序的入口地址,設(shè)為0x00000000,?,F(xiàn)在要做的就是將RW section移到以0x30000000開始的地方,并且創(chuàng)造一個ZI section。
首先比較Image$$RO$$Limit和Image$$RW$$Base,如果相等,說明execution view下RW section的地址和load view下RW section的地址相同,這樣,不需要移動RW section;如果不等,說明需要移動RW section到它在execution view中的地方,把ROM里|Image$$RO$$Limt|開始的RW初始數(shù)據(jù)拷貝到RAM里面|Image$$RW$$Base|開始的地址,當RAM這邊的目標地址到達|Image$$ZI$$Base|后就表示RW區(qū)的結(jié)束和ZI區(qū)的開始,接下去就對這片ZI區(qū)進行清零操作,直到遇到結(jié)束地址|Image$$ZI$$Limit|
示例代碼如下:
IMPORT|Image$$RO$$Limit|
IMPORT|Image$$RW$$Base|
IMPORT|Image$$ZI$$Base|
IMPORT|Image$$ZI$$Limit|
IMPORTmain;聲明C程序中的Main()函數(shù)
AREAStart,CODE,READONLY;聲明代碼段Start
ENTRY;標識程序入口
CODE32;聲明32位ARM指令
ResetLDRSP,=0x40003F00
;初始化C程序的運行環(huán)境
LDRR0,=|Image$$RO$$Limit|;得到RW數(shù)據(jù)源的起始地址
LDRR1,=|Image$$RW$$Base|;RW區(qū)在RAM里的執(zhí)行區(qū)起始地址
LDRR3,=|Image$$ZI$$Base|;ZI區(qū)在RAM里面的起始地址
CMPR0,R1;檢查RW section的地址在load view和execution view下是否相等
BEQLOOP1;如果相等就不移動RW section,直接建立ZI scetion
LOOP0;否則就copy RW section到execution view下指定的地址
CMPR1,R3
LDRCCR2,[R0],#4;它把從R0中的地址開始的section copy到R1中的地址開始的section
STRCCR2,[R1],#4
BCCLOOP0
LOOP1
LDRR1,=|Image$$ZI$$Limit|;ZI section末地址
MOVR2,#0;將ZI section需要的初始化量裝入R2
LOOP2
CMPR3,R1;建立并初始化ZI section
STRCCR2,[R3],#4
BCCLOOP2
Bmain;跳轉(zhuǎn)到C程序代碼Main()函數(shù)
END
注:LDRCCR2,[R0],#4;將地址為R0的內(nèi)存單元數(shù)據(jù)讀取到R2中,然后R0=R0+4
CC(小于)為條件碼。
評論