📄 init-ma.s
字号:
SRAM_SADDR EQU 0x60000000 ; SRAM 起始地址
ISR_BADDR EQU 0x60000000 ; 中断服务程序起始地址
SFR_BADDR EQU 0x80000000 ; 特殊功能寄存器起始地址
SRAM_SIZE EQU 48*1024 ; 48K 内部 SRAM
SRAM_EADDR EQU SRAM_SADDR+SRAM_SIZE-1 ; 内部 SRAM 结束地址.
_SVC_STKSIZE EQU 1024*20 ; ARM 管理模式 下堆栈大小 20 K
_UND_STKSIZE EQU 256 ; ARM 未定义模式 下堆栈大小 256 B
_ABT_STKSIZE EQU 256 ; ARM 中止模式 下堆栈大小 256 B
_IRQ_STKSIZE EQU 1024*1 ; ARM 正常中断(一般中断)模式 下堆栈大小 1K
_FIQ_STKSIZE EQU 256 ; ARM 快速中断模式 下堆栈大小 256 B
STK_SIZE EQU _SVC_STKSIZE+_UND_STKSIZE+_ABT_STKSIZE+_IRQ_STKSIZE+_FIQ_STKSIZE ;总堆栈大小
STK_SADDR EQU SRAM_EADDR+1-STK_SIZE ;堆栈起始地址
;Register definition ;内部寄存器地址定义
rMEMCFG1 EQU SFR_BADDR+0x0180
rMEMCFG2 EQU SFR_BADDR+0x01C0
rINTMR1 EQU SFR_BADDR+0x0280
rINTMR2 EQU SFR_BADDR+0x1280
rINTSR1 EQU SFR_BADDR+0x0240
rINTSR2 EQU SFR_BADDR+0x1240
rSDCONF EQU SFR_BADDR+0x2300
rSDRFPR EQU SFR_BADDR+0x2340
rSYSCON1 EQU SFR_BADDR+0x0100
rSYSCON2 EQU SFR_BADDR+0x1100
rSYSCON3 EQU SFR_BADDR+0x2200
rPADR EQU SFR_BADDR+0x0000
rPBDR EQU SFR_BADDR+0x0001
rPADDR EQU SFR_BADDR+0x0040
rPBDDR EQU SFR_BADDR+0x0041
;Pre-defined constants ; ARM 工作模式值定义 参考ARM程序状态寄存器格式 , ARM 运行模式位 M[4:0] 具体含义
USERMODE EQU 0x10 ; 用户模式
FIQMODE EQU 0x11 ; FIQ 模式
IRQMODE EQU 0x12 ; IRQ 模式
SVCMODE EQU 0x13 ; 管理模式
ABORTMODE EQU 0x17 ; 中止模式
UNDEFMODE EQU 0x1b ; 用户模式
MODEMASK EQU 0x1f ; 蔽屏数据
NOINT EQU 0xc0 ; 清零数据
MACRO
$HandlerLabel HANDLER $HandleLabel
;;
$HandlerLabel ;; r0<----sp
sub sp,sp,#4 ;; <---sp HandleLabel
stmfd sp!,{r0} ;; <---origin sp
ldr r0,=$HandleLabel
ldr r0,[r0]
str r0,[sp,#4]
ldmfd sp!,{r0,pc}
MEND
;--------------------- MACRO 解释 --有图示解释 程序堆栈情况 见文件 images/ 1--4.bmp
; MACRO 伪指令标示宏的开始, MEND 伪指令标示宏的结束
;($HandlerLabel)是标号,展开后为该段展开程序的 首地址。
; (HANDLER) 为宏的名字,($HandleLabel) 为宏的参数。
; (sub sp,sp,#4) 为程序计数器 PC 保留一个位置。
; 保存工作寄存器 R0 (stmfd sp!,{r0}) ,ARM 满递减栈 采用 STMFD LDMFD 两个指令 批量传输。
; 因为 宏中用到了 R0 寄存器,所以要保存 R0 寄存器。
; 将($HandleLabel)的地址传入R0中 (ldr r0,=$HandleLabel),该地址定义在 数据段 ISR_HOOK (在程序最后面,你可以搜索 ISR_HOOK)
; 将($HandleLabel)的地址中的内容传入R0中(ldr r0,[r0])内容为 该中断服务程序的入口地址
; (str r0,[sp,#4]) 将该中断服务程序的入口地址 保存在栈中。
; (ldmfd sp!,{r0,pc})出栈 ,此时弹出保存的 r0,ISR, pc计数器中为该中断服务程序的入口地址(ISR)
; 然后执行中断服务程序。
;
;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;
AREA Init, CODE, READONLY;|Assembly$$code|, CODE, READONLY ; 定义一个代码段
ENTRY ;该程序的入口处
b ResetHandler ;for debug ;程序执行的 第一句,复位入口地址
b HandlerUndef ;handlerUndef ;跳到未定义异常处理
b HandlerSWI ;SWI interrupt handler ; 跳到软件中断处理
b HandlerPabort ;handlerPAbort ; 跳到预取值中止中断处理
b HandlerDabort ;handlerDAbort ; 跳到数据中止处理
b . ;handlerReserved ; loop here 循环 跳到当前位置
b HandlerIRQ ;handlerIRQ ; 跳到 IRQ 中断处理
b HandlerFIQ ;handlerFIQ ; 跳到 FIQ 中断处理
HandlerFIQ HANDLER HandleFIQ ; 宏 HandleFIQ 定义在 程序最后面 (在程序最后面,你可以搜索 ISR_HOOK)
HandlerIRQ HANDLER HandleIRQ ;宏
HandlerUndef HANDLER HandleUndef ;宏
HandlerSWI HANDLER HandleSWI ;宏
HandlerDabort HANDLER HandleDabort ;宏
HandlerPabort HANDLER HandlePabort ;宏
;*****************************************************************************
;
; ResetHandler is the startup code to be used
;
;*****************************************************************************
ResetHandler ;复位后 跳转到此处
ldr r0,=0x00000000
;
;disable all interrupts (they should be disabled on reset, but just in case...)
;除能所有中断 设置 rINTMR1 rINTMR2 寄存器
ldr r12,=rINTMR1
str r0,[r12] ;INTMR1 = 0x8000.0280
ldr r12,=rINTMR2
str r0,[r12] ;INTMR2 = 0x8000.1280
;
; Set bits 1:2 in SYSCON3 for 74 MHz clock speed (default is 18MHz on reset)
; 配置 寄存器 SYSCON3 更该系统时钟频率 为 74 MHZ
ldr r1,=0x06
ldr r12,=rSYSCON3
str r1,[r12] ;init syscon3 register at 0x8000.2200
;sdram config
;内存初始化配置 各个片选信号 nCS0-nCS5 配置
; Now configure the MemConfig register to get the following:
;
; nCS0 = NOR FLASH, 32-bit, 3 wait states 线性闪存 系统启动时 默认 nCS0
; nCS1 = NAND FLASH, 32-bit, 2 wait states 海量闪存
; nCS2 = Ethernet, 16-bit, 8 wait states (was 32-bit =0x00) 网卡
; nCS3 = Parallel/Keyboard/GPIOs, 8-bit, 1 wait state 并口 键盘
; nCS4 = USB, 8-bit, 1 wait state, 2 w/s random (was 32-bit, =0x3c) USB通讯
; nCS5 = Unused/general purpose, 32-bit, 8 wait states 未定义
; 系统的片选信号分配情况
MemConfig1value EQU 0x1201190c ;12
MemConfig2value EQU 0x0000013d ;boot rom and internal SRAM are ignored
;
; configure nCS0-nCS3
;
ldr r1,=MemConfig1value
ldr r12,=rMEMCFG1
str r1,[r12] ;MEMCFG1 = 0x8000.0180
;
; configure nCS4 &nCS5
;
ldr r1,=MemConfig2value
ldr r12,=rMEMCFG2
str r1,[r12] ;MEMCFG2 = 0x8000.01c0
; **************************************************************************
; Define Stacks
; The follow section defines the stack pointer for IRQ and SVC modes.
; This is optional as the debugger will assign it's own stack area with the
; $top_of_memory variable in "debugger internals".
; However, this code is necessary if this program is used to launch an
; embedded applications in C or assembly.
; **************************************************************************
ldr sp,=SVCStack ;
bl InitStacks ;跳到 初始化 ARM 各工作模式下的 堆栈子程序。
;Call the actual C program.
;
IMPORT c_entry ;定义一个外部标号
bl c_entry ;C Entry 跳到该处执行 C 代码 入口地址
;
; Normally, the program should not return, but just in case, branch to the
; reset vector and start over.
;通常进入 C 程序后 程序是不会返回的 ,为了防止 C程序 出现异常,返回使程序死掉,
;因此加了 b ResetHandler 使其跳到 复位处,使其重新执行。
b ResetHandler ; Precautionary
;初始化 ARM 各工作模式下的 堆栈 的子程序入口。
InitStacks
;Don't use DRAM,such as stmfd,ldmfd......
;SVCstack is initialized before
;Under toolkit ver 2.50, 'msr cpsr,r1' can be used instead of 'msr cpsr_cxsf,r1'
mrs r0,cpsr ;CPSR->R0
bic r0,r0,#MODEMASK ;将 CPSR 中的模式位清零
orr r1,r0,#UNDEFMODE|NOINT ;设置模式位为未定义模式
msr cpsr,r1 ;UndefMode ;切换到未定义模式
ldr sp,=UndefStack ;设置该模式下的堆栈
orr r1,r0,#ABORTMODE|NOINT ;设置模式位为中止模式
msr cpsr,r1 ;AbortMode
ldr sp,=AbortStack ;设置该模式下的堆栈
orr r1,r0,#IRQMODE|NOINT ;设置模式位为IRQ模式
msr cpsr,r1 ;IRQMode
ldr sp,=IRQStack ;设置该模式下的堆栈
orr r1,r0,#FIQMODE|NOINT ;设置模式位为FIQ模式
msr cpsr,r1 ;FIQMode
ldr sp,=FIQStack ;设置该模式下的堆栈
bic r0,r0,#MODEMASK|NOINT ;设置模式位为管理模式
orr r1,r0,#SVCMODE
msr cpsr,r1 ;SVCMode
ldr sp,=SVCStack ;设置该模式下的堆栈
;USER mode is not initialized.
mov pc,lr ;The LR register may be not valid for the mode changes.
; 子程序返回
;
;*****************************************************************************
;
; Zero-initialized read/write data area for stacks.
; This area is determined by the RW value in the Linker under "entry and base".
;*****************************************************************************
AREA SYS_STK, DATA, READWRITE, NOINIT
;定义一个内存数据段 储存了ARM各个工作模式下的 堆栈。
;*****************************************************************************
;
; Memory buffers to contain the stacks for the various processor modes which
; we will be using.
;
;*****************************************************************************
^ STK_SADDR ; ^的同义词是 MAP ,MAP 用于 定义一个结构化的内存表(storage map)的首地址。
;该内存块的首地址是 STK_SADDR
;# 的同义词是 FIELD ,FIELD 用于定义一个结构化的内存标的数据域。
UserStack # _SVC_STKSIZE ; UserStack 相对于 STK_SADDR 的偏移量是 0 ,长度 为 _SVC_STKSIZE
SVCStack # _UND_STKSIZE ; SVCStack 相对于 STK_SADDR 的偏移量是 _SVC_STKSIZE ,长度 为 _UND_STKSIZE
UndefStack # _ABT_STKSIZE ; SVCStack 相对于 STK_SADDR 的偏移量是(_ SVC_STKSIZE+_UND_STKSIZE),长度 为 _ABT_STKSIZE
AbortStack # _IRQ_STKSIZE ;依此类推
IRQStack # _FIQ_STKSIZE
FIQStack # 0
AREA ISR_HOOK, DATA, READWRITE, NOINIT
;定义了一个中断向量表
^ ISR_BADDR ;;^,,set the address ISR_BADDR
HandleReset # 4 ;同上 解释
HandleUndef # 4
HandleSWI # 4
HandlePabort # 4
HandleDabort # 4
HandleReserved # 4
HandleIRQ # 4
HandleFIQ # 4
;
;*****************************************************************************
;
END
;***********************************************************
;==================如有不对之处请多多指教====================
;-----------------互相探讨---------------------------------
;==================www.earm.com.cn==========================
;
; 不知道你的这个文件 是那个片子的 所以解释仅供参考
;
;
;*************************************************************
;
; 不管什么 ARM 处理器 一般初始化包括以下步骤.
; 1)定义程序入口点 Entry Point
; 2)设置异常向量
; 3)初始化存储器系统
; 4)初识化堆栈指针寄存器
; 5)如有必要,初始化临界的I/O设备
; 6)如有必要,改变处理器的运行模式和状态
; 7)使能中断
; 8)进入 C 代码运行
;
;-----------------参考资料================ ARM =============================
; ARM 应用系统开发详解
; -----基于S3C4510的系统设计
; 李驹光 编著 4.4 系统的初始化过程
; 清华大学出版社
;
; ARM 体系结构与编程
; 杜春雷 编著 4.1.2 数据定义伪操作
; 清华大学出版社
;
; 嵌入式系统设计与
; 开发实例详解
; ---基于 ARM 的应用
; 胥 静 主编 附录 C 44binit.s 初始化程序研究
; 北京航空航天大学出版社
;
; 基于S3C44B0X嵌入式
; uClinux 系统原理及应用
; 李 岩 荣盘祥 编著
; 满春涛 审 2.3.1.7 堆栈寻址
; 清华大学出版社
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -