关于OK6410的NandFlash启动的一些事实

起因

在学习OK6410附赠的源代码uboot1.1.6-V5.50-2014-09-19中,发现从nandflash拷贝代码到ram时,以下代码不明白(看中文注释):

/*
 * uboot1.1.6\cpu\s3c64xx\nand_cp.c
 * Read data from NAND.
 */
static int nandll_read_blocks (ulong dst_addr, ulong size, int large_block)
{
    uchar *buf = (uchar *)dst_addr;
    int i;
    uint page_shift = 9;

    if (large_block==1)
        page_shift = 11;

    if(large_block==2)
        page_shift = 12;

    if(large_block==3)
        page_shift =13;

    if(large_block == 2)
    {
        /* Read pages */
        /* buf+=(1<<(page_shift-1))这里为什么要1左移11位呢? */
        /* 那岂不是前4页复制的代码会重叠 */
        for (i = 0; i < 4; i++, buf+=(1<<(page_shift-1))) {
            nandll_read_page(buf, i, large_block);
        }


        /* Read pages */
        /* 还有为什么要分开读取呢?先读前4页,其他正常4K读取? */
        for (i = 4; i < (0x3c000>>page_shift); i++, buf+=(1<<page_shift)) {
            nandll_read_page(buf, i, large_block);
        }

    }else if(large_block == 3)  //K9GAG08U0E
    {
        /* Read pages */
        for (i = 0; i < 4; i++, buf+=(1<<(page_shift-2))) {
            nandll_read_page(buf, i, large_block);
        }


        /* Read pages */
        for (i = 4; i < (0x3c000>>page_shift); i++, buf+=(1<<page_shift)) {
            nandll_read_page(buf, i, large_block);
        }
    }
    else
    {
        for (i = 0; i < (0x3c000>>page_shift); i++, buf+=(1<<page_shift)) {
            nandll_read_page(buf, i, large_block);
        }
    }
    return 0;
}

 经过

经过一天的试错和百度,终于弄懂其中微妙之处了。

首先,谢谢这位朋友的博文。我从中知道了nandflash启动的一个秘密。

既然知道这个秘密,但又没有找到相关的文档说明。所以决定证实一下这位朋友的说法。

首先我的代码流程是这样的:

测试代码如下:

/* 以下代码将在内存中运行 */
void DRAM_Main(void){
    u_int32* ptr_ram1 = (u_int32 *)(0x50000000 + 4096);
    u_int32* ptr_ram2 = (u_int32 *)(0x50000000 + 2 * 4096);
    u_int32* ptr_ram3 = (u_int32 *)(0x50000000 + 3 * 4096);
    u_int32* ptr_ram4 = (u_int32 *)(0x50000000 + 4 * 4096);
    temp(*ptr_ram1);
    temp(*ptr_ram2);
    temp(*ptr_ram3);
    temp(*ptr_ram4);

    LED_on(LED2);                               /* 测试点:3, 点亮LED2 */

    /* mprintf("This is in DRAM!!"); */
    for(;;){

    }
}

 因为我是把nandflash中的0块,整个拷贝到内存了,所以通过指针,分别指向内存中的4K、8K、12K、16K的位置。相当于读取nandflash中的1页、2页、3页、4页(页地址从0开始)开头的4字节数据。读出的数据如下:

然后,查看二进制文件:

扫描二维码关注公众号,回复: 9066451 查看本文章

这是映像文件中的2K位置,和读出来的一样

这是映像文件中4K位置的数据,一样的

这是映像文件6K的位置,一样的

8K的位置,还是和串口输出的一样的 

结果 

从这里就可以证明,从nandflash启动时,BL0是将nandflash的块0的前4页中,每页头2K组合成8K,拷贝到steppingstone中的。BL0是厂家固化好的代码,我们改不了。如果我们要自己一些启动代码就需要这点。无论是写入,还是读取这8K的启动代码,也要遵循这样的约定。

现在回过头来看uboot的代码,终于明白为什么要buf+=(1<<(page_shift-1))了。

这也是为什么要先读取前4页,然后正常读取后面的页的原因。 

发布了27 篇原创文章 · 获赞 18 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/drsonxu/article/details/104251279