專注電子技術學習與研究
當前位置:單片機教程網(wǎng) >> MCU設計實例 >> 瀏覽文章

自制bootloader 之 文本代碼

作者:佚名   來源:本站原創(chuàng)   點擊數(shù):  更新時間:2010年12月18日   【字體:

   想移植uboot1.4到板子上,搞了半天沒成功,決心弄明白uboot原理,大概流程,所以決定寫個簡單的bootloader來理順一下應該做些什么,怎么做~~~~

    首先應該描述一下該bootloader的基本功能:板子上電后能進行LED流水燈(萬能的流水燈啊)。實現(xiàn)該功能分兩步:第一步,真正的bootloader功能,即實現(xiàn)硬件的初始化以及將內核程序(LED流水燈)從ROM(flash)搬移到RAM(sdram);第二步,內核程序的實現(xiàn)

    第一步也可分兩段:1,板子硬件初始化;2,內核程序的搬移。代碼文件:boot.s

    板子硬件初始化:1. 異常向量初始化
              2. 初始化CPSR,包括關閉中斷及設定svc模式等
              3. 關閉看門狗定時器
              4. 初始化系統(tǒng)時鐘
                    5. 初始化CPU Cache(這步可以不做,但是系統(tǒng)效率會明顯下降許多)

    內核執(zhí)行流程:1,內核異常向量初始化

        2,初始化堆棧

        3,跳轉到C程序中執(zhí)行萬能的流水燈~~~~

代碼如下:  

equ     SYSCFG,        0x01c00000    
.equ     BWSCON,        0x01c80000   
.equ     WTCON,         0x01d30000   
.equ     PLLCON,        0x01d80000   
.equ     CLKCON,        0x01d80004   

.equ     KERNEL_START,  0x0c000100        @ 內核執(zhí)行的起始位置(RAM)    

.equ     KERNEL_VECTOR, 0x0c000000        @ 內核的異常向量入口(RAM)    

.equ     KERNEL_DATA,   0x00000100        @ 內核數(shù)據(jù)在ROM中的起始位置    

.equ     KERNEL_CPLMT,  0x00001000        @ 復制界限(內核數(shù)據(jù)在ROM中的終止位置,4KB)

.equ     REFEN,    0x01

.equ  TREFMD,   0x0

.equ  Trp,      0x1

.equ  Trc,          0x1

.equ      Tchr,       0x2

.equ      REFCNT,   1550

vectors:

    b    reset

    ldr    pc, = KERNEL_VECTOR            @ 未定義協(xié)處理器指令    
       ldr    pc, = KERNEL_VECTOR + 4        @ SWI(軟中斷)    
              ldr    pc, = KERNEL_VECTOR + 8        @ 預取指令中止     

              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     ;關看門狗

    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    ;提供給所有外設時鐘

    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}

;將內核程序(LED流水燈)從0x00000100(flash)復制到0x0c000000(sdram)

    ldr    fp,=KERNEL_DATA

    ldr    ip,=KERNEL_VECTOR

    ldr    sp,=KERNEL_CPLMT

1:   ldmia   fp!,{r0-r7}

    stmia   ip!,{r0-r7}

    cmp    fp,ip

    bcc     1b

    ldr    pc,=KERNEL_START

smrdata :   
.word      0x11110090

.word      0x00000600

.word      0x00000700                    @ BANKCON1: 默認    
.word      0x00000700                    @ BANKCON2: 默認    
.word      0x00000700                    @ BANKCON3: 默認    
.word      0x00000700                    @ BANKCON4: 默認    
.word      0x00000700                    @ BANKCON5: 默認    
.word      0x00018000                    @ BANKCON6: SDRAM,SCAN=8位,Trcd=2個時鐘    
.word      0x00000700                    @ BANKCON7: 默認   

.word      ((REFEN<<23)+(TREFMD<<22)+(Trp<<20)+(Trc<<18)+(Tchr<<16)+REFCNT)  ;refresh register 
    
.word      0x00000016                    @ BANKSIZE: SLCKEN=1, BK76MAP=8M    
.word      0x00000020                    @ MRSRB6: CL=2個時鐘  

.word   0x20                                @MRSRB7

第二步:內核程序的實現(xiàn),代碼文件 head.s

內核程序大致三步:1,內核異常向量初始化;2,內核堆棧初始化;3,執(zhí)行LED程序;

代碼如下:

.equ    KERNEL_STACK,    0x0c002000

.equ    KERNEL_LIMIT,       0x0c001000

vectors:

 b     undef_handler                  @ 內核異常向量0    
    b     swi_handler                    @ 內核異常向量1    
    b     pabort_handler                 @ 內核異常向量2    
    b     dabort_handler                 @ 內核異常向量3    
    b     irq_handler                    @ 內核異常向量4    
    b     fiq_handler                    @ 內核異常向量5

.space    0x100-6*4       @字節(jié)填充至地址:0x0c000100

start:

    ldr    sp,=KERNEL_STACK

    ldr    sl,=KERNEL_LIMIT

    bl    entry

undef_handler:   

swi_handler:   

pabort_handler:   

dabort_handler:   

irq_handler:   

fiq_handler:   

    b     .                              @ 目前什么都不做 

  以上兩個文本程序基本實現(xiàn)了一個bootloader的功能,至少符合我的板子,只要再加上上一篇LED篇中的LED程序,就是一個完整的bootloader程序了。當然,還是需要幾番調試的。而大debug之前還是有很多工作要做滴。下一篇再說吧,這里太長了~~~~

關閉窗口

相關文章