作用:初始化CPU、内存、Flash,复制EBoot到内存并跳入EBoot中运行。

原理:S3C2416有 8-KB 的steppingstone(暂时翻译为垫脚石),在Nand启动模式下可把Nand的前8K内容在CPU上电后自动复制到物理地址(0x40000000)上面并运行。

程序入口:startup.s

常见汇编指令下载

     OPT 

     INCLUDE kxarm.h
     INCLUDE s3c2416.inc

     OPT
     OPT 

 ; Pre-defined constants.

 USERMODE      EQU    0x10
 FIQMODE        EQU    0x11
 IRQMODE        EQU    0x12
 SVCMODE        EQU    0x13
 ABORTMODE     EQU    0x17
 UNDEFMODE     EQU    0x1b
 MODEMASK      EQU    0x1f
 NOINT         EQU    0xc0

 ; Amount of memory (in bytes) allocated for stacks

 Len_FIQ_Stack    EQU
 Len_IRQ_Stack    EQU
 Len_ABT_Stack    EQU
 Len_UND_Stack    EQU
 Len_SVC_Stack    EQU    

 ; Offsets will be loaded as immediate values.
 ; Offsets must be 8 byte aligned.

 Offset_FIQ_Stack    EQU
 Offset_IRQ_Stack    EQU    Offset_FIQ_Stack + Len_FIQ_Stack
 Offset_ABT_Stack    EQU    Offset_IRQ_Stack + Len_IRQ_Stack
 Offset_UND_Stack    EQU    Offset_ABT_Stack + Len_ABT_Stack
 Offset_SVC_Stack    EQU    Offset_UND_Stack + Len_UND_Stack

 ; Stack locations.

 FIQStack        EQU    (top_of_stacks - 0x0)              ; 0x33ffff00 ~
 IRQStack        EQU    (FIQStack   - Offset_FIQ_Stack)    ; 0x33fffe00 ~
 AbortStack      EQU    (IRQStack   - Offset_IRQ_Stack)    ; 0x33fffd00 ~
 UndefStack      EQU    (AbortStack - Offset_ABT_Stack)    ; 0x33fffc00 ~
 SVCStack        EQU    (UndefStack - Offset_UND_Stack)    ; 0x33fffb00 ~
 UserStack       EQU    (SVCStack   - Offset_SVC_Stack)    ; 0x33fff700 ~

 ;------------------------------------------------------------------------------
 ; Sleep state constants
 ;
 ; Location of sleep data

 ; BUGBUG - this needs to be declared as a local var.

 SLEEPDATA_BASE_PHYSICAL        EQU    0x30028000
 ; WORD_SIZE                    EQU    0x4
 ; Sleep State memory locations

 SleepState_Data_Start    EQU    ()
 SleepState_WakeAddr      EQU    (SleepState_Data_Start    + )
 SleepState_MMUCTL        EQU    (SleepState_WakeAddr      + WORD_SIZE)
 SleepState_MMUTTB        EQU    (SleepState_MMUCTL        + WORD_SIZE)
 SleepState_MMUDOMAIN     EQU    (SleepState_MMUTTB        + WORD_SIZE)
 SleepState_SVC_SP        EQU    (SleepState_MMUDOMAIN     + WORD_SIZE)
 SleepState_SVC_SPSR      EQU    (SleepState_SVC_SP        + WORD_SIZE)
 SleepState_FIQ_SPSR      EQU    (SleepState_SVC_SPSR      + WORD_SIZE)
 SleepState_FIQ_R8        EQU    (SleepState_FIQ_SPSR      + WORD_SIZE)
 SleepState_FIQ_R9        EQU    (SleepState_FIQ_R8        + WORD_SIZE)
 SleepState_FIQ_R10       EQU    (SleepState_FIQ_R9        + WORD_SIZE)
 SleepState_FIQ_R11       EQU    (SleepState_FIQ_R10       + WORD_SIZE)
 SleepState_FIQ_R12       EQU    (SleepState_FIQ_R11       + WORD_SIZE)
 SleepState_FIQ_SP        EQU    (SleepState_FIQ_R12       + WORD_SIZE)
 SleepState_FIQ_LR        EQU    (SleepState_FIQ_SP        + WORD_SIZE)
 SleepState_ABT_SPSR      EQU    (SleepState_FIQ_LR        + WORD_SIZE)
 SleepState_ABT_SP        EQU    (SleepState_ABT_SPSR      + WORD_SIZE)
 SleepState_ABT_LR        EQU    (SleepState_ABT_SP        + WORD_SIZE)
 SleepState_IRQ_SPSR      EQU    (SleepState_ABT_LR        + WORD_SIZE)
 SleepState_IRQ_SP        EQU    (SleepState_IRQ_SPSR      + WORD_SIZE)
 SleepState_IRQ_LR        EQU    (SleepState_IRQ_SP        + WORD_SIZE)
 SleepState_UND_SPSR      EQU    (SleepState_IRQ_LR        + WORD_SIZE)
 SleepState_UND_SP        EQU    (SleepState_UND_SPSR      + WORD_SIZE)
 SleepState_UND_LR        EQU    (SleepState_UND_SP        + WORD_SIZE)
 SleepState_SYS_SP        EQU    (SleepState_UND_LR        + WORD_SIZE)
 SleepState_SYS_LR        EQU    (SleepState_SYS_SP        + WORD_SIZE)
 SleepState_Data_End      EQU    (SleepState_SYS_LR        + WORD_SIZE)
 SLEEPDATA_SIZE           EQU    (SleepState_Data_End - SleepState_Data_Start) / 

 ;---------------------------------------------------------------------------
 ;
 ; Macro to feed the LED Reg (The GPIO) with the value desired for debugging.
 ; Uses physical address
 ;
 ; GPFDAT [7:4] is assigned to LEDs.

     IMPORT main        ; C entrypoint for Steppingstone loader.

     EXPORT MMU_EnableICache
      EXPORT MMU_SetAsyncBusMode

     STARTUPTEXT

     LEAF_ENTRY StartUp

     b        ResetHandler    ;1、进入入口函数
     b        .
     b        .
     b        .
     b        .
     b        .
     b        .
     b        .

 ;----------------------------
 ; 1st NAND Bootloader Entry Point
 ;----------------------------

 ResetHandler                ;2、入口函数

     ;------------------------
     ; disable the watchdog timer.    ;2.1、关看门狗,此阶段用不上,若不关在指定时间内不喟狗CPU就会重启。

     ldr        r0, =WTCON

     str        r1, [r0]

     ;------------------------
     ; EBI configuration

     ;ldr        r0, =EBICON            ; EBI
     ;ldr        r1, =EBICON_VAL        ; Refer s3c2416.inc
     ;str        r1, [r0]

     ;-------------------------
     ; Configure GPA data High
     ldr        r0, = GPACDH
     ldr     r1, = 0x1AA8A
     str        r1, [r0]

     ;------------------------
     ; GIPO configuration for LED

     ldr        r0, =GPFCON
     ldr        r1, =0x5500
     str        r1, [r0]

     ;------------------------
     ; Interrupt configuration        ;2.2、屏蔽所有的中断,此阶段用不上,若不屏蔽程序运行过程会被中断且因没有填充中断处理函数会造成死循环。

     ldr    r0, =INTMSK1          ; mask all first-level interrupts.
     ldr    r1, =0xffffffff
     str    r1, [r0]

     ldr    r0, =INTMSK2          ; mask all first-level interrupts.
     ldr    r1, =0xffffffff
     str    r1, [r0]

     ldr    r0, =INTSUBMSK       ; mask all second-level interrupts.
     ldr    r1, =0x1fffffff
     str    r1, [r0]

     ldr   r0, = INTMOD1
     mov   r1, #0x0            ; set all interrupt as IRQ
     str   r1, [r0]

     ldr   r0, = INTMOD2
     mov   r1, #0x0            ; set all interrupt as IRQ
     str   r1, [r0]

     ;------------------------
     ; Clock configuration            ;2.3、设置时钟,初始时CPU的时钟为外部输入的12MHz频率的时钟信号,设置完分频后可在400MHz时钟下运行。

     ldr        r0, =CLKDIV0            ; Set Clock Divider
     ldr        r1, [r0]
     bic        r1, r1, #0x37            ; clear HCLKDIV, PREDIV, PCLKDIV
     bic        r1, r1, #(0xf<<)        ; clear ARMCLKDIV
     ldr        r2, =((Startup_ARMCLKdiv<<)+(Startup_PREdiv<<)+(Startup_PCLKdiv<<)+(Startup_HCLKdiv))
     orr        r1, r1, r2
     str        r1, [r0]

     ldr        r0, =LOCKCON0            ; Set lock time of MPLL. added by junon
     mov        r1, #0xe10                ; Fin = 12MHz -0x800, 16.9844MHz -0xA00
     str        r1, [r0]

     ldr        r0,=LOCKCON1            ;    Set lock time of EPLL. added by junon
     mov        r1,#0x800                ;    Fin = 12MHz - 0x800, 16.9844MHz - 0xA00
     str        r1,[r0]

     ldr        r0, =MPLLCON            ; Set MPLL
     ldr        r1,=((<<)+(Startup_Mdiv<<)+(Startup_Pdiv<<)+(Startup_Sdiv))
     str        r1, [r0]

       ldr        r0,=EPLLCON                ;    Set EPLL
     ldr        r1,=((<<)+(Startup_EMdiv<<)+(Startup_EPdiv<<)+(Startup_ESdiv))
     str        r1,[r0]

     ldr        r0, =CLKSRC                ; Select MPLL clock out for SYSCLK
     ldr        r1, [r0]
     orr        r1, r1, #0x50
     str        r1, [r0]

     ;----------------------------
     ; MMU set Asynchonous Bus Mode     ;2.4、设置MMU为异步模式

     bl        MMU_SetAsyncBusMode

        ;----------------------------
     ; Memory Controller initialize     ;2.5、初始化内存控制器

     bl        InitMEM

        ;----------------------------
     ; SMC initialize                 ;2.6、初始化CPU的SD控制器

     bl        InitSSMC

        ;----------------------------
     ; Reset Case handling                 ;2.7.1、判断复位状态,如果不是唤醒则跳到下面的标号2中运行

     ldr        r1, =RSTSTAT
     ldr        r0, [r1]
     tst        r0, #0x8
     beq        %F2                                ; if not wakeup from PowerOffmode case, Jump to normal booting seauence

        ;------------------------------        ;2.7.2、判断唤醒状态,如果不是RTC唤醒则跳到下面的标号6中运行
     ; Wakeup from PowerOff Mode case

     ldr        r1, =WKUPSTAT
     ldr        r0, [r1]
     tst        r0, #(<<)
     beq        %f6                             ; if not wakeup from PowerOffmode Skip

                                          ;2.7.3、直接跳入内存中运行
     ldr        r2, =0x200000                    ; offset into the RAM
     add        r2, r2, #0x30000000                ; add physical base
     mov        pc, r2                            ; & jump to StartUp address
     nop
     nop
     nop
     b        .

     ldr        r1, =RSTSTAT                ;2.7.4、判断唤醒状态,如果不是深度休眠唤醒则跳到下面的标号BringUpWinCE中运行
     ldr        r0, [r1]
     tst        r0, #(<<)
     beq        BringUpWinCE                    ; if not wakeup from PowerOffmode Skip

 JumpToRAM                                 ;2.7.5、直接跳入内存中运行
     ldr        r2, =0x200000                    ; offset into the RAM
     add        r2, r2, #0x30000000                ; add physical base
     mov       pc, r2                            ;  & jump to StartUp address
     nop
     nop
     nop
     b .

 BringUpWinCE                         ;2.8、执行冷启动流程
     ;--------------------
     ; Clear RAM                         ;2.8.1、清空内存

     ldr        r0, =0x30000000        ; Start address (physical 0x3000.0000).
     ldr        r9, =0x04000000        ; 64MB of RAM.

     stmia     r0!, {r1-r8}
     subs      r9, r9, #
     bne        %B20

     ;---------------------
     ; Initialize stacks.                 ;2.8.2、初始化堆栈,为进入C语言的代码作环境准备

     mrs        r0, cpsr
     bic        r0, r0, #MODEMASK

 ;    orr        r1, r0, #UNDEFMODE | NOINT
 ;    msr        cpsr_cxsf, r1            ; UndefMode
 ;    ldr        sp, =UndefStack            ; UndefStack=0x33FF_5C00

 ;    orr        r1, r0, #ABORTMODE | NOINT
 ;    msr        cpsr_cxsf, r1            ; AbortMode
 ;    ldr        sp, =AbortStack            ; AbortStack=0x33FF_6000

     orr        r1, r0, #IRQMODE | NOINT
     msr        cpsr_cxsf, r1            ; IRQMode
     ldr        sp, =IRQStack            ; IRQStack=0x33FF_7000

 ;    orr        r1, r0, #FIQMODE | NOINT
 ;    msr        cpsr_cxsf, r1            ; FIQMode
 ;    ldr        sp, =FIQStack            ; FIQStack=0x33FF_8000

     bic        r0, r0, #MODEMASK | NOINT
     orr        r1, r0, #SVCMODE
     msr        cpsr_cxsf, r1            ; SVCMode
     ldr        sp, =SVCStack            ; SVCStack=0x33FF_5800

     ;----------------------
     ; Jump to main C routine.             ;2.8.3、跳入C语言代码编写的main函数里面继续执行

     bl        main

     b         .

     ENTRY_END

 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

 ;------------------------------
 ; Sub Routines for Boot Loader
 ;-------------------------------

     LTORG

     ;------------------------
     ; Memory Controller initialize

 IF :DEF: mSDR         ;2.5、如果定义了mSDR则内存初始化函数为下面所示

 InitMEM

         ;Set GPK port when using x32 bus width.
             ldr        r0,=GPKCON
             ldr        r1,=0xaaaaaaaa    ; set Sdata[31:16]
             str        r1, [r0]

             ;Set SDR Memory parameter control registers
             ldr        r0,=BANKCFG
             ldr        r1,=BANKCFGVAL     ; set Sdata[31:16]
             str        r1, [r0]

             ldr        r0,=BANKCON1
             ldr        r1,=BANKCON1VAL      ; set Sdata[31:16]
             str        r1, [r0]

             ldr        r0,=BANKCON2
             ldr        r1,=BANKCON2VAL       ; set Sdata[31:16]
             str        r1, [r0]

             ldr        r0,=BANKCON3
             ldr        r1,=BANKCON3VAL       ; set Sdata[31:16]
             str        r1, [r0]

             ldr        r2,=BANKCON1
             ldr        r1,[r2]
             bic        r1,r1,#(0x3<<)
             orr        r1,r1,#(0x1<<)       ;4nd:Issue a PALL command
             str        r1,[r2]

             ldr        r4,=REFRESH           ;5fh : refresh cycle every 255-clock cycles
             ldr        r0,=0xff
             str        r0,[r4]

             mov    r0, #0x100                 ;6th : wait 2 auto - clk
             subs    r0, r0,#;
             bne    %B02

             bic        r1,r1,#(0x3<<)        ;7th:Issue a MRS command
             orr        r1,r1,#(0x2<<)
             str        r1,[r2]

             ldr        r4,=REFRESH            ;8fh : refresh  normal
             ldr        r0,=REFCYC
             str        r0,[r4]

             orr        r1,r1,#(0x3<<)         ;9th: Issue a EMRS command
             str        r1,[r2]

             bic        r1,r1,#(0x3<<)         ;10th:Issue a Normal mode
             str        r1,[r2]

             mov        pc, lr

 ENDIF

 IF :DEF: mDDR         ;2.5、如果定义了mDDR则内存初始化函数为下面所示
 InitMEM
         ;Set GPK port when using x32 bus width.
             ldr        r0,=GPKCON
             ldr        r1,=0xaaaaaaaa    ; set Sdata[31:16]
             str        r1, [r0]

             ;Set DDR Memory parameter control registers
             ldr        r0,=BANKCFG
             ldr        r1,=BANKCFGVAL     ; set Sdata[31:16]
             str        r1, [r0]

             ldr        r0,=BANKCON1
             ldr        r1,=BANKCON1VAL      ; set Sdata[31:16]
             str        r1, [r0]

             ldr        r0,=BANKCON2
             ldr        r1,=BANKCON2VAL       ; set Sdata[31:16]
             str        r1, [r0]

             ldr        r0,=BANKCON3
             ldr        r1,=BANKCON3VAL       ; set Sdata[31:16]
             str        r1, [r0]

             ldr        r2,=BANKCON1
             ldr        r1,[r2]
             bic        r1,r1,#(0x3<<)
             orr        r1,r1,#(0x1<<)       ; 4nd:Issue a PALL command
             str        r1,[r2]

             ldr        r4,=REFRESH            ;    5fh : refresh cycle every 255-clock cycles
             ldr        r0,=0xff
             str        r0,[r4]

             mov    r0, #0x100                    ;    6th : wait 2 auto - clk
             subs    r0, r0,#;
             bne    %B02

             bic        r1,r1,#(0x3<<)            ;    7th    :    Issue a MRS command
             orr        r1,r1,#(0x2<<)
             str        r1,[r2]

             ldr        r4,=REFRESH            ;    8fh : refresh  normal
             ldr        r0,=REFCYC
             str        r0,[r4]

             orr        r1,r1,#(0x3<<)            ;    9th    :    Issue a EMRS command
             str        r1,[r2]

             bic        r1,r1,#(0x3<<)            ;    10th    :    Issue a Normal mode
             str        r1,[r2]

             mov        pc, lr

 ENDIF

 IF :DEF: DDR2             ;2.5、如果定义了DDR2则内存初始化函数为下面所示,此定义在SRC\Inc\s3c2416.inc里面有定义 GBLL DDR2
 InitMEM

         ;Set GPK port when using x32 bus width.
             ldr        r0,=GPKCON
             ldr        r1,=0xaaaaaaaa    ; set Sdata[31:16]
             str        r1, [r0]

             ;Set DDR2 Memory parameter control registers
             ldr        r0,=BANKCFG
             ldr        r1,=BANKCFGVAL     ; set Sdata[31:16]
             str        r1, [r0]

             ldr        r0,=BANKCON1
             ldr        r1,=BANKCON1VAL      ; set Sdata[31:16]
             str        r1, [r0]

             ldr        r0,=BANKCON2
             ldr        r1,=BANKCON2VAL       ; set Sdata[31:16]
             str        r1, [r0]

             ldr        r2,=BANKCON1            ;    4nd    :    Issue a PALL command
             ldr        r1,[r2]
             bic        r1,r1,#(0x3<<)
             orr        r1,r1,#(0x1<<)
             str        r1,[r2]

             ldr        r2,=BANKCON3            ;    5th    :    Issue a EMRS2 command
             ldr        r3,=0xffff0000
             ldr        r1,[r2]
             bic        r1,r1,r3
             orr        r1,r1,#(BA_EMRS2<<)
             str        r1,[r2]

             ldr        r2,=BANKCON1
             ldr        r1,[r2]
             bic        r1,r1,#(0x3<<)
             orr        r1,r1,#(0x3<<)
             str        r1,[r2]

             ldr        r2,=BANKCON3            ;    6th    :    Issue a EMRS3 command
             ldr        r3,=0xffff0000
             ldr        r1,[r2]
             bic        r1,r1,r3
             orr        r1,r1,#(BA_EMRS3<<)
             str        r1,[r2]

             ldr        r2,=BANKCON1
             ldr        r1,[r2]
             bic        r1,r1,#(0x3<<)
             orr        r1,r1,#(0x3<<)
             str        r1,[r2]

             ldr        r2,=BANKCON3            ;    7th    :    Issue a EMRS1 command
             ldr        r3,=0xffff0000
             ldr        r4,=((BA_EMRS1<<)+(RDQS_DIS<<)+(nDQS_DIS<<)+(OCD_MODE_EXIT<<)+(DLL_EN<<))
                                   ; (0x1<<30)|(0x0<<27)|(0x1<<26)|(0x0<<23)|(0x0<<16)
             ldr        r1,[r2]
             bic        r1,r1,r3
             orr        r1,r1,r4
             str        r1,[r2]

             ldr        r2,=BANKCON1
             ldr        r1,[r2]
             bic        r1,r1,#(0x3<<)
             orr        r1,r1,#(0x3<<)
             str        r1,[r2]

             ldr        r2,=BANKCON3            ;    8th    :    Issue a MRS command
             ldr        r3,=0xffff
             ldr        r1,[r2]
             bic        r1,r1,r3
             orr        r1,r1,#((BA_MRS<<)+(DLL_RESET_HIGH<<)+(TM<<)+(CL_MRS<<))
             str        r1,[r2]

             ldr        r2,=BANKCON1
             ldr        r1,[r2]
             bic        r1,r1,#(0x3<<)
             orr        r1,r1,#(0x2<<)
             str        r1,[r2]

             ldr        r2,=BANKCON1            ;    9nd    :    Issue a PALL command
             ldr        r1,[r2]
             bic        r1,r1,#(0x3<<)
             orr        r1,r1,#(0x1<<)
             str        r1,[r2]

             ldr        r4,=REFRESH                ;    10th : wait 2 auto - clk
             ldr        r0,=0x20
             str        r0,[r4]

             ldr        r2,=BANKCON3            ;    11th    :    Issue a MRS command
             ldr        r3,=0xffff
             ldr        r1,[r2]
             bic        r1,r1,r3
             orr        r1,r1,#((BA_MRS<<)+(DLL_RESET_LOW<<)+(TM<<)+(CL_MRS<<))
             str        r1,[r2]

             ldr        r2,=BANKCON1
             ldr        r1,[r2]
             bic        r1,r1,#(0x3<<)
             orr        r1,r1,#(0x2<<)
             str        r1,[r2]

             mov     r0, #0x100                    ; Wait 200 clock
            subs    r0, r0,#;
             bne     %B2

             ldr        r2,=BANKCON3             ; 12th : Issue a EMRS1 command For OCD Mode Set to default
             ldr        r3,=0xffff0000
             ldr        r4,=((BA_EMRS1<<)+(RDQS_DIS<<)+(nDQS_DIS<<)+(OCD_MODE_DEFAULT<<)+(DLL_EN<<))
             ldr        r1,[r2]
             bic        r1,r1,r3
             orr        r1,r1,r4
             str        r1,[r2]

             ldr        r2,=BANKCON1
             ldr        r1,[r2]
             bic        r1,r1,#(0x3<<)
             orr        r1,r1,#(0x3<<)
             str        r1,[r2]

             ldr        r2,=BANKCON3
             ldr        r3,=0xffff0000
             ldr        r4,=((BA_EMRS1<<)+(RDQS_DIS<<)+(nDQS_DIS<<)+(OCD_MODE_EXIT<<)+(DLL_EN<<))
             ldr        r1,[r2]
             bic        r1,r1,r3
             orr        r1,r1,r4
             str        r1,[r2]

             ldr        r2,=BANKCON1
             ldr        r1,[r2]
             bic        r1,r1,#(0x3<<)
             orr        r1,r1,#(0x3<<)
             str        r1,[r2]

             ldr        r4,=REFRESH            ;    13fh : refresh  normal
             ldr        r0,=REFCYC
             str        r0,[r4]

             ldr        r2,=BANKCON1          ;    14th : Issue a Normal mode
             ldr        r1,[r2]
             bic        r1,r1,#(0x3<<)
             str        r1,[r2]
 ENDIF

     ;-----------------------------
     ; Static Memory Controller Initialize     ;2.6、初始化CPU的SD控制器

 InitSSMC

     ; Set SMC Memory parameter control registers : AMD Flash
         ldr        r0, =SMBIDCYR0
         ldr        r1, =IDCY0
         str        r1, [r0]

         ldr        r0, =SMBWSTRDR0
         ldr        r1, =WSTRD0
         str        r1, [r0]

         ldr        r0, =SMBWSTWRR0
         ldr        r1, =WSTWR0
         str        r1, [r0]

         ldr        r0, =SMBWSTOENR0
         ldr        r1, =WSTOEN0
         str        r1, [r0]

         ldr        r0, =SMBWSTWENR0
         ldr        r1, =WSTWEN0
         str        r1, [r0]

         ldr        r0, =SMBCR0
         ldr        r1, =(SMBCR0_2+SMBCR0_1+SMBCR0_0)
         str        r1, [r0]

         ldr        r0,=SMBWSTBRDR0
         ldr        r1,=WSTBRD0
         str        r1,[r0]

         ldr        r0, =SMBWSTBRDR0
         ldr        r1, =WSTBRD0
         str        r1, [r0]

         ldr        r0, =SSMCCR
         ldr        r1, =((MemClkRatio<<)+(SMClockEn<<))
         str        r1, [r0]

         ldr        r0, =SMBWSTRDR5
         ldr        r1, =0xe
         str        r1, [r0]

         mov        pc, lr

         LTORG

         ;------------------------------------
         ; MMU Cache/TLB/etc on/off functions

         R1_I     EQU    (<<)
         R1_C    EQU    (<<)
         R1_A    EQU    (<<)
         R1_M    EQU    ()
         ;R1_iA    EQU    (1<<31)
         ;R1_nF    EQU    (1<<30)

     ;------------------------------------
     ; void MMU_EnableICache(void);
     LEAF_ENTRY    MMU_EnableICache

         mrc        p15, , r0, c1, c0,
         orr        r0, r0, #R1_I
         mcr        p15, , r0, c1, c0,
         mov        pc, lr

         ; void MMU_SetAsyncBusMode(void);
         ; FCLK:HCLK= 1:2

     ;------------------------------------
     LEAF_ENTRY    MMU_SetAsyncBusMode

         mrc        p15, , r0, c1, c0,
         orr        r0, r0, #R1_nF:OR:R1_iA
         mcr        p15, , r0, c1, c0,
         mov       pc, lr

     ; NAND code...         ;3.0、Nand操作相关
     ;
     A410_BASE_ADDR    EQU    0x2000000

     ;;;    MACRO
     ;;;    LDR4STR1 $src,$tmp1,$tmp2
     ;;;    ldrb    $tmp1,[$src]
     ;;;    ldrb    $tmp2,[$src]
     ;;;    orr        $tmp1,$tmp1,$tmp2,LSL #8
     ;;;    ldrb    $tmp2,[$src]
     ;;;    orr        $tmp1,$tmp1,$tmp2,LSL #16
     ;;;    ldrb    $tmp2,[$src]
     ;;;    orr        $tmp1,$tmp1,$tmp2,LSL #24
     ;;;    MEND

     EXPORT    __RdPage512
 __RdPage512
     ;input:a1(r0)=pPage
     stmfd    sp!,{r1-r11}

     ldr        r1,=0x4e000010      ;NFDATA
     mov        r2,#0x200

     ldr     r4,[r1]
     ldr     r5,[r1]
     ldr     r6,[r1]
     ldr     r7,[r1]
     ldr     r8,[r1]
     ldr     r9,[r1]
     ldr     r10,[r1]
     ldr     r11,[r1]
     stmia    r0!,{r4-r11}
     subs    r2,r2,#
     bne        %B10

     ldmfd    sp!,{r1-r11}
     mov        pc,lr

 END

程序跳转:main.c

 #include <windows.h>
 #include <pehdr.h>
 #include <romldr.h>
 #include "option.h"
 #include "s2416ADDR.h"

 // Constants.
 //
 #define MESSAGE_ON        FALSE  //TRUE
 #define LED_ON            0xa
 #define LED_OFF            0x0

 #define NAND_SB_PAGE_SIZE_BYTES        (0x200)        // 1 Page = 0x200 (512 Bytes)
 #define NAND_SB_BLOCK_SIZE_BYTES    (0x4000)    // 1 Block = 16 KB
 #define NAND_SB_PAGES_PER_BLOCK        (NAND_SB_BLOCK_SIZE_BYTES / NAND_SB_PAGE_SIZE_BYTES)    // 32-pages

 #define NAND_LB_PAGE_SIZE_BYTES        (0x800)        // 1 Page = 0x800 (2048 Bytes)
 #define NAND_LB_BLOCK_SIZE_BYTES    (0x20000)    // 1 Block = 128 KB
 #define NAND_LB_PAGES_PER_BLOCK        (NAND_LB_BLOCK_SIZE_BYTES / NAND_LB_PAGE_SIZE_BYTES)    // 64-pages

 // NOTE: we assume that this Steppingstone loader occupies *part* the first (good) NAND flash block.  More
 // specifically, the loader takes up 4096 bytes (or 8 NAND pages) of the first block.  We'll start our image
 // copy on the very next page.
 #define NAND_COPY_PAGE_OFFSET       (2*((bLARGEBLOCK==TRUE)?NAND_LB_PAGES_PER_BLOCK:NAND_SB_PAGES_PER_BLOCK))

 #define LOAD_ADDRESS_PHYSICAL       0x30038000
 #define LOAD_SIZE_BYTES                 0x00040000
 #define LOAD_SIZE_PAGES                 (LOAD_SIZE_BYTES / ((bLARGEBLOCK==TRUE)?NAND_LB_PAGE_SIZE_BYTES:NAND_SB_PAGE_SIZE_BYTES))

 // Globals variables.
 //
 ROMHDR * ;

 // Function prototypes.
 //
 void MMU_EnableICache(void);
 void Led_Display(int);
 void Port_Init(void);
 void NF_Init(void);
 DWORD ReadFlashID(void);
 int NF_ReadPage(UINT32 block, UINT32 page, volatile BYTE *buffer);

 extern BOOL bLARGEBLOCK;
 //
 typedef void (*PFN_IMAGE_LAUNCH)();

 /*
     @func   BOOLEAN | SetupCopySection | Copies the IPL image's copy section data (initialized globals) to the correct fix-up location.  Once completed, the IPLs initialized globals are valid.
     @rdesc  TRUE == Success and FALSE == Failure.
     @comm
     @xref
 */
 static BOOLEAN SetupCopySection(ROMHDR *const pTOC)
 {
     // This code doesn't make use of global variables so there are no copy sections.  To reduce code size, this is a stub function...
     //
     return(TRUE);
 }

 /*
     @func   void | main | C entrypoint function for the Steppingstone loader.
     @rdesc  None.
     @comm
     @xref
 */
 void main(void)
 {
     register nBlock;
     register nPage;
     register nBadBlocks;
     volatile BYTE *pCopyPtr;

 #if MESSAGE_ON==1
     volatile DWORD boot_code;
 #endif

     // Set up copy section (initialized globals).
     //
     // NOTE: after this call, globals become valid.
     //
     //SetupCopySection(pTOC);

     // Enable the ICache.
     //
     MMU_EnableICache();

     // Set up all GPIO ports.
     //
     // TBD - DonGo
     Port_Init();        //1、初始化IO口

     Uart_Init();        //2、初始化打印信息的串口

     Uart_SendString("\rMicrosoft Windows CE 5.0 Stepldr for DMA2416\r\n");

     // Initialize the NAND flash interface.
     //
     //Uart_SendString("NF_Init...");
     NF_Init();         //3、初始化Flash

     // Turn the LEDs off.
     Led_Display(LED_OFF);

     //---------------------------------
     // Copy image from NAND flash to RAM.//4、准备复制Flash文件到内存中运行
     //
     pCopyPtr = (BYTE *)LOAD_ADDRESS_PHYSICAL;

 #if MESSAGE_ON==1
     Uart_SendString("Image copy NAND block from ");
     Uart_SendDWORD(NAND_COPY_PAGE_OFFSET/NAND_PAGES_PER_BLOCK,);
     Uart_SendString(" to ");
     Uart_SendDWORD((LOAD_SIZE_PAGES + NAND_COPY_PAGE_OFFSET)/NAND_PAGES_PER_BLOCK,);
     Uart_SendString("Download memory address at ");
     Uart_SendDWORD(LOAD_ADDRESS_PHYSICAL,);
 #endif

     if (ReadFlashID() != TRUE)
     {
         //Uart_SendString("NAND Flash is not supported!!\r\n");
         );
     }

     nBadBlocks = ;
     for (nPage = NAND_COPY_PAGE_OFFSET ; nPage < (LOAD_SIZE_PAGES + NAND_COPY_PAGE_OFFSET) ; nPage++)  //5、执行拷贝操作
     {
         nBlock = ((nPage / ((bLARGEBLOCK==TRUE)?NAND_LB_PAGES_PER_BLOCK:NAND_SB_PAGES_PER_BLOCK)) + nBadBlocks);
         //Uart_SendDWORD(nPage,1);
         //Uart_SendString(" ");
         if (!NF_ReadPage(nBlock, (nPage % ((bLARGEBLOCK==TRUE)?NAND_LB_PAGES_PER_BLOCK:NAND_SB_PAGES_PER_BLOCK)), pCopyPtr))//6、读取Flash写入内存
         {
             //Uart_SendString(hex2char(nBlock));
             )
             {
                 //Led_Display(0x9);    // real ECC Error.
                 //Uart_SendString("ECC Error.\r\n");
                 // Spin forever...
                 )
                 {
                 }
             }

             // ECC error on a block boundary is (likely) a bad block - retry the page 0 read on the next block.
             nBadBlocks++;
             nPage--;
             continue;
         }
         //Uart_SendDWORD(*pCopyPtr,0);
         //Uart_SendString("\n");

         pCopyPtr += ((bLARGEBLOCK==TRUE)?NAND_LB_PAGE_SIZE_BYTES:NAND_SB_PAGE_SIZE_BYTES);
     }

     // Turn the LEDs on.
     //
     //Led_Display(0x5);

 #if MESSAGE_ON==1
     boot_code = *(volatile DWORD *)LOAD_ADDRESS_PHYSICAL;
     Uart_SendString("Bboot code : ");
     Uart_SendDWORD(boot_code,);
     //-----------------------------
     // Jump to the image...
     //
     Uart_SendString("Now Jump to ");
     Uart_SendDWORD(LOAD_ADDRESS_PHYSICAL,);
 #endif

     ((PFN_IMAGE_LAUNCH)(LOAD_ADDRESS_PHYSICAL))();    //7、跳入内存指定地址运行

 }

程序编译配置文件:stepldr.bib

MEMORY
;   Name      Start     Size      Type
;   -------   --------  --------  ----
    STEPLDR        RAMIMAGE ;此处地址是CPU内置的RAM的地址文章最上面的图所示,大小为8K,即2416所支持的最大的自动复制大小
    STACK    33ff5800     RESERVED ;程序运行时的栈指针
    RAM      33ff0000     RAM    ;程序运行内存

CONFIG
    COMPRESSION=ON
    PROFILE=OFF
    KERNELFIXUPS=ON

    ROMSTART=
    ROMWIDTH=
    ROMSIZE=00001000              ;实际大小只用了4K

MODULES
;   Name        Path                                                               Memory Type
;   ----------  --------------------------------------------------------------     -----------
    nk.exe      $(_TARGETPLATROOT)\target\$(_TGTCPU)\$(WINCEDEBUG)\stepldr.exe     STEPLDR

CE STEPLDR的更多相关文章

  1. CE修改器修改DNF 测试视频 阿修罗提升智力增加攻击力

    使用CE修改器来修改网络游戏,如DNF 测试视频: CE修改器:指的是Cheat Engine,字面上的意思指的是作弊引擎的意思,是一款内存修改编辑工具.通过修改游戏的内存数据来得到一些原本无法实现的 ...

  2. PreEmptive Dotfuscator and Analytics CE

    PreEmptive Dotfuscator and Analytics CE Dotfuscator 是领先的 .NET 模糊处理程序和压缩程序,有助于防止程序遭到反向工程,同时使程序更小更高效.D ...

  3. Visual Studio 2005 搭建Windows CE 6.0环境之准备

    Microsoft Visual Studio 2005 Visual Studio 2005 Professional 官方90天试用版英文版:http://download.microsoft.c ...

  4. 游戏外挂四之利用CE和OD查找被选中怪物和怪物列表

    合肥程序员群:49313181.    合肥实名程序员群:128131462 (不愿透露姓名和信息者勿加入)Q  Q:408365330     E-Mail:egojit@qq.com 这一节我们利 ...

  5. CE 进程间通信

    WINCE下进程间通信常用的方式有:剪贴板(Clipboard),网络套接字(Socket),WM_COPYDATA消息,共享内存,管道(消息队列),注册表等 剪贴板 //////////////// ...

  6. CE 进程同步-事件

    事件(event)分为有名的和无名的,使用有名事件的时候,在不同进程中创建的同名事件,其实就是同一个,这样就可以在不同的进程中使用了.两个进程里面都要创建事件,事件名要一致. //进程1 HANDLE ...

  7. CE搜索内存数据的原理

      最近发现有朋友在玩游戏时, 使用一款工具来修改游戏的部分数据,作弊的效果, 也就是CE(Cheat Engine),这款工具是 delphi 编写的, 于是好奇, 然后瞬间想到API OpenPr ...

  8. ce游戏内存修改器(Cheat Engine)

    ce修改器(Cheat Engine)一款专门修改内存修改编辑的游戏工具它包括16进制编辑,反汇编程序,内存查找工具新版6.1 版的CE与6.0 最大的区别就是添加了修改器制作工具,比之前 5.6.1 ...

  9. CE 文件读写操作

    写入字符到文件中: // TODO: 写字符到文件 // 参数: CString类型的文件名FileName;char *类型的数据内容;unsigned int类型内容长度 // 返回: 成功返回T ...

随机推荐

  1. MyEclipse Java Build Path详解

    转载自:http://blog.163.com/magicc_love/blog/static/185853662201111161580631/ 1.设置"source folder&qu ...

  2. my vim

    set nu set cindent set smartindent set cursorline set showcmd set completeopt=preview,menu set autow ...

  3. Visual Studio 2015 Update 2

    Visual Studio Community 2015(带Update2)(社区版,针对个人免费): 简体中文版 || SHA1:待更新 繁体中文版 || SHA1:待更新 英文版 || SHA1: ...

  4. WebAPI返回数据类型解惑[转]

    最近开始使用WebAPI,上手很容易,然后有些疑惑 1.WebAPI默认返回什么数据类型,json还是xml? 2.怎么修改WebAPI的返回数据类型,我用IE浏览器请求返回的数据都是JSON格式的, ...

  5. Linq Group By

    TableA { Id int, Name string, Group  int Score int } 从 Id Name Group Score 1 张三 A 70 2 李四 A 80 3 王五 ...

  6. Apache Tomcat开机后台启动

    作为软件开发人员,经常接触Tomcat,完成的项目,需要部署到服务器上的Tomcat,才能供其他人访问浏览. 因为存在以下问题,所以需要把Tomcat设置为后台自动启动: 1.服务器可能因环境故障面临 ...

  7. jsp九大内置对象和四大作用域

    看到网上一些Jsp内置对象介绍的都不是很全,今天我把各位大神的整理了一下. JSP九大对象:内置对象(又叫隐含对象,有9个内置对象):不需要预先声明就可以在脚本代码和表达式中随意使用. 一.reque ...

  8. 1Caesar加密

    Julius Caesar发明的较早的加密术,举个例子: 明文: meet me after the toga party 密文:   PHHW PH DIWHU WKH WRJD SDUWB 其实就 ...

  9. 模板volist自增变量

  10. python bytes to string

    python bytes 转化成 string 会遇到如下错误: codec can't decode byte 0xff in position 5: illegal multibyte seque ...