Nand flash文件系统总结.docx
- 文档编号:24214876
- 上传时间:2023-05-25
- 格式:DOCX
- 页数:34
- 大小:294.35KB
Nand flash文件系统总结.docx
《Nand flash文件系统总结.docx》由会员分享,可在线阅读,更多相关《Nand flash文件系统总结.docx(34页珍藏版)》请在冰豆网上搜索。
Nandflash文件系统总结
NANDflash文件系统
目前flash的文件系统比较多,用的比较多的就是JFFS2文件系统。
基于NORflash上的JFFS2文件系统可以说算是比较成熟了,支持NANDflash的JFFS2也已经发布了。
源代码可以到http:
//www.linux-mtd.infradead.org上面下载。
但是在我的测试过程中,在nandflash上挂接的JFFS2文件系统很不稳定,经常有CRC错误产生。
特别是进行写操作的时候,每次复位都会产生CRC错误,可以说支持NANDflash的JFFS2文件系统目前还不成熟。
而YAFFS文件系统则是专门针对NANDflash的,源代码可以到
http:
//www.aleph1.co.uk/yaffs/index.html上下载。
在测试过程中稳定性能比JFFS2文件系统要稳定的多,而且mount分区的时间也比JFFS2文件系统少的多。
用JFFS2mount一个2m的文件系统大约需要1s。
下面分别介绍在uclinux下面使用JFFS2和YAFFS文件系统。
1、JFFS2
到http:
//www.linux-mtd.infradead.org上面下载最新的MTD和JFFS2压缩包。
压缩包里面还有有关的内核补丁和一些MTD的相关工具。
主要的补丁就是ilookup-2.4.23.patch,因为最新的MTD驱动中要用到一个ilookup()函数。
打完补丁、更新了MTD驱动和JFFS2文件系统之后就开始写自己nandflash驱动了。
如果不想把JFFS2作为根文件系统的话,还需要修改MTD_BLOCK_MAJOR。
驱动可以参考里面的例子,最简单的就是参考spia.c。
写驱动主要工作是定义flash分区结构、定义flash读写地址、写控制flash的**_hwcontrol()函数。
具体的操作要看所用的nandflash的芯片资料。
相对NORflash来说驱动要简单多了。
:
)
改完之后再配置
MemoryTechnologyDevices(MTD)下
CONFIG_MTD=Y
CONFIG_MTD_DEBUG=Y
CONFIG_MTD_DEBUG_VERBOSE=3
CONFIG_MTD_PARTITIONS=Y
CONFIG_MTD_CHAR=Y
CONFIG_MTD_BLOCK=Y
NANDFlashDeviceDrivers下
CONFIG_MTD_NAND=Y
定义自己的驱动文件
Filesystems下
CONFIG_JFFS2_FS=Y
CONFIG_JFFS2_FS_DEBUG=2
CONFIG_JFFS2_FS_NAND=y/*这个是新加的*/
在uClinuxv1.3.4Configuration下
FlashTools下
CONFIG_USER_MTDUTILS=Y
CONFIG_USER_MTDUTILS_ERASE=Y
CONFIG_USER_MTDUTILS_ERASEALL=Y
CONFIG_USER_MTDUTILS_MKFSJFFS2=Y
最后就是辛苦了调试工作了。
:
(MTD驱动调试完之后,就可以在上面挂接JFFS2文件系统了。
参看flash分区情况:
cat/proc/mtd,擦除分区:
eraseall/dev/mtd*.例如把第一个分区mount到/mnt目录下面:
先:
eraseall/dev/mtd0
然后:
mount-tjffs2/dev/mtdblock0/mnt
2、YAFFS
YAFFS意义为'yetanotherflashfilesystem',也是一个开源的文件系统。
YAFFS是目前为止唯一一个专门为NANDflash设计的文件系统,具有很好的可移植性,能够在linux,uclinux,和wince
下面运行。
在http:
//www.aleph1.co.uk/yaffs/index.html上下载源代码。
压缩包里面也包含YAFFS的说明文档。
YAFFS文件系统的源文件就devextras.h,yaffs_ecc.c,yaffs_ecc.h,yaffs_guts.c,yaffs_guts.h,yaffs_mtdif.h,yaffs_mtdif.c和yportenv.h
另外需要配置的宏:
CONFIG_YAFFS_FS和CONFIG_YAFFS_MTD_ENABLED,就是配置在mtd上面挂接YAFFS,其它还有一些辅助配置需要时也可以配置。
在fs目录下面建一个yaffs目录,把以上说的文件考里面去,新建一个makefile:
O_TARGET:
=yaffs.o
obj-y:
=yaffs_fs.oyaffs_guts.oyaffs_mtdif.oyaffs_ecc.o
obj-m:
=$(O_TARGET)
include$(TOPDIR)/Rules.make
接下来就是改fs目录下面config.in和makefile,在配置YAFFS的时候,把YAFFS连接进去。
如果像前面一样已经把NANDMTD驱动调好了,加YAFFS就很简单了。
因为YAFFS是自己做ECC校验的,所以要把MTD驱动里面的ECC去掉。
在驱动里面改成this->eccmode=NAND_ECC_NONE就可以了。
另外YAFFS是用mkyaffs来擦除flash,所以在mtd-utils中加上mkyaffs.c,一起编译进去。
最后就是编译了,呵呵。
中间会有一些警告没有关系的,就是写没有用的变量和函数,不过话说回来YAFFS的代码写的确实不太规范。
当然它的性能确实没话说。
有兴趣的可以试一下-。
1.JFFS2文件系统
JFFS2是JFFS的后继者,由RedHat重新改写而成。
JFFS2的全名为JournallingFlashFileSystemVersion2(闪存日志型文件系统第2版),其功能就是管理在MTD设备上实现的日志型文件系统。
与其他的存储设备存储方案相比,JFFS2并不准备提供让传统文件系统也可以使用此类设备的转换层。
它只会直接在MTD设备上实现日志结构的文件系统。
JFFS2会在安装的时候,扫描MTD设备的日志内容,并在RAM中重新建立文件系统结构本身。
除了提供具有断电可靠性的日志结构文件系统,JFFS2还会在它管理的MTD设备上实现“损耗平衡”和“数据压缩”等特性。
节点头部定义和兼容性
JFFS2将文件系统的数据和原数据以节点的形式存储在闪存上,具体来说节点头部的定义如下:
图一
幻数屏蔽位:
0x1985用来标识JFFS2文件系统。
节点类型:
JFFS2自身定义了三种节点类型,但是考虑到文件系统可扩展性和兼容性,JFFS2从ext2借鉴了经验,节点类型的最高两位被用来定义节点的兼容属性,具体来说有下面几种兼容属性:
JFFS2_FEATURE_INCOMPAT:
当JFFS2发现了一个不能识别的节点类型,并且它的兼容属性是JFFS2_FEATURE_INCOMPAT,那么JFFS2必须拒绝挂载(mount)文件系统。
JFFS2_FEATURE_ROCOMPAT:
当JFFS2发现了一个不能识别的节点类型,并且它的兼容属性是JFFS2_FEATURE_ROCOMPAT,那么JFFS2必须以只读的方式挂载文件系统。
JFFS2_FEATURE_RWCOMPAT_DELETE:
当JFFS2发现了一个不能识别的节点类型,并且它的兼容属性是JFFS2_FEATURE_RWCOMPAT_DELETE,那么在垃圾回收的时候,这个节点可以被删除。
JFFS2_FEATURE_RWCOMPAT_COPY:
当JFFS2发现了一个不能识别的节点类型,并且它的兼容属性是JFFS2_FEATURE_RWCOMPAT_COPY,那么在垃圾回收的时候,这个节点要被拷贝到新的位置。
节点总长度:
包括节点头和数据的长度。
节点头部CRC校验:
包含节点头部的校验码,为文件系统的可靠性提供了支持。
节点类型
JFFS2定义了三种节点类型:
JFFS2_NODETYPE_INODE:
INODE节点包含了i-节点的原数据(i节点号,文件的组ID,属主id,访问时间,偏移,长度等),文件数据被附在INODE节点之后。
除此之外,每个INODE节点还有一个版本号,它被用来维护属于一个i-节点的所有INODE节点的全序关系。
下面举例来说明这个全序关系在JFFS2的使用:
图二
因此,当文件系统从闪存上读节点信息后,会生成下面的映射信息:
图三
根据这个映射信息表,文件系统就知道到相应的INODE节点去读取相应的文件内容。
最后要说明的是,JFFS2支持文件数据的压缩存储,因此在INODE节点中还包含了所使用的压缩算法,在读取数据的时候选择相应的压缩算法来解压缩。
JFFS2_NODETYPE_DIRENT:
DIRENT节点就是把文件名与i节点对应起来。
在DIRENT节点中也有一个版本号,这个版本号的作用主要是用来删除一个dentry。
具体来说,当我们要从一个目录中删除一个dentry时,我们要写一个DIRENT节点,节点中的文件名与被删除的dentry中的文件名相同,i节点号置为0,同时设置一个更高的版本号。
JFFS2_NODETYPE_CLEANMARKER:
当一个擦写块被擦写完毕后,CLEANMARKER节点会被写在NORflash的开头,或NANDflash的OOB(Out-Of-Band)区域来表明这是一个干净,可写的擦写块。
在JFFSv1中,如果扫描到开头的1K都是0xFF就认为这个擦写块是干净的。
但是在实际的测试中发现,如果在擦写的过程中突然掉电,擦写块上也可能会有大块连续0xFF,但是这并不表明这个擦写块是干净的。
于是我们需要CLEANMARKER节点来确切的标识一个干净的擦写块。
JFFS2节点,擦写块在内存中的表示和操作
JFFS2维护了几个链表来管理擦写块,根据擦写块上的内容,一个擦写块会在不同的链表上。
具体来说,当一个擦写块上都是合法(valid)的节点时,它会在clean_list上;当一个擦写块包含至少一个过时(obsolete)的节点时,它会在dirty_list上;当一个擦写块被擦写完毕,并被写入CLEANMARKER节点后,它会在free_list上。
通常情况下,JFFS2顺序的在擦写块上写入不同的节点,直到一个擦写块被写满。
此时JFFS2从free_list上取下一个擦写块,继续从擦写块的开头开始写入节点。
当free_list上擦写块的数量逐渐减少到一个预先设定的阀值的时候,垃圾回收就被触发了,为文件系统清理出更多的可用擦写块。
为了减少对内存的占用,JFFS2并没有把i节点所有的信息都保留在内存中,而只是把那些在请求到来时不能很快获得的信息保留在内存中。
具体来说,对于在闪存上的每个i节点,在内存里都有一个structjffs2_inode_cache与之对应,这个结构里保存了i节点号,指向i节点的连接数,以及一个指向属于这个i节点的物理节点链表的指针。
所有的structjffs2_inode_cache存储在一个哈希表中。
闪存上的每个节点在内存中由一个structjffs2_raw_node_ref表示,这个结构里保存了此节点的物理偏移,总长度,以及两个指向structjffs2_raw_node_ref的指针。
一个指针指向此节点在物理擦写块上的下一个节点,另一个指针指向属于同一个i-节点的物理节点链表的下一个节点。
图四
在闪存上的节点的起始偏移都是4字节对齐的,所以structjffs2_inode_cache中flash_offset的最低两位没有被用到。
JFFS2正好利用最低位作为此节点是否过时的标记。
下面举一例来说明JFFS2是如何使用这些数据结构的。
VFS调用iget()来得到一个i节点的信息,当这个i节点不在缓存中的时候,VFS就会调用JFFS2的read_inode()回调函数来得到i节点信息。
传给read_inode()的参数是i节点号,JFFS2用这个i节点号从哈希表中查找相应的structjffs2_inode_cache,然后利用属于这个i节点的节点链表从闪存上读入节点信息,建立类似于表三的映射信息。
JFFS2挂载过程
JFFS2的挂载过程分为四个阶段:
1)JFFS2扫描闪存介质,检查每个节点CRC校验码的合法性,同时分配了structjffs2_inode_cache和structjffs2_raw_node_ref
2)扫描每个i节点的物理节点链表,标识出过时的物理节点;对每一个合法的dentry节点,将相应的jffs2_inode_cache中的nlink加一。
3找出nlink为0的jffs2_inode_cache,释放相应的节点。
4释放在扫描过程中使用的临时信息。
JFFS2垃圾回收机制
当free_list上的擦写块数太少了,垃圾回收就会被触发。
垃圾回收主要的任务就是回收那些已经过时的节点,但是除此之外它还要考虑磨损平衡的问题。
因为如果一味的从dirty_list上选取擦写块进行垃圾回收,那么dirty_list上的擦写块将先于clean_list上的擦写块被磨损坏。
JFFS2的处理方式是以99%的概率从dirty_list,1%的概率从clean_list上取一个擦写块下来。
由此可以看出JFFS2的设计思想是偏向于性能,同时兼顾磨损平衡。
对这个块上每一个没有过时的节点执行相同的操作:
1找出这个节点所属的i节点号(见图五)。
2调用iget(),建立这个i节点的文件映射表。
3找出这个节点上没有过时的数据内容,并且如果合法的数据太少,JFFS2还会合并相邻的节点。
4将数据读入倒缓存里,然后将它拷贝到新的擦写块上。
5将回收的节点置为过时。
当擦写块上所有的节点都被置为过时,就可以擦写这个擦写块,回收使用它。
挂载时间过长
JFFS2的挂载过程需要对闪存从头到尾的扫描,这个过程是很慢的,我们在测试中发现,挂载一个16M的闪存有时需要半分钟以上的时间。
磨损平衡的随意性(randomnature)
JFFS2对磨损平衡是用概率的方法来解决的,这很难保证磨损平衡的确定性。
在某些情况下,可能造成对擦写块不必要的擦写操作;在某些情况下,又会引起对磨损平衡调整的不及时。
很差的扩展性
JFFS2中有两个地方的处理是O(N)的,这使得它的扩展性很差。
首先,挂载时间同闪存的大小,闪存上节点数目成正比。
其次,虽然JFFS2尽可能的减少内存的占用,但通过上面对JFFS2的介绍我们可以知道实际上它对内存的占用量是同i节点数和闪存上的节点数成正比的。
因此在实际应用中,JFFS2最大能用在128M的闪存上。
JFFS2的新特性
最近加入到JFFS2中的两个补丁程序分别解决了上面提到的挂载时间过长和磨损平衡随意性的问题。
磨损块小结补丁程序
这个补丁程序最基本的思想就是用空间来换时间。
具体来说,就是将每个擦写块每个节点的原数据信息写在这个擦写块的最后,当JFFS2挂载的时候,对每个擦写块只需要读一次来读取这个小结节点,因此大大减少了挂载时间。
使用了磨损块小结补丁程序,一个擦写块的结构就像下面这样:
图五
根据我们的测试,使用磨损块小结补丁程序,挂载一个12M的闪存需要2~3秒,挂载一个16M的闪存需要3~4秒。
改进的磨损平衡补丁程序
这个补丁程序的基本思想是,记录每个擦写块的擦写次数,当闪存上各个擦写块的擦写次数的差距超过某个预定的阀值,开始进行磨损平衡的调整。
调整的策略是,在垃圾回收时将擦写次数小的擦写块上的数据迁移到擦写次数大的擦写块上。
这样一来我们提高了磨损平衡的确定性,我们可以知道什么时候开始磨损平衡的调整,也可以知道选取哪些擦写块进行磨损平衡的调整。
擦写块头部补丁程序
在写改进的磨损平衡补丁程序的过程之中,我们需要记录每个擦写块的擦写次数,这个信息需要记录在各自的擦写块上。
可是我们发现JFFS2中缺少一种灵活的对每个擦写块的信息进行扩展的机制。
于是我们为每个擦写块引入了擦写块头部(header),这个头部负责纪录每个擦写块的信息(比如说擦写次数),并且它提供了灵活的扩展机制,将来如果有新的信息需要记录,可以很容易的加入到头部之中。
[1]
2.YAFFS文件系统简介
YAFFS(YetAnotherFlashFileSystem)是第一个专门为NANDFlash存储器设计的嵌入式文件系统,适用于大容量的存储设备;并且是在GPL(GeneralPublicLicense)协议下发布的,可在其网站免费获得源代码。
YAFFS是基于日志的文件系统,提供磨损平衡和掉电恢复的健壮性。
它还为大容量的Flash芯片做了很好的调整,针对启动时间和RAM的使用做了优化。
它适用于大容量的存储设备,已经在Linux和WinCE商业产品中使用。
YAFFS中,文件是以固定大小的数据块进行存储的,块的大小可以是512字节、1024字节或者2048字节。
这种实现依赖于它能够将一个数据块头和每个数据块关联起来。
每个文件(包括目录)都有一个数据块头与之相对应,数据块头中保存了ECC(ErrorCorrectionCode)和文件系统的组织信息,用于错误检测和坏块处理。
充分考虑了NANDFlash的特点,YAFFS把这个数据块头存储在Flash的16字节备用空间中。
当文件系统被挂载时,只须扫描存储器的备用空间就能将文件系统信息读入内存,并且驻留在内存中,不仅加快了文件系统的加载速度,也提高了文件的访问速度,但是增加了内存的消耗。
为了在节省内存的同时提高文件数据块的查找速度,YAFFS利用更高效的映射结构把文件位置映射到物理位置。
文件的数据段被组织成树型结构,这个树型结构具有32字节的节点,每个内部节点都包括8个指向其他节点的指针,叶节点包括16个2字节的指向物理地址的指针。
YAFFS在文件进行改写时总是先写入新的数据块,然后将旧的数据块从文件中删除。
这样即使在修改文件时意外掉电,丢失的也只是这一次修改数据的最小写入单位,从而实现了掉电保护,保证了数据完整性。
结合贪心算法的高效性和随机选择的平均性,YAFFS实现了兼顾损耗平均和减小系统开销的目的。
当满足特定的小概率条件时,就会尝试随机选择一个可回收的页面;而在其他情况下,则使用贪心算法来回收最“脏”的块[2]。
原理简介
YAFFS文件系统是按层次结构设计的,分成以下4部分:
yaffs_guts.c,文件系统的主要算法,这部分代码完全是用可移植的C语言编写的;yaffs_fs.c,LinuxVFS层的接口;NAND接口,yaffs_guts和NAND内存访问函数之间的包装层,例如调用Linuxmtd层或者RAM模拟层;可移植函数,服务的包装函数。
最重要的一点是,为了获得更好的移植性,YAFFS提供直接调用的模式,这才使得我们有机会来实现YAFFS文件系统在C51系统上的移植。
3.SFFSFlashFileSystem
Summary
SFFSisaSafeFlashFileSystemthatcansupportalmostanyNORorNANDflashdevice. Itprovidesahighdegreeofreliabilityandcompleteprotectionagainstunexpectedpowerfailureorresetevents. SFFSprovideswearleveling,badblockhandlingandECCalgorithmstoensureyougetoptimaluseoutofaflashdevice.SFFSispre-integratedwiththeMQXRTOSandallowsyoutoquicklycreateaarobustfilesystemforanembeddeddeviceusingon-chiporon-boardflashdevices.
KeyFeatures
DesignedforEmbedded|NAND/NORSupport|Reliability&Integrity|HighPerformance|MaximumUseofFlash|OptimizedforColdFireandPowerArchitecture|Licensing|CompatibleProducts
DesignedforEmbeddedApplications
TheSFFSFlashFileSystemwasspecificallydesignedforembeddedsystems. Takingintoaccountthelimitedmemoryandreal-timeresponserequirementofmanyembeddedapplications,SFFSallowsembeddedsoftwaredeveloperstoimplementafullfeaturedfilesystemthatusesflashdevicesasastoragemedium.Thismeansthatembeddedapplicationscanreadandstoredataintonon-volatileandinexpensiveflashmemoryinsteadofrequiringaharddiskdriveorothermechanicalmedia.Akeyrequirementofaruggedflashfilesystemistheabilitytomaintainthefilesystemintegrityacrossunexpectedpowerlossorresetsthatarecommoninmanyembeddeddevices.SFFSisdesignedtoensurethatthesoftwareneverriskscor
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Nand flash文件系统总结 flash 文件系统 总结