新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > 自動識別啟動模式Nand Or Nor

        自動識別啟動模式Nand Or Nor

        作者: 時間:2016-11-22 來源:網絡 收藏

        UBOOT-2010-03在S3C2440上的移植<二>------------硬件初始化

        http://www.linuxidc.com/Linux/2011-11/46993p2.htm

        Notes:2)下面代碼段紅色部分為刪除部分

        本文引用地址:http://www.104case.com/article/201611/319957.htm

        Notes:3)下面代碼段綠色部分為添加部分

        4.1)Notes:以下資源來自大神Tekkaman Ninja博客點擊查看原文

        移植之前還是請大家先看S3C2440數據手冊<第五章存儲器控制器>中的(也就是那個映射圖),從理論上來講,對于0x40000000以后的內存,只有在Nor boot的時候才存在;而在nand

        boot 的時候他被映射到了0x00000000,在0x40000000以后不存在內存。如果我們在啟動的時候,將一些特定的數據寫入0x40000000~0x40001000之間,那么按照數據手冊上的說法,如果回讀的結果和寫入的一致說明是nor boot,否則就是nand boot!<寫這個文章的時候我又看了一次。。。。。。。。。>

        從上圖我們可以看出,無論是Nor boot還是nandboot ,這4K的內部SRAM都被映射到了0x40000000,而在nandboot的時候,這塊內存同時還被映射到了0x00000000。那么一開始提出的辦法就不可行了,而且在nandboot 的時候,寫入0x40000000~0x40001000還會破壞自身的程序。

        但是通過上面的圖,我想到了解決的辦法:
        在啟動的時候,用程序將0x40000000~0x40001000中的某些位置清零,如果回讀0x00000000~0x00001000中的相應位置后為零,說明是Nand boot,如果是原來的數據(一定要選非零的位置)就是Nor boot。判斷完后如果是nand boot,還要恢復被改動的數據,再進入自拷貝階段。
        只要檢測的位置合理,這方法是可行的。現在的關鍵是選什么位置的數據最好呢?經過查看源碼,我選擇了在start.S文件開頭,全局中斷向量之后的:


        .balignl 16,0xdeadbeef


        選這個數據作為檢測位置的理由如下:
        (1)他是非零數,而且數據是確定的:0xdeadbeef;
        (2)他的位置是固定的:0x0000003c(0x4000003c);
        (3)他在檢測程序之前,不會影響程序的向下運行;
        (4)他不屬于程序,他是一個程序中的魔數(Magic Number),用魔數來檢測也比較合理。

        所以我最后的檢測步驟是:
        在啟動的時候,將0x4000003c位置開始的四個字節清零,然后讀取0x0000003c位置開始的四個字節。如果回讀的結果為零,說明是nand boot,否則就是Nor boot(為了保險還可以判斷是否為0xdeadbeef,不是的話就說明有未知錯誤,死循環!)。但是最后有一點很重要:如果是Nand boot,必須要復原清零的數據。原因是:在nand boot過后,會核對內部SRAM中的4K程序,和從Nand中拷貝到SDRAM的前4K程序是否一致,如果不一致會進入死循環。


        .globl bBootFrmNORFlash
        bBootFrmNORFlash:
        .word 0
        4.1.2)判斷當前代碼位置,如果在內存,直接跳到stack_setup


        #ifndef CONFIG_SKIP_LOWLEVEL_INIT
        bl cpu_init_crit
        #endif


        adr r0, _start
        ldr r1, _TEXT_BASE
        cmp r0, r1
        beq stack_setup

        4.1.3)如果代碼當前位置不在內存中,就判斷啟動方式為Nand Flash或者Nor Flash

        Notes:沒有說明就默認在以上代碼的后面添加


        ldr r1, =( (4<<28)|(3<<4)|(3<<2) )
        mov r0, #0
        str r0, [r1]


        mov r1, #0x3c
        ldr r0, [r1]
        cmp r0, #0
        bne relocate


        ldr r0, =(0xdeadbeef)
        ldr r1, =( (4<<28)|(3<<4)|(3<<2) )
        str r0, [r1]

        4.1.4)在Nand Flash中啟動的話,那么Nand Flash搬移代碼如下:

        Notes:定義u-boot在Nand flash中存放的長度為#define LENGTH_UBOOT 0x100000<1M>,可以方便修改u-boot因為裁剪和增添大小的改變而占的長度。



        #define LENGTH_UBOOT 0x100000
        #define NAND_CTL_BASE 0x4E000000

        #ifdef CONFIG_S3C2440

        #define oNFCONF 0x00
        #define oNFCONT 0x04
        #define oNFCMD 0x08
        #define oNFSTAT 0x20

        @ reset NAND
        mov r1, #NAND_CTL_BASE
        ldr r2, =( (7<<12)|(7<<8)|(7<<4)|(0<<0) )
        str r2, [r1, #oNFCONF]
        ldr r2, [r1, #oNFCONF]

        ldr r2, =( (1<<4)|(0<<1)|(1<<0) ) @ Active low CE Control
        str r2, [r1, #oNFCONT]
        ldr r2, [r1, #oNFCONT]

        ldr r2, =(0x6) @ RnB Clear
        str r2, [r1, #oNFSTAT]
        ldr r2, [r1, #oNFSTAT]

        mov r2, #0xff @ RESET command
        strb r2, [r1, #oNFCMD]

        mov r3, #0 @ wait
        nand1:
        add r3, r3, #0x1
        cmp r3, #0xa
        blt nand1

        nand2:
        ldr r2, [r1, #oNFSTAT] @ wait ready
        tst r2, #0x4
        beq nand2


        ldr r2, [r1, #oNFCONT]
        orr r2, r2, #0x2 @ Flash Memory Chip Disable
        str r2, [r1, #oNFCONT]

        @ 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 U-Boot to RAM
        ldr r0, =TEXT_BASE
        mov r1, #0x0
        mov r2, #LENGTH_UBOOT
        bl nand_read_ll
        tst r0, #0x0
        beq ok_nand_read

        bad_nand_read:
        loop2:
        b loop2 @ infinite loop
        ok_nand_read:
        @ verify
        mov r0, #0
        ldr r1, =TEXT_BASE
        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 stack_setup
        bne go_next

        notmatch:
        loop3:
        b loop3 @ infinite loop
        #endif

        4.1.5)在Nor Flash中啟動的話,那么Nor Flash搬移代碼如下:


        relocate:

        ldr r1, =(0xdeadbeef)
        cmp r0, r1
        bne loop3

        adr r0, _start
        ldr r1, _TEXT_BASE
        ldr r2, _armboot_start
        ldr r3, _bss_start
        sub r2, r3, r2
        add r2, r0, r2

        copy_loop:
        ldmia r0!, {r3-r10}
        stmia r1!, {r3-r10}
        cmp r0, r2
        ble copy_loop

        SetBootFlag:
        ldr r0, =bBootFrmNORFlash
        mov r1, #1
        str r1, [r0]

        4.1.6)刪除下面這段代碼

        //#ifndef CONFIG_SKIP_RELOCATE_UBOOT
        //relocate:
        // adr r0, _start
        // ldr r1, _TEXT_BASE
        // cmp r0, r1
        // beq stack_setup

        // ldr r2, _armboot_start
        // ldr r3, _bss_start
        // sub r2, r3, r2
        // add r2, r0, r2

        //copy_loop:
        // ldmia r0!, {r3-r10}
        // stmia r1!, {r3-r10}
        // cmp r0, r2
        // ble copy_loop
        //#endif

        4.2.1)在_start_armboot: .word start_armboot 后面添加:

        #define STACK_BASE 0x33f00000
        #define STACK_SIZE 0x10000
        .align 2
        DW_STACK_START: .word STACK_BASE+STACK_SIZE-4

        Notes1):如果你不是第一次移植UBOOT那么建議好好的理解一下上面這些代碼<當然加入你還是第一次的話那么好了直接COPY吧很管用的>

        Notes2):上面用到了一個nand_read_ll函數,該函數用來讀NANDFLASH的<下一篇就是實現這個UBOOT對NAND的支持了先休息一下吧>



        評論


        技術專區

        關閉
        主站蜘蛛池模板: 武陟县| 禹州市| 湖南省| 行唐县| 河南省| 固原市| 灵石县| 吉首市| 兴海县| 上虞市| 郎溪县| 华容县| 康乐县| 金昌市| 凭祥市| 黑水县| 新宁县| 信丰县| 泽州县| 手机| 原平市| 大化| 漯河市| 兴隆县| 安多县| 宜川县| 五常市| 两当县| 夏津县| 镇坪县| 巴彦淖尔市| 余江县| 吴堡县| 崇文区| 仪陇县| 通渭县| 哈巴河县| 太仆寺旗| 沂源县| 茶陵县| 乐昌市|