ARM启动代码注释
下边是完整的工程
运行平台:mini2440
启动代码ourdev_444408.rar(文件大小:61K)(原文件名:MicroOS.rar)
;---------------------------------------------------------------------
;startup.s
;系统启动代码
;起始时间 : 2009.5.7----->2009.5.11
;---------------------------------------------------------------------
;---------------------------------------------------------------------
GET ./Include/s3c2440.inc ;寄存器地址信息
GET ./Include/memcfg.inc ;内存控制器配置信息
;处理器模式
USERMODE EQU 0x10
FIQMODE EQU 0x11
IRQMODE EQU 0x12
SVCMODE EQU 0x13
ABORTMODE EQU 0x17
UNDEFMODE EQU 0x1b
SYSMODE EQU 0x1f
;相关掩码
MODEMASK EQU 0x1f
NOINT EQU 0xc0
;各个处理器模式下堆栈设置
_STACK_BASEADDRESS EQU 0x33ff8000 ;BANK664MB顶部
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~
;导入操作系统入口函数
IMP
;导入外部C语言编写的异常与中断处理函数
IMP
IMP
IMP
IMP
IMP
IMP
;导入镜像装载域段起始地址
IMP
IMP
IMP
IMP
;--------------------------------------------------------------------
;------------------------------------------------------
AREAstartup,CO
ENTRY
;系统向量表
b vectorRESET ;复位向量
b vectorUNDEF ;未定义指令
b vectorSWI ;软中断
b vectorPABT ;预取指终止
b vectorDABT ;数据终止
b . ;系统保留
b vectorIRQ ;外部中断
b vectorFIQ ;快速中断
;-------------------------------------------------------
;--------------------------------------------------------------------------
;复位向量
;复位向量是ARM处理器上电后第一个被执行的异常
;此时系统处理管理(SVC)模式
vectorRESET
;复位向量有以下六件事要做
;第一步 :关闭看门狗定时器屏蔽所有中断
;第二步:配置系统时钟
;第三步 :配置内存控制器
;第四步 :配置每种处理器模式下堆栈指针
;第五步 :初始化镜像运行域
;第六步 :跳转到操作系统入口
;------------------------------------------
;第一步 :关闭看门狗定时器
;具体内容请参看s3c2440a数据手册的第18章
ldr r0,=WTCON
ldr r1,=0x0
str r1,[r0,#0x0]
;屏蔽所有中断
ldrr0,=INTMSK
ldrr1,=0xffffffff
strr1,[r0]
;------------------------------------------
;------------------------------------------
;第二步 :配置系统时钟
;具体内容请看手册第7章
;先减少锁相环锁定时间,s3c2440a要求PLL
;锁定时间>300us,在上电时s3c2440a预设值
;mpll为晶体频率,我用的晶体频率为12MHz
;300us*12M=3600设置LOCKTIME=0xfff
;足够了
ldrr0,=LOCKTIME
ldrr1,=0xfff0fff0 ;高16为对应UPLL
;低16为对应MPLL
strr1,[r0,#0x0]
;根据器件手册我们还有以下几个事要做
;step1.配置UPLL
;step2.配置MPLL
;注:手册要求先配置UPLL后MPLL
; 且之间要间隔7NOP
; 详请看手册第7-21.
;step3.配置分频系数
;step1:
ldrr0,=UPLLCON
ldrr1,=((56<12)+(2<4)+2)
ldrr1,[r0]
;按手册要求插入7个NOP
nop
nop
nop
nop
nop
nop
nop
;step2:
ldrr0,=MPLLCON
ldrr1,=((127<12)+(2<4)+1)
ldrr1,[r0]
;step3:
ldrr0,=CLKdivN
ldrr1,=((0<3)+(2<2)+1)
ldrr1,[r0]
;------------------------------------------
;------------------------------------------
;第三步 :配置内存控制器
;内存控制内的寄存器器地址是连续分布的
;从0x4800_0000--0x4800_0030,所以可以
;通过一个循环依次填入各个寄存器的内容
ldrr0,=SMRDATA ;装入配置值的地址
ldrr1,=BWSCON ;装入起始寄存器地址
addr2,r0,#0x34 ;计算结束地址
;下面是用于向内存控制器
;装入配置信息的循环
0
ldrr3,[r0],#4 ;装入配置值到r3,后变址
strr3,[r1],#4 ;把r3内包含的配置值写入
;内存控制器的寄存器
cmpr2,r0 ;结束否?
bne%B0 ;没结束则继续
;------------------------------------------
;------------------------------------------
;第四步 :配置每种处理器模式下堆栈指针
;方法与原则:
;1: 通过CPSR寄存器切换处理器模式
;2: 对CPSR的操作方式为读-修改-写回
;3: 绝对不要跳到用户模式,跳过去容易
; 回来就难了
;4:切到新处理器模式后要屏蔽IRQ和FIQ
; 防止在未设置好堆栈前进入中断处理
; 程序,但是在启动代码的最先我们已
; 经屏蔽了所有的32个中断源,所以感
; 觉是否屏蔽都可以
;step1:先把程序状态寄存器读到r0
mrs r0,cpsr
;step2:清除处理器模式位(最前面5位)
bic r0,r0,#MODEMASK
;step3: 设置未定义状态下的堆栈指针
orr r1,r0,#UNDEFMODE|NOINT
msr cpsr_cxsf,r1 ;UndefMode
ldr sp,=UndefStack ;UndefStack=0x33FF_5C00
;step4:设置终止状态下的堆栈指针
orr r1,r0,#ABORTMODE|NOINT
msr cpsr_cxsf,r1 ;AbortMode
ldr sp,=AbortStack ;AbortStack=0x33FF_6000
;step5: 设置中断模式下的堆栈指针
orr r1,r0,#IRQMODE|NOINT
msr cpsr_cxsf,r1 ;IRQMode
ldr sp,=IRQStack ;IRQStack=0x33FF_7000
;step6: 设置快速中断模式下的堆栈指针
orr r1,r0,#FIQMODE|NOINT
msr cpsr_cxsf,r1 ;FIQMode
ldr sp,=FIQStack ;FIQStack=0x33FF_8000
;step7:设置管理模式下的堆栈指针
orr r1,r0,#SVCMODE|NOINT
msr cpsr_cxsf,r1 ;SVCMode
ldr sp,=SVCStack ;SVCStack=0x33FF_5800
;step8:因为管理模式与用户模式共用
; 堆栈指针,所以借着系统模式
; 来设置用户模式的堆栈指针
orrr1,r0,#SYSMODE|NOINT
msrcpsr_cxsf,r1 ;SYSMode
ldrsp,=UserStack ;SVCStack&USERMode=0x33ff4800
;现在处理器处于系统模式
;------------------------------------------
;------------------------------------------
;第五步 :初始化镜像运行域
;复制RW段和ZI段到SDRAM指定地址
LDRr0,=|Image$$RO$$Limit|;装入RO段结束地址
LDRr1,=|Image$$RW$$Base|;装入RW段起始地址
LDRr3,=|Image$$ZI$$Base|;装入ZI段起始地址
;|Image$$RO$$Limit|==|Image$$RW$$Base|?跳过RW段复制:复制RW段
CMPr0,r1
BEQ%F2
;复制RW段
1
CMPr1,r3
LDRCCr2,[r0],#4
STRCCr2,[r1],#4
BCC%B1
2
LDRr1,=|Image$$ZI$$Limit|
MOVr2,#0
;构造ZI段
3
CMPr3,r1
STRCCr2,[r3],#4
BCC%B3
;------------------------------------------
;------------------------------------------
;第六步 :跳转到操作系统入口
b OSEntry ;不要使用main,因为如果使用main
;ads还会调用_main()初始化RW和ZI
;段,但是那里的数据和本程序不同
b .
;------------------------------------------
;---------------------------------------------------------------------------
SMRDATADA
;这里是内存控制器的配置数据
;配置数据需要根据你使用的存储器修改
;在第三步时会将以下数据写入
;内存控制器的相关寄存器中
;共13个寄存器的配置值
DCD(0+(B1_BWSCON<4)+(B2_BWSCON<8)+(B3_BWSCON<12)+(B4_BWSCON<16)+(B5_BWSCON<20)+(B6_BWSCON<24)+(B7_BWSCON<28))
DCD((B0_Tacs<13)+(B0_Tcos<11)+(B0_Tacc<8)+(B0_Tcoh<6)+(B0_Tah<4)+(B0_Tacp<2)+(B0_PMC));GCS0
DCD((B1_Tacs<13)+(B1_Tcos<11)+(B1_Tacc<8)+(B1_Tcoh<6)+(B1_Tah<4)+(B1_Tacp<2)+(B1_PMC));GCS1
DCD((B2_Tacs<13)+(B2_Tcos<11)+(B2_Tacc<8)+(B2_Tcoh<6)+(B2_Tah<4)+(B2_Tacp<2)+(B2_PMC));GCS2
DCD((B3_Tacs<13)+(B3_Tcos<11)+(B3_Tacc<8)+(B3_Tcoh<6)+(B3_Tah<4)+(B3_Tacp<2)+(B3_PMC));GCS3
DCD((B4_Tacs<13)+(B4_Tcos<11)+(B4_Tacc<8)+(B4_Tcoh<6)+(B4_Tah<4)+(B4_Tacp<2)+(B4_PMC));GCS4
DCD((B5_Tacs<13)+(B5_Tcos<11)+(B5_Tacc<8)+(B5_Tcoh<6)+(B5_Tah<4)+(B5_Tacp<2)+(B5_PMC));GCS5
DCD((B6_MT<15)+(B6_Trcd<2)+(B6_SCAN));GCS6
DCD((B7_MT<15)+(B7_Trcd<2)+(B7_SCAN));GCS7
DCD((REFEN<23)+(TREFMD<22)+(Trp<20)+(Trc<18)+(Tchr<16)+REFCNT)
DCD0x32 ;SCLKpowersavingmode,BANKSIZE128M/128M
DCD0x30 ;MRSR6CL=3clk
DCD0x30 ;MRSR7CL=3clk
ALIGN ;数据边界对齐
END
我在写一个
ARM启动代 相关文章:
- 分析ARM启动代码和中断处理过程(11-25)
- ARM简单启动代码及中断处理分析(11-24)
- ARM启动代码分析(2440init.c)(11-22)
- arm启动代码详细分析(11-21)
- LPC2000系列ARM启动代码(startup部分)(11-20)
- ARM启动代码研究(11-20)