首页 > 代码库 > s3c2440笔记1(启动)

s3c2440笔记1(启动)

s3c2440启动方式
  1. 从nand flash 启动
    1.1 上电后将nand flash中的前4KB数据复制到“Stepping Stone”;
    1.2 CPU 执行“Stepping Stone”中的代码;
    //通常的做法是将nand flash中的代码拷贝至sdram;

  2. 从nor flash 启动
    2.1 根据nor flash的总线数据宽度,从第一条指令开始执行;
    //通常的做法:是用这段程序将nor flash中的代码拷贝至sdram;

启动代码核心分析

        GET option.inc ;栈地址等常量定义
        GET memcfg.inc ;SDRAM初始化相关
        GET 2440addr.inc ;特殊功能寄存器
        
        USERMODE    EQU     0x10 ;定义运行模式常量,即CPSR寄存器的模式控制位赋值
        
        UserStack    EQU    (_STACK_BASEADDRESS-0x3800)    ;0x33ff4800 ~ ;定义各模式堆栈地址
        
        ;实现$HandleAddr宏
        $HandlerLabel
            sub        sp,sp,#4            ; sp = sp -4
            stmfd    sp!,{r0}            ; sp = sp -4, r0寄存器的值入栈
            ldr     r0,=$HandleAddr        ; $HandleAddr是该宏的参数,将该值赋给r0
            ldr     r0,[r0]                 ; $HandleAddr相当于是一个函数指针,此时将该指针所指向函数入口地址赋值给r0
            str     r0,[sp,#4]          ; ro入栈,即$HandleAddr
            ldmfd   sp!,{r0,pc}         ; 出栈,恢复r0,将$HandleAddr赋值给pc
            MEND
        
        ;入口地址,定义一个init段
        ;初始化异常向量表
        b    ResetHandler;  0x00000000 为ResetHandler
        
        如上例:CPU上电时从0x0000000启动,此时ResetHandler被执行
        
        ;实现arm对中断的处理,IsrIRQ
        IsrIRQ
            sub    sp,sp,#4       ;reserved for PC
            stmfd    sp!,{r8-r9} ;保存r8、r9

            ldr    r9,=INTOFFSET ;中断偏移寄存器,当ENT0时,该值为0,随后32个外部中断源依次递增
            ldr    r9,[r9]
            ldr    r8,=HandleEINT0 
            add    r8,r8,r9,lsl #2 ;r9左移2位、r8 = r8 + r9,
            ldr    r8,[r8]
            str    r8,[sp,#8]
            ldmfd    sp!,{r8-r9,pc} ;跳转到中断服务函数

            LTORG
            
        ;ResetHandler 实现
        ;1. WTCON 关闭看门狗;
        ;2. INTMSK\INTSUBMSK 中断屏蔽;
        ;3. 系统时钟初始化
        ;4. 存储器初始化
            adrl r0, SMRDATA    ; SDRAM的13个特殊寄存器设置参数
            ldmia r0,{r1-r13}
            ldr    r0,=BWSCON
            stmia r0,{r1-r13}
            
        ;堆栈初始化
            bl    InitStacks
        ;在InitStacks中,初始化各模式堆栈例如
            mrs    r0,cpsr
            bic    r0,r0,#MODEMASK
            orr    r1,r0,#UNDEFMODE|NOINT
            msr    cpsr_cxsf,r1        ;UndefMode ,通过修改CPSR,将处理器切换到该模式
            ldr    sp,=UndefStack        ; UndefStack=0x33FF_5C00
            
        ;执行启动
        ldr    r0, =BWSCON
        ldr    r0, [r0]
        ands    r0, r0, #6        ;OM[1:0] != 0, NOR FLash boot
        bne    copy_proc_beg        ;do not read nand flash
        adr    r0, ResetEntry        ;OM[1:0] == 0, NAND FLash boot
        cmp    r0, #0                ;if use Multi-ice, 
        bne    copy_proc_beg        ;do not read nand flash for boot
        ;nop
        ;===========================================================
        nand_boot_beg ;从nand 启动
            bl RdNF2SDRAM ;该函数将代码从nand 拷贝到 内存
            ldr    pc, =copy_proc_beg
        
        ;copy_pro_beg实现
        ;arm的可执行程序的映像文件,分为RO(代码段和只读数据段)、RW(可读/写数据段)和ZI 未初始化数据段
        ;根据link的设置,从0x00000000处跳转到SDRAM的0x30000000处
        copy_proc_beg
            adr    r0, ResetEntry
            ldr    r2, BaseOfROM  ;RO段的目标地址
            cmp    r0, r2
            ldreq    r0, TopOfROM
            beq    InitRam    ;搬移RW
            ldr r3, TopOfROM
        0    
            ldmia    r0!, {r4-r7} ;利用r4-r7,每次搬移16个字节
            stmia    r2!, {r4-r7}
            cmp    r2, r3
            bcc    %B0
    
        sub    r2, r2, r3
        sub    r0, r0, r2                
        
        InitRam    
            ldr    r2, BaseOfBSS
            ldr    r3, BaseOfZero    
        0
            cmp    r2, r3
            ldrcc    r1, [r0], #4
            strcc    r1, [r2], #4
            bcc    %B0    
            
            ;初始化ZI段
            mov    r0,    #0
            ldr    r3,    EndOfBSS
        1    
            cmp    r2,    r3
            strcc    r0, [r2], #4
            bcc    %B1
        
        ;跳转到c函数
        b    Main    ;