FAT over NAND Flash

2010-07-27  张芳芳 

FAT over NAND Flash


引子

最近有一个项目需要在NAND FLASH裸片上建立文件系统,由于必须通过USBWindows访问,所以FAT是唯一的选择。由于FAT不是为Flash设计,因此需要透过FTLFlash Translation Layer)来访问NAND FLASH

原本以为FTL的支持在嵌入式Linux下是很成熟的,因为在编译内核时,MTD下就有可选的FTLNFTL可供选择,但是dig进去才发现原来事情比想象的复杂。

首先科普一下:

1 FLASH的擦除循环寿命比较有限。对于NOR FLASH大约100万次,对于NAND FLASH大约10万次(SLC)或几万次(MLC)。

2NAND FLASH出厂时可能存在坏块,而且在使用中有可能不断地产生新的坏块。所谓坏块其实通常从仅有一个bitSLC)或数个bitsMLC)出错开始。一般可以通过ECCBCHRS算法还原数据来大幅度提升NAND FLASH的寿命(10倍左右)。

3)可擦除块: FLASH与磁盘的一个重要区别,就是FLASH在写入之前必须先进行擦除。经过擦除后的FLASH,内容全部为‘1’。写入的过程就是把一些'1'的比特改成'0'。对于FLASH存储器,内容为'0'的比特数据需要擦除为‘1’后才能再次写入(变为'0')。对于NAND FLASH还更复杂些,NAND FLASH的存储单位被组织成页,页的大小一般为512/1024/2048/4096字节,同一个页的写入次数有限制(称为'写入区'写入区的个数就是页写入的最大次数),通常为2次。FLASH的可擦除块一般在数十k到几百k

4FTL FLASH传输层软件,有两个作用,一是对FLASH写入进行负载均衡,由此提升FLASH的寿命;二是提供类似传统磁盘大小的块(512 bytes)访问界面,以便可以在FLASH上使用为磁盘存储介质而设计的文件系统,如FAT

5NFTL:适合NAND FLASHFTL。与NOR FLASH相比,增加了坏块管理,页管理,以及ECC等纠错措施。

为什么要FTL

由于传统的文件系统不是为Flash而设计的,如果直接在Flash上运行会很快使Flash局部老化而丢失数据,或崩溃。另外由于FLASH的块比较大,如果直接映射成块设备的话,空间利用率低。

FTL的作用就是解决负载均衡与提供适合传统文件系统的,大小合适(如512字节)的块设备。

MTD

很多刚接触Linux MTD系统的人,很容易把mtdFTL搞混了。mtd设备是一个字符设备(或者叫"flash"设备),它提供了访问FLASH存储器的通用界面。MTD还带了一个简单的模拟块设备:mtdblock。虽然mtdblock提供了大小合适的块,但它不具备负载均衡的能力,也不具备坏块管理的能力。我们可以通过mtdblock设备安装传统文件系统(如FAT文件系统),但是如果在上面进行写入操作的话,会迅速磨损FLASH。(如果安装的是一个只读文件系统,则没有问题)

许多Flash-aware-filesystem,如JFFSYAFFS,通过mtd来访问FLASH;而要在FLASH上使用传统文件系统,一个可靠的FTL是一定需要的。

Linux下的FTLNFTL

Linux内核的MTD子系统中带有FTLNFTL,但它们实际上不是通用的FTL,有诸多的限制。更要命的是它的许可证:

写道

LEGAL NOTE: The FTL format is patented by M-Systems. They have
granted a license for its use with PCMCIA devices:

"M-Systems grants a royalty-free, non-exclusive license under
any presently existing M-Systems intellectual property rights
necessary for the design and development of FTL-compatible
drivers, file systems and utilities using the data formats with
PCMCIA PC Cards as described in the PCMCIA Flash Translation
Layer (FTL) Specification."

Use of the FTL format for non-PCMCIA applications may be an
infringement of these patents. For additional information,
contact M-Systems (http://www.m-sys.com) directly.

 

在嵌入式系统中,FLASH通常是直接与CPU通过内存总线通讯,而不是PCMCIA接口,因此这个许可证就使得通过非PCMCIA接口使用FTL有可能侵权。

也许是因为这个原因,FTLNFTL代码中并不提供对非DiskOnChip(PCMCIA) 设备的支持。

UBI

UBI原本是为了实现更好的负载均衡(全片负载均衡)和更好的扩展性。UBI架构在MTD之上,它要完成的工作就是实现透明的负载均衡和坏块管理,让上层的文件系统从这两部分繁重的工作中释放出来。

看起来与FTL很接近了,只可惜它提供的不是我们需要的块设备。与MTD一样,它提供的界面是"flash"设备,供flash-aware-filesystem使用。例如可以在UBI之上使用JFFS2(据说可以获得更好的负载均衡特性),或者专门设计的UBIFS

UBI是由Nokia开发人员发起的项目,开发者声称基于UBI建立FTL很容易...容易到他们都不屑于去实现它了。我们悲哀地发现,虽然UBI项目已经有好几年了,也进入main stream内核了,却还看不到基于它的FTL

其实并不是没有人需要FTL,在google上搜一下就会发现有大把的人在寻找在Linux下可用的FTL,最终得到的答案要么是没有,要么是基于UBI很容易实现FTL”云云。

其实从技术上讲基于UBI实现FTL确实是省了很多事。事实上确实有人做过,也把patch发到UBI项目,但被拒了,好像是由于几个很小的问题,包括代码格式等等。其实那些UBI家伙根本不想(或这不屑?)去实现FTL界面,他们的逻辑是:FTL是给legacy filesystem用的,既然有更好的flash-aware-filesystem,为什么不用?FAT?不是应该扔垃圾堆了么?....他们在无视某些东西。

丑陋的妥协方案

项目不能等UBI家伙们实现FTL,而自己实现时间上不允许。只能用丑陋的妥协方案:

 

1)在NAND上安装YAFFS2over mtd

2)在YAFFS2分区上创建一个文件,attach一个loop device到这个文件。

3)对这个loop device运行fdisk创建分区,格式化等。

4)重新attach loop device到这个文件(从分区偏移量处开始)。

5mount FAT到这个loop device上进行读写。

6)要通过USB访问时,指定usb mass storage模块的file参数到此文件上即可。

 

这些工作通过几个简单的脚本即可完成。

这个方案的优点是借用YAFFS2实现了负载均衡,缺点是透过loop device来安装FAT文件系统性能差。实际测试,通过USB传输大约仅300KB/s ARM9, 200MHZ, USB 2.0 full speed)。而如果通过mtdblock而不是loop mount的话,可以达到700KB/s.

399°/3994 人阅读/0 条评论 发表评论

登录 后发表评论