一种微嵌入式Flash文件系统——μEFFS
2008-07-02
作者:胡德鹏1,2,李仁发1
摘 要: 针对Flash存储器的特性提出一种分层文件系统" title="文件系统">文件系统架构,抽象出逻辑存储器作为中间层" title="中间层">中间层,屏蔽了底层物理器件操作上的不足。本文件系统非常适合1GB以下容量的Flash存储器,具有可移植性高、访问效率高、寿命均衡等特性。
关键词: Flash存储器, Block, Page, 逻辑存储器, FAT
随着嵌入式系统" title="嵌入式系统">嵌入式系统应用的迅速发展,嵌入式系统被广泛应用于各行各业,嵌入式系统的数据存储问题随之变成了一个最核心的关键问题。由于Flash器件的迅速普及,使得Flash存储器的使用变得十分重要。同时,Flash器件本身固有的擦写寿命、不可字节擦除等特点也使Flash器件存储管理" title="存储管理">存储管理变得非常复杂。
目前嵌入式系统领域已有了一些较为成熟的Flash文件系统,如:嵌入式Linux中普遍使用的JFFS2日志文件系统、YAFFS文件系统。但是这些文件系统本身比较大,适合于大系统运行;并且经实践检验,这些文件系统对寿命的均衡处理并不像宣传的那样好,文件系统效率和可靠性也有待提高。
本文通过中间抽象逻辑存储器建立一种短小精炼、高性能、高可靠性、适合于嵌入式小型设备的嵌入式Flash文件系统——μEFFS。
实际上,通过更改底层物理存储器(软件),此文件系统也可以很方便地移植到其他器件上。而且通用文件系统(如:FAT文件系统)很容易移植到本文提出的中间层逻辑存储器上,从而使得通用文件系统也获得了Flash文件系统的特性,如:寿命均衡。
1 Flash存储器特性
(1)NAND Flash器件特点:高存储密度,采用页读写(读写速度快)、块擦除方式操作;容易发生位反转;存在坏块(存储不可靠性);容量一般较大(大于32MB);擦写寿命一般为100万次。
(2)NOR Flash器件特点:随机读写、块擦除;坏块少;器件本身存储可靠性高;擦写速度较慢;容量一般较小(小于16MB),擦写寿命一般为10万次。
(3)块(block):擦除的最小单元。
(4)页(page):即扇区,写的最小单元(NorFlash写的最小单元是字节,无页的概念)。
(5)擦除:存储单元的相应数据位由“0”变成“1”。Flash器件和普通存储器件不一样,它只能采用块擦除和片擦除两种操作方式。
2 Flash器件存储管理
由于Flash器件的读写特性,使Flash器件存储管理较为复杂,且容易出问题。
(1)寿命均衡问题:如果经常对同一单元进行擦写操作,这些单元将很快达到寿命极限,导致损坏。
(2)效率问题:如果每次改写1个字节的数据都采用擦写方式,将导致操作效率低下。
(3)NOR和NAND两种Flash区别明显。
嵌入式Flash文件系统需解决的核心问题都是围绕寿命均衡产生的,同时要兼顾性能和可靠性,最好能同时兼容两种Flash器件(NOR和NAND)。
3 μEFFS的核心原理
建立一种完美的“逻辑存储器”,在此逻辑存储器上,可以完全像操作硬盘一样进行读、写操作。
系统层次结构如图1所示。
这样利用抽象中间层逻辑存储器完全屏蔽了底层物理存储器的具体实现,同时各层之间接口简单,简化了系统,提高了系统的可移植性。中间层逻辑存储器将复杂的Flash操作简单化。系统结构如图2所示。
中间层逻辑存储器是对物理器件的一种抽象,这样做的好处是上层文件系统无需考虑底层的具体实现,同时有利于移植到其他物理器件上。
为适应各种不同的器件需要,系统建立统一的逻辑扇区Logic Sector(LS)。逻辑扇区大小和物理扇区相等,但是逻辑扇区的物理位置不固定,其实际地址通过BSAT来确定。同时系统为每个逻辑扇区编号(LSN),这个就是逻辑扇区访问的惟一指示器。对于每个物理块建立一个BSAT(块内扇区分配表,占用该块第一个扇区),用以描述这个块内所有扇区使用情况,分配表的每个单元最高2位表示扇区使用情况,剩下各位为逻辑扇区号。例如BSAT表项采用16位(即BSAT16),BSAT表项结构如表1所示。这样对整个存储系统的访问就完全变成对逻辑扇区的访问了。系统本质是建立逻辑扇区到物理扇区的映射表,同时在操作过程中维护这个映射表。
4 底层物理存储器
用于访问物理层硬件的主要函数有:
(1)FlashEraseChip():芯片整片擦除。
(2)FlashEraseBlock(INT32U dwBlockNo):块擦除。
(3)FlashWrite(INT32U dwAddr,INT8U * pBuff,INT32U dwSzie):将缓冲区的数据写入目标地址处。
(4)FlashWrite1Sec(INT32U dwSecNo,INT8U * pBuff):向目标扇区写数据。
(5)FlashRead(INT8U * pBuff,INT32 dwAddr,INT32U dwSzie):从指定地址处读数据。
(6)FlashRead1Sec(INT8U * pBuff,INT32U dwSecNo):从指定扇区读数据。
5 中间层逻辑存储器
5.1 系统初始化
对Flash进行扫描,建立Flash空扇区表和物理扇区映射表。
(1)空扇区表:EmptySecTable[SecNum/8],表中每一位表示一个扇区,为1表示该扇区为空,否则该扇区非空。
(2)物理扇区映射表:PhySecTable[LogicSecNum],表中每个单元的值为物理扇区号。
5.2 读访问
(1)根据PhySecTable[]找到逻辑扇区对应的物理扇区号。
(2)根据物理扇区号计算出物理地址。
(3)根据物理地址和扇区大小读取数据。
5.3 修改访问
(1)先按读访问,读取扇区数据。
(2)在内存中修改数据。
(3)根据EmptySecTable[]选取一个空扇区,将修改后的数据写入新扇区。
(4)改写新扇区所在块的BSAT表,标记该扇区为有效状态,同时将逻辑扇区号写入BSAT。
(5)修改EmptySecTable[]表中该扇区为非空扇区。
(6)修改原扇区的BSAT项,标记为无效状态。
注:修改访问都选择一个新物理扇区(page),然后写入数据,再将原物理扇区标记为无效,从而达到寿命均衡访问。
5.4 缓冲块
系统保留两个块用于碎片整理缓冲,缓冲块也称交换块,如果要实现更好的寿命均衡,也可以采用逻辑块的形式建立缓冲块。
5.5 Flash碎片整理
Flash碎片整理分为手动整理和自动整理。如果系统空扇区少于20%时,系统将自动进行碎片整理。
(1)系统复位初始化时,通过EmptySecTable[]判断是否需要整理;如果需要,则整理出一个块(block)。
(2)增加数据或修改数据时,如果发现空扇区少于10%,则整理出一个块,然后再进行操作。
(3)由于碎片整理比较耗时,所以每次只整理出一个块,目的是提高单次操作的性能。
(4)手动整理将对整个存储器进行整理,它可以在空扇区少于40%的情况下进行。
(5)整理过程:先擦除缓冲块(Buff block),然后将欲整理的块中有效扇区全部按顺序转移到缓冲块中,再擦除该块, 最后将缓冲块中的数据原样复制到该块。整理后需要更新空扇区表和块扇区分配表。
(6)整个系统只有碎片整理程序才会进行擦除操作,因此各块的寿命(次数)实际上就等于碎片整理的次数。
(7)碎片整理均衡策略:碎片整理每次只整理一个物理块,设立一个碎片整理块指针,用于指示下次需整理的块。这样保证均衡整理各块,均衡了各块寿命。
5.6 中间层逻辑存储器主要函数
(1)LogicMemFormat():擦除整片Flash,供上层调用。
(2)LogicMemInit():系统复位初始化调用,通过扫描Flash产生空扇区表和物理扇区映射表。
(3)ReadLogicSec(INT8U * buff,INT16U wLogicSecNo):根据逻辑扇区号读取扇区数据。
(4)WriteLogicSec(INT16U wLogicSecNo,INT8U * buff):将数据写入逻辑扇区,这个要考虑是追加还是修改。
(5)INT16U GetAFreeSec():获取一个空扇区号(未使用的物理扇区号)。
(6)FlashMemRep1Block():碎片整理1块。
(7)FlashMemRepAll():整片碎片整理。
6 上层文件系统
在中间层逻辑存储器的基础上,可以建立各种类型的文件系统。这样建立的文件系统已经具有良好的Flash文件系统特性。本文件系统采用类似于FAT文件系统的处理方法。
(1)主引导记录MBR(保留区):包含启动代码和分区表" title="分区表">分区表,这个区主要借鉴了已有文件系统的设计思想(采用磁盘文件系统类似的方法处理),主引导记录占用逻辑扇区0。实际上只要有BIOS的支持,本文件系统完全可以和已有的文件系统一样引导操作系统或者应用软件(只要搜索到逻辑算区0就找到了主引导记录);采用分区表的方法则有利于扩大整个文件系统管理空间的大小(如采用FAT16格式,4个分区表项分别指示4个不同的分区,相当于文件系统所能管理的空间扩大了4倍)。
主引导记录占用逻辑扇区0。
(2)系统引导记录DBR:用于指示文件分配表的位置、大小、个数和根目录区位置、大小、项数。系统引导记录占用逻辑扇区1。
(3)文件分配表(FAT):用于指示文件的逻辑扇区号链,由于建立了物理扇区映射表,所以,可以高效地进行数据访问。文件分配表本身占用逻辑扇区号,文件分配表的大小、个数,由系统引导记录指示。
(4)文件目录表(FDT):分为根目录和子目录。子目录实际上也是文件(和普通文件完全一样),这里不详细讨论。根目录表主要目的用于指示根目录中各文件(含子目录)在FAT中的第一个扇区号。
根目录的位置和大小在系统引导记录中指示。
7 系统整体运行机制
(1)系统初始化:系统启动时进行初始化,构建中间层逻辑存储器。此时建立空扇区表和逻辑扇区到物理扇区的映射表。
(2)文件读、写操作:根据主引导记录(逻辑扇区0)找到所在分区引导记录(系统引导记录);根据分区引导记录找到根目录区;根据根目录项,找到文件分配表(FAT)中相应的入口;根据FAT入口进行文件读、写操作。上述所有操作都是根据逻辑扇区号进行访问的,实际访问通过查找物理扇区映射表进行。
本文通过中间层抽象逻辑存储器建立了一种Flash文件系统,并命名为μEFFS。μEFFS特别适合于小型嵌入式系统(8位、16位、32位系统均可良好运行),具有寿命均衡、性能好、可靠性高的特点,经受了实践的考验。通过对本系统的裁剪,很容易将其移植到单片机系统中,这样也给目前的低端8位单片机系统提供了一种数据存储解决方案。
参考文献
[1] 马忠梅,李善平,康慨,等.ARM&Linux嵌入式系统教程.北京:北京航空航天大学出版社,2005.
[2] 周立功.ARM嵌入式系统实验教程(2).广州:广州周立功单片机发展有限公司,2005.
[3] LABROSSE J J著,邵贝贝译.?滋C/OS-Ⅱ-源代码公开的实时嵌入式操作系统.北京:中国电力出版社,2001.
[4] MALIK V.JFFS-Aracticalguid.http://www.embeddelinuxworks.com/articles/,2001,05.