嵌入式startup.s分析

;---------------------------------------------------------------------
;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                ;BANK6 64MB顶部
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 ~

;导入操作系统入口函数
        IMPORT        OSEntry
        
;导入外部C语言编写的异常与中断处理函数
        IMPORT        vectorUNDEF
        IMPORT        vectorSWI
        IMPORT        vectorPABT
        IMPORT        vectorDABT
        IMPORT        vectorIRQ
        IMPORT        vectorFIQ

;导入镜像装载域段起始地址
        IMPORT  |Image$$RO$$Limit|  ; End of ROM code (=start of ROM data)
        IMPORT  |Image$$RW$$Base|   ; Base of RAM to initialise
        IMPORT  |Image$$ZI$$Base|   ; Base and limit of area
        IMPORT  |Image$$ZI$$Limit|  ; to zero initialise
;--------------------------------------------------------------------


;------------------------------------------------------
        AREA startup, CODE, READONLY
        
        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]
                
        ;屏蔽所有中断
                ldr r0, =INTMSK        
                ldr r1, =0xffffffff        
                str r1, [r0]
        ;------------------------------------------
        
        
        
        ;------------------------------------------
        ;第二步        : 配置系统时钟
        ;具体内容请看手册第7章
        
                ;先减少锁相环锁定时间,s3c2440a要求PLL
                ;锁定时间>300us,在上电时s3c2440a预设值
                ;mpll为晶体频率,我用的晶体频率为12MHz
                ;300us*12M = 3600设置LOCKTIME = 0xfff
                ;足够了
                ldr r0, =LOCKTIME
                ldr r1, =0xfff0fff0        ;高16为对应UPLL
                                                        ;低16为对应MPLL
                str r1, [r0, #0x0]
                
                ;根据器件手册我们还有以下几个事要做
                ;step1.配置UPLL
                ;step2.配置MPLL
                        ;注:手册要求先配置UPLL后MPLL
                        ;        且之间要间隔7NOP
                        ;        详请看手册第7-21.
                ;step3.配置分频系数
                
                        ;step1:
                        ldr r0, =UPLLCON
                        ldr r1, =((56<<12) + (2<<4) + 2)
                        ldr r1, [r0]
                        
                        ;按手册要求插入7个NOP
                        nop
                        nop
                        nop
                        nop
                        nop
                        nop
                        nop
                        
                        ;step2:
                        ldr r0, =MPLLCON
                        ldr r1, =((127<<12) + (2<<4) + 1)
                        ldr r1, [r0]
                        
                        ;step3:
                        ldr r0, =CLKDIVN
                        ldr r1, =((0<<3) + (2 << 2) + 1)
                        ldr r1, [r0]
        ;------------------------------------------
        
        
        
        ;------------------------------------------
        ;第三步        : 配置内存控制器
        ;内存控制内的寄存器器地址是连续分布的
        ;从0x4800_0000 -- 0x4800_0030,所以可以
        ;通过一个循环依次填入各个寄存器的内容
        
                ldr r0, =SMRDATA        ;装入配置值的地址
                ldr r1, =BWSCON                ;装入起始寄存器地址
                add r2, r0, #0x34        ;计算结束地址
                
                ;下面是用于向内存控制器
                ;装入配置信息的循环
0                
                ldr r3, [r0], #4        ;装入配置值到r3,后变址
                str r3, [r1], #4         ;把r3内包含的配置值写入
                                                        ;内存控制器的寄存器
                cmp r2, 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: 因为管理模式与用户模式共用
                        ;                堆栈指针,所以借着系统模式
                        ;                来设置用户模式的堆栈指针
                        orr r1, r0, #SYSMODE|NOINT
                        msr cpsr_cxsf, r1                ;SYSMode
                        ldr sp, =UserStack                ;SVCStack & USERMode=0x33ff4800
                        
                        ;现在处理器处于系统模式
        ;------------------------------------------
                  
                  
                  
        ;------------------------------------------
        ;第五步        : 初始化镜像运行域
        ;复制RW段和ZI段到SDRAM指定地址
        
                LDR     r0, =|Image$$RO$$Limit| ; 装入RO段结束地址
                LDR     r1, =|Image$$RW$$Base|  ; 装入RW段起始地址
                LDR     r3, =|Image$$ZI$$Base|  ; 装入ZI段起始地址
        
                
                ;|Image$$RO$$Limit| == |Image$$RW$$Base| ? 跳过RW段复制 : 复制RW段
                CMP     r0, r1     
                BEQ     %F2
                
                ;复制RW段
1       
                CMP     r1, r3  
                LDRCC   r2, [r0], #4     
                STRCC   r2, [r1], #4
                BCC     %B1
2       
                LDR     r1, =|Image$$ZI$$Limit| 
                MOV     r2, #0
                
                ;构造ZI段
3       
                CMP     r3, r1     
                STRCC   r2, [r3], #4
                BCC     %B3
        
        ;------------------------------------------          
        
        
        
        ;------------------------------------------
        ;第六步        : 跳转到操作系统入口
        
                b        OSEntry                ;不要使用main,因为如果使用main
                                                ;ads还会调用_main()初始化RW和ZI
                                                ;段,但是那里的数据和本程序不同
                                                
                b        .
                
        ;------------------------------------------
        
;---------------------------------------------------------------------------

 

SMRDATA DATA

        ;这里是内存控制器的配置数据
        ;配置数据需要根据你使用的存储器修改
        ;在第三步时会将以下数据写入
        ;内存控制器的相关寄存器中
        ;共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)
        DCD 0x32            ;SCLK power saving mode, BANKSIZE 128M/128M
        DCD 0x30            ;MRSR6 CL=3clk
        DCD 0x30            ;MRSR7 CL=3clk

        ALIGN                ;数据边界对齐
        
        END


本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/qiaohuiic/archive/2009/06/04/4242836.aspx

先贴出来了再好好看,好晕啊

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值