新聞中心

EEPW首頁 > 嵌入式系統(tǒng) > 設計應用 > S3C2440-啟動分析

S3C2440-啟動分析

作者: 時間:2016-12-02 來源:網絡 收藏
本文是我對bootloader中2440init.s文件的一些理解,詳細注釋了一下,希望對大家有所幫助,下一步我準備移植一下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相當于C語言中的include,也就是包含一個源文件到當文
GET memcfg.inc ;件中,并將被包含的文件在當前位置進行匯編。
GET 2440addr.inc
BIT_SELFREFRESH EQU (1<<22) ;EQU相當于C語言中的define,為(1<<2)定義的符號名稱
re-defined constants
USERMODE EQU 0x10 ;預定義一下各種工作模式
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,編譯器有相對應的16位和32位兩種編譯方式。16位環(huán)境使用tasm.exe編譯。[|]相當于C語言中的IF ELSE ENDIF。
;Check if tasm.exe(armasm -16 ...@ADS 1.0) is used.
GBLL THUMBCODE
[ {CONFIG} = 16
THUMBCODE SETL {TRUE} ;SETL偽操作給一個全局或局部變量賦值
CODE32 ;CODE32告訴我們下面是32位的arm指令
|
THUMBCODE SETL {FALSE}
]
/*******************************************************************
下面是一個宏,用來實現子程序返回的。也就是將LR(子程序鏈接寄存器)的內容放入PC中。如果是THUMBCODE為真,那么bx lr。也就是跳轉到lr所指向的位置執(zhí)行。bx可以用來進行工作狀態(tài)的切換。
*******************************************************************/
MACRO
MOV_PC_LR
[ THUMBCODE
bx lr
|
mov pc,lr
]
MEND
;與上邊的類似,只是加了一個是否相等的判斷。
MACRO
MOVEQ_PC_LR
[ THUMBCODE
bxeq lr
|
moveq pc,lr
]
MEND
/*******************************************************************
這個宏用來把HandlerLabel這個地址標號和HandleLabel這個地址標號綁定在一起。注意前面比后面多了一個r。在后面可以看到這樣的指令 b HandlerUndef ;這是硬件自動產生的中斷向量表,也是第一級中斷向量表。比如產生了一個ENT0中斷,如果在矢量模式下,首先是跳轉b HandlerIRQ,然后就是這個宏,進入HandleIRQ,可是到底是那個中斷呢,在HandleIRQ這個位置,硬件會自動產生跳轉到中斷處理程序的指令,也就是說是哪個中斷源由硬件自己判斷,并將跳轉指令自動送過來。如果是非矢量模式,首先跳轉到b b HandlerIRQ,然后宏展開,跳轉到HandleIRQ的位置,HandleIRQ里存放的是IsrIRQ,IsrIRQ用于找到是哪一個中斷源,并定位它在中斷向量表中的位置。這個中斷向量表在SDRAM的0x33ffff00 " 0x33ffffff,共256個字節(jié),一個中斷向量占4個字節(jié),即一個字,所以這個位置可以存放64個中斷源。2440只能有60個中斷源。這個位置也是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
;這些符號是ADS生成的,是根據我們填的RO,RW,ZI生成的。IMPORT偽操作是導入別的文件生命的變量
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
;========
;復位
;========
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.
/*******************************************************************
是否進行大小端切換。ASSERT斷言錯誤偽操作,如果表達式為假就報錯,這里如果未定義ENDIAN_CHANGE就報錯,如果ENDIAN_CHANGE為true,如果未定義ENTRY_BUS_WIDTH,就報錯。根據不同的總線寬度32,16,8進行大小段的切換。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
;這段是復位程序,先進行大小段切換,然后進入復位異常處理程序
]
;這段時異常中斷向量表
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在后面進行了實現,主要是進入IDLE模式和SLEEP模式
;@0x20
b EnterPWDN ; Must be @0x20.
;從小端切換到大端的實現過程
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
]
;相當于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進行關聯,所謂的“加載程序”
HandlerFIQ HANDLER HandleFIQ
HandlerIRQ HANDLER HandleIRQ
HandlerUndef HANDLER HandleUndef
HandlerSWI HANDLER HandleSWI
HandlerDabort HANDLER HandleDabort
HandlerPabort HANDLER HandlePabort
/*******************************************************************
下面這段代碼用于非矢量中斷。INTOFFSET中斷偏移寄存器。中斷偏移寄存器顯示了哪個IRQ中斷模式的請求在INTPND寄存器中。該位可以通過清除SRCPND和INTPND寄存器被自動清除。 在匯編中INTOFFSET等寄存器的名字是指寄存器的地址,比如INTOFFSET是INTOFFSET這個寄存器的地址,所以ldr r9 = INTOFFSET,在C語言中,INTOFFSET是INTOFFSET這個寄存器的內容。
*******************************************************************/

上一頁 1 2 3 4 下一頁

評論


技術專區(qū)

關閉