主题 : 关于uboot和友善Linux2.6.38 硬件ECC 问题 复制链接 | 浏览器收藏 | 打印
级别: 侠客
UID: 41214
精华: 0
发帖: 88
金钱: 450 两
威望: 90 点
贡献值: 0 点
综合积分: 176 分
注册时间: 2011-03-27
最后登录: 2018-05-24
楼主  发表于: 2012-08-08 14:52

 关于uboot和友善Linux2.6.38 硬件ECC 问题

        本人以tekkamanninja的uboot 和友善之臂的u-boot 为基本在uboot201207的基础上,完成了tekkamanninja的uboot  和友善之臂的u-boot的基本功能。在Kasim的指导下,本想做完uboot烧写大容量yaffs2文件后就开源整个uboot。 不想在这里遇到了问题,一连好几天都没有得到解决,关于uboot中ECC修改思路:
    
    1: 友善之臂的Linux2.6.38 的硬件检测有两部分,一部分是主扇区的的数据ECC,还有一部分是备用扇区的数据ECC. 两部分数据任何一部分出错都会在内核启动的时候出现ecc检查错误。当然这个结论是我测试得出来的。
    
    2: uboot中对于nand flash的硬件ECC只有主数据部分的ECC,并无备用数据部分。所以需要对uboot中进行修改。

    3: 使用友善之辈的u-boot里面提供的nand_write_opts写yaffs 数据是不可行的。 友善之臂的方法是修改nand flash的ecclayout结构体来修改yaffs2备用数据存储时候的偏移量,而友善之辈的u-boot使用的ecclayout可以看出是完全不对。 这个可以从友善之臂superboot烧写镜像后读取数据内容,查看后可以得到,其实友善那样烧写数据是不对的。所以不采用友善之辈提供的nand_write_opts进行烧写。
    
    针对以上进行uboot进行修改。

    针对以上修改如下:
1:  ECC增加备用数据部分,程序如下


static void nand_write_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
                  const uint8_t *buf)
{
    int i, eccsize = chip->ecc.size;
    int eccbytes = chip->ecc.bytes;
    int eccsteps = chip->ecc.steps;
    uint8_t *ecc_calc = chip->buffers->ecccalc;
    const uint8_t *p = buf;
    uint32_t *eccpos = chip->ecc.layout->eccpos;
    int secc_start = mtd->oobsize - eccbytes;
    
    for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
        chip->ecc.hwctl(mtd, NAND_ECC_WRITE);
        chip->write_buf(mtd, p, eccsize);
        chip->ecc.calculate(mtd, p, &ecc_calc);
    }

    for (i = 0; i < chip->ecc.total; i++)
        chip->oob_poi[eccpos] = ecc_calc;

    /* spare area */
    chip->ecc.hwctl(mtd, NAND_ECC_WRITE);
    chip->write_buf(mtd, chip->oob_poi, secc_start);
    chip->ecc.calculate(mtd, p, &ecc_calc[chip->ecc.total]);

    for (i = 0; i < eccbytes; i++)
        chip->oob_poi[secc_start + i] = ecc_calc[chip->ecc.total + i];

    chip->write_buf(mtd, chip->oob_poi + secc_start, eccbytes);

}
  
   为了方便,ecc底层调用函数为:
static void s3c_nand_enable_hwecc(struct mtd_info *mtd, int mode)
{
    u_long nfcont, nfconf;

    nfconf = readl(NFCONF);
    nfconf &= ~(0x3 << 23);
    nfconf |= NFCONF_ECC_1BIT;
    writel(nfconf, NFCONF);

    /* Initialize & unlock */
    nfcont = readl(NFCONT);
    nfcont |= NFCONT_INITECC;
    nfcont &= ~NFCONT_MECCLOCK;

    if (mode == NAND_ECC_WRITE)
        nfcont |= NFCONT_ECC_ENC;
    else if (mode == NAND_ECC_READ)
        nfcont &= ~NFCONT_ECC_ENC;

    writel(nfcont, NFCONT);
}
    
static int s3c_nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat,
                  u_char *ecc_code)
{
    u_long nfcont, nfmecc0;

    nfcont = readl(NFCONT);
    nfcont |= NFCONT_MECCLOCK;
    writel(nfcont, NFCONT);

    nfmecc0 = readl(NFMECC0);

    ecc_code[0] = nfmecc0 & 0xff;
    ecc_code[1] = (nfmecc0 >> 8) & 0xff;
    ecc_code[2] = (nfmecc0 >> 16) & 0xff;
    ecc_code[3] = (nfmecc0 >> 24) & 0xff;

    return 0;
}


修改完后,下载友善提供的rootfs_qtopia_qt4.img的镜像,以下是错误信息,前面的信息我就不贴出来了....
ALSA device list:
  #0: MINI6410
TCP cubic registered
NET: Registered protocol family 17
VFP support v0.3: implementor 41 architecture 1 part 20 variant b rev 5
s3c-rtc s3c64xx-rtc: setting system clock to 2000-08-25 00:10:15 UTC (967162215)
Freeing init memory: 1412K
FAT: utf8 is not a recommended IO charset for FAT filesystems, filesystem will be case sensitive!
FAT: utf8 is not a recommended IO charset for FAT filesystems, filesystem will be case sensitive!
yaffs: dev is 32505858 name is "mtdblock2" rw
yaffs: passed flags ""
s3c-nand: 1 bit error detected at byte 136, correcting from 0x00 to 0x01...OK
s3c-nand: 1 bit error detected at byte 176, correcting from 0x00 to 0x04...OK
s3c-nand: 1 bit error detected at byte 57, correcting from 0x00 to 0x04...OK
s3c-nand: 1 bit error detected at byte 56, correcting from 0x11 to 0x01...OK
s3c-nand: 1 bit error detected at byte 404, correcting from 0xb8 one_wire_status: 2
to 0xb9...OK
s3c-nand: 1 bit error detected at byte 405, correcting from 0xc3 to 0x83...OK
s3c-nand: 1 bit error detected at byte 1602, correcting from 0x60 to 0x70...OK
s3c-nand: 1 bit error detected at byte 205, correcting from 0x00 one_wire_status: 4
to 0x10...OK
s3c-nand: 1 bit error detected at byte 1701, correcting from 0x6b to 0x7b...OK
s3c-nand: 1 bit error detected at byte 98, correcting from 0x73 to 0x77...OK
one_wire_status: 4
s3c-nand: 1 bit error detected at byte 430, correcting from 0x00 to 0x04...OK
s3c-nand: 1 bit error detected at byte 416, correcting from 0x72 to 0x62...OK
s3c-nand: 1 bit error detected at byte 343, correcting from 0x00 one_wire_status: 5
to 0x02...OK
s3c-nand: 1 bit error detected at byte 93, correcting from 0x90 to 0x94...OK
s3c-nand: 1 bit error detected at byte 349, correcting from 0x93 to 0x97...OK
s3c-nand: 1 bit error detected at byte 29, correcting from 0x94 to 0xd4...OK
s3c-nand: 1 bit error detected at byte 272, correcting from 0x01 to 0x03...OK
s3c-nand: 1 bit error detected at byte 69, correcting from 0x00 to 0x01...OK
s3c-nand: 1 bit error detected at byte 155, correcting from 0x61 one_wire_status: 2
to 0x69...OK
s3c-nand: 1 bit error detected at byte 462, correcting from 0x00 to 0x04...OK
s3c-nand: 1 bit error detected at byte 179, correcting from 0xe5 to 0xa5...OK
one_wire_status: 4
s3c-nand: 1 bit error detected at byte 197, correcting from 0xe0 to 0xf0...OK
s3c-nand: 1 bit error detected at byte 461, correcting from 0x10 to 0x90...OK
s3c-nand: 1 bit error detected at byte 320, correcting from 0xe4 one_wire_status: 4
to 0xe6...OK
s3c-nand: 1 bit error detected at byte 1408, correcting from 0xfd to 0xf5...OK
s3c-nand: 1 bit error detected at byte 70, correcting from 0x00 to 0x10...OK
s3c-nand: 1 bit error detected at byte 1340, correcting from 0xf6 to 0xf4...OK
s3c-nand: 1 bit error detected at byte 16, correcting from 0x27 to 0x67...OK
s3c-nand: 1 bit error detected at byte 1815, correcting from 0xdd to 0xdf...OK
s3c-nand: 1 bit error detected at byte 341, correcting from 0x46 one_wire_status: 2
to 0x44...OK
s3c-nand: 1 bit error detected at byte 517, correcting from 0x89 to 0x88...OK
s3c-nand: 1 bit error detected at byte 96, correcting from 0x00 one_wire_status: 4
to 0x02...OK
s3c-nand: 1 bit error detected at byte 499, correcting from 0x15 to 0x1d...OK
s3c-nand: 1 bit error detected at byte 441, correcting from 0x0d to 0x05...OK
s3c-nand: 1 bit error detected at byte 45, correcting from 0x5e to 0x5c...OK
s3c-nand: 1 bit error detected at byte 54, correcting from 0xb2 to 0xf2...OK
s3c-nand: 1 bit error detected at byte 855, correcting from 0x70 to 0x30...OK
s3c-nand: 1 bit error detected at byte 284, correcting from 0x25 one_wire_status: 2
to 0x2d...OK
s3c-nand: 1 bit error detected at byte 406, correcting from 0x73 to 0x77...OK
s3c-nand: 1 bit error detected at byte 202, correcting from 0x6d to 0xed...OK
s3c-nand: 1 bit error detected at byte 294, correcting from 0x6f one_wire_status: 4
to 0x6e...OK
s3c-nand: 1 bit error detected at byte 122, correcting from 0x61 to 0x41...OK
s3c-nand: 1 bit error detected at byte 439, correcting from 0x64 one_wire_status: 4
to 0xe4...OK
s3c-nand: 1 bit error detected at byte 283, correcting from 0x54 to 0x5c...OK
s3c-nand: 1 bit error detected at byte 76, correcting from 0x48 to 0x08...OK
s3c-nand: 1 bit error detected at byte 208, correcting from 0x68 one_wire_status: 5
to 0x78...OK
s3c-nand: 1 bit error detected at byte 326, correcting from 0x64 to 0x74...OK
s3c-nand: 1 bit error detected at byte 474, correcting from 0x6c to 0x2c...OK
s3c-nand: 1 bit error detected at byte 1888, correcting from 0x74 to 0xf4...OK
s3c-nand: 1 bit error detected at byte 414, correcting from 0x41 to 0x45...OK
s3c-nand: 1 bit error detected at byte 220, correcting from 0x4e to 0x0e...OK
one_wire_status: 2
s3c-nand: 1 bit error detected at byte 158, correcting from 0x66 to 0x62...OK
s3c-nand: 1 bit error detected at byte 44, correcting from 0x65 to 0x67...OK
s3c-nand: 1 bit error detected at byte 55, correcting from 0x74 one_wire_status: 4
to 0x54...OK
s3c-nand: 1 bit error detected at byte 80, correcting from 0x00 to 0x01...OK
s3c-nand: 1 bit error detected at byte 439, correcting from 0x66 to 0x26...OK
s3c-nand: 1 bit error detected at byte 388, correcting from 0x67 one_wire_status: 4
to 0x66...OK
s3c-nand: 1 bit error detected at byte 234, correcting from 0x6c to 0x2c...OK
s3c-nand: 1 bit error detected at byte 430, correcting from 0x76 to 0x74...OK
s3c-nand: 1 bit error detected at byte 51, correcting from 0x6d to 0x7d...OK
s3c-nand: 1 bit error detected at byte 1384, correcting from 0xdb to 0x9b...OK
s3c-nand: 1 bit error detected at byte 452, correcting from 0x61 to 0x41...OK
one_wire_status: 2
s3c-nand: 1 bit error detected at byte 364, correcting from 0x6c to 0x68...OK
s3c-nand: 1 bit error detected at byte 298, correcting from 0x6e to 0x2e...OK
s3c-nand: 1 bit error detected at byte 73, correcting from 0x65 one_wire_status: 4
to 0x45...OK
s3c-nand: 1 bit error detected at byte 15, correcting from 0x0e t133, correcting from 0x6e to 0xee...OK
s3c-nand: 1 bit error detected at byte 435, correcting from 0x69 to 0x29...OK
s3c-nand: 1 bit error detected at byte 360, correcting from 0x25 to 0x27...OK
s3c-nand: 1 bit error detected at byte 94, correcting from 0x00 one_wire_status: 2
to 0x01...OK
s3c-nand: 1 bit error detected at byte 404, correcting from 0x65 to 0x25...OK
s3c-nand: 1 bit error detected at byte 446, correcting from 0x72 to 0xf2...OK
s3c-nand: 1 bit error detected at byte 138, correcting from 0x64 one_wire_status: 4
to 0x6c...OK
s3c-nand: 1 bit error detected at byte 149, correcting from 0x75 to 0x7d...OK
s3c-nand: 1 bit error detected at byte 299, correcting from 0x62 to 0x42...OK
one_wire_status: 4
s3c-nand: 1 bit error detected at byte 20, correcting from 0x00 to 0x80...OK
s3c-nand: 1 bit error detected at byte 1726, correcting from 0xfe to 0xff...OK
s3c-nand: 1 bit error detected at byte 366, correcting from 0x64 one_wire_status: 4
to 0x6c...OK
s3c-nand: 1 bit error detected at byte 1680, correcting from 0xf5 to 0xe5...OK
s3c-nand: 1 bit error detected at byte 491, correcting from 0x66 to 0x6e...OK
s3c-nand: 1 bit error detected at byte 1639, correcting from 0xfc to 0xbc...OK
s3c-nand: 1 bit error detected at byte 481, correcting from 0x73 to 0x7b...OK
s3c-nand: 1 bit error detected at byte 575, correcting from 0xfb to 0xbb...OK
s3c-nand: 1 bit error detected at byte 63, correcting from 0x80 one_wire_status: 2
to 0xc0...OK
s3c-nand: 1 bit error detected at byte 1906, correcting from 0xff to 0xfe...OK
s3c-nand: 1 bit error detected at byte 361, correcting from 0x68 one_wire_status: 4
to 0x69...OK
s3c-nand: 1 bit error detected at byte 474, correcting from 0x00 to 0x40...OK
s3c-nand: 1 bit error detected at byte 111, correcting from 0xff to 0xfe...OK
s3c-nand: 1 bit error detected at byte 7, correcting from 0xe2 one_wire_status: 4
to 0xa2...OK
s3c-nand: 1 bit error detected at byte 497, correcting from 0x02 to 0x12...OK
s3c-nand: 1 bit error detected at byte 357, correcting from 0xff to 0xbf...OK
s3c-nand: 1 bit error detected at byte 208, correcting from 0x00 to 0x10...OK
s3c-nand: 1 bit error detected at byte 10, correcting from 0xa0 to 0xe0...OK
s3c-nand: 1 bit error detected at byte 53, correcting from 0x00 to 0x10...OK
one_wire_status: 2
s3c-nand: 1 bit error detected at byte 434, correcting from 0x86 to 0xa6...OK
s3c-nand: 1 bit error detected at byte 174, correcting from 0xa0 to 0xa8...OK
s3c-nand: 1 bit error detected at byte 1938, correcting from 0xe1 one_wire_status: 4
to 0xe9...OK
s3c-nand: 1 bit error detected at byte 456, correcting from 0x00 to 0x01...OK
s3c-nand: 1 bit error detected at byte 1374, correcting from 0xbc to 0xbe...OK
s3c-nand: 1 bit error detected at byte 200, correcting from 0xc2 one_wire_status: 4
to 0xc3...OK
s3c-nand: 1 bit error detected at byte 16, correcting from 0x0f to 0x0b...OK
s3c-nand: 1 bit error detected at byte 51, correcting from 0xe5 to 0xf5...OK
one_wire_status: 4
s3c-nand: 1 bit error detected at byte 874, correcting from 0x5f to 0x5e...OK
s3c-nand: 1 bit error detected at byte 213, correcting from 0x00 to 0x20...OK
s3c-nand: 1 bit error detected at byte 448, correcting from 0xf4 to 0xd4...OK
s3c-nand: 1 bit error detected at byte 430, correcting from 0x70 to 0x50...OK
s3c-nand: 1 bit error detected at byte 2036, correcting from 0x08 to 0x0c...OK
s3c-nand: 1 bit error detected at byte 478, correcting from 0xff one_wire_status: 2
to 0xf7...OK
s3c-nand: 1 bit error detected at byte 258, correcting from 0x00 to 0x40...OK
s3c-nand: 1 bit error detected at byte 289, correcting from 0x20 to 0x00...OK
s3c-nand: 1 bit error detected at byte 57, correcting from 0x00 one_wire_status: 4
to 0x80...OK
s3c-nand: 1 bit error detected at byte 180, correcting from 0x3c to 0xbc...OK
s3c-nand: 1 bit error detected at byte 332, correcting from 0x01 to 0x41...OK
one_wire_status: 4
s3c-nand: 1 bit error detected at byte 449, correcting from 0x10 to 0x50...OK
s3c-nand: 1 bit error detected at byte 200, correcting from 0xbb to 0x9b...OK
s3c-nand: 1 bit error detected at byte 281, correcting from 0x00 one_wire_status: 4
to 0x40...OK
s3c-nand: 1 bit error detected at byte 1547, correcting from 0xfb to 0xf9...OK
s3c-nand: 1 bit error detected at byte 133, correcting from 0x10 to 0x90...OK
s3c-nand: 1 bit error detected at byte 1585, correcting from 0xff to 0xef...OK
s3c-nand: 1 bit error detected at byte 44, correcting from 0x01 to 0x21...OK
s3c-nand: 1 bit error detected at byte 241, correcting from 0x00 to 0x02...OK
s3c-nand: 1 bit error detected at byte 78, correcting from 0x50 one_wire_status: 2
to 0x40...OK
s3c-nand: 1 bit error detected at byte 202, correcting from 0xff to 0xef...OK
s3c-nand: 1 bit error detected at byte 117, correcting from 0x10 to 0x12...OK
one_wire_status: 4
s3c-nand: 1 bit error detected at byte 870, correcting from 0xff to 0xfe...OK
s3c-nand: 1 bit error detected at byte 455, correcting from 0xe3 to 0xe2...OK
s3c-nand: 1 bit error detected at byte 1930, correcting from 0xfa one_wire_status: 4
to 0xea...OK
s3c-nand: 1 bit error detected at byte 91, correcting from 0xe3 to 0xe7...OK
s3c-nand: 1 bit error detected at byte 209, correcting from 0x50 to 0x58...OK
s3c-nand: 1 bit error detected at byte 260, correcting from 0x81 to 0x80...OK
s3c-nand: 1 bit error detected at byte 433, correcting from 0x39 to 0x19...OK
s3c-nand: 1 bit error detected at byte 149, correcting from 0xff to 0xdf...OK
s3c-nand: 1 bit error detected at byte 66, correcting from 0xff one_wire_status: 2
to 0x7f...OK
s3c-nand: 1 bit error detected at byte 358, correcting from 0xff to 0x7f...OK
s3c-nand: 1 bit error detected at byte 510, correcting from 0x00 one_wire_status: 4
to 0x08...OK
s3c-nand: 1 bit error detected at byte 209, correcting from 0x00 to 0x80...OK
s3c-nand: 1 bit error detected at byte 227, correcting from 0x00 to 0x10...OK
s3c-nand: 1 bit error detected at byte 416, correcting from 0x48 one_wire_status: 4
to 0xc8...OK
s3c-nand: 1 bit error detected at byte 277, correcting from 0x74 to 0x70...OK
s3c-nand: 1 bit error detected at byte 441, correcting from 0x6c to 0x64...OK
s3c-nand: 1 bit error detected at byte 465, correcting from 0x65 one_wire_status: 4
to 0x64...OK
s3c-nand: 1 bit error detected at byte 381, correcting from 0x72 to 0x70...OK
s3c-nand: 1 bit error detected at byte 78, correcting from 0x28 to 0x08...OK
s3c-nand: 1 bit error detected at byte 463, correcting from 0x20 to 0x22...OK
s3c-nand: 1 bit error detected at byte 316, correcting from 0x65 to 0xe5...OK
s3c-nand: 1 bit error detected at byte 136, correcting from 0x65 one_wire_status: 2
to 0x64...OK
s3c-nand: 1 bit error detected at byte 1720, correcting from 0xff to 0xdf...OK
s3c-nand: 1 bit error detected at byte 207, correcting from 0x65 to 0x67...OK
s3c-nand: 1 bit error detected at byte 1887, correcting from 0x78 one_wire_status: 4
to 0xf8...OK
s3c-nand: 1 bit error detected at byte 351, correcting from 0x00 to 0x80...OK
s3c-nand: 1 bit error detected at byte 945, correcting from 0x24 to 0xa4...OK
one_wire_status: 5
s3c-nand: 1 bit error detected at byte 337, correcting from 0x00 to 0x08...OK
Kernel panic - not syncing: Attempted to kill init!
[<c0178c44>] (unwind_backtrace+0x0/0xe4) from [<c0512d74>] (panic+0x58/0x174)
[<c0512d74>] (panic+0x58/0x174) from [<c018ae48>] (do_exit+0x68/0x5e4)
[<c018ae48>] (do_exit+0x68/0x5e4) from [<c018b688>] (do_group_exit+0x90/0xc4)
[<c018b688>] (do_group_exit+0x90/0xc4) from [<c01950c0>] (get_signal_to_deliver+0x30c/0x344)
one_wire_status: 2

这样应该是下载的yaffs文件系统的错误吧,
当然如果rootfs_qtopia_qt4.img文件只下载一部分是没有nand 错误的,就是我只下载rootfs_qtopia_qt4.img的一半是不会出来nand flash的错误的,只会出来系统启动不了,那么证明ecc的错误只是出现在几个区域,我也对比过友善的superboot下载rootfs_qtopia_qt4.img开始部分内容是完全一样的。我看了半天s3c6410的手册看到上面有专门为备用扇区做ecc的寄存器,我看了一下uboot中关于这个寄存器根本没有使用,所以这里来请教一下高手....uboot应该怎么计算硬件ECC,才能让友善之臂的2.6.38的内核成功运行...
*無鈳取玳
级别: 论坛版主
UID: 27
精华: 12
发帖: 5398
金钱: 40120 两
威望: 17929 点
贡献值: 71 点
综合积分: 11036 分
注册时间: 2008-01-16
最后登录: 2014-11-22
1楼  发表于: 2012-08-08 18:19
我想对于ECC的问题,可以从下面几个方面入手
1. ECC在OOB中的位置
2. ECC的字节数
3. ECC的计算方法 (从你的分析来看,应该是硬件ECC)

确保这几点在你的u-boot和内核之间是一致的应该就可以了。
"If you have an apple and I have an apple and we exchange apples, then you and I will
still each have one apple. But if you have an idea and I have an idea and we exchange
these ideas, then each of us will have two ideas."
级别: 侠客
UID: 41214
精华: 0
发帖: 88
金钱: 450 两
威望: 90 点
贡献值: 0 点
综合积分: 176 分
注册时间: 2011-03-27
最后登录: 2018-05-24
2楼  发表于: 2012-08-08 19:02
1: 友善之臂Linux 中ECC的OOB位置是2,

2: ECC的字节数据,主数据区的ECC是16个字节,备用扇区的ECC是4个字节。 主数据区域应该是写512字节后产生4个字节效验.....

3: 按照步骤2这样的配置从S3C6410数据手册来看,好像Linux内核采用的是4bit 效验,不是1bit 效验。 为什么友善SLC的效验都采用4bit 效验嗯。弄不明白。


唯一让我很纠结的是Linux内核采用4bit效验的ECC,那么uboot得跟着修改,可是我配置4bit 效验一直配置不对,除了官方手册,版主还有什么参考的吗?有没有示例的...