新聞中心

S3C2440-啟動(dòng)分析

作者: 時(shí)間:2016-12-02 來源:網(wǎng)絡(luò) 收藏
本文是我對(duì)bootloader中2440init.s文件的一些理解,詳細(xì)注釋了一下,希望對(duì)大家有所幫助,下一步我準(zhǔn)備移植一下uboot。
;=========================================
; NAME: 2440INIT.S
; DESC: C start up codes
; Configure memory, ISR ,stacks
; Initialize C-variables
; HISTORY:
; 2002.02.25:kwtark: ver 0.0
; 2002.03.20:purnnamu: Add some functions for testing STOP,Sleep mode
; 2003.03.14onGo: Modified for 2440.
;=========================================
GET option.inc ;GET相當(dāng)于C語言中的include,也就是包含一個(gè)源文件到當(dāng)文
GET memcfg.inc ;件中,并將被包含的文件在當(dāng)前位置進(jìn)行匯編。
GET 2440addr.inc
BIT_SELFREFRESH EQU (1<<22) ;EQU相當(dāng)于C語言中的define,為(1<<2)定義的符號(hào)名稱
re-defined constants
USERMODE EQU 0x10 ;預(yù)定義一下各種工作模式
FIQMODE EQU 0x11
IRQMODE EQU 0x12
SVCMODE EQU 0x13
ABORTMODE EQU 0x17
UNDEFMODE EQU 0x1b
MODEMASK EQU 0x1f
NOINT EQU 0xc0
;定義了一下堆棧的地址我只用的開發(fā)板SDRAM中堆棧的地址范圍是0x33ff4800"0x33ff7fff。
;The location of stacks
UserStack EQU (_STACK_BASEADDRESS-0x3800) ;0x33ff4800 "
SVCStack EQU (_STACK_BASEADDRESS-0x2800) ;0x33ff5800 "
UndefStack EQU (_STACK_BASEADDRESS-0x2400) ;0x33ff5c00 "
AbortStack EQU (_STACK_BASEADDRESS-0x2000) ;0x33ff6000 "
IRQStack EQU (_STACK_BASEADDRESS-0x1000) ;0x33ff7000 "
FIQStack EQU (_STACK_BASEADDRESS-0x0) ;0x33ff8000 "
;ARM有兩種工作狀態(tài)16位的Thumb和32位的Arm,編譯器有相對(duì)應(yīng)的16位和32位兩種編譯方式。16位環(huán)境使用tasm.exe編譯。[|]相當(dāng)于C語言中的IF ELSE ENDIF。
;Check if tasm.exe(armasm -16 ...@ADS 1.0) is used.
GBLL THUMBCODE
[ {CONFIG} = 16
THUMBCODE SETL {TRUE} ;SETL偽操作給一個(gè)全局或局部變量賦值
CODE32 ;CODE32告訴我們下面是32位的arm指令
|
THUMBCODE SETL {FALSE}
]
/*******************************************************************
下面是一個(gè)宏,用來實(shí)現(xiàn)子程序返回的。也就是將LR(子程序鏈接寄存器)的內(nèi)容放入PC中。如果是THUMBCODE為真,那么bx lr。也就是跳轉(zhuǎn)到lr所指向的位置執(zhí)行。bx可以用來進(jìn)行工作狀態(tài)的切換。
*******************************************************************/
MACRO
MOV_PC_LR
[ THUMBCODE
bx lr
|
mov pc,lr
]
MEND
;與上邊的類似,只是加了一個(gè)是否相等的判斷。
MACRO
MOVEQ_PC_LR
[ THUMBCODE
bxeq lr
|
moveq pc,lr
]
MEND
/*******************************************************************
這個(gè)宏用來把HandlerLabel這個(gè)地址標(biāo)號(hào)和HandleLabel這個(gè)地址標(biāo)號(hào)綁定在一起。注意前面比后面多了一個(gè)r。在后面可以看到這樣的指令 b HandlerUndef ;這是硬件自動(dòng)產(chǎn)生的中斷向量表,也是第一級(jí)中斷向量表。比如產(chǎn)生了一個(gè)ENT0中斷,如果在矢量模式下,首先是跳轉(zhuǎn)b HandlerIRQ,然后就是這個(gè)宏,進(jìn)入HandleIRQ,可是到底是那個(gè)中斷呢,在HandleIRQ這個(gè)位置,硬件會(huì)自動(dòng)產(chǎn)生跳轉(zhuǎn)到中斷處理程序的指令,也就是說是哪個(gè)中斷源由硬件自己判斷,并將跳轉(zhuǎn)指令自動(dòng)送過來。如果是非矢量模式,首先跳轉(zhuǎn)到b b HandlerIRQ,然后宏展開,跳轉(zhuǎn)到HandleIRQ的位置,HandleIRQ里存放的是IsrIRQ,IsrIRQ用于找到是哪一個(gè)中斷源,并定位它在中斷向量表中的位置。這個(gè)中斷向量表在SDRAM的0x33ffff00 " 0x33ffffff,共256個(gè)字節(jié),一個(gè)中斷向量占4個(gè)字節(jié),即一個(gè)字,所以這個(gè)位置可以存放64個(gè)中斷源。2440只能有60個(gè)中斷源。這個(gè)位置也是SDRAM最后的地址。我的SDRAM是64M,從0x30000000"0x34000000。
*******************************************************************/
MACRO
$HandlerLabel HANDLER $HandleLabel
$HandlerLabel
sub sp,sp,#4 ;decrement sp(to store jump address)
stmfd sp!,{r0} USH the work register to stack(lr does t push because it return to original address)
ldr r0,=$HandleLabel;load the address of HandleXXX to r0
ldr r0,[r0] ;load the contents(service routine start address) of HandleXXX
str r0,[sp,#4] ;store the contents(ISR) of HandleXXX to stack
ldmfd sp!,{r0,pc} OP the work register and pc(jump to ISR)
MEND
;這些符號(hào)是ADS生成的,是根據(jù)我們填的RO,RW,ZI生成的。IMPORT偽操作是導(dǎo)入別的文件生命的變量
IMPORT |Image$$RO$$Base| ; Base of ROM code
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 MMU_SetAsyncBusMode
IMPORT MMU_SetFastBusMode
IMPORT Main ; The main entry of mon program
AREA Init,CODE,READONLY
ENTRY
EXPORT __ENTRY
__ENTRY
;========
;復(fù)位
;========
ResetEntry
;1)The code, which converts to Big-endian, should be in little endian code.
;2)The following little endian code will be compiled in Big-Endian mode.
; The code byte order should be changed as the memory bus width.
;3)The pseudo instruction,DCD can t be used here because the linker generates error.
/*******************************************************************
是否進(jìn)行大小端切換。ASSERT斷言錯(cuò)誤偽操作,如果表達(dá)式為假就報(bào)錯(cuò),這里如果未定義ENDIAN_CHANGE就報(bào)錯(cuò),如果ENDIAN_CHANGE為true,如果未定義ENTRY_BUS_WIDTH,就報(bào)錯(cuò)。根據(jù)不同的總線寬度32,16,8進(jìn)行大小段的切換。andeq r14,r7,r0,lsl #20 ,streq r0,[r0,-r10,ror #1] ,與b ChangeBigEndian的作用相同。
*******************************************************************/
ASSERT EF:ENDIAN_CHANGE
[ ENDIAN_CHANGE
ASSERT EF:ENTRY_BUS_WIDTH
[ ENTRY_BUS_WIDTH=32
b ChangeBigEndian ;DCD 0xea000007
]
[ ENTRY_BUS_WIDTH=16
andeq r14,r7,r0,lsl #20 ;DCD 0x0007ea00
]
[ ENTRY_BUS_WIDTH=8
streq r0,[r0,-r10,ror #1] ;DCD 0x070000ea
]
|
b ResetHandler
;這段是復(fù)位程序,先進(jìn)行大小段切換,然后進(jìn)入復(fù)位異常處理程序
]
;這段時(shí)異常中斷向量表
b HandlerUndef ;handler for Undefined mode
b HandlerSWI ;handler for SWI interrupt
b HandlerPabort ;handler for PAbort
b HandlerDabort ;handler for DAbort
b . ;reserved
b HandlerIRQ ;handler for IRQ interrupt
b HandlerFIQ ;handler for FIQ interrupt
;電源管理 EnterPWDN在后面進(jìn)行了實(shí)現(xiàn),主要是進(jìn)入IDLE模式和SLEEP模式
;@0x20
b EnterPWDN ; Must be @0x20.
;從小端切換到大端的實(shí)現(xiàn)過程
ChangeBigEndian
;@0x24
[ ENTRY_BUS_WIDTH=32
DCD 0xee110f10 ;0xee110f10 => mrc p15,0,r0,c1,c0,0
DCD 0xe3800080 ;0xe3800080 => orr r0,r0,#0x80; //Big-endian
DCD 0xee010f10 ;0xee010f10 => mcr p15,0,r0,c1,c0,0
]
[ ENTRY_BUS_WIDTH=16
DCD 0x0f10ee11
DCD 0x0080e380
DCD 0x0f10ee01
]
[ ENTRY_BUS_WIDTH=8
DCD 0x100f11ee
DCD 0x800080e3
DCD 0x100f01ee
]
;相當(dāng)于NOP指令,作用是等待從小端模式向大端模式切換
DCD 0xffffffff ;swinv 0xffffff is similar with NOP and run well in both endian mode.
DCD 0xffffffff
DCD 0xffffffff
DCD 0xffffffff
DCD 0xffffffff
b ResetHandler
;將HandlerLabel與HandleLabel進(jìn)行關(guān)聯(lián),所謂的“加載程序”
HandlerFIQ HANDLER HandleFIQ
HandlerIRQ HANDLER HandleIRQ
HandlerUndef HANDLER HandleUndef
HandlerSWI HANDLER HandleSWI
HandlerDabort HANDLER HandleDabort
HandlerPabort HANDLER HandlePabort
/*******************************************************************
下面這段代碼用于非矢量中斷。INTOFFSET中斷偏移寄存器。中斷偏移寄存器顯示了哪個(gè)IRQ中斷模式的請(qǐng)求在INTPND寄存器中。該位可以通過清除SRCPND和INTPND寄存器被自動(dòng)清除。 在匯編中INTOFFSET等寄存器的名字是指寄存器的地址,比如INTOFFSET是INTOFFSET這個(gè)寄存器的地址,所以ldr r9 = INTOFFSET,在C語言中,INTOFFSET是INTOFFSET這個(gè)寄存器的內(nèi)容。
*******************************************************************/

上一頁 1 2 3 4 下一頁

評(píng)論


技術(shù)專區(qū)

關(guān)閉