CE STEPLDR
作用:初始化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的更多相关文章
- CE修改器修改DNF 测试视频 阿修罗提升智力增加攻击力
使用CE修改器来修改网络游戏,如DNF 测试视频: CE修改器:指的是Cheat Engine,字面上的意思指的是作弊引擎的意思,是一款内存修改编辑工具.通过修改游戏的内存数据来得到一些原本无法实现的 ...
- PreEmptive Dotfuscator and Analytics CE
PreEmptive Dotfuscator and Analytics CE Dotfuscator 是领先的 .NET 模糊处理程序和压缩程序,有助于防止程序遭到反向工程,同时使程序更小更高效.D ...
- Visual Studio 2005 搭建Windows CE 6.0环境之准备
Microsoft Visual Studio 2005 Visual Studio 2005 Professional 官方90天试用版英文版:http://download.microsoft.c ...
- 游戏外挂四之利用CE和OD查找被选中怪物和怪物列表
合肥程序员群:49313181. 合肥实名程序员群:128131462 (不愿透露姓名和信息者勿加入)Q Q:408365330 E-Mail:egojit@qq.com 这一节我们利 ...
- CE 进程间通信
WINCE下进程间通信常用的方式有:剪贴板(Clipboard),网络套接字(Socket),WM_COPYDATA消息,共享内存,管道(消息队列),注册表等 剪贴板 //////////////// ...
- CE 进程同步-事件
事件(event)分为有名的和无名的,使用有名事件的时候,在不同进程中创建的同名事件,其实就是同一个,这样就可以在不同的进程中使用了.两个进程里面都要创建事件,事件名要一致. //进程1 HANDLE ...
- CE搜索内存数据的原理
最近发现有朋友在玩游戏时, 使用一款工具来修改游戏的部分数据,作弊的效果, 也就是CE(Cheat Engine),这款工具是 delphi 编写的, 于是好奇, 然后瞬间想到API OpenPr ...
- ce游戏内存修改器(Cheat Engine)
ce修改器(Cheat Engine)一款专门修改内存修改编辑的游戏工具它包括16进制编辑,反汇编程序,内存查找工具新版6.1 版的CE与6.0 最大的区别就是添加了修改器制作工具,比之前 5.6.1 ...
- CE 文件读写操作
写入字符到文件中: // TODO: 写字符到文件 // 参数: CString类型的文件名FileName;char *类型的数据内容;unsigned int类型内容长度 // 返回: 成功返回T ...
随机推荐
- MyEclipse Java Build Path详解
转载自:http://blog.163.com/magicc_love/blog/static/185853662201111161580631/ 1.设置"source folder&qu ...
- my vim
set nu set cindent set smartindent set cursorline set showcmd set completeopt=preview,menu set autow ...
- Visual Studio 2015 Update 2
Visual Studio Community 2015(带Update2)(社区版,针对个人免费): 简体中文版 || SHA1:待更新 繁体中文版 || SHA1:待更新 英文版 || SHA1: ...
- WebAPI返回数据类型解惑[转]
最近开始使用WebAPI,上手很容易,然后有些疑惑 1.WebAPI默认返回什么数据类型,json还是xml? 2.怎么修改WebAPI的返回数据类型,我用IE浏览器请求返回的数据都是JSON格式的, ...
- Linq Group By
TableA { Id int, Name string, Group int Score int } 从 Id Name Group Score 1 张三 A 70 2 李四 A 80 3 王五 ...
- Apache Tomcat开机后台启动
作为软件开发人员,经常接触Tomcat,完成的项目,需要部署到服务器上的Tomcat,才能供其他人访问浏览. 因为存在以下问题,所以需要把Tomcat设置为后台自动启动: 1.服务器可能因环境故障面临 ...
- jsp九大内置对象和四大作用域
看到网上一些Jsp内置对象介绍的都不是很全,今天我把各位大神的整理了一下. JSP九大对象:内置对象(又叫隐含对象,有9个内置对象):不需要预先声明就可以在脚本代码和表达式中随意使用. 一.reque ...
- 1Caesar加密
Julius Caesar发明的较早的加密术,举个例子: 明文: meet me after the toga party 密文: PHHW PH DIWHU WKH WRJD SDUWB 其实就 ...
- 模板volist自增变量
- python bytes to string
python bytes 转化成 string 会遇到如下错误: codec can't decode byte 0xff in position 5: illegal multibyte seque ...