三、启动代码完成的主要功能
1) 建立异常中断的入口向量
2) 建立中断向量表
3) 为ARM 每种运行模式设置堆栈
4) 初始化ARM 的MPLL 时钟
5) 初始化MMU(内存管理单元)
6) 初始化存储器控制器
7) 关闭看门狗、关闭中断
8) 判断IRQ 中断的中断入口
9) 将RW 段的内容从flash 拷贝到SDRAM,初始化ZI 段为0
10) 跳转到应用程序(C 代码)
四、S3C2410 初始化说明
1 创建中断向量表
中断向量表创建到SDRAM 高位地址上,主要是因为SDRAM 的地址位置需要放置执行的映象程序,而且在SDRAM 中查找向量表速度会快很多。中断向量表放置时需要字对齐。
?????? ALIGN ;通过添加补丁字节使当前位置满足一定的对齐方式
?????????????????? ;可读写的数据段
?????? AREA RamData,DATA,READWRITE
;^=MAP:定义一个结构化的内存表(storage map)的首地址,地址为0x33ff8000
?????? ^ _ISR_STARTADDRESS ;0x33ff8000
HandleReset # 4 ;#--Field:定义一个结构化内存表中的数据域,该域为4 个字节
HandleUndef # 4
HandleSWI # 4
HandlePabort # 4
HandleDabort # 4
HandleReserved # 4
HandleIRQ # 4
HandleFIQ # 4
;Don't use the label 'IntVectorTable',
;The value of IntVectorTable is different with the address you think it may be.
;IntVectorTable'
HandleEINT0 # 4
HandleEINT1 # 4
HandleEINT2 # 4
HandleEINT3 # 4
HandleEINT4_7 # 4
HandleEINT8_23 # 4
HandleRSV6 # 4
HandleBATFLT # 4
HandleTICK # 4
HandleWDT # 4
HandleTIMER0 # 4
HandleTIMER1 # 4
HandleTIMER2 # 4
HandleTIMER3 # 4
HandleTIMER4 # 4
HandleUART2 # 4
HandleLCD # 4
HandleDMA0 # 4
HandleDMA1 # 4
HandleDMA2 # 4
HandleDMA3 # 4
HandleMMC # 4
HandleSPI0 # 4
HandleUART1 # 4
HandleRSV24 # 4
HandleUSBD # 4
HandleUSBH # 4
HandleIIC # 4
HandleUART0 # 4
HandleSPI1 # 4
HandleRTC # 4
HandleADC # 4
2 创建异常中断的入口函数
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
异常向量的入口函数是由8 个跳转指令组成的,这8 个跳转指令需要按照顺序放置到固定的地址上,地址是0x00~0x1c,这8 个跳转指令是ARM 汇编指令,所以条指令占4 个字节的位置。
3 关闭看门狗、关闭中断
ldr r0,=WTCON ;watch dog disable
ldr r1,=0x0
str r1,[r0]
ldr r0,=INTMSK
ldr r1,=0xffffffff ;all interrupt disable
str r1,[r0]
ldr r0,=INTSUBMSK
ldr r1,=0x3ff ;all sub interrupt disable
str r1,[r0]
4 设置ARM 的主始终频率
;To reduce PLL lock time,adjust the LOCKTIME register.
ldr r0,=LOCKTIME
ldr r1,=0xffffff
str r1,[r0]
;Configure MPLL
ldr r0,=MPLLCON
ldr r1,=((M_MDIV<<12)+(M_PDIV<<4)+M_SDIV) ;Fin=12MHz,Fout=50MHz
str r1,[r0]
5 设置存储器控制器
?????? ;Set memory control registers
??????? adr r0,SMRDATA
????? ldr r1,=BWSCON ;BWSCON Address
????? add r2,r0,#52 ;End address of SMRDATA 一共13 个寄存器
0
????? ldr r3,[r0],#4
????? str r3,[r1],#4
????? cmp r2,r0
????? bne %B0
LTORG ;声明一个数据缓冲池的开始
SMRDATA DATA
DCD 0x2211D110 ; BWSCON
DCD 0x0700 ; BANKCON0
DCD 0x7FFC ; BANKCON1
DCD 0x0700 ; BANKCON2
DCD 0x0700 ; BANKCON3
DCD 0x0700 ;BANKCON4
DCD 0x0700 ;BANKCON5
DCD 0x18005 ;BANKCON6
DCD 0x18005 ; BANKCON7
DCD 0x008E0459 ;REFRESH
DCD 0x32 ;BANKSIZE=0x32
DCD 0x30 ;MRSR6 CL=3clk
DCD 0x30 ;MRSR7
以上是对S3C2410A 的存储器进行初始化,存储器的初始化是和具体的硬件平台相关的,具体的内容见S3C2410A 的使用手册。
6 堆栈初始化及ARM 工作模式转换
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 ~ InitStacks
;UndefMode 堆栈
mrs r0,cpsr
bic r0,#MODEMASK
orr r1,#UNDEFMODE|NOINT
msr cpsr_cxsf,r1 ;UndefMode
ldr sp,=UndefStack
;AbortMode 堆栈
orr r1,#ABORTMODE|NOINT
msr cpsr_cxsf,r1 ;AbortMode
ldr sp,=AbortStack
;IRQMode 堆栈
orr r1,#IRQMODE|NOINT
msr cpsr_cxsf,r1 ;IRQMode
ldr sp,=IRQStack
;FIQMode 堆栈
orr r1,#FIQMODE|NOINT
msr cpsr_cxsf,r1 ;FIQMode
ldr sp,=FIQStack
;SVCMode 堆栈
bic r0,#MODEMASK|NOINT
orr r1,#SVCMODE
msr cpsr_cxsf,r1 ;SVCMode
ldr sp,=SVCStack
mov pc,lr
7 将RW 内容从flash 中copy 到SDRAM 中,并将ZI 内容初始化为0
????? adr r0,ResetEntry
????? ldr r2,BaSEOfROM
????? cmp r0,r2
????? ldreq r0,TopOfROM
????? beq InitRam
????? ldr r3,TopOfROM
;将RO 区域的代码copy 到RW 域中并且将ZI 区域初始化为0。
0
????? ldmia r0!,{r4-r7}
????? stmia r2!,{r4-r7}
????? cmp r2,r3
????? bcc %B0
????? sub r2,r2,r3
????? sub r0,r2
InitRam
????? ldr r2,BaSEOfBSS
????? ldr r3,BaSEOfZero
0
????? cmp r2,r3 ;copy 初始化代码
????? ldrcc r1,#4
?????? strcc r1,[r2],#4
????? bcc %B0
????? mov r0,#0 ;初始化ZI 区域为0
????? ldr r3,EndOfBSS
1
????? cmp r2,r3
8 创建查找IRQ 中断源程序 ???? ldr r0,=HandleIRQ ;This routine is needed ??? ldr r1,=IsrIRQ ;if there isn't 'subs pc,lr,#4' at 0x18,0x1c' ???? str r1,[r0] IsrIRQ ????? sub sp,sp,#4 ????? stmfd sp!,{r8-r9} ????? ldr r9,=INTOFFSET ????? ldr r9,[r9] ????? ldr r8,=HandleEINT0 ????? add r8,r8,r9,lsl #2 ????? ldr r8,[r8] ????? str r8,[sp,#8] ????? ldmfd sp!,{r8-r9,pc}