主题 : 关于新版yaffs2源码的mkyaffs2image生成OOB导致坏块标记不正确的问题 复制链接 | 浏览器收藏 | 打印
级别: 新手上路
UID: 68915
精华: 0
发帖: 27
金钱: 135 两
威望: 27 点
综合积分: 54 分
注册时间: 2012-04-28
最后登录: 2016-08-06
楼主  发表于: 2015-04-20 09:58

 关于新版yaffs2源码的mkyaffs2image生成OOB导致坏块标记不正确的问题

我用最新yaffs2源码(2013以后的都试过了)编译的mkyaffs2iamge工具制作文件系统,用winhex打开后发现0x800h处是0x01 0x00数据,烧写后导致uboot识别为坏块,请问大家有没有遇到这种个问题
[ 此帖被tom365在2015-04-20 15:46重新编辑 ]
^很多问题的背后都是简单的原因......
级别: 荣誉会员
UID: 34780
精华: 0
发帖: 1219
金钱: 6230 两
威望: 1246 点
综合积分: 2438 分
注册时间: 2010-12-21
最后登录: 2017-09-18
1楼  发表于: 2015-04-20 13:06
uboot 对 nandflash 的烧写 必须与 makeyaffs2image 配合好,同时还要和内核中的 oob 定义匹配
级别: 新手上路
UID: 68915
精华: 0
发帖: 27
金钱: 135 两
威望: 27 点
综合积分: 54 分
注册时间: 2012-04-28
最后登录: 2016-08-06
2楼  发表于: 2015-04-20 15:04

 回 1楼(911gt3) 的帖子

我明白,但是OOB的头两个字节不是统一规定作为坏块标记使用么,yaffs2怎么能修改这个规定呢
^很多问题的背后都是简单的原因......
级别: 荣誉会员
UID: 34780
精华: 0
发帖: 1219
金钱: 6230 两
威望: 1246 点
综合积分: 2438 分
注册时间: 2010-12-21
最后登录: 2017-09-18
3楼  发表于: 2015-04-20 15:17
所以你需要分析你正在使用的 mkyaffs2iamge,重点是在生成 image 时 OOB 的使用是怎么样的
级别: 新手上路
UID: 68915
精华: 0
发帖: 27
金钱: 135 两
威望: 27 点
综合积分: 54 分
注册时间: 2012-04-28
最后登录: 2016-08-06
4楼  发表于: 2015-04-20 15:40
static void shuffle_oob(char *spareData, struct yaffs_packed_tags2 *pt)
{
    assert(sizeof(*pt) <= spareSize);
    // NAND LAYOUT: For non-trivial OOB orderings, here would be a good place to shuffle.
    memcpy(spareData, pt, sizeof(*pt));
}

static int write_chunk(u8 *data, u32 id, u32 chunk_id, u32 n_bytes)
{
    struct yaffs_ext_tags t;
    struct yaffs_packed_tags2 pt;
    char spareData[spareSize];

    if (write(outFile,data,chunkSize) != chunkSize)
        fatal("write");

    memset(&t, 0, sizeof(t));
    
    t.chunk_id = chunk_id;
//    t.serial_number = 0;
    t.serial_number = 1;    // **CHECK**
    t.n_bytes = n_bytes;
    t.obj_id = id;
    
    t.seq_number = YAFFS_LOWEST_SEQUENCE_NUMBER;

// added NCB **CHECK**
    t.chunk_used = 1;

    if (convert_endian)
    {
            little_to_big_endian(&t);
    }

    nPages++;

    memset(&pt, 0, sizeof(pt));
    yaffs_pack_tags2(&pt,&t,1);

    memset(spareData, 0xff, sizeof(spareData));
    shuffle_oob(spareData, &pt);

    if (write(outFile,spareData,sizeof(spareData)) != sizeof(spareData))
        fatal("write");
    return 0;
}
是直接先将yaffs_packed_tags2写入的,

struct yaffs_packed_tags2 {
    struct yaffs_packed_tags2_tags_only t;
    struct yaffs_ecc_other ecc;
};
struct yaffs_packed_tags2_tags_only {
    unsigned seq_number;
    unsigned obj_id;
    unsigned chunk_id;
    unsigned n_bytes;
};
struct yaffs_ecc_other {
    unsigned char col_parity;
    unsigned line_parity;
    unsigned line_parity_prime;
};
总共4*7=28字节,直接放OOB最前面了。而且从2013年的版本都是这样的。
级别: 新手上路
UID: 68915
精华: 0
发帖: 27
金钱: 135 两
威望: 27 点
综合积分: 54 分
注册时间: 2012-04-28
最后登录: 2016-08-06
5楼  发表于: 2015-04-20 15:48
如果修改mkyaffs2image,给OOB增加2个0xff字节,但是内核中的yaffs2源码能还能正常解析吗,表示很疑惑
^很多问题的背后都是简单的原因......
级别: 荣誉会员
UID: 34780
精华: 0
发帖: 1219
金钱: 6230 两
威望: 1246 点
综合积分: 2438 分
注册时间: 2010-12-21
最后登录: 2017-09-18
6楼  发表于: 2015-04-20 17:46
>> 总共4*7=28字节,直接放OOB最前面了。而且从2013年的版本都是这样的。

请检查你的内核中 nandflash 驱动的 OOB,你烧写的时候需要将此28字节写入到与内核匹配的位置
级别: 新手上路
UID: 68915
精华: 0
发帖: 27
金钱: 135 两
威望: 27 点
综合积分: 54 分
注册时间: 2012-04-28
最后登录: 2016-08-06
7楼  发表于: 2015-04-20 23:25
通过修改mkyaffs2image,可以正确烧写了,就是修改write_chunk函数中的shuffle_oob(spareData, &pt);为shuffle_oob(spareData + 2, &pt);
让OOB位置右移2个字节。现在内核仍然无法加载,也许是内核OOB布局的问题。内核最终停在:
yaffs: dev is 32505861 name is "mtdblock5" rw
yaffs: passed flags ""
VFS: Mounted root (yaffs2 filesystem) on device 31:5.
devtmpfs: error mounting -2
Freeing unused kernel memory: 148K (803ab000 - 803d0000)
Failed to execute /linuxrc.  Attempting defaults...
Kernel panic - not syncing: No init found.  Try passing init= option to kernel. See Linux Documentation/init.txt for guidance.
CPU: 0 PID: 1 Comm: swapper Not tainted 3.10.60 #33
[<80012d58>] (unwind_backtrace+0x0/0xf8) from [<80010c54>] (show_stack+0x10/0x14)
[<80010c54>] (show_stack+0x10/0x14) from [<8029d6c8>] (panic+0x8c/0x1d8)
[<8029d6c8>] (panic+0x8c/0x1d8) from [<8029c9c8>] (kernel_init+0xc0/0xe4)
[<8029c9c8>] (kernel_init+0xc0/0xe4) from [<8000e0d8>] (ret_from_fork+0x14/0x3c)

而且这时重启用nand dump去检查文件系统分区的数据会发现全部变成0xff了。
我现在内核关闭了硬件ecc功能,并且修改了vim drivers/mtd/nand/s3c2410.c中的NAND_ECC_SOFT为NAND_ECC_NONE。
内核也配置了采用yaffs ecc选项,照理说这时oob布局会采用mtd默认的nand_oob_64,应该没问题了:
static struct nand_ecclayout nand_oob_64 = {
    .eccbytes = 24,
    .eccpos = {
           40, 41, 42, 43, 44, 45, 46, 47,
           48, 49, 50, 51, 52, 53, 54, 55,
           56, 57, 58, 59, 60, 61, 62, 63},
    .oobfree = {
        {.offset = 2,
         .length = 38} }
};
0~1前2个字节作为坏块标记,2~39作为yaffs的OOB区域,剩下是yaffs ECC校验信息,应该没问题了啊
但是依然不能正常启动,实在想不通还有什么问题。
级别: 新手上路
UID: 40127
精华: 0
发帖: 9
金钱: 45 两
威望: 9 点
综合积分: 18 分
注册时间: 2011-03-15
最后登录: 2018-01-30
8楼  发表于: 2015-10-15 17:48

 回 7楼(tom365) 的帖子

楼主你的问题解决了吗?我也遇到跟你一样的问题,一直没搞明白哪里出错了
级别: 新手上路
UID: 127068
精华: 0
发帖: 20
金钱: 100 两
威望: 20 点
综合积分: 40 分
注册时间: 2016-08-02
最后登录: 2017-05-12
9楼  发表于: 2016-10-18 10:00
我表示很生气,我也遇到这个问题,请问楼主,有没有解决