开始阅读YAFFS源码 2.6.18以上需要打补丁 yaffs2 内核 kernel的ecc布局
来源:互联网 发布:美国弗吉尼亚大学知乎 编辑:程序博客网 时间:2024/06/06 03:23
开始阅读YAFFS2源码,有不少收获。
初步明白为什么在新内核上原来的yaffs会有问题,让我突然觉得那些
拿了别人可以烧写yaffs的uboot 又问linux 2.6.22怎么出问题的那些人挺可笑的,其实我自己一开始也这样,算是自嘲了。感觉纯粹的就是拿来,不去自己分析其中的问题,这样学不到东西。
这两天我对原来uboot烧写yaffs的功能作了深入分析,因为补丁其实很短小,反复看看就明白了。再加上对新的yaffs2代码做了初步阅读,不能说完全明白,但已经找到了问题所在。事实上,yaffs2的代码目前用在linux2.6.23.9上已经和原来我用在2.6.20.3上的不一样了!
先来说说YAFFS1的NAND数据组织。
K9F1208 这块FLASH是 512字节+16字节 1个page。512字节用来存放数据,16字节oob。
MTD中,用了8字节做ECC,这8个字节是16字节中的低8字节,详细阅读linux源码中drivers/mtd/nand/nand_base.c中
static struct nand_ecclayout nand_oob_16 = {
.eccbytes = 6,
.eccpos = {0, 1, 2, 3, 6, 7},
.oobfree = {
{.offset = 8,
. length = 8}}
};
//这个oob layout是在xxx_nand_probe->nand_scan->nand_scan_tail()调用的.
可见,可用的freeoob是高8字节。
原来的yaffs中使用nandmtd_WriteChunkToNAND函数将它的chunk写入FLASH,我开始不关心他的512字节数据区,关键还是分析它的oob。原本的yaffs中,他有个yaffs_Spare结构,在yaffs_guts.h中定义的
typedef struct {
__u8 tagByte0;
__u8 tagByte1;
__u8 tagByte2;
__u8 tagByte3;
__u8 pageStatus; /* set to 0 to delete the chunk */
__u8 blockStatus;
__u8 tagByte4;
__u8 tagByte5;
__u8 ecc1[3];
__u8 tagByte6;
__u8 tagByte7;
__u8 ecc2[3];
} yaffs_Spare;
正好是16字节。所以如果在用MTD_ECC的,必然需要一个转化,因为你需要把低8字节的oob让出来给MTD的ECC,只用高8字节的oob,这个功能是由translate_spare2oob函数完成的。读出来时的时候正好反过来translate_oob2spare。实际YAFFS在调用 mtd->write_oob的时候只写了8字节,由上很容易推测这是高8字节的oob,低8字节由mtd去计算ECC了。
再来看mkyaffsimage的代码,他在512字节之后是包含了16字节oob的,但是从代码中发现,这个16字节的oob就是他的yaffs_Spare结构,也就是说你用MTD_ECC的话,这个16字节是不适合NAND的oob结构的,所以需要translate_spare2oob的做法来转换。到这里,就明白为什么uboot补丁中
#ifdef CFG_NAND_YAFFS1_NEW_OOB_LAYOUT
/* translate OOB for yaffs1 on Linux 2.6.18+ */
oob_buf[15] = oob_buf[12];
oob_buf[14] = oob_buf[11];
oob_buf[13] = (oob_buf[7] & 0x3f)
| (oob_buf[5] == 'Y' ? 0 : 0x80)
| (oob_buf[4] == 0 ? 0 : 0x40);
oob_buf[12] = oob_buf[6];
oob_buf[11] = oob_buf[3];
oob_buf[10] = oob_buf[2];
oob_buf[9] = oob_buf[1];
oob_buf[8] = oob_buf[0];
memset(oob_buf, 0xff, 8);
这段代码就是在调整oob,实际上就是translate_spare2oob功能,将低8字节填充0xFF这样MTD会自己计算ECC,高8字节转化成有用的信息。
到这里就对上了,uboot中烧写的yaffs就能和linux中的yaffs对上。
现在出了什么问题呢?!现在的yaffs2代码中,用高版本内核的话,已经不是调用nandmtd_WriteChunkToNAND这个函数了!!参看yaffs_fs.c。
#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17))
/* use the MTD interface in yaffs_mtdif1.c */
dev->writeChunkWithTagsToNAND =
nandmtd1_WriteChunkWithTagsToNAND;
dev->readChunkWithTagsFromNAND =
nandmtd1_ReadChunkWithTagsFromNAND;
dev->markNANDBlockBad = nandmtd1_MarkNANDBlockBad;
dev->queryNANDBlock = nandmtd1_QueryNANDBlock;
#else
dev->writeChunkToNAND = nandmtd_WriteChunkToNAND;
dev->readChunkFromNAND = nandmtd_ReadChunkFromNAND;
#endif
再看yaffs_nand.c
if (dev->readChunkWithTagsFromNAND)
result = dev->readChunkWithTagsFromNAND(dev, realignedChunkInNAND, buffer,
tags);
else
result = yaffs_TagsCompatabilityReadChunkWithTagsFromNAND(dev,
realignedChunkInNAND,
buffer,
tags);
可见linux.2.6.17以上就调用的是 nandmtd1_WriteChunkWithTagsToNAND这个函数,而低版本的通过yaffs_TagsCompatabilityReadChunkWithTagsFromNAND来调用nandmtd_WriteChunkToNAND。
现在的这个函数用的不是yaffs_spare结构,而是
typedef struct {
unsigned chunkId:20;
unsigned serialNumber:2;
unsigned byteCount:10;
unsigned objectId:18;
unsigned ecc:12;
unsigned deleted:1;
unsigned unusedStuff:1;
unsigned shouldBeFF;
} yaffs_PackedTags1;
这个结构。
都是靠yaffs_ExtendedTags转过去的。相应的mkyaffsimage也没有对应上!!
今天就分析到这里,相信能给广大的开发人员指明一个方向。还是建议阅读阅读代码,自己分析,实际上并不是很复杂。
只需要修改mkyaffsimage代码和uboot相应代码就能解决问题了。
(转载自:http://www.armchina.cn 作者hiboy)
- 开始阅读YAFFS源码 2.6.18以上需要打补丁 yaffs2 内核 kernel的ecc布局
- Linux内核---29.yaffs2的ECC
- Yaffs2的ecc校验
- Linux内核目录结构(2.6版本以上的kernel)
- 2440移植Linux Kernel笔记(四)------yaffs2打补丁
- S3C6410使用---21yaffs2的ECC
- yaffs and ecc
- kernel 打补丁
- 实现u-boot对yaffs/yaffs2文件系统下载的支持
- 实现u-boot对yaffs/yaffs2文件系统下载的支持
- 实现u-boot对yaffs/yaffs2文件系统下载的支持
- linux 2.6.2x中 mtd yaffs ecc layout分析
- samsung ECC的问题(关系到yaffs2等系统)
- 记一次Yaffs2与Nand Ecc产生的问题
- 阅读linux内核需要的名词注释
- yaffs文件系统在2.6内核上的移植
- yaffs文件系统在2.6内核上的移植
- yaffs文件系统在2.6内核上的移植
- 恢复.mdf数据库
- 中美印日四国程序员比较
- System.Length - 获取字符串或数组的长度
- 用.NET的File控件上传文件的解决方案
- Ubuntu source list
- 开始阅读YAFFS源码 2.6.18以上需要打补丁 yaffs2 内核 kernel的ecc布局
- StrComp 和 StrIComp 函数
- 遇到这样的男人,请把自己嫁了
- 使用OpenLDAP做通讯录遇到的几个问题
- 学会自己健康的活着!
- SysUtils.StringReplace - 替换
- SysUtils.CompareStr、SysUtils.CompareText - 字符串比较
- 请高手看看我的Java程序怎么了
- 乡愁--------故乡才是永不磨灭的印记