自制bootloader 之文本代碼
首先應(yīng)該描述一下該bootloader的基本功能:板子上電后能進(jìn)行LED流水燈(萬能的流水燈?。?。實現(xiàn)該功能分兩步:第一步,真正的bootloader功能,即實現(xiàn)硬件的初始化以及將內(nèi)核程序(LED流水燈)從ROM(flash)搬移到RAM(sdram);第二步,內(nèi)核程序的實現(xiàn)
第一步也可分兩段:1,板子硬件初始化;2,內(nèi)核程序的搬移。代碼文件:boot.s
板子硬件初始化:1. 異常向量初始化
2. 初始化CPSR,包括關(guān)閉中斷及設(shè)定svc模式等
3. 關(guān)閉看門狗定時器
4. 初始化系統(tǒng)時鐘
5. 初始化CPU Cache(這步可以不做,但是系統(tǒng)效率會明顯下降許多)
內(nèi)核執(zhí)行流程:1,內(nèi)核異常向量初始化
2,初始化堆棧
3,跳轉(zhuǎn)到C程序中執(zhí)行萬能的流水燈~~~~
代碼如下: .equ SYSCFG, 0x01c00000 .equ BWSCON, 0x01c80000 .equ WTCON, 0x01d30000 .equ PLLCON, 0x01d80000 .equ CLKCON, 0x01d80004 .equ KERNEL_START, 0x0c000100 @ 內(nèi)核執(zhí)行的起始位置(RAM) .equ KERNEL_VECTOR, 0x0c000000 @ 內(nèi)核的異常向量入口(RAM) .equ KERNEL_DATA, 0x00000100 @ 內(nèi)核數(shù)據(jù)在ROM中的起始位置 .equ KERNEL_CPLMT, 0x00001000 @ 復(fù)制界限(內(nèi)核數(shù)據(jù)在ROM中的終止位置,4KB).equ REFEN, 0x01.equ TREFMD, 0x0.equ Trp, 0x1.equ Trc, 0x1.equ Tchr, 0x2.equ REFCNT, 1550vectors: b reset ldr pc, = KERNEL_VECTOR @ 未定義協(xié)處理器指令 ldr pc, = KERNEL_VECTOR + 4 @ SWI(軟中斷) ldr pc, = KERNEL_VECTOR + 8 @ 預(yù)取指令中止 ldr pc, = KERNEL_VECTOR + 12 @ 數(shù)據(jù)中止 b . ldr pc, = KERNEL_VECTOR + 16 @ IRQ(普通中斷請求) ldr pc, = KERNEL_VECTOR + 20 @ FIQ(快速中斷請求)reset: mov r0,0xd3 ;禁止IRQ,F(xiàn)IQ,SVC模式 msr cpsr_c,r0 ldr r0,=WTCON ;關(guān)看門狗 mov r1,#0 str r1,[r0] ldr r0,=PLLCON ;初始化PLLCON mov r1,#0x48032
;Fin=10M Fpllo=40M Mdiv=0x48 Pdiv=0x3 Sdiv=0x2 str r1,[r0] ldr r0,=CLKCON ldr r1,=0x7f88 ;提供給所有外設(shè)時鐘 str r1,[r0] ldr r0,=SYSCFG ;初始化cpu cach mov r1,#0x0e ;8K cache 寫緩沖使能 str r1,[r0] ldr r0,=SMRDATA ;初始化存儲器 ldmia r0,{r1-r13} ldr r0,=BWSCON stmia r0,{r1-r13};將內(nèi)核程序(LED流水燈)從0x00000100(flash)復(fù)制到0x0c000000(sdram) ldr fp,=KERNEL_DATA ldr ip,=KERNEL_VECTOR ldr sp,=KERNEL_CPLMT1: ldmia fp!,{r0-r7} stmia ip!,{r0-r7} cmp fp,ip bcc 1b ldr pc,=KERNEL_STARTsmrdata : .word 0x11110090.word 0x00000600.word 0x00000700 @ BANKCON1: 默認(rèn) .word 0x00000700 @ BANKCON2: 默認(rèn) .word 0x00000700 @ BANKCON3: 默認(rèn) .word 0x00000700 @ BANKCON4: 默認(rèn) .word 0x00000700 @ BANKCON5: 默認(rèn) .word 0x00018000 @ BANKCON6: SDRAM,SCAN=8位,Trcd=2個時鐘 .word 0x00000700 @ BANKCON7: 默認(rèn) .word
((REFEN23)+(TREFMD22)+(Trp20)+(Trc18)+(Tchr16)+REFCNT)
;refresh register .word 0x00000016 @ BANKSIZE: SLCKEN=1, BK76MAP=8M .word 0x00000020 @ MRSRB6: CL=2個時鐘 .word 0x20 @MRSRB7第二步:內(nèi)核程序的實現(xiàn),代碼文件 head.s內(nèi)核程序大致三步:1,內(nèi)核異常向量初始化;2,內(nèi)核堆棧初始化;3,執(zhí)行LED程序;代碼如下:.equ KERNEL_STACK, 0x0c002000.equ KERNEL_LIMIT, 0x0c001000vectors: b undef_handler @ 內(nèi)核異常向量0 b swi_handler @ 內(nèi)核異常向量1 b pabort_handler @ 內(nèi)核異常向量2 b dabort_handler @ 內(nèi)核異常向量3 b irq_handler @ 內(nèi)核異常向量4 b fiq_handler @ 內(nèi)核異常向量5.space 0x100-6*4 @字節(jié)填充至地址:0x0c000100start: ldr sp,=KERNEL_STACK ldr sl,=KERNEL_LIMIT bl entryundef_handler: swi_handler: pabort_handler: dabort_handler: irq_handler: fiq_handler: b . @ 目前什么都不做
以上兩個文本程序基本實現(xiàn)了一個bootloader的功能,至少符合我的板子,只要再加上上一篇LED篇中的LED程序,就是一個完整的bootloader程序了。當(dāng)然,還是需要幾番調(diào)試的。而大debug之前還是有很多工作要做滴。下一篇再說吧,這里太長了~~~~
評論