本身寫的嵌入式bootloader stage1,用LED完成測試(基於vivi)

1:作嵌入式bootloader開發也有一段時間了,今天終於重構了本身的第一個代碼,主要目的用來測試,並驗證stage1的啓動,爲後續開發增長點信息。從開始的毫無頭緒,到如今本身寫的這個代碼。感受上仍是頗有成就。

硬件環境:
開發板:恆豐銳科 HF2410A +3.5"觸摸屏
  • CPU:S3C2410AL ARM920t
  • 存儲器:
      1. 64M(32M*2) SDRAM(K4S561632H-UC75)
      2. 64M Nand Flash (KF1208)
  • 一個總線擴展接口。
  • 2個串口輸出
  • JTAG調試接口
    軟件環境:
    XP+VMware+RH linux 9+Source Insight



    stage1:軟件架構參考下圖
  •  

    軟件大致分爲三部分:主代碼區、調用子函數代碼區、數據區


    /*
    * vivi/arch/s3c2410/head.S:
    *
    * bootloader stage1
    *
    * modify by forl on 2008/3/14
    */
    #include "config.h"
    #include "linkage.h"
    #include "machine.h"
    .text
    /*
      **********************************************
      *
      *code Area
      *
      **********************************************
      */
      
    /*
      ***********************************************
      *
      * Exception vector table
      *
      ***********************************************
      */
    .globl _start
    _start: b Reset
           b    undefined_instruction
        b    software_interrupt
        b    prefetch_abort
        b    data_abort
        b    not_used
        b    irq
        b    fiq
       
    /*
      **************************************************
      *
      *the actual reset code
      *
      **************************************************
      */
    Reset:
        /*disable watch dog timer*/
       
        mov    r1, #0x53000000
        mov    r2, #0x0
        str    r2, [r1]
       
        /*disable all interrupts*/
       
        mov    r1, #0x4A000000
        mov    r2, #0xffffffff
        str    r2, [r1, #0x08]
        ldr    r2, =0x7ff
        str    r2, [r1, #0x1C]   
        /* initialise system clocks*/
        mov    r1, #0x4C000000
        mvn    r2, #0xff000000
        str    r2, [r1, #0x00]
        @ 1:2:4
        mov    r1, #0x4C000000
        mov    r2, #0x3
        str    r2, [r1, #0x14]
        mrc    p15, 0, r1, c1, c0, 0        @ read ctrl register
        orr    r1, r1, #0xc0000000        @ Asynchronous
        mcr    p15, 0, r1, c1, c0, 0        @ write ctrl register
        @ now, CPU clock is 200 Mhz
        mov    r1, #0x4C000000
        ldr r2, mpll_200mhz
        str    r2, [r1, #0x04]
            
             /*
             *********************
                 *
                 *initialise memory
                 *
             *********************
             */
          
         bl memsetup
         bl led_memsetup
             /*
             *********************
                 *
                 * SDRAM test
                 *
             *********************
             */
         bl memtest
         bl led_memtest
       
             /*
             *********************
                 *
                 *initialise uart 0
                 *
             *********************
             */
             
         bl init_uart   @獨立用c函數完成

         bl led_init_uart  
       
             /*
             *********************
                 *
                 *copy vivi to SDRAM
                 *
             *********************
             */
             
         bl copy_myself
         bl led_copy_myself
         
              /*
             *********************
                 *
                 *jump to ram
                 *
             *********************
             */
             
        ldr r1, =on_the_ram
        add    pc, r1, #0
        nop
        nop
    1:  b    1b        @ infinite loop
    on_the_ram:
        @ get read to call C functions
        ldr    sp, DW_STACK_START    @ setup stack pointer
        mov    fp, #0            @ no previous frame, so fp=0
        mov    a2, #0            @ set argv to NULL
       
        bl led_main
        bl    main            @ call main
        mov    pc, #0x000        @ otherwise, reboot
    /*
      ***********************************************************
      *
      * End VIVI head
      *
      ***********************************************************
      */
    /*
      ***********************************************************
      *
      * sub program
      *
      ************************************************************
      */
    /* initialise memory*/
         /* initialise SDRAM*/

    memsetup:
        mov    r1, #0x48000000
        adrl    r2, mem_cfg_val
        add    r3, r1, #52
    1:  ldr    r4, [r2], #4
        str    r4, [r1], #4
        cmp    r1, r3
        bne    1b
    /*
      ***********************************************************
      *
      * copy_myself: copy vivi to ram
      *
      ************************************************************
      */
    copy_myself:
        mov    r10, lr
       
        /*initialise NAND flash*/
        mov    r1, #0x4E000000
        ldr    r2, =0xf830        @ initial value
        str    r2, [r1, #0x00]
        ldr    r2, [r1, #0x00]
        bic    r2, r2, #0x800        @ enable chip
        str    r2, [r1, #0x00]
        mov    r2, #0xff         @ RESET command
        strb    r2, [r1, #0x40]
        mov    r3, #0             @ wait
    1:  add    r3, r3, #0x1
        cmp    r3, #0xa
        blt    1b
    2:  ldr    r2, [r1, #0x10]    @ wait ready
        tst    r2, #0x1
        beq    2b
        ldr    r2, [r1, #0x00]
        orr    r2, r2, #0x800        @ disable chip
        str    r2, [r1, #0x00]
       
        /*get read to call C functions (for nand_read())*/
       
        ldr sp, DW_STACK_START @ setup stack pointer
        mov fp, #0 @ no previous frame, so fp=0
       
        @ copy vivi to RAM
        ldr    r0, =VIVI_RAM_BASE
        mov r1, #0x0
        mov    r2, #0x20000
        bl    nand_read_ll
        cmp    r0, #0x0
        beq    ok_nand_read
             /*bad nand read*/
    bad_nand_read:
    bl led_bad_nand_read
    1: b  1b    @ infinite loop
         /*ok nand read*/
    ok_nand_read:

        /*verify 0x000-0x400 and 0x33f0000-0x33f0400*/
        mov    r0, #0
        ldr    r1, =0x33f00000
        mov    r2, #0x400    @ 4 bytes * 1024 = 4K-bytes
    go_next:

        ldr r3, [r0], #4
        ldr    r4, [r1], #4
        teq    r3, r4
        bne    notmatch
        subs    r2, r2, #4
        beq    done_nand_read   
        bne    go_next
       
    notmatch:
    bl led_notmatch
       
    1:    b    1b
      /* done nand read to ram*/
    done_nand_read:
      mov lr, r10
      mov pc, lr
       
    /*
      *******************************************************
      *
      *Simple memory test function
      *
      *******************************************************
      */
    memtest:
    mov r10, lr
    /* check the first 1MB of BLOB_START in increments of 4k */
    mov r7, #0x1000
    mov r6, r7, lsl #8 /* 4k
    關於led測試:
    在開發板上有四個led燈 D二、D三、D四、D5查看開發板原理圖,其與GPIO的GPF[4:7]
    一一對應。利用寫GPF[4:7]的值來調試查看程序的運行。對於延時程序能夠利用S3C2410自帶的硬件計時器,亦可軟件實現(本人所採用)
    調試stage1過程當中D二、D三、D四、D5依次順序點亮,最後全亮,其對應的程序運行點以下:
    D2
    memsetup
    D3
    memtest
    D4
    init_uart
    D5
    copy_myself
    D2,D3,D4,D5
    main
    上面這個能夠本身設置,個性化的東西。

    調試:
    這是個很花時間的過程,一個小小的問題都會致使整個過程歷來。而用JTAG燒寫程序看程序運行狀態的方法實在笨的不行。又佔PC資源,又慢。因此開始編譯時必定要當心。特別是注意不要轉入某個循環不出來(由於這種狀況交叉編譯是能經過的),這點要注意保存程序指針。
    我就陷入過其中,檢查不出來,不得不用設置多個led點的方法看其出錯地點,而後去修改。

    開始寫程序,沒有初始化串口(開始覺得在第二階段初始化),結果bootloader運行正常,沒有啓動信息輸出,着實鬱悶了我。

    調試是個痛快的過程,有耐心的能夠試下,以上的程序我已通過驗證,pass。^_^

    後記:
    關於bootloader stage1 程序的具體分析,包括硬件如何正確初始化,如何設置正確的寄存器的值,還有一些程序的理解在個人另外一篇文章中有過詳細而囉嗦的描述。可供耐心的人蔘考~~網址以下
    http://blog.chinaunix.net/u1/58203/showart_489453.html

    下一步要作的是完成Stage2的結構分析,構建本身的bootloader stage2 而後增強其網絡功能。期待ING
    html

    相關文章
    相關標籤/搜索