UBOOT-2010-03在S3C2440上的移植<三>------------自动识别启动模式Nand Or Nor

四、自动识别启动模式Nand Or Nor

Notes:1)上文连接

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

Notes:2)下面代码段红色部分为删除部分

Notes:3)下面代码段绿色部分为添加部分

4.1)Notes:以下资源来自大神Tekkaman Ninja博客点击查看原文

移植之前还是请大家先看S3C2440数据手册<第五章 存储器控制器>中的<Figure 5-1. S3C2440A Memory Map after Reset>(也就是那个映射图),从理论上来讲,对于0x40000000以后的内存,只有在Nor boot的时候才存在;而在nand

boot 的时候他被映射到了0x00000000,在 0x40000000以后不存在内存 。如果我们在启动的时候,将一些特定的数据写入0x40000000~0x40001000之间,那么按照数据手册上的说法,如果回读的结果和写入的一致说明是nor boot,否则就是nand boot! <写这个文章的时候我又看了一次。。。。。。。。。>

从上图我们可以看出,无论是Nor boot还是nand boot ,这4K的内部SRAM都被映射到了0x40000000,而在nand boot的时候,这块内存同时还被映射到了0x00000000那么一开始提出的办法就不可行了,而且在nand boot 的时候写入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程序是否一致,如果不一致会进入死循环。

/**************好了看完这一对白虽然明白了很多但是跟随着的问题也多了很多,我就在想.balignl 16,0xdeadbeef 这个东东究竟是起到什么作用的,你又怎么知道它的位置就是固定的而且又是0x0000003c(0x4000003c)呢?为此我纠结了好久还好通过一番纠结我终于找到了答案<这得感谢我哥:baiu and google>1)点击查看答案and2)点击查看答案 那么接下来是时候动手代码的移植了

4.1.1)打开之前我们修改的那个start.S文件 第90行左右添加一个Flash启动标志

/************************标志位从Nand启动时将其设置为0,从Nor启动时将其设置为1*****/
.globl bBootFrmNORFlash
bBootFrmNORFlash:
 .word 0

4.1.2)判断当前代码位置,如果在内存,直接跳到stack_setup 

 /*
     * we do sys-critical inits only at reboot,
     * not when booting from ram!
     */
#ifndef CONFIG_SKIP_LOWLEVEL_INIT
    bl    cpu_init_crit
#endif  /***找到这段代码在下面添加:***/

/***************** CHECK_CODE_POSITION ******************************************/
    adr    r0, _start        /* r0 <- current position of code   */
    ldr    r1, _TEXT_BASE        /* test if we run from flash or RAM */
    cmp    r0, r1            /* don't reloc during debug         */
    beq    stack_setup
/***************** CHECK_CODE_POSITION ******************************************/

4.1.3)如果代码当前位置不在内存中,就判断启动方式为Nand Flash或者Nor Flash 

Notes:没有说明就默认在以上代码的后面添加

/***************** CHECK_BOOT_FLASH ******************************************/
    ldr    r1, =( (4<<28)|(3<<4)|(3<<2) )        /* address of Internal SRAM  0x4000003C*/
    mov    r0, #0        /* r0 = 0 */
    str    r0, [r1]


    mov    r1, #0x3c        /* address of men  0x0000003C*/
    ldr    r0, [r1]
    cmp    r0, #0
    bne    relocate

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

4.1.4)在Nand Flash中启动的话,那么Nand Flash搬移代码如下:

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

/***************** NAND_BOOT *************************************************/

#define LENGTH_UBOOT 0x100000
#define NAND_CTL_BASE 0x4E000000

#ifdef CONFIG_S3C2440
/* Offset */
#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
/***************** NAND_BOOT *************************************************/
 

4.1.5)在Nor Flash中启动的话,那么Nor Flash搬移代码如下:

/***************** NOR_BOOT *************************************************/
relocate:                /* relocate U-Boot to RAM        */      
      /*********** CHECK_FOR_MAGIC_NUMBER***************/
    ldr    r1, =(0xdeadbeef)
    cmp    r0, r1
    bne    loop3
      /*********** CHECK_FOR_MAGIC_NUMBER***************/
    adr    r0, _start        /* r0 <- current position of code   */
    ldr    r1, _TEXT_BASE        /* test if we run from flash or RAM */
    ldr    r2, _armboot_start
    ldr    r3, _bss_start
    sub    r2, r3, r2        /* r2 <- size of armboot            */
    add    r2, r0, r2        /* r2 <- source end address         */

copy_loop:
    ldmia    r0!, {r3-r10}        /* copy from source address [r0]    */
    stmia    r1!, {r3-r10}        /* copy to   target address [r1]    */
    cmp    r0, r2            /* until source end addreee [r2]    */
    ble    copy_loop

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

4.1.6)删除下面这段代码

//#ifndef CONFIG_SKIP_RELOCATE_UBOOT
//relocate:                /* relocate U-Boot to RAM        */
//    adr    r0, _start        /* r0 <- current position of code   */
//    ldr    r1, _TEXT_BASE        /* test if we run from flash or RAM */
//    cmp    r0, r1            /* don't reloc during debug         */
//    beq    stack_setup

//    ldr    r2, _armboot_start
//    ldr    r3, _bss_start
//    sub    r2, r3, r2        /* r2 <- size of armboot            */
//    add    r2, r0, r2        /* r2 <- source end address         */

//copy_loop:
//    ldmia    r0!, {r3-r10}        /* copy from source address [r0]    */
//    stmia    r1!, {r3-r10}        /* copy to   target address [r1]    */
//    cmp    r0, r2            /* until source end addreee [r2]    */
//    ble    copy_loop
//#endif    /* CONFIG_SKIP_RELOCATE_UBOOT */

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

/**********************************到此完了。。。。********/

Notes:该文档下载链接:点击下载该文档

Notes1):如果你不是第一次移植UBOOT那么建议好好的理解一下上面这些代码<当然加入你还是第一次的话那么好了直接COPY吧很管用的>

Notes2):上面用到了一个nand_read_ll函数,该函数用来读NANDFLASH的<下一篇就是实现这个UBOOT对NAND的支持了先休息一下吧>

下文接

UBOOT-2010-03在S3C2440上的移植<四>------------支持NANDFLASH


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值