主题 : 分析一下tiny210v2的16bitECC校验(已经实现u-boot for tiny210v2) 复制链接 | 浏览器收藏 | 打印
:)
级别: 骑士
UID: 61588
精华: 5
发帖: 248
金钱: 1500 两
威望: 300 点
贡献值: 5 点
综合积分: 596 分
注册时间: 2012-01-02
最后登录: 2018-03-05
楼主  发表于: 2013-06-05 17:13

 分析一下tiny210v2的16bitECC校验(已经实现u-boot for tiny210v2)

管理提醒: 本帖被 xoom 执行加亮操作(2013-06-05)
提供了:u-boot for tiny210v2 ,源代码回复可见。
本部分内容设定了隐藏,需要回复后才能看到


开发板:tiny210v2
NandFlash:K9GAG08U0F
网上的针对这个板子的u-boot大多都不太好用,很多都是启动的时候从NandFlash往DRAM中拷贝没有进行ECC校验,导致只能启动不完整。
就决定自己做BL1代码,初始化DRAM了什么的都可以从u-boot中提取,没有什么区别。
BL1有代码主要是实现ECC16bit校验,具体用的什么算法,我到目前还不清楚,但是我已经实现了Main区的校验。因为S5PV210的手册上都是傻瓜式的,按照它的做就完全可以实现校验。主要说明步骤在这里:


数据手册转换为代码:


  
测试方法是制作一个里边全是‘A’的bin文件,贴到上边的代码的后边。这个用MiniTools+SuperBoot以下载bootloader的方法下载此程序的时候,这个bin文件会被下载到第4页的地方,然后我的程序从第4页开始拷贝,拷贝到内存中并打印出来。
这中间的拷贝就用了16bit,ECC校验的方式进行读取的。从下图的第4页的OOB区的内容可以推测出来,SuperBoot是怎么放置这些校验码的:


根据这些校验码的位置,和上边三星提供的步骤,得出了上边的代码。

下面实例分析一下出现一位翻转的情况:




  

Main区的修改函数是按照三星提供的第4步进行写的:
/*
* 修复Main区的反转位
*
*/
int fixEcc(uchar* buf, int num, int flag)
{
    uint subst[16];
    uchar pattern[16];
    int i = 0;

    // 数组赋值为0
    for(i=0; i<16; i++)
    {
        subst=pattern=0;
    }
#if 1
    subst[0] = (NFECCERL0_REG>>0) & 0x1ff;
    pattern[0] = (NFECCERP0_REG>>0) & 0xff;

    subst[1] = (NFECCERL0_REG>>16) & 0x1ff;
    pattern[1] = (NFECCERP0_REG>>8) & 0xff;

    subst[2] = (NFECCERL1_REG>>0) & 0x1ff;
    pattern[2] = (NFECCERP0_REG>>16) & 0xff;

    subst[3] = (NFECCERL1_REG>>16) & 0x1ff;
    pattern[3] = (NFECCERP0_REG>>24) & 0xff;

    subst[4] = (NFECCERL2_REG>>0) & 0x1ff;
    pattern[4] = (NFECCERP1_REG>>0) & 0xff;

    subst[5] = (NFECCERL2_REG>>16) & 0x1ff;
    pattern[5] = (NFECCERP1_REG>>8) & 0xff;

    subst[6] = (NFECCERL3_REG>>0) & 0x1ff;
    pattern[6] = (NFECCERP1_REG>>16) & 0xff;

    subst[7] = (NFECCERL3_REG>>16) & 0x1ff;
    pattern[7] = (NFECCERP1_REG>>24) & 0xff;

    subst[8] = (NFECCERL4_REG>>0) & 0x1ff;
    pattern[8] = (NFECCERP2_REG>>0) & 0xff;

    subst[9] = (NFECCERL4_REG>>16) & 0x1ff;
    pattern[9] = (NFECCERP2_REG>>8) & 0xff;

    subst[10] = (NFECCERL5_REG>>0) & 0x1ff;
    pattern[10] = (NFECCERP2_REG>>16) & 0xff;

    subst[11] = (NFECCERL5_REG>>16) & 0x1ff;
    pattern[11] = (NFECCERP2_REG>>24) & 0xff;

    subst[12] = (NFECCERL6_REG>>0) & 0x1ff;
    pattern[12] = (NFECCERP3_REG>>0) & 0xff;

    subst[13] = (NFECCERL6_REG>>16) & 0x1ff;
    pattern[13] = (NFECCERP3_REG>>8) & 0xff;

    subst[14] = (NFECCERL7_REG>>0) & 0x1ff;
    pattern[14] = (NFECCERP3_REG>>16) & 0xff;

    subst[15] = (NFECCERL7_REG>>16) & 0x1ff;
    pattern[15] = (NFECCERP3_REG>>24) & 0xff;

#endif
    if(flag)
    {    
        for(i=0; i<512; i++)
        {
            puthex(buf);
            putc(' ');
        }
    }
    putc('\n');putc('\r');

    for(i=0; i<num; i++)
    {
        buf[subst] ^= pattern;
//        printf("%02X\t", buf[subst]);
        if(flag)
        {    
            put32bits(subst);putc(' ');puthex(pattern);
            putc('\n');putc('\r');
        }
    }
    
    if(flag)
    {    
        for(i=0; i<512; i++)
        {
            puthex(buf);
            putc(' ');
        }
    }
    putc('\n');putc('\r');
    return 0;
}

其实到这里已经完整的实现了Main区的16bit的ECC校验,但是还有一个问题是校验码也是从NandFlash中读取的,校验码也会发生翻转,这就需要进行数据手册上的第6步检验SPACE区的ECC
下边给一下ECC码也发生的翻转的实例:



同样是全是‘A’,这个校验码读错了,造成原来对的就会改成了错误的(高亮那Byte正确的应该是‘03’)。
(可以看到它把原来的第6Byte的‘AA’,根据错误的校验码改成了‘BA’)  
[ 此帖被kangear在2013-06-27 17:17重新编辑 ]
级别: 新手上路
UID: 125674
精华: 0
发帖: 10
金钱: 50 两
威望: 10 点
贡献值: 0 点
综合积分: 20 分
注册时间: 2016-06-01
最后登录: 2023-11-12
1楼  发表于: 2019-07-09 01:06
学习学习吧