YAFFS文件系统在2.6内核上的移植
2010-03-21 14:30
381 查看
来源:http://blog.chinaunix.net/u3/93625/showart_2020160.html
一、简介:
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文件系统代码,下载网址:
http://www.aleph1.co.uk/cgi-bin/viewcvs.cgi/
点击页面左下角的Download tarball即可下载全部相关代码。
(2)将下载的文件cvs-root.tar.gz拷贝到你的一个临时目录中,假设是/tmp,并解压:
解压后得到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文件。
(4)配置内核支持YAFFS文件系统:
注意:
在这里没有选上Lets Yaffs do its own ECC选项和修改MTD驱动,也就是说不是用yaffs自身的ECC校验方法,而是使用MTD设备层中的ECC校验方法。
好了,到这里内核已经支持yaffs文件系统了,重新编译内核。
三、制作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文件中)所示:
新、老结构有细微差别:老结构中有两位没有使用(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:
把nand_ecc.c和yaffs_packedtags1.c编译进mkyaffsimage工具:
现在,在utils目录下执行make命令生成mkyaffsimage工具了。把生成的mkyaffsimage可执行文件拷贝到/usr/bin目录下。
(2)制作yaffs映像文件
把之前做好的文件系统制作为yaffs映像:
到此,我们就可以把yaffs映像文件烧写到Nand Flash中。
一、简介:
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文件系统代码,下载网址:
http://www.aleph1.co.uk/cgi-bin/viewcvs.cgi/
点击页面左下角的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文件中)所示:
typedef struct { unsigned chunkId:20; unsigned serialNumber:2; unsigned byteCountLSB:10; unsigned objectId:18; unsigned ecc:12; unsigned byteCountMSB:2; } yaffs_Tags; |
新格式的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结构体。
#include "yaffs_packedtags1.h" |
2)修改mkyaffsimage.c文件的write_chunk函数:
static int write_chunk(__u8 *data, __u32 objId, __u32 chunkId, __u32 nBytes) { /* Modify by cjy*/ #ifdef CONFIG_YAFFS_9BYTE_TAGS /* 如果要生成老格式的yaffs1映像文件,定义这个宏 */ ……/* 原来的代码 */ …… return write(outFile,&s,sizeof(yaffs_Spare)); #else yaffs_PackedTags1 pt1; yaffs_ExtendedTags etags; __u8 ecc_code[6]; __u8 oobbuf[16]; /* 写页数据,512字节 */ error = write(outFile,data,512); if(error < 0) return error; /* 构造tag */ etags.chunkId = chunkId; etags.serialNumber = 0; etags.byteCount = nBytes; etags.objectId = objId; etags.chunkDeleted = 0; /* * 重定位oob区中的可用数据(称为tag) */ yaffs_PackTags1(&pt1, &etags); /* 计算tag本身的ECC码 */ yaffs_CalcTagsECC((yaffs_Tags *)&pt1); memset(oobbuf, 0xff, 16); memcpy(oobbuf+8, &pt1, 8); /* * 使用与内核MTD层相同的方法计算一页数据(512字节)的ECC码 * 并把它们填入oob */ nand_calculate_ecc(data, &ecc_code[0]); nand_calculate_ecc(data+256, &ecc_code[3]); /* 对应新格式yaffs1 ECC校验码的存放位置 */ oobbuf[0] = ecc_code[0]; oobbuf[1] = ecc_code[1]; oobbuf[2] = ecc_code[2]; oobbuf[3] = ecc_code[3]; oobbuf[6] = ecc_code[4]; oobbuf[7] = ecc_code[5]; nPages++; /* 写oob数据,16字节 */ return write(outFile, oobbuf, 16); #endif } |
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中。
相关文章推荐
- yaffs文件系统在2.6内核上的移植
- yaffs文件系统在2.6内核上的移植--操作步骤(转载)
- yaffs文件系统在2.6内核上的移植
- 内核移植(4)移植yaffs文件系统
- 移植内核学习笔记3-----支持yaffs文件系统
- linux2.6.30.4内核移植(3)——yaffs文件系统移植
- 移植内核之支持Yaffs文件系统
- 【移植Linux 3.4.2内核之四】修改内核代码支持YAFFS文件系统
- 基于Linux2.6的YAFFS文件系统移植
- Linux-2.6.28内核移植及Yaffs文件系统制作 for FL2440(一)
- linux2.6.30.4内核移植(5)——构建根文件系统(yaffs文件系统格式的镜像)
- Linux-2.6.28内核移植及Yaffs文件系统制作 for FL2440(二)
- linux 2.6.32.2 mini2440平台移植--内核移植、yaffs2文件系统移植
- linux 内核移植和根文件系统的制作
- 2012-Linux->19(Linux-2.6.32.2内核在mini2440上的移植---根文件系统制作)
- linux 内核移植和根文件系统的制作
- Linux-2.6.32.2内核在mini2440上的移植(二)---yaffs2文件系统移植
- yaffs 文件系统移植
- Linux-2.6.32.2内核在mini2440上的移植(二)---yaffs2文件系统移植
- 内核移植和文件系统制作(3)Ramdisk简介和常见问题