Flash文件系统介绍和平台采用squashfs+ubifs原因
嵌入式系统与通用PC机不同,一般没有硬盘这样的存储设备而是使用Flash闪存芯片、小型闪存卡等专为嵌入式系统设计的存储装置。因此在嵌入式系统很少使用PC上常用的文件系统,取而代之是根据flash其特点定制的文件系统。
一、常见文件系统简介
Romfs 传统型的Romfs文件系统是最常使用的一种文件系统,它是一种简单的、紧凑的、只读的文件系统,不支持动态擦写保存;它按顺序存放所有的文件数据,所以这种文件系统格式支持应用程序以XIP方式运行,在系统运行时,可以获得可观的RAM节省空间。uClinux系统通常采用Romfs文件系统。
XIP(eXecuteIn Place,即芯片内执行,指应用程序可以直接在flash闪存内运行,不必再把代码读到系统RAM中。flash内执行是指norflash 不需要初始化,可以直接在flash内执行代码。但往往只执行部分代码,比如初始化RAM.) Cramfs Cramfs是Linux的创始人LinusTorvalds开发的一种可压缩只读文件系统在Cramfs文件系统中,每一页被单独压缩,可以随机页访问,其压缩比高达2:1,为嵌入式系统节省大量的Flash存储空间。Cramfs文件系统以压缩方式存储,在运行时解压缩,所以不支持应用程序以XIP方式运行,所有的应用程序要求被拷到RAM里去运行,但这并不代表比Ramfs需求的RAM空间要大一点,因为Cramfs是采用分页压缩的方式存放档案,在读取档案时,不会一下子就耗用过多的内存空间,只针对目前实际读取的部分分配内存,还没有读取的部分不分配内存空间,当我们读取的档案不在内存时,Cramfs文件系统自动计算压缩后的资料所存的位置,再即时解压缩到RAM中。
另外,它的速度快,效率高,其只读的特点有利于保护文件系统免受破坏,提高了系统的可靠性;但是它的只读属性同时又是它的一大缺陷,使得用户无法对其内容对进扩充。cramfs支持最大单个文件是16M。 Ramfs/Tmpfs Ramfs也是LinusTorvalds开发的,Ramfs文件系统把所有的文件都放在RAM里运行,通常是Flash系统用来存储一些临时性或经常要修改的数据,相对于ramdisk来说,Ramfs的大小可以随着所含文件内容大小变化,不像ramdisk的大小是固定的。Tmpfs是基于内存的文件系统,因为tmpfs驻留在RAM中,所以写/读操作发生在RAM中。tmpfs文件系统大小可随所含文件内容大小变化,使得能够最理想地使用内存;tmpfs驻留在RAM,所以读和写几乎都是瞬时的。tmpfs的一个缺点是当系统重新引导时会丢失所有数据。
SQUASHFS
Squashfs(.sfs)是一套供Linux核心使用的GPL开源只读压缩文件系统。Squashfs能够为文件系统内的文件、inode及目录结构进行压缩,并支持最大1024千字节的区段,以提供更大的压缩比。
Squashfs的设计是专门为一般的只读文件系统的使用而设计,它可应用于数据备份,或是系统资源紧张的电脑上使用。标准版的Squashfs采用gzip的数据压缩。
以下是squashfs文件系统的特点:
1.数据(data),节点(inode)和目录(directories)都被压缩。
2.保存了全部的32位UID/GIDS和文件的创建时间.(注: cramfs是8位,没有创建时间)。
3.支持多达4G的文件系统.(cramfs是16M)。
4.节点和目录都是高度压缩,而且都是存储在字节边界(packedon byte boundaries); 所有压缩的节点长度平均在8个字节左右.(具体的长度根据文件的类型是不同的.比如,普通文件,目录,符号链接,块设备和字符设备的节点的大小就不一样)。
5.squashfs可以on-the-flight:一种将许多比块size小的文件存储在一个块中,以达到更大的压缩率。同时支持big和littleendian架构.
JFFS2 JFFS2是RedHat公司基于JFFS开发的闪存文件系统,最初是针对RedHat公司的嵌入式产品eCos开发的嵌入式文件系统,所以JFFS2也可以用在Linux,uCLinux中。JFFS文件系统最早是由瑞典AxisCommunications公司基于Linux2.0的内核为嵌入式系统开发的文件系统。JFFS2是一个可读写的、压缩的、日志型文件系统,并提供了崩溃/掉电安全保护,克服了JFFS的一些缺点:使用了基于哈希表的日志节点结构,大大加快了对节点的操作速度;支持数据压缩;提供了“写平衡”支持;支持多种节点类型;提高了对闪存的利用率,降低了内存的消耗。这些特点使JFFS2文件系统成为目前Flash设备上最流行的文件系统格式,它的缺点就是当文件系统已满或接近满时,JFFS2运行会变慢,这主要是因为碎片收集的问题。 YAFFS YAFFS/YAFFS2是一种和JFFSx类似的闪存文件系统,它是专为嵌入式系统使用NAND型闪存而设计的一种日志型文件系统。和JFFS2相比它减少了一些功能,所以速度更快,而且对内存的占用比较小。此外,YAFFS自带NAND芯片的驱动,并且为嵌入式系统提供了直接访问文件系统的API,用户可以不使用Linux中的MTD与VFS,直接对文件系统操作。YAFFS2支持大页面的NAND设备,并且对大页面的NAND设备做了优化。JFFS2在NAND闪存上表现并不稳定,更适合于NOR闪存,所以相对大容量的NAND闪存,YAFFS是更好的选择。在具体的嵌入式系统设计中可根据不同目录存放的内容不同以及存放的文件属性,确定使用何种文件系统。
UBIFS
无排序区块图像文件系统(UnsortedBlock Image File System,UBIFS)是用于固态硬盘存储设备上,并与LogFS相互竞争,作为JFFS2的后继文件系统之一。真正开始开发于2007年,并于2008年10月第一次加入稳定版本于Linux核心2.6.27版。
UBIFS最早在2006年由IBM与Nokia的工程师ThomasGleixner,ArtemBityutskiy所设计,专门为了解决MTD(MemoryTechnology Device)设备所遇到的瓶颈。由于NandFlash容量的暴涨,YAFFS等皆无法再去控制NandFlash的空间。UBIFS通过子系统UBI处理与MTDdevice之间的动作。与JFFS2一样,UBIFS建构于MTDdevice 之上,因而与一般的blockdevice不兼容。
UBIFS在设计与性能上均较YAFFS2、JFFS2更适合MLCNAND FLASH。[1]例如:UBIFS支持write-back,其写入的数据会被cache,直到有必要写入时才写到flash,大大地降低分散小区块数量并提高I/O效率。UBIFSUBIFS文件系统目录存储在flash上,UBIFSmount时不需要scan整个flash的数据来重新创建文件目录。支持on-the-flight压缩文件数据,而且可选择性压缩部份文件。另外UBIFS使用日志(journal),可减少对flashindex的更新频率。
JFFS2运行在MTD设备之上,而UBIFS则只能工作于UBIvolume之上。也可以说,UBIFS涉及三个子系统:
1. MTD 子系统,提供对flash芯片的访问接口,MTD子系统提供了MTDdevice的概念,比如/dev/mtdx,MTD可以认为是rawflash
2. UBIsubsystem,为flashdevice提供了wear-leveling和volume management功能;UBI工作在MTD设备之上,提供了UBIvolume;UBI是MTD设备的高层次表示,对上层屏蔽了一些直接使用MTD设备需要处理的问题,比如wearing-leveling以及坏块管理。
3.UBIFS文件系统,工作于UBI之上
以下是UBIFS的一些特点:
(1)可扩展性:UBIFS对flash尺寸有着很好的扩展性;也就是说mount时间,内存消耗以及I/O速度都不依赖于flash尺寸(对于内存消耗的描述并不完全准确,但是依赖性非常的低);UBIFS可以很好的运行在GB级的flashe设备; 当然UBI本身还是有扩展性的问题,无论如何UBI/UBIFS都比JFFS2的可扩展性好,如果UBI成为瓶颈,可以改进UBI而不需改变UBIFS本身。
(2)快速mount:不像JFFS2,UBIFS在mount阶段不需要扫描整个文件系统,UBIFSmount的时间只是毫秒级,时间不依赖与flash的尺寸;然而UBI的初始化时间是依赖flash的尺寸的,因此必须把这个时间考虑在内。
(3)write-back支持:回写或者叫延迟写更准确些吧,同JFFS2的write-through(立即写入内存)相比可以显著的提高文件系统的吞吐量。
(4)异常unmount适应度:UBIFS是一个日志文件系统可以容忍突然掉电以及unclean重启;UBIFS 通过replay日志来恢复uncleanunmount,在这种情况下replay会消耗一些时间,因此mount时间会稍微增加,但是replay过程并不会扫描整个flash介质,所以UBIFS的异常mount时间大概在几分之一秒。
(5)快速I/O- 即使我们disablewrite-back(可以在unmount时使用-osync mount选项), UBIFS的性能仍然接近JFFS2;记住,JFFS2的同步I/O是非常惊人的,因为JFFS2不需要在flash上维护indexingdata结构, 所以就没有因此而带来的负担;而UBIFS恰恰是有index数据的,UBIFS之所以够快是因为UBIFS提交日志的方式:不是把数据从一个地方移动到另外一个位置,而只是把数据的地址加到文件系统的index,然后选择不同的eraseblock作为新的日志块,此外还有multi-headed日志方式等技巧。
(6)on-the_flightcompression -存储在flash介质上的数据是压缩的;同时也可以灵活的针对单个文件来打开关闭压缩。例如,可能需要针对某个特定的文件打开压缩;或者可能缺省方式下支持压缩,但是对多媒体文件则关闭压缩。
(7)可恢复性- UBIFS可以从index破坏后恢复;UBIFS中的每一片信息都用一个header来描述,因此可以通过扫描整个flash介质来重构文件系统,这点和JFFS2非常类似。想像一下,如果你擦除了FAT文件系统的FAT表,对于FAT文件系统是致命的错误,但是如果擦除UBIFS的index,你仍然可以重构文件系统,当然这需要使用一个用户空间程序来做恢复
(8)完整性-UBIFS通过把checksum写到flash介质上来保证数据的完整性,UBIFS不会无视损坏的文件数据或meta-data;缺省的情况,UBIFS仅仅检查meta-data的CRC,但是你可以通过mount选项,强制进行dataCRC的检查。
二、目前我们andorid项目上可选的文件系统
对于nandflash适合用的文件系统 有cramfssquashfs yaffs/yaffs2 ubifs。
Cramfssquash是只读性质的文件系统,有利于保护文件系统不受损坏,但无法对其文件进行改变,不利于测试时文件的替换与更改以及升级时候的增量升级。
对于slc:一般用cramfs+yaffs.很多项目都有用,经的起验证的。Ubifs最近才流行的文件系统,在slc上博通和我们都做过验证,没有发现什么问题。
对于大容量的MLC我们做过的验证:4台盒子nandflash型号为MT29F32G08CBACAWP(4GB),ubifs文件系统、/rootfs(系统文件存放区)挂载为只读、/data(应用安装文件所在区)挂载为读写。120s断电一次,拷机7天: