📄 init.s
字号:
irqAddr DCD irqHandler
fiqAddr DCD fiqHandler
;**************************************************************************************************
;* 初始化期间禁止FIQ和IRQ,并切换到监管模式,为此要修改CPSR:
;* --关闭IRQ和FIR,以屏蔽初始化期间偶然的外部中断干扰
;* --切换到SVC32,以获得对硬件的完全控制
;* 注:如果是硬件复位,则该操作并不需要,因为ARM7TDMI上电或通过复位引脚复位时,默认处于监
;* 管模式、ARM状态且IRQ和FIQ被关闭;
;* 如果是软件复位,则该操作是必需的,因为软件复位时,CPSR可能是任何值。
;**************************************************************************************************
resetHandler
MRS r0, cpsr
BIC r0, r0, #MASK_MODE
ORR r0, r0, #MODE_SVC32
ORR r0, r0, #I_BIT
ORR r0, r0, #F_BIT
MSR cpsr_c, r0 ;--cpsr_c意思是只更新cpsr位0~位7(模式位、状态位和中断使能),
; 其他位被屏蔽,不会被修改
;--cpsr_x意思是只更新cpsr位15~8
;--cpsr_s意思是只更新cpsr位23~16
;--cpsr_f意思是只更新cpsr位31~24(标志位)
;**************************************************************************************************
;* 初始化期间禁止所有中断:
;* 注:如果是硬件复位,则该操作并不需要,因为ARM7TDMI上电或通过复位引脚复位时,默认处于监
;* 管模式、ARM状态且IRQ和FIQ被关闭;
;* 如果是软件复位,则该操作是必需的,因为软件复位时,中断控制器专用寄存器可能是任何值。
;**************************************************************************************************
LDR r2, =ARM7_INTMASK ;r2=中断屏蔽寄存器地址0x03FF4008
MVN r1, #0 ;r1=0xFFFFFFFF
STR r1, [r2] ;屏蔽所有中断
LDR r2, =ARM7_INTPEND ;r2=中断挂起寄存器地址0x03FF4004
MVN r1, #0 ;r1=0xFFFFFFFF
STR r1, [r2] ;清除所有中断标志,注意INTPND寄存器是通过写1来清0的
;**************************************************************************************************
;* 存储空间重映射:
;*
;* --------------------------------0x03FFFFFF(64MB-1),s3c4510b最大寻址能力64MB
;* ~ 专用寄存器组 ~
;* --------------------------------0x03FF0000专用寄存器组起始地址
;* ~ 未定义(64KB-8KB) ~
;* --------------------------------内部SRAM/Cache地址上限
;* ~ 内部SRAM/Cache未使用(8KB) ~ ~
;* --------------------------------0x03FE0000(内部SRAM/Cache起始地址)
;* ~ 未定义(45MB-128KB) ~
;* ~ ~
;* --------------------------------0x01300000(19MB),ROM1地址上限
;* ~ ROM1(2MB) ~
;* --------------------------------0x01100000(17MB),ROM1起始地址,即ROM0地址上限
;* ~ ROM0(1MB) ~
;* --------------------------------0x01000000(16MB),ROM0起始地址,SDRAM0地址上限
;* ~ SDRAM顶部空间用于堆栈 ~
;* ~ ~
;* ~ SDRAM0(16MB) ~
;* ~ ~
;* ~ SDRAM底部放中断向量 ~
;* --------------------------------0,SDRAM0起始地址
;*
;**************************************************************************************************
; --保存重映射之后,紧接着要执行的那条指令的重映射地址
LDR r14, goOnAfterRemap
; --配置SYSCFG
SYNC_DRAM
LDR r0, =ARM7_SYSCFG
LDR r1, =0x87ffff90 ;SYSCFG的值
STR r1, [r0] ;SYSCFG=0b1_000,01_11,1111,1111_,1111,1111,10_01_,0_0_0_0
;Stall=0,关闭Cache和WB,内部8K Cache,内部Cache地址0x03FE0000
;专用寄存器地址0x03FF0000,产品ID号00001,采用4个DRAM组的SDRAM
; --配置ROM/RAM,根据s3c4510bDef.h中的宏定义,初始化系统管理专用寄存器组
LDR r1, =rEXTDBWTH ;ROM0 8位,ROM1 16位,DRAM0 32位,其余存储器组均被屏蔽不用
LDR r2, =rROMCON0_S ;ROM0上电时的基地址为0x0,作为Boot ROM使用,执行地址0x01000000(16M)~0x01100000(17M)
LDR r3, =rROMCON1 ;ROM1执行地址均为0x01100000(17MB)~0x01300000(19MB)
LDR r4, =rROMCON2
LDR r5, =rROMCON3
LDR r6, =rROMCON4
LDR r7, =rROMCON5
LDR r8, =rSDRAMCON0_S ;SDRAM0执行地址0x0(1MB)~0x01000000(17MB)
LDR r9, =rSDRAMCON1
LDR r10,=rSDRAMCON2
LDR r11,=rSDRAMCON3
LDR r12,=rSREFEXTCON
LDR r0, =ARM7_EXTDBWTH ;EXTDBWTH寄存器地址(0x03FF3010),即系统控制专用寄存器组的起始地址
STMIA r0, {r1-r12}
; --重映射后,跳转到紧接着要执行的那条指令的重映射地址
MOV pc, r14
goOnAfterRemap DCD initSP
;**************************************************************************************************
; 初始化堆栈指针
;**************************************************************************************************
initSP
;--初始化FIQ模式下的堆栈指针
MRS r0, cpsr
BIC r0, r0, #0x1F
ORR r0, r0, #Mode_FIQ
MSR cpsr_c, r0
LDR sp, =FIQ_Stack_Base ;根据s3c4510bDef.s中的定义
;--初始化IRQ模式下的堆栈指针
MRS r0, cpsr
BIC r0, r0, #0x1F
ORR r0, r0, #Mode_IRQ
MSR cpsr_c, r0
LDR sp, =IRQ_Stack_Base ;根据s3c4510bDef.s中的定义
;--初始化ABT模式下的堆栈指针
MRS r0, cpsr
BIC r0, r0, #0x1F
ORR r0, r0, #Mode_ABT
MSR cpsr_c, r0
LDR sp, =ABT_Stack_Base ;根据s3c4510bDef.s中的定义
;--初始化UND模式下的堆栈指针
MRS r0, cpsr
BIC r0, r0, #0x1F
ORR r0, r0, #Mode_UND
MSR cpsr_c, r0
LDR sp, =UND_Stack_Base ;根据s3c4510bDef.s中的定义
;--初始化SVC模式下的堆栈指针
MRS r0, cpsr
BIC r0, r0, #0x1F
ORR r0, r0, #Mode_SVC
MSR cpsr_c, r0
LDR sp, =SVC_Stack_Base ;根据s3c4510bDef.s中的定义
;--初始化USR模式与SYS模式共用的堆栈指针
MRS r0, cpsr
BIC r0, r0, #0x1F
ORR r0, r0,#Mode_SYS
MSR cpsr_c, r0
LDR sp, =SYS_USR_Stack_Base ;根据s3c4510bDef.s中的定义
;**************************************************************************************************
;* 根据程序要求切换到相应的工作模式和状态
;**************************************************************************************************
;--回到SVC模式
MRS r0, cpsr
BIC r0, r0, #0x1F
ORR r0, r0, #Mode_SVC
MSR cpsr_c, r0
;**************************************************************************************************
;* 中断使能
;**************************************************************************************************
;**************************************************************************************************
;* 中断向量重装载
;**************************************************************************************************
intVecReload
LDR r0, = expVectors
LDR r1, = 0
LDR r2, = (resetHandler-expVectors)
BL copy
;**************************************************************************************************
;* C语言模块运行环境初始化
;**************************************************************************************************
; --当采用-RO和-RW形式的简单Scatter load时,C语言模块运行环境的初始化
IMPORT |Image$$RO$$Base|
IMPORT |Image$$RO$$Limit|
IMPORT |Image$$RW$$Base|
IMPORT |Image$$RW$$Limit|
IMPORT |Image$$ZI$$Base|
IMPORT |Image$$ZI$$Limit|
LDR r0, = |Image$$RO$$Limit|
LDR r1, = |Image$$RW$$Base|
LDR r2, = |Image$$ZI$$Base|
CMP r0, r1 ;比较RO与RW区是否是比邻
BEQ doZIInit ;如果比邻,则无需将RW重新装载,直接初始化ZI区即可
BL copy ;否则用copy子模块重新将RW装载到RAM中去
doZIInit
LDR r1, = |Image$$ZI$$Base|
LDR r2, = |Image$$ZI$$Limit|
MOV r3, #0
BL fill
;**************************************************************************************************
;* 跳转到C入口
;**************************************************************************************************
;IMPORT __main
;B __main
;BL __main
;LDR pc, =__main ;跳到C代码入口.
IMPORT C_Entry
;B C_Entry
;BL C_Entry
LDR pc, =C_Entry
;**************************************************************************************************
;* 一些汇编子模块
;**************************************************************************************************
; --copy子模块将r0指向的存储区拷贝到r1指向的存储区,所拷贝的字节数为(r2-r1)字节
copy
CMP r1, r2
LDRCC r3, [r0], #4
STRCC r3, [r1], #4
BCC copy
MOV PC, LR
; --fill子模块将将r3中的值填写进r1指向的存储区,填写的字节数为(r2-r1)字节
fill
CMP r1, r2
STRCC r3, [r1], #4
BCC fill
MOV PC, LR
;**************************************************************************************************
;* 该汇编伪指令指示汇编器结束对init.s文件的汇编
;**************************************************************************************************
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -