分类: 嵌入式
2009-08-07 00:03:43
一、简介:
Yaffs(Yet Another Flash File System)文件系统是专门针对NAND 闪存设计的嵌入式文件系统,目前有YAFFS 和YAFFS2 两个版本,两个版本的主要区别之一在于YAFFS2 能够更好的支持大容量的NAND FLASH芯片。
Yaffs 文件系统有些类似于JFFS/JFFS2 文件系统,与之不同的是JFFS1/2 文件系统最初是针对NOR FLASH的应用场合设计的,而NOR FLASH 和NAND FLASH本质上有较大的区别,所以尽管JFFS1/2 文件系统也能应用于NAND FLASH,但由于它在内存占用和启动时间方面针对NOR 的特性做了一些取舍,所以对NAND来说通常并不是最优的方案。
二、yaffs/yaffs2在2.6.30.3中的移植
(1)下载YAFFS文件系统代码,下载网址:
点击页面左下角的Download tarball即可下载全部相关代码。
(2)将下载的文件cvs-root.tar.gz拷贝到你的一个临时目录中,假设是/tmp,并解压:
# cd /tmp # tar xzvf cvs-root.tar.gz |
解压后得到cvs目录,该目录里有两个子目录:yaffs和yaffs2。考虑到现在的NAND FLASH容量越做越大,而且yaffs2可以自动选择挂载是yaffs1还是yaffs2文件系统,这里我们移植yaffs2。当然如果你的NAND FLASH只是512+16B的,可以只移植yaffs,因为即使你移植了yaffs2,它也会自动选择挂载yaffs1的。
(3)为Linux打上支持yaffs2的补丁。
进入cvs/yaffs2目录,执行patch-ker.sh脚本即可。这个脚本完成把yaffs源码拷贝到linux源码目录的fs/yaffs2下和修改fs目录下的Kconfig、Makefile文件。
#./patch-ker.sh c /root/linux-2.6.30.3/ |
(4)配置内核支持YAFFS文件系统:
File systems ---> Miscellaneous filesystems ---> <*> YAFFS2 file system support -*- 512 byte / page devices [ ] Use older-style on-NAND data format with pageStatus byte [ ] Lets Yaffs do its own ECC -*- 2048 byte (or larger) / page devices [*] Autoselect yaffs2 format [*] Disable lazy loading [ ] Turn off wide tnodes [ ] Force chunk erase check [*] Cache short names in RAM |
注意:
在这里没有选上Lets Yaffs do its own ECC选项和修改MTD驱动,也就是说不是用yaffs自身的ECC校验方法,而是使用MTD设备层中的ECC校验方法。
好了,到这里内核已经支持yaffs文件系统了,重新编译内核。
#./make uImage
三、制作yaffs文件系统映像文件
(1)修改制作yaffs映像文件的工具
在yaffs源码中有个utils目录(假如/cvs/yaffs2/utils),里面是工具mkyaffsimage和mkyaffs2image的源代码。前者用来制作yaffs1映像文件,后者用来制作yaffs2映像文件。
目前mkyaffsimage工具只能生成老格式的yaffs1映像文件,因为我们在配置内核时没有选上支持旧格式(没有设置CONFIG_YAFFS_9BYTE_TAGS)的yaffs1映像文件,所以需要修改源码来支持新格式。
在修改源码之前,我们先来看看yaffs1新、老格式的不同点。他们的不同在于oob区的使用发生了变化:一是ECC校验码的位置发生了变化,二是可用空间即标记(tag)的数据结构定义发生了变化。
另外,由于配置内核是没有设置Lets Yaffs do its own ECC,yaffs文件系统将使用MTD设备层的ECC校验方法,制作映像文件时也应该使用与MTD设备层相同的函数计算ECC码。
oob区中校验码的位置变化:
oob区中使用6个字节来存放ECC校验码,前3个字节对应上半页,后3个字节对应下半页。由nand_oob_16结构可知,以前的校验码在oob区中存放的位置为8、9、10、13、14、15,而现在改为0、1、2、3、6、7。
‚oob区中可用空间的数据结构定义变化:
oob区中可用的空间有8个字节,他用来存放文件系统的数据,代码中这些数据被称为标记(tag)。
老格式的yaffs1中,这8个字节的数据结构定义如下(在yaffs_guts.h文件中)所示:
|
新格式的yaffs1中,定义如下(在yaffs_packedtags.h文件中)所示:
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;
/* 新格式中,shouldBeFF没有使用,yaffs_PackedTags1还是8个字节 */
} yaffs_PackedTags1;
新、老结构有细微差别:老结构中有两位没有使用(unusedStuff);新结构中只有一位没有使用,另一位(deleted)被用来标识当前页是否已经删除。
ƒoob区中ECC码的计算:
如果配置内核时设置了Lets Yaffs do its own ECC,则yaffs文件系统将使用yaffs2/yaffs_ecc.c文件中的yaffs_ECCCalculate函数来计算ECC码;否则使用drivers/mtd/nand/nand_ecc.c文件中的nand_calculate函数。
mkyaffsimage工具原来的代码中使用yaffs_ECCCalculate函数。由于上面配置内核时,我们没有选择Lets Yaffs do its own ECC,为了使映像文件与内核保持一致,下面我们来修改mkyaffsimage源码,使用nand_calculate_ecc函数计算ECC码。
1)添加头文件:
修改文件mkyaffsimage.c,加上下面这行,里面定义了yaffs_PackedTags1结构体。
|
2)修改mkyaffsimage.c文件的write_chunk函数:
|
3)添加文件,修改Makefile:
#cp ../yaffs_packedtags1.c
把nand_ecc.c和yaffs_packedtags1.c编译进mkyaffsimage工具:
#vi Makefile |
MKYAFFSSOURCES = mkyaffsimage.c yaffs_packedtags1.c nand_ecc.c
现在,在utils目录下执行make命令生成mkyaffsimage工具了。把生成的mkyaffsimage可执行文件拷贝到/usr/bin目录下。
#cp mkyaffsimage /usr/bin
(2)制作yaffs映像文件
把之前做好的文件系统制作为yaffs映像:
#mkyaffsimage filesystem filesystem.yaffs
到此,我们就可以把yaffs映像文件烧写到Nand Flash中。