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    ;

 

你可能感兴趣的:(笔记)