作用:初始化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. iOS autoresizing布局

    在对UIView以及其子类空间的布局方案有多种,今天温习了一下autoresizing布局 一.了解一下相关知识: 1.UIView其中一个属性为 @property(nonatomic) UIVie ...

  2. freeCAD文档结构

    一个freecad文档包含了你场景中的所有物体.它可以包含组及任何工作平台制造的物体.你可以切换工作台,但是它仍然工作在同一个文档上.当您保存您的工作时,该文件就被保存到磁盘上.你可以同时打开多个fr ...

  3. goldengate for big data 12.2.0.1.1新增功能

    新格式支持:包括Avro OCF和HDFS顺序文件,OGG现在支持将数据写入Avro对象容器(Object container format)和HDFS顺序文件 支持Hadoop平台元数据或DDL更新 ...

  4. Python的平凡之路(12)

    一.数据库介绍 数据库(Database)是按照数据结构来组织.存储和管理数据的仓库,每个数据库都有一个或多个不同的API用于创建,访问,管理,搜索和复制所保存的数据.我们也可以将数据存储在文件中,但 ...

  5. 亲身试用python简单小爬虫

    前几天基友分享了一个贴吧网页,有很多漂亮的图片,想到前段时间学习的python简单爬虫,刚好可以实践一下. 以下是网上很容易搜到的一种方法: #coding=utf-8 import urllib i ...

  6. wireshark流跟踪和分析

  7. MFC 屏幕截图方法

    //获取当前屏幕的并且保存图片 LRESULT CFeetScanView::SaveViewBMP(WPARAM wParam, LPARAM lParam) { CRect rect; this- ...

  8. DIV+CSS布局网站基本框架

    html代码 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www. ...

  9. 关于HTML标签那些事儿

    关于html相信对于每一个互联网从业者来说实在熟悉不过的一个名词,特别是web前端工程师来说更是基础中的基础.html是hyper text markup language的首字母缩写,翻译过来就是超 ...

  10. 强大反调试cm的奇葩破解

    系统 : Windows xp 程序 : Crackme-xp 程序下载地址 :http://pan.baidu.com/s/1slUwmVr 要求 : 编写注册机 使用工具 : OD & I ...