📄 start.s
字号:
;********************************************************************************
;* 文 件 名:START.S
;* 作 者:张人柏
;* 开发日期:2007-8-12
;* 功能描述:S3C2410的启动程序
;* 修改日期:
;* 技术支持:zhangrenbai@163.com
;********************************************************************************
;********************************************************************************
;引入的外部标号在这声明
;********************************************************************************
IMPORT |Image$$RO$$Base| ; 只读代码的开始地址
IMPORT |Image$$RO$$Limit| ; 只读区域大小
IMPORT |Image$$RW$$Base| ; 可读写存储区域起始地址
IMPORT |Image$$ZI$$Base| ; 清零区域起始地址
IMPORT |Image$$ZI$$Limit| ; 清零区域大小
IMPORT Main ;引入外部函数Main,进入C程序。
;********************************************************************************
;给外部使用的标号在这声明
;********************************************************************************
EXPORT ResetEntry
;********************************************************************************
;内部常量定义
;********************************************************************************
;工程实际存储空间定义
SDRAM_END EQU 0x34000000 ;64M SDRAM存储空间
;开始堆栈地址空间
_STACK_BASEADDRESS EQU (SDRAM_END-0x8000) ;0x33ff8000堆栈基地址
_MMUTT_STARTADDRESS EQU (SDRAM_END-0x8000) ;0x33ff8000定义MMU 表基地址
_ISR_STARTADDRESS EQU (SDRAM_END-0x100) ;0x33ffff00堆栈服务程序开始地址
;ARM 异常模式的定义
USERMODE EQU 0x10 ;0b10000 用户模式
FIQMODE EQU 0x11 ;0b10001 FIQ模式
IRQMODE EQU 0x12 ;0b10010 IRQ模式
SVCMODE EQU 0x13 ;0b10011 管理模式
ABORTMODE EQU 0x17 ;0b10111 中止模式
UNDEFMODE EQU 0x1b ;0b11011 未定义
MODEMASK EQU 0x1f ;0b11111 系统模式
NOINT EQU 0xc0 ;屏蔽中断位
;ARM时钟定义
FCLK EQU 50000000
M_MDIV EQU 0x5c ;Fin=12.0MHz Fout=50.0MHz
M_PDIV EQU 0x4
M_SDIV EQU 0x2
;控制寄存器的地址定义
WTCON EQU 0x53000000 ;看门狗定时器模式寄存器
INTMSK EQU 0x4a000008 ;中断屏蔽控制寄存器
INTSUBMSK EQU 0x4a00001c ;次级中断屏蔽寄存器
LOCKTIME EQU 0x4c000000 ;PLL 锁定时间控制寄存器
MPLLCON EQU 0x4c000004 ;MPLL 控制寄存器
BWSCON EQU 0x48000000 ;总线宽度和等待控制寄存器
INTOFFSET EQU 0x4a000014 ;中断请求源偏移寄存器
;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 ~ 快速中断模式下的堆栈地址
;********************************************************************************
;内部宏定义
;********************************************************************************
;宏定义-进入异常流程
;HANDLER-宏的名称
;$HandleLabel-宏的参数
;这个宏的作用是把各个中断程序的地址装入当前的PC,2410有两种装断模式 一种是没有中断向量表,一种是使用中断向量表的
;使用中断向量表只能是IRQ方式,当使用中断向量表的时候,中断发生时由2410的中断控制器自动跳转到相应的位置
MACRO
$HandlerLabel HANDLER $HandleLabel
$HandlerLabel
sub sp, sp, #4 ; 栈空间递减保存跳转地址
stmfd sp!,{r0} ; 保存工作寄存器r0到栈
ldr r0, =$HandleLabel ; 载入中断入口地址所在位置到r0
ldr r0, [r0] ; 载入中断入口地址到r0
str r0, [sp,#4] ; 保存中断入口地址到栈
ldmfd sp!,{r0,pc} ; 恢复工作寄存器并跳转到中断ISR函数
MEND
;********************************************************************************
;ARM汇编程序段,段名为SelfBoot,程序段为只读的代码段。
;********************************************************************************
CODE32
AREA SelfBoot, CODE, READONLY
ENTRY
;程序入口地址
ResetEntry ;程序段执行的第一跳指令,为8个异常中断处理向量,要按顺序放置。
b ResetHandler ;复位跳到复位程序去执行
b HandlerUndef ;跳到Und复位程序去执行
b HandlerSWI ;跳到SWI复位程序去执行
b HandlerPabort ;跳到Abt复位程序去执行
b HandlerDabort ;跳到Dbt复位程序去执行
b . ;保留
b HandlerIRQ ;跳到IRQ复位程序去执行
b HandlerFIQ ;跳到FIQ复位程序去执行
b . ;保留电源管理入口
LTORG ;声明一个数据缓冲池的开始
HandlerFIQ HANDLER HandleFIQ ;用宏汇编程在这里生成快速中断处理的程序,以下同理
HandlerIRQ HANDLER HandleIRQ
HandlerUndef HANDLER HandleUndef
HandlerSWI HANDLER HandleSWI
HandlerDabort HANDLER HandleDabort
HandlerPabort HANDLER HandlePabort
;采用INTOFFSET寄存器判定IRQ中断源
IsrIRQ
sub sp,sp,#4 ;reserved for PC,中断分发例程入口地址预留栈空间
stmfd sp!,{r8-r9} ;将r8、r9内容保存到堆栈
ldr r9,=INTOFFSET ;INTOFFSET寄存器各位表明发生了应该调用那个中断子程序。
ldr r9,[r9] ;r9中存放INTOFFSET的内容
ldr r8,=HandleEINT0 ;取EINT0的地址
add r8,r8,r9,lsl #2 ;r8=r8+r9*4
ldr r8,[r8] ;加载中断服务函数地址到r8
str r8,[sp,#8] ;保存到sp,作为新的PC
ldmfd sp!,{r8-r9,pc} ;跳转到新的PC运行
;======================================================
; 复位程序
;======================================================
;初始化程序入口指令
ResetHandler
ldr r0,=WTCON ;看门狗禁止
ldr r1,=0x0
str r1,[r0]
ldr r0,=INTMSK
ldr r1,=0xffffffff ;全局中断用高优先级中断禁止
str r1,[r0]
ldr r0,=INTSUBMSK ;子中断也一样屏蔽
ldr r1,=0x3ff
str r1,[r0]
ldr r0,=LOCKTIME ;设置时钟控制器
ldr r1,=0xffffff
str r1,[r0]
ldr r0,=MPLLCON ;设置时钟,所有模块的时钟开启
ldr r1,=((M_MDIV<<12)+(M_PDIV<<4)+M_SDIV) ;Fin=12MHz,Fout=50MHz
str r1,[r0]
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
bl InitStacks ;初始化堆栈
ldr r0,=HandleIRQ ;建立IRQ中断
ldr r1,=IsrIRQ
str r1,[r0]
;将RO区域的代码copy到RW域中并且将ZI区域初始化为0,提供C语言运行环境。
adr r0, ResetEntry
ldr r2, |Image$$RO$$Base|
cmp r0, r2
ldreq r0, |Image$$RO$$Limit|
beq InitRam
ldr r3, |Image$$RO$$Limit|
0
ldmia r0!, {r4-r7}
stmia r2!, {r4-r7}
cmp r2, r3
bcc %B0
sub r2, r2, r3
sub r0, r0, r2
InitRam
ldr r2, |Image$$RW$$Base|
ldr r3, |Image$$ZI$$Base|
0
cmp r2, r3 ;copy 初始化代码
ldrcc r1, [r0], #4
strcc r1, [r2], #4
bcc %B0
mov r0, #0 ;初始化ZI区域为0
ldr r3, |Image$$ZI$$Limit|
1
cmp r2, r3
strcc r0, [r2], #4
bcc %B1
;跳入Main函数,进入C程序。
bl Main ;bl Main
b .
;堆栈初始化子程序
InitStacks
;UndefMode堆栈
mrs r0,cpsr
bic r0,r0,#MODEMASK
orr r1,r0,#UNDEFMODE|NOINT
msr cpsr_cxsf,r1 ;进入UndefMode模式
ldr sp,=UndefStack ;设置UndefMode堆栈
;AbortMode堆栈
orr r1,r0,#ABORTMODE|NOINT
msr cpsr_cxsf,r1 ;AbortMode
ldr sp,=AbortStack
;IRQMode堆栈
orr r1,r0,#IRQMODE|NOINT
msr cpsr_cxsf,r1 ;IRQMode
ldr sp,=IRQStack
;FIQMode堆栈
orr r1,r0,#FIQMODE|NOINT
msr cpsr_cxsf,r1 ;FIQMode
ldr sp,=FIQStack
;SVCMode堆栈
bic r0,r0,#MODEMASK|NOINT
orr r1,r0,#SVCMODE
msr cpsr_cxsf,r1 ;返回超级用户模式并设置超级用户栈空间
ldr sp,=SVCStack
mov pc,lr ;子程序返回
LTORG ;声明一个数据缓冲池的开始
;存储器控制的参数
SMRDATA DATA
DCD 0x2211D110
DCD 0x0700
DCD 0x7FFC
DCD 0x0700
DCD 0x0700
DCD 0x0700
DCD 0x0700
DCD 0x18005
DCD 0x18005
DCD 0x008E0459
DCD 0x32
DCD 0x30
DCD 0x30
;********************************************************************************
;ARM汇编可读写数据段,段名为RamData
;********************************************************************************
ALIGN ;通过添加补丁字节使当前位置满足一定的对齐方式
AREA RamData, DATA, READWRITE
;定义一个结构化的内存表(storage map)的首地址,地址为0x33ff8000
MAP _ISR_STARTADDRESS ;0x33ff8000
HandleReset # 4 ;#--Field:定义一个结构化内存表中的数据域,该域为4个字节
HandleUndef # 4
HandleSWI # 4
HandlePabort # 4
HandleDabort # 4
HandleReserved # 4
HandleIRQ # 4
HandleFIQ # 4
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
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -