首页 理论教育 YAFFS原理解析起步—嵌入式Linux编程入门与开发实例

YAFFS原理解析起步—嵌入式Linux编程入门与开发实例

时间:2023-10-31 理论教育 版权反馈
【摘要】:YAFFS文件系统提供了应用程序接口。YAFFS文件系统数据的存储布局见表7-4。为了避免这种情况下的二义性,YAFFS在空闲空间中使用了一个2比特的标识符。YAFFS对坏块的管理分以下两种情况。

YAFFS原理解析起步—嵌入式Linux编程入门与开发实例

YAFFS文件系统提供了应用程序接口(API)。用户可以不必使用MTD和VFS就能直接操作文件。与YFFS2文件系统相比,YAFFS文件系统少了一些功能,但同时也获得了更少的内存占用和更快的速度。

1.数据结构

所有YAFFS涉及到的数据结构都在yaffs_guts.h文件中已定义,主要的数据结构有yaffs_Object、yaffs_Tnode和yaffs_Device。yaffs_Tnode和yaffs_Object按组分配,以减少总的内存分配和释放。已经被释放的yaffs_Tnode和yaffs_Object保存在一个空闲链表上,并被重新使用。

(1)yaffs_Object结构

其定义如下:

978-7-111-33316-6-Chapter07-24.jpg

在yaffs_Object结构中主要包含:

文件属性,如修改时间、用户ID和组ID等。

●用做yaffs文件系统维护用的各种标记位,如脏(dirty)标记和删除标记等。

●用做组织结构的,如指向父目录的parent指针,以及指向同级目录中其他对象链表的siblings双向链表头结构等。

此外,根据Object类型(目录、文件、链接)的不同,对应于某一具体类型的Object在yaffs_Object中还有其各自专有的数据内容。

yaffs_Object可以是一个文件、目录、软链接或者硬链接。yaffs_Object知道它们在NAND中对应的yaffs_ObjectHeader以及这个对象的数据。

(2)yaffs_Tnode结构

yaffs_Tnode组成一个树的数据结构,这样就能在一个文件中快速搜索到所需的数据块。随着文件的增大,树的层数也相应地增加。yaffs_Tnode结构有固定的大小——32B。最下面一层由16个2B的入口组成,每个入口给出了用来查找块ID的索引。其他几层由8个4B的指针组成,这些指针指向树中更底层的树节点。

当文件刚被分配到物理页面中时,它先分配一个Tnode。随着文件的逐渐增大,分配的页面也越来越多,到了一个Tnode已经不能容纳下这些分配的页面时,就再分配一个Tnode,另外再加一个内部Tnode,这个Tnode里的指针指向上面两个Tnode。随着文件越来越大,底层和上层的Tnode也就逐步多了起来。

(3)yaffs_Device结构

yaffs_Device结构为文件和存储页面建立了映射关系,主要用来存储一些相关软硬件的配置信息、相关函数指针和统计信息等,包括

●起始参数设置:每页的字节数、每块的页数、起始块、结束块和保留的块数等。

●NAND访问函数,需要在YAFFS调用前设置。

●两个信号量,用来保证线程互斥的变量。

●块信息:使用的位图指针、位图占用的字节数、擦除的块、分配的块、分配的页、查找下一个可以分配的块。

●运行时的状态:创建的节点数量、空闲的节点、空闲的节点数量,分配的节点列表、创建的对象数量、空闲的对象、空闲对象的数量、可分配的对象列表和空闲的页等。(www.xing528.com)

●挂载后的状态。

2.YAFFS文件系统数据在NAND上的存储方式

YAFFS将文件系统上的所有内容(如正常文件、目录、链接和设备文件等)统一当做文件来处理,每个文件都有一个页面专门存放文件头。文件头保存了文件的模式、所有者id、组id、长度、文件名和parentObjectID等信息。因为需要在一页内放下这些内容,所以对文件名的长度,符号链接对象的路径名等长度都有限制。对于NANDFlash上的每一页数据,都有额外的空间用来存储附加信息。通常,NAND驱动只使用了这些空间的一部分。YAFFS充分利用了NANDFlash提供的每个页面16B的额外空间。YAFFS参考了SmartMedia的设定,使用6B用做页面数据的ECC,2B分别用做块状态字和数据状态字,其余的8B(64位)用来存放文件系统的组织信息,即元数据。这些元数据包括页面所属的文件id(18位),页面在文件中的位置(22位),序列号(2位),页面内实际使用的字节数(10位),以及元数据本身的ECC(12位)。YAFFS文件系统数据的存储布局见表7-4。

3.日志技术的实现

YAFFS中使用了“先写后清除”的措施,保证了如果出现错误,原始的数据还是可用的,从而保证了数据的可恢复性。

表7-4 YAFFS文件系统数据的存储布局

978-7-111-33316-6-Chapter07-25.jpg

“先写后清除”算法是保证文件系统可恢复性的核心。当需要更新Flash上一个数据块或者数据页面的数据时,并不按照传统方式先将该数据块数据清除,再写入新数据,而是在系统中找一个干净的数据块进行写操作,等到数据写操作完成后,才将原来的数据块清空。在写操作提交以前,文件系统中只有原始的数据块才是有效的。

但是应该看到,如果在一个写操作中已经将对应的日志节点头等信息写入,没有将旧的页面置为无效页面,如果在这时发生系统故障,就会在文件系统中出现两个相同的日志节点,而这两个节点的校验都是合法的。为了避免这种情况下的二义性,YAFFS在空闲空间中使用了一个2比特的标识符。页面发生替换时,文件页面替换对应的标识符序列增加1,序列号大的就是新的页面,就不会出现上面提到的同时具有两个有效页面的问题了。

4.坏块管理

由于Flash内部会有坏块,因此Flash存储管理系统需要对Flash进行坏块管理。YAFFS对坏块的管理分以下两种情况。

1)初始坏块的处理:Flash存储器在使用前可能会有坏块,而且这些坏块是随机分布的,所以对Flash存储器进行初始化扫描以发现坏块,并将坏块标记为不可用。

2)操作过程中坏块的处理:如果在擦除或者编程过程中发生错误,YAFFS将该块中其他页的数据重新复制到一个新的空块中,然后再将该块标记为坏块。在这个处理过程中,由于对Flash的擦除或者编程操作都会使得Flash存储单元块的内容改变,所以Flash文件管理系统一旦发现Flash存储器的存储单元块成为坏块后,便不再对该块进行擦除或编程操作,以免将坏块标志位数据清除掉。

在进行上述坏块管理后,坏块单元对用户应用是完全透明的。

5.YAFFS的块和页面管理

文件在存储介质中都是按照块来存储的,而且这些块的大小都是固定的。在NAND Flash中,每个块的大小都是16KB。块的大小确定后,接下来的问题是如何记录空闲块,目前有两种方法可以使用:一种是使用磁盘块的链接表,每个块中包含尽可能多的空闲磁盘块号,对于1KB大小的块和32位的磁盘块号,空闲块链表中的每个块都包含有255个空闲块块号(需要使用一个项存放指向下一个块的指针)。通常是使用空闲块来存放空闲块链表。

空闲块的另一个办法是使用位图。N个块的磁盘需要N位的位图。在位图中,空闲块用1表示,分配块用0表示(反之亦可)。空闲块较多时,位图模型所需要的空间要远远少于链表模型所需的磁盘空间。在链表模型中每个块要用到32位,而在位图模型中每个块只需1位。只有磁盘已经快满时,链接表方案需要的空间才会比位图方案小。在嵌入式系统中,非易失性存储空间本来就不会很多,也不需要用多少内存来存放位图,所以采用位图方案是嵌入式系统应用的必然选择。

YAFFS中的每个擦除块都有一个数据结构来描述它的状态,并将这些数据结构组织在一个数组中。该数据结构记录了块状态,并用一个32位的位图表示块内各个页面的使用情况。在YAFFS中有且仅有一个块处于“当前分配”状态。新页面从当前进行分配的块中顺序进行分配。若当前块已满,则顺序寻找下一个空闲块。

6.YAFFS的垃圾搜集机制

日志文件系统中采用的垃圾回收算法很多,贪心策略就是其中的一种。但是,这些基于块状态计算的方法都会产生损耗的不平均。JFFS的顺序回收方法虽然有完美的损耗平均性能,但效率低,开销太大。YAFFS使用一种多策略混合的算法来进行垃圾回收,将贪心策略和随机选择策略按一定比例混合使用。当满足特定的小概率条件时,垃圾回收器会试图随机选择一个可回收的页面,而在其他情况下,则使用贪心策略回收最“脏”的块。通过使用多策略混合的方法,YAFFS能够有效地改善贪心策略造成的不平均,而通过不同的混合比例,可以控制损耗平均和系统开销之间的平衡。考虑到NANDFlash的擦除很快(和NORFlash相比可忽略不计),YAFFS将垃圾收集的检查放在写入新页面时进行,而不是采用JFFS那样的后台线程方式,从而简化了设计。

免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。

我要反馈