微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > S3C2440 2440init.s分析第二篇(一)

S3C2440 2440init.s分析第二篇(一)

时间:11-20 来源:互联网 点击:
S3C2440 2440init.s分析第二篇(一)

;=========================================
; NAME: 2440INIT.S
; DESC: C start up codes
; Configure memory, ISR ,stacks
; Initialize C-variables
; HISTORY:
; 2002.02.25:kwtark: ver 0.0
; 2002.03.20:purnnamu: Add some functions for testing STOP,Sleep mode
; 2003.03.14:DonGo: Modified for 2440.
;=========================================

;首先,启动代码定义了一些常量
GET option.inc
GET memcfg.inc
GET 2440addr.inc

BIT_SELFREFRESH EQU (1<22)

;处理器模式常量
USERMODE EQU 0x10
FIQMODE EQU 0x11
IRQMODE EQU 0x12
SVCMODE EQU 0x13
ABORTMODE EQU 0x17
UNDEFMODE EQU 0x1b
MODEMASK EQU 0x1f
NOINT EQU 0xc0

;定义处理器各模式下堆栈地址常量
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 ~

;检查在tasm.exe里是否设置了采用THUMB(16位)代码(armasm -16 ...@ADS 1.0)
GBLL THUMBCODE ;定义THUMBCODE全局变量
[ {CONFIG} = 16 ;如果发现是才用16位代码的话
THUMBCODE SETL {TRUE} ;把THUMBCODE设置为TURE
CODE32 ;把处理器从新设置成为ARM模式
| ;如果处理器现在就是ARM模式
THUMBCODE SETL {FALSE} ;把THUMBCODE设置为FALSE就行了
]

MACRO ;一个根据THUMBCODE把PC寄存的值保存到LR的宏
MOV_PC_LR
[ THUMBCODE
bx lr ;在ARM模式中要使用BX指令转跳到THUMB指令,并转换模式
|
mov pc,lr ;如果目标地址也是ARM指令的话就采用这种方式
]
MEND

MACRO ;和上面的宏一样,只是多了一个相等的条件
MOVEQ_PC_LR
[ THUMBCODE
bxeq lr
|
moveq pc,lr
]
MEND

;=======================================================================================
;下面这个宏是用于第一次查表过程的实现中断向量的重定向,如果你比较细心的话就是发现
;在_ISR_STARTADDRESS=0x33FF_FF00里定义的第一级中断向量表是采用型如Handle***的方式的.
;而在程序的ENTRY处(程序开始处)采用的是b Handler***的方式.
;在这里Handler***就是通过HANDLER这个宏和Handle***进立联系的.
;这种方式的优点就是正真定义的向量数据在内存空间里,而不是在ENTRY处的ROM(FLASH)空间里,
;这样,我们就可以在程序里灵活的改动向量的数据了.
;========================================================================================

MACRO
$HandlerLabel HANDLER $HandleLabel

$HandlerLabel
sub sp,sp,#4 ;减少sp(用于存放转跳地址)
stmfd sp!,{r0} ;把工作寄存器压入栈(lr does not push because it return to original address)
ldr r0,=$HandleLabel;将HandleXXX的址址放入r0
ldr r0,[r0] ;把HandleXXX所指向的内容(也就是中断程序的入口)放入r0
str r0,[sp,#4] ;把中断服务程序(ISR)压入栈
ldmfd sp!,{r0,pc} ;用出栈的方式恢复r0的原值和为pc设定新值(也就完成了到ISR的转跳)
MEND

;=========================================================================================
;在这里用IMPORT伪指令(和c语言的extren一样)引入|Image$$RO$$Base|,|Image$$RO$$Limit|...
;这些变量是通过ADS的工程设置里面设定的RO Base和RW Base设定的,
;最终由编译脚本和连接程序导入程序.
;那为什么要引入这玩意呢,最简单的用处是可以根据它们拷贝自已
;==========================================================================================
IMPORT |Image$$RO$$Base| ; ROM code(也就是代码)的开始地址
IMPORT |Image$$RO$$Limit| ; ROM code的结束地址 (=ROM data的开始地址)
IMPORT |Image$$RW$$Base| ; 要初始化的RAM的开始地址
IMPORT |Image$$ZI$$Base| ; area(需要清零的RAM区域)的开始地址
IMPORT |Image$$ZI$$Limit| ; area的结束地址

;这里引入一些在其它文件中实现在函数,包括为我们所熟知的main函数
IMPORT MMU_SetAsyncBusMode
IMPORT MMU_SetFastBusMode ;hzh

IMPORT Main ; The main entry of mon program

;从这里开始就是正真的代码入口了!
AREA Init,CODE,READONLY ;这表明下面的是一个名为Init的代码段

ENTRY ;定义程序的入口(调试用)

EXPORT __ENTRY ;导出符号_ENTRY,但在那用到就还没查明
__ENTRY
ResetEntry
;1)The code, which converts to Big-endian, should be in little endian code.
;2)The following little endian code will be compi

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top