在NAND FLASH存储器上建立FAT文件系统的优化方法
技术领域
本发明涉及一种建立FAT文件系统的优化方法,尤其是涉及在NANDFLASH上建立FAT文件系统的优化方法,实现FAT文件系统的掉电保护,负载均衡,坏块管理和优化读写速度。
背景技术
随着Nand闪存制造工艺的不断改进以及制造成本的不断下降,Nand闪存已经成为移动存储市场的主流存储介质。NAND Flash存储器是一种数据正确性非理想的器件,容易出现位反转现象,同时在使用中可能会有坏损单元。数据写入必须在空白的区块或者擦除后的区块中进行,其底层技术要求以块为单位进行擦除(将“0xff”写入到要擦除的存储块中),再按页写入。NAND Flash存储器的擦除次数是有限的,一般是100000次。根据以上特点,为了避免某些块的过度操作,而导致存储卡使用寿命降低,设计专门针对Flash存储器的文件系统是必要的。
目前嵌入式设备的Flash文件系统主要有三种:MSystems公司的TrueFFS、J FFSx以及唯一专门针对NAND Flash设计的YAFFS。但是现在大多数嵌入式手持设备上的操作系统采用FAT文件系统,而FAT文件系统并不适合直接移植到NAND Flash存储器中,这主要有以下两个原因:第一,嵌入式系统的应用条件恶劣,电源电压不稳定,突发性断电以及非法插拔都将对Flash的存储造成灾难性的影响;通用文件系统对于可靠性的设计考虑不足。第二,通用文件系统的记录信息需要被多次改写(如FAT表),而记录信息放在固定的区块中,将导致该区块的频繁使用,影响整个Flash器件的使用寿命。如果通过灵活的校验机制与坏区管理,则可以达到更高效的存储空间利用率,这对成本敏感的嵌入式系统来说是更加需要考虑的。
传统的块映射技术将Flash存储器上的块以线性方式映射,但会带来两个问题。第一,当写入的页面数比Flash规格块页面数小时,也要将整个块拷入内存中,修改对应的页面,擦写Flash块,然后把内存的块数据写入Flash,而且由于频繁的数据拷贝,会导致访问Flash速度变慢。第二,仍然解决不了擦写平衡的问题。另外如果系统断电,那么不仅仅是要写入的数据,而且全部的块数据也全部丢失。
发明内容
本发明的目的在于提供一种在NAND Flash存储器上建立FAT文件系统的优化方法,使NAND Flash存储器支持FAT文件系统,并且提高对NAND Flash存储器的访问速度。
操作文件系统的基本原理是:把NAND Flash存储器的存储空间划分为连续的逻辑块,逻辑块划分为连续的逻辑页面,逻辑页面包含多个连续的字节。文件系统发来带逻辑地址的读写请求,每次读写一个或多个页面。文件系统需要根据逻辑地址计算出该逻辑地址所在的逻辑块,然后根据逻辑块和物理块的对应关系找到实际的物理块,再在该物理块上找到真正要读写的物理页面。
本发明采用逻辑块与物理块采用一对多的机制,将NAND Flash存储器文件系统中映射到同一个逻辑块的多个物理块采用双向链表的形式表示;双向链表的头节点(逻辑块节点)表示一个逻辑块,物理块节点表示一个物理块,如果多个物理块映射到同一个逻辑块,则对应这些物理块的物理块节点链接在逻辑块节点上,组成一个双向链表;另外文件系统有多个逻辑块,本发明再把多个逻辑块节点又以双向链表的方式连接起来,这样就组成了一个二层次的双向链表;这个二层次的双向链表就是逻辑地址和物理地址的映射链表。本发明同时建立一个数据结构叫MTD代理对象,这个数据结构标明每个逻辑块是否对应有物理块映射在双向链表中。
本发明中将物理块记录在链表上,文件系统每次读写请求都经过这个映射链表找到真正要读写的NAND Flash物理块;文件系统需要写某个逻辑块里的某些页面,可以取出一个NAND Flash物理块,建立一个物理块节点表示该物理块,再把物理块节点链接在逻辑块头节点上,然后把数据写到该物理块上的那些页面上。如果采用一个逻辑块对应一个物理块,因为NAND Flash先擦后写的特性,首先要把对应的物理块原有的所有页面的数据拷贝到内存上,然后把数据写在内存块中需要写的页面上,再擦除原来的物理块,最后才把内存中的那一整块所有页面写到物理块上。而采用本发明采用一对多的映射关系只需在内存中建立一些数据结构,只写需要写的物理页面,不用写整个物理块所有页面,大大提高的速度。
当在NAND Flash存储器的某个物理块第一次使用时,因为物理块中没有原始数据,所以可以直接写那个物理块,并不需要去访问双向链表去找到实际要写的物理块。如果没有物理块映射在链表中,则通过简单通用的线性映射找到物理块,找到物理块并写完数据后,就建立一个物理块节点,挂接在链表上,原来的简单通用线性映射就改变为链表方式映射了。如果有物理块映射在链表中,则要查找链表,从而找到一个可写的物理块。
作为对本发明进一步的改进和优化,在文件系统的长期使用过程中,当文件系统发来写请求时,需要在双向链表上查找可写的物理块,如果不可以在已映射的物理块上写,则要取出一个新的物理块。本发明还在NAND Flash存储器中划分一定数目的物理块作为备用物理块,在内存中建立一个备用块对象用于管理备用物理块;备用块的数目约占NAND Flash存储器总物理块数的5%-10%。备用块在NAND Flash存储器中的位置不是固定的,备用块对象要记录好每个备用块的位置;上述需要的新物理块就可以从备用物理块中取出。
取出备用块作为物理块,把该物理块映射到逻辑块上,因此会不断地消费备用块,最后令备用块不断减少,所以必须要释放掉多余的物理块,作为回收的备用块。释放掉多余的物理块可以采用以下两种途径:
(1)映射到同一逻辑块的多个物理块的相同页面都写有数据,表示该逻辑块的那个逻辑页面先后被内核写了几次,最近写的那次才是有效的数据,以前写的数据都是无效的。因为本发明把每次写的数据都保留下来,写在多个物理块中,也就是说一个逻辑页面对应多个物理页面,只有最近一次写的那个物理页面是有效的。如果发现几个物理块在相同页面号的逻辑页面上都写有数据,则只有一个物理块是有效的,则只需保留最新写有数据的物理块,其他物理块就释放并作为备用块。
(2)在文件系统的长期使用过程中,会随机访问各个逻辑块,有些逻辑块先后被写多次。当备用块减少到一定程度时,选择写次数最少的逻辑块,从备用块中分配一个物理块,把映射到该逻辑块的多个物理块的有效数据拷贝到取出的物理块中,拷贝完后多个物理块就可以释放掉,然后把那一个物理块映射到该逻辑块上。
由于挂接在链表上的物理块分散在NAND Flash存储器上,所以回收这些物理块作为备用块最终会使备用块分散在NAND Flash存储器中;这样备用块是分散且位置不断变化,所以从长期来看,达到了写均衡的效果。
作为对本发明进一步的改进和优化,本发明在NAND Flash存储器每一个块内的每一个页中的空闲区(OOB)除存放ECC校验,坏块信息外,还把层次关系,写次数,最大使用页面号信息写入空闲区;内存中也要建立数据结构记录这些信息。在每一块第一页的空闲区(OOB)设定块标记字段,标记该块是否为备用块。当重启系统或者意外掉电,都能够根据这些信息重新建立起各种数据结构,达到断电保护的作用。
本发明中,如果文件系统需要逆序写或者该逻辑块的某个逻辑页面重复写,那么就在备用块对象中分配一个物理块,映射到双向链表中。当文件系统需要往某个逻辑块写数据时,并不是每次都要从备用块中取出一块作为可写物理块。MLC型NAND Flash有不可逆序写的特性:一个物理块内的某个页面写了数据,下一次又要写该物理块的另外一些页面,并且要写的页面号小于当前已经写有数据的页面号,这就是逆序写。通用的方法是把该物理块原有的全部页面拷贝到内存中,再把文件系统要写的页面数据也写到内存中,两部分页面数据组成一个新的块,然后擦除原来的物理块,再把内存中的那个块的数据写到物理块中。本方案则采取另外的办法,当发现要逆序写时就从备用块中分配一块作为可写物理块。与MLC型NAND Flash不同,SLC型的NAND Flash是可以逆序写的。无论是MLC型还是SLC型,都不允许重复写:当文件系统需要往一个物理块的某个页面写数据,而该页面已经写有数据,这种情况通用的方法也是先擦后写,而本方案则是从备用块中分配一个物理块。由于文件系统并不是每次请求都是逆序的或者重复写同一个页面,所以并不是每次都要从备用块中分配物理块,有时还是可以在原有映射的物理块中直接写其他页面的,只是从长期的运行来看,本方案会不断地取出备用块作为可写物理块。本方案会对MLC型和SLC型NANDFlash区别对待。
本发明与现有技术相比,具有以下的效果:
(1)由于将NAND Flash存储器文件系统中映射到同一个逻辑块的多个物理块采用双向链表的形式表示,每次写请求只需写那几个需要写的页面,并不用写整个块所有页面,从而提高了写文件的速度。
(2)由于释放掉多余的物理块给备用块对象去管理,可以令备用块分布在NAND Flash的各个地方,当写操作需要从备用块中取出一块时,这一物理块的地址具有随机性,保证了写均衡。
(3)由于在页面的空闲区(OOB)中保留了各种信息,当系统正常重启或者意外掉电重启时,系统根据这些信息得以重新建立逻辑地址和物理地址的映射关系、记录坏块地址和建立其他各种数据结构,可以恢复到原来的状态,实现掉电保护的功能。
附图说明
图1是逻辑块与物理块的映射图,映射到同一逻辑地址的物理块采用双向链表连接。
图2是扫描操作流程图。
图3是MTD扫描过程对象关系图。
图4是MTD写操作流程图。
图5是MTD写过程对象关系图。
图6是MTD读操作流程图。
图7是MTD读过程对象关系图。
具体实施方式
采用本发明方法在linux的MTD层的基础上实现对NAND Flash存储器的写均衡、坏块管理、掉电处理功能。
逻辑块与物理块采用一对多的机制,映射到同一个逻辑块的多个物理块采用双向链表连接,如图1所示。用逻辑块节点结构体记录一个逻辑块的相关信息,如该逻辑块的逻辑地址、写次数、最大使用页地址,用物理块节点结构体记录一个物理块的信息,映射到同一个逻辑块的物理块结构体就以双链表的方式连接在一起。文件系统逻辑块号通过地址映射链表对象找到NAND Flash物理块号。
同时从NAND Flash中划分固定数目的物理块作为备用物理块,备用块的数目约占NAND Flash存储器总物理块数的5%-10%。
如图2、图3所示,系统每次使用NAND Flash前都要对NAND Flash进行扫描操作,读取块和页面信息,用以建立起逻辑地址和物理地址的映射关系,还建立几个结构体对象:
1)MTD代理对象,该对象主要用于处理内核发来的读写请求,内核请求可以通过它找到实际物理地址。MTD代理对象记录两种类型的地址映射关系:一种是逻辑地址映射物理地址,另一种是逻辑地址映射逻辑块节点在内存中的地址。
2)备用块对象,备用块对象主要用于对备用(Spare)块的管理,主要负责分配备用物理块用于读写操作,回收物理块到备用区。
3)地址映射链表,该对象用于记录一个逻辑地址影射多个物理地址的信息,并且管理双向链表。逻辑块节点结构体记录一个逻辑块的相关信息,如该逻辑块的逻辑地址、写次数等;物理块节点结构体记录一个物理块的信息,如该物理块的物理地址、最大使用的页面地址、在双向链表中的位置。
4)Flash驱动,对Flash的底层读写操作。
在NAND Flash存储器的每一个页中均包含一个2048字节的数据区和64字节的空闲区,或者包含一个512字节的数据区和16字节的空闲区(OOB)。OOB区除了存放ECC校验,坏块信息外,还把层次关系,写次数,最大使用页面号写入OOB区。另外NAND Flash第一次使用时备用块在Flash低地址处,但在Flash的使用过程中,备用块分布在整个Flash中,在每一块第一页的空闲区(OOB)设定块标记字段,可以标记该块是否为备用块。同时内存中也要建立对象记录上述所有的信息。
扫描时,读取空闲区(OOB)信息,发现如果是备用块,则在备用块对象中记录该块是备用块。如果是有效物理块,分两种情况:如果在OOB中发现该物理块记录着一个逻辑块地址,则在MTD代理对象中用简单线性方式映射物理地址和逻辑地址;如果在OOB中发现该物理块记录的是一个内存地址,这个内存地址就是逻辑块节点在内存中的地址,证明上次使用NAND Flash时在地址映射链表对象中存在逻辑块节点和物理节点对应该物理块,因此需要根据OOB信息在内存中复原这个链表节点,同时修改MTD代理对象,表明该物理块是用链表方式映射的。如果是坏块,则丢弃。
如图4、图5所示,写操作时内核发来的读写请求地址是逻辑地址,内核请求首先访问MTD代理对象,分两种情况:
1)在MTD代理对象中发现该逻辑块与物理块是线性映射的,证明该逻辑块第一次使用,并且在地址映射链表对象中还没有表示该逻辑地址的逻辑块节点和物理块节点,因此需要在内存中分配一个逻辑块节点和一个物理块节点,把它们挂接在双向链表上,接着MTD代理对象记录逻辑地址与该逻辑块节点内存地址的映射关系,这时才把数据写入物理块上。
2)在MTD代理对象中发现该逻辑地址对应的是逻辑块节点的内存地址,则利用MTD代理对象找到逻辑块节点的内存地址,然后通过双向链表找到物理块节点,再通过物理块节点找到实际的物理地址,然后写数据。
通过双向链表找物理块节点的过程是:首先访问地址映射链表对象看能否在已经映射的物理块上写数据,如果是逆序写或一个页面重复写,则不能在已经映射的物理块上写,而需要从备用块对象中分配一个块,然后把数据写入新的物理块,同时要建立一个表示该物理块的节点,把它挂接在链表上。写完数据后还需要把逻辑块节点的内存地址、最大使用的页面地址、在双向链表中的位置等信息写入当前物理块的OOB区,目的在于下次启动做扫描操作时能恢复这个链表。
数据和OOB都写完以后,检查一下当前备用分区中已经分配了多少个物理块,在NAND Flash的使用过程中,逻辑地址和物理地址的映射层次越来越多,备用块的消耗也越来越多,如果达到一定数目,可以根据实际需要设定该数目,可以设为剩余备用块占总数的四分之一,就要释放掉多余的物理块,并把这些释放掉的物理块给备用块对象去管理。
回收物理块的途径有两个:第一,由于有多个物理块映射到同一逻辑块,在Flash的使用过程中,可能多个物理块内相同页号的逻辑页面都写有数据,因此只需保留最新的物理块就行了,其他物理块就可以释放并作为备用块;第二,从备用块中分配一个物理块,选择写次数最少的逻辑块,把映射到同一逻辑块的多个物理块的数据拷贝到那一块中,拷贝完后多个物理块就可以释放掉。这样可以令备用块分布在NAND Flash的各个地方,当写操作需要从备用块中取出一块时,这一块的地址具有随机性,保证了写均衡。
如图6、图7所示,读操作时,也首先访问MTD代理对象,如果在MTD代理对象中发现该逻辑地址对应的是物理地址,则直接在那个物理块上读数据;如果在MTD代理对象中发现该逻辑地址对应的是逻辑块节点的内存地址,则访问地址映射链表对象,从映射该逻辑地址的多个物理块中选择一个正确的物理块,然后把数据读出来。
另外,当系统正常重启或者意外掉电重启时,由于在页面的空闲区(OOB)中保留了各种信息,系统根据这些信息得以重新建立逻辑地址和物理地址的映射关系、记录坏块地址和建立其他各种数据结构;建立好所有对象后还要进行物理块的合并操作和回收备用块。