ARM初始化程序分析
源代碼與分析注釋如下:
本文引用地址:http://www.ex-cimer.com/article/201611/316974.htm;初始化C程序運行環(huán)境,然后進(jìn)入C程序代碼
IMPORT |Image$$RO$$Limit|
IMPORT |Image$$RW$$Base|
IMPORT |Image$$ZI$$Base|
IMPORT |Image$$ZI$$Limit|
IMPORT Main ;聲明C程序中的Main函數(shù)
AREA Start,CODE,READONLY
ENTRY
CODE32
RESET LDR SP,=0x40003F00
LDR R0,=|Image$$RO$$Limit| ;RO段結(jié)束地址加1 ,表示RO區(qū)末地址后面的地址,
;即RW數(shù)據(jù)源的起始地址,應(yīng)該是RW的加載地址
LDR R1,=|Image$$RW$$Base| ;RW區(qū)在RAM里的執(zhí)行區(qū)起始地址,也就是編譯器選項
;RW_Base指定的地址,應(yīng)該是RW運行地址
LDR R3,=|Image$$ZI$$Base|;ZI區(qū)在RAM里面的起始地址
CMP R0,R1
BEQ LOOP1 ;R0與R1相等就跳轉(zhuǎn)
LOOP0 CMP R1,R3 ;R1小于R3
LDRCC R2,[R0],#4
STRCC R2,[R1],#4
BCC LOOP0
; COPY ROM TORAM
LOOP1 LDR R1,=|Image$$ZI$$Limit|
MOV R2,#0
LOOP2 CMP R3,R1
STRCC R2,[R3],#4 ;
BCC LOOP2 ;R3小于0,跳轉(zhuǎn)到LOOP2
; ZI清零
B Main
END
;一個arm由RO,RW,ZI三個段組成 其中RO為代碼段,RW是已經(jīng)初始化的全局變量,ZI是未初始化的全局變量(對于GNU工具 對應(yīng)的概念是TEXT ,DATA,BSS)bootloader
;bootloader要將RW段復(fù)制到ram中并將ZI段清零 編譯器使用下列段來記錄各段的起始和結(jié)束地址
; |Image$$RO$$Base| ; RO段起始地址 2
; |Image$$RO$$Limit| ; RO段結(jié)束地址加1 ,表示RO區(qū)末地址后面的地址,即RW數(shù)據(jù)源的起始地址
; |Image$$RW$$Base| ; RW段起始地址
; |Image$$RW$$Limit| ; RW段結(jié)束地址加1
; |Image$$ZI$$Base| ; ZI段起始地址
; |Image$$ZI$$Limit| ; ZI段結(jié)束地址加1
;IMPORT |Image$$RO$$Limit| ; End of ROM code (=start of ROM data)
;IMPORT |Image$$RW$$Base| ; Base of RAM to initialise
;IMPORT |Image$$ZI$$Base| ; Base and limit of area
;IMPORT |Image$$ZI$$Limit| ; to zero initialise
;IMPORT Main ; The main entry of mon program
;大總結(jié)!!!!!!!!!!!!!映像一開始總是存儲在ROM/Flash里面的,其RO部分既可以在ROM/Flash里面執(zhí)行,也可以轉(zhuǎn)移到速度更快的RAM中執(zhí)行;而RW和ZI這兩部分是必須轉(zhuǎn)移到可寫的RAM里去。所謂應(yīng)用程序執(zhí)行環(huán)境的初始化,就是完成必要的從ROM到RAM的數(shù)據(jù)傳輸和內(nèi)容清零。
;r0是RW區(qū)的load address
;r1是RW區(qū)的execution address
;當(dāng)兩者相等時就不用拷貝
;不相等時,程序先把ROM里|Image$$RO$$Limt|開始的RW初始數(shù)據(jù)拷貝到RAM里面|Image$$RW$$Base|開始的地址,當(dāng)RAM這邊的目標(biāo)地址到達(dá)|Image$$ZI$$Base|后就表示RW區(qū)的結(jié)束和ZI區(qū)的開始,接下去就對這片ZI區(qū)進(jìn)行清零操作,直到遇到結(jié)束地址|Image$$ZI$$Limit|
這個啟動程序,是為下面C語言程序做準(zhǔn)備的,其實這個程序很有意義,為以后自己寫C程序建立了環(huán)境
#define uint8 unsigned char
#define uint32 unsigned int
#define N 100
uint32 sum;
//計算1加到N N是大于0的數(shù)
void Main(void)
{
uint32 i;
sum=0;
for(i=0;i { sum+=i; } while(1); } 非常感謝網(wǎng)上的朋友寫的日志,看了你們的日志我才慢慢弄懂是啟動是怎么會事情
評論