UBIFS
无排序区块镜像文件系统(Unsorted Block Image File System, UBIFS)是用于固态存储设备上,并与LogFS相互竞争,作为JFFS2的后继文件系统之一。真正开始开发于2007年,并于2008年10月第一次加入稳定版本于Linux核心2.6.27版。 由IBM、nokia工程师Thomas Gleixner、Artem Bityutskiy等人于2006年发起,致力于开发性能卓越、扩展性高的FLASH专用文件系统,以解决嵌入式环境下以FLASH作为MTD设备使用时的技术瓶颈。在设计与性能上均较YAFFS2、JFFS2更实用于MLC NAND FLASH。1. UBI layerUBIFS涉及三个子系统:>MTD系统,提供对各种flash芯片的访问接口;drivers/mtd>UBI系统,工作在MTD上,提供UBI volume;drivers/mtd/ubi>UBIFS文件系统,工作在UBI之上;fs/ubifsUBI指的是UBI subsystem,其工作在MTD设备上,是MTD设备的高层次表示,对上屏蔽了一些MTD需要处理的问题,如wearing和坏块处理;而UBIFS指的是UBIFS file system,工作在UBI卷层之上。2. UBIubi provide logical volumes instead of MTD partitionsubi volumes are in a way similar to LVM volumesubi volumes may be dynamcially created, deleted and re-sizedubi does wear-leveling(磨损平衡算法) across whole MTD device
Wear-leveling is done by UBI, not by the UBI user3. UBI volume vs MTD partition底层MTD的物理分区(PEB)和上层逻辑分区(LEB)有映射关系,这样做的好处是在上层读写数据时不会考虑底层坏块的影响。4. volume update operationVolume is in “corrupted” state if update is interrupted“corrupted” volumes are not usable and must be updatedDynamic volumes are read-write
Static volumes are read-onlyStatic volumes are protected by CRC-32 checksum5. 如何挂载ubi文件系统UBI character devices:a) /dev/ubi0, /dev/ubi1, … – UBI devices: volume create, delete, re-size, and get device description operationsb) /dev/ubi0_0, /dev/ubi0_1, … - UBI volumes: read, write, update, and get volume description operationsUBI sysfs interface: /sys/class/ubi UBI in-kernel interface: include/linux/mtd/ubi.h Linux 系统中有关mtd和ubi的接口:(1) cat /proc/mtd:可以看到当前系统的各个mtd情况,(2) cat /proc/partitions: 分区信息,有上面的类似(3) cat /sys/class/ubi/ubi0/*:当前系系统的ubi情况(4) ls /dev/*, 查看设备节点假设我们想在mtdblock1上加载ubifs文件系统,步骤如下:(1)./ubiformat /dev/mtd1 -----格式化mtdblock1(2)./ubiattach /dev/ubi_ctrl -m 1 -----将mtdblock1与ubi建立连接,命令输出如下:[ 977.342492] UBI: attaching mtd1 to ubi2[ 977.346417] UBI: physical eraseblock size: 131072 bytes (128 KiB)[ 977.352631] UBI: logical eraseblock size: 126976 bytes[ 977.357948] UBI: smallest flash I/O unit: 2048UBI device number 2, total 2000 LEBs (253952000 bytes, 242.2 MiB), available 1976 LEBs (250904576 bytes, 239.3 MiB), LEB size 126976 bytes (124.0 KiB) 系统自动将mtd1关连到ubi2上,假设系统中已经存在ubi0, ubi1了。(3) ls /sys/class/ubi/ -----可以看到该目录下增加了一个ubi2的子目录(4) cat /sys/class/ubi/ubi2/dev -----可以得到该ubi2设备的主次设备号,如249:0(5) cat /sys/class/ubi/ubi2/volumes_count -----结果为0,表示该ubi上没有任何volume(6) ls /dev/ubi* -----如果/dev中没有ubi2, 则手工创建“mknod /dev/ubi2 c 249 0”(7) ./ubimkvol /dev/ubi2 -s 100MiB -N my_ubi_vol -----在ubi2上创建一个volume(8) ls /sys/class/ubi/ -----可以看到该目录下增加一个ubi2_0的目录,代表ubi2上的第一个volume,如果“cat /sys/class/ubi/ubi2_0/name”, 你可以得到“my_ubi_vol”,这就是(7)中的名字。(9) cat /sys/class/ubi/ubi2_0/dev -----得到该volume的主次设备号,如249:1(10) mknod /dev/ubi2_0 c 249 1 -----如果/dev中没有ubi2_0, 则需要手工创建(11) mount -t ubifs ubi2_0 /mnt -----将ubi2_0挂载到本地目录 /mnt上,(12) mount -----可以看到ubi2_0成功挂载在/mnt上。linux源码中Documentation/filesystems/ubifs.txt中含有ubifs mount的用法:Mount options=============(*) == default.bulk_read read more in one go to take advantage of flash media that read faster sequentiallyno_bulk_read (*) do not bulk-readno_chk_data_crc skip checking of CRCs on data nodes in order to improve read performance. Use this option only if the flash media is highly reliable. The effect of this option is that corruption of the contents of a file can go unnoticed.chk_data_crc (*) do not skip checking CRCs on data nodescompr=none override default compressor and set it to "none"compr=lzo override default compressor and set it to "lzo"compr=zlib override default compressor and set it to "zlib"Quick usage instructions========================The UBI volume to mount is specified using "ubiX_Y" or "ubiX:NAME" syntax, where "X" is UBI device number, "Y" is UBI volume number, and "NAME" is UBI volume name.
Mount volume 0 on UBI device 0 to /mnt/ubifs:
$ mount -t ubifs ubi0_0 /mnt/ubifsMount "rootfs" volume of UBI device 0 to /mnt/ubifs ("rootfs" is volume name):
$ mount -t ubifs ubi0:rootfs /mnt/ubifsThe following is an example of the kernel boot arguments to attach mtd0 to UBI and mount volume "rootfs":
ubi.mtd=0 root=ubi0:rootfs rootfstype=ubifs6. ubi简介ubi子系统可以理解为ubifs的驱动层,它在文件系统层和MTD层之间起到衔接作用。主要负责以下几个功能:》LEB到PEB的映射;》坏块的回收;》物理擦除块损耗均衡处理;》处理位翻转现象;》衔接MTD设备到UBI;》创建UBI卷;》挂载UBI文件系统UBI子系统重要的数据结构
》UBI卷表、UBI卷》LEB擦除块头:EC头、VID头》EC表、EBA表;(在内存中构建)》损耗均衡模块UBI卷
可分为静态卷和动态卷,静态卷只读,由CRC32校验和保护;动态卷是可读写的,该数据完整性由上层负责。根据用途,UBI卷可分为用户卷和内部卷,内部卷外部不可见,仅供UBI内部使用,现在UBI中只有一个内部卷:布局(layout)卷,其余全是用户卷。volume表:包含每个卷信息,比如卷的大小、卷更新标记、卷号等。维护在flash上,volume表存储在layout卷中,layout卷包含两个LEB,每个LEB都包含一份volume表。volume表仅在ubi卷被创建、删除和重定义大小时改变。
EBA(Erase Block Association,擦除块关联)表:所有LEB到PEB的映射信息。
EC(Erase Counter,擦除计数)表:EC表包含着每一个PEB的擦写次数。EBA和EC表是在每次挂载MTD设备时建立,这也意味着UBI必须扫描整个Flash,从每个PEB读取VID和EC头部以构造EBA和EC表。相对于volume表,EBA和EC表变动较大,因为每次对PEB写时都有可能修改表。每个UBI卷都有一个EBA表,用eba_tbl结构表示。EBA表的map和unmap操作对EBA表最重要的操作是map和unmap,map过程是首先找到相应的PEB,然后将VID头写入PEB,然后修改内存中相应的EBA表。unmap首先解除LEB与相应PEB的映射,然后调度擦除该PEB,unmap并不会等到擦除完成,该擦除由UBI后台进程负责。EC头:包含物理擦除块的擦除次数以及其它一些不太重要的信息。64bytes
VID头:包含属于这个PEB的卷ID和逻辑块号,及其它信息。512bytes注:每个非坏的PEB都包含一个EC头和VID头,一般EC在一个擦除块的第一页,所以偏移量是0,VID在擦除块的第二页,偏移量为一页大小。这也是逻辑擦除块小于PEB大小的原因,EC头和VID头占用了一些空间(两页大小)。UBI运行的时候需要占用一部分flash空间,这部分flash空间包括:2片PEB用于存储卷表(volume table)。卷表是一种数据结构,包含了UBI设备上每一卷的信息,它是一系列volume table record,其中每一个记录块上包含以下信息:卷大小(volume size)、卷名(volume name)、卷类型(volume type,dynamic or static)、volume alignment、更新标记(update marker,防止数据更新发生意外打断,可以恢复)、自重整大小旗标(auto-resize flags)、CRC-32 校验和等信息。之所以保留两份卷表,是为了提高稳定性和防止出现突然断电的状况。当访问MTD设备时,UBI需要确保两卷表是一致的,如果由于掉电或意外重启导致任何一种不一致状况,需要用较旧的卷表覆盖较新的卷表,确保一致;一旦有一个卷表损坏,可以使用另一个卷表。这俩卷表对用户来说,是不可见和不可访问的。1片PEB用于损耗平衡(wear-leveling)。UBI支持损耗平衡,这对有限次读写的flash来说可极大提高其使用寿命。在UBI模块中,会包含一个负责实现损耗平衡的独立损耗均衡单元,这个单元依据EC header和VID header来实现对每个物理擦除块所擦除的次数和所属逻辑单元的读取,利用红黑树法对每个擦除块进行保护和移动。
1片PEB用于atomic LEB change operation。
一部分PEB用于保存坏块的句柄。
7. UBIFS简介UBIFS文件系统运行在UBI系统之上,它会把UBI volume划分为6个部分:超级块(superblock area),使用LEB0区块。它在文件系统创建时建立,占用一片LEB存储uperblock node,一般来说,superblock node保存文件系统很少变化的参数。superblock node仅仅占用LEB0的前4096个字节。superblock几乎不改变,只有一种情况会导致superblock node被重写,就是自动resize时。之所以需要自动resize,是因为创建ubifs文件系统镜像时,并不知道将要mount的UBI bolume的大小,所以当我们将UBIFS镜像安装到UBI上时,UBI的尺寸可能实际上小于UBIFS镜像所需要的最大空间,此时就需要把UBIFS resize以适合UBI volume。存储配置信息,如索引树扇出(indexing tree fanout)、压缩类型等,在mount时被读。主节点区(master area),占用LEB1和LEB2两个分区。一般情况下,这两个LEBs保存着相同数据,master node尺寸为512 bytes,每次写入master node会顺序的使用LEB的空闲page,直到没有空闲page时,再从offset zero开始写master node,这时会重新unmapped LEBs为另一个erased LEB。注意,master node不会同时unmapped两个LEBs,因为这会导致文件系统没有有效master node,如果此时掉电,系统无法找到有效master node。master区域中每个master node指向一个索引的root node,这样就只需要在挂载的时候扫描master area便可以得到所有文件的信息。主节点存储着所有flash上没有固定逻辑位置的结构的位置(The master node stores the position of all on-flash structures that are not at fixed logical positions.)。
日志区间(Journal/log area,或commit area),从LEB3开始,占用空间不确定。UBIFS使用日志的目的是为了减少对flash index(main area区的文件的索引,实际索引)的更新频率,因为更新文件系统时,一旦添加叶子节点,整个文件系统的索引节点都要定期更新,这样的话会非常影响效率。因此采用日志区间,当添加叶子节点时,会先将其添加到日志中,只更新内存中的节点,不再提交到flash中,然后再定期提交日志,这样的话,效率会有极大的提高。当需要修改索引树叶节点时并不会马上更新flash上的索引树,首先要更新RAM中的TNC(索引在内存中的copy),同时将更新信息以日志方式记录在flash中(增加新的bud),等到commit时再更新闪存上的索引树。日志由log和bud(芽)组成,log记录日志位置,log包含两种类型的节点:commit开始节点(UBIFS_CS_NODE)、引用节点(UBIFS_REF_NODE)。commit开始节点记录commit过程的开始,引用节点记录bud的数量。日志有多个head,日志LEBs可以不连续。
UBI文件系统日志区是建立在Flash上的,每当文件系统运行时,都会将日志区这个结构映射到内存中,我们称为TNC树(也是B+树)。当我们要对文件系统节点修改、写数据的时候,先在内存TNC树做标记,等到commit的时候把修改的数据统一写到Flash中。TNC树是日志区在内存中的一个拷贝。内存紧张时TNC可被压缩LEB属性树区(LEB Properties Tree area,LPT area),跟随在log area之后,其大小在创建文件系统后确定(比main区indexing树小的多),LPT使用B+树(游离树)结构。LPT area 包含LEB Properties树,LPT area eraseblock表(ltab),以及saved LEB numbers表(lsave)。LPT area的大小在文件系统创建时就已经确定了,通过LEB 尺寸和文件系统最大LEB count自动计算出LPT area占用的LEB数目。LPT area类似一个小型的自包含文件系统,它有自己的LEB properties,也就是LEB properties area的LEB properties(ltab)。LPT area有自己的垃圾收集器。LPT area要求不能耗光自己的空间,能够快速访问和update,以及算法上的可扩展性。
UBIFS存储Flash上每个LEB信息(LEB类型:indexing或data,free和dirty space大小),整个flash信息(free和dirty space大小)等,方便UBIFS了解LEB信息。通过此区域可找到可用的LEB,可找到dirty LEB(供GC回收)等。孤儿区(orphan area),在LPT area和main area之间,使用固定数目的LEBs,一般来说占用一个LEB就够了,debug时额外占用一个LEB。orphan area记录已经删除的文件的索引号(inode number)。orphan area的意义在于删除过程unclean unmount发生,已经删除的孤儿inodes必须被删除,这就要求扫描整个index来查找他们,或者在某处保存一个列表,ubifs就是在orphan area保存这样一个列表。The orphan area is a fixed number of LEBs situated between the LPT area and the main area
main area,最后一个area,保存文件系统index node和non-index node,存储实际数据。UBIFS包含几种类型的non-index节点:file inode, directory entry,extend attribute entry和file data node。UBIFS维护着一棵wandering tree,叶子节点保存着文件信息,它们是文件系统的有效节点。树的内部节点是index node保存着到children的索引。所以wandering tree可以视为两个部分,顶部保存树结构的索引节点(index nodes),底部则是真正文件数据的leaf node(叶子节点)。
8. ubifs文件系统索引节点结构—B+树(游离树)
9. 垃圾回收一个空的LEB总是保留用作GC。10. Ubifs优点通过上面了解可推测出ubifs的性能特点。>>Good scalabilityData structures are treesOnly journal has to be replayed>> High performanceWrite-¬backBackground commitRead/write is allowed during commitMulti-¬head journal minimizes amount of GCTNC makes look¬ups fastLPT caches make LEB searches fast>>On¬-the-¬flight compression>>Power-¬cut toleranceAll updates are out¬-of-¬placeWas extensively tested>>High reliabilityAll data is protected by CRC32 checksumChecksum may be disabled for data>>RecoverabilityAll nodes have a header which fully describes the nodeThe index may be fully re¬constructed from the headers11. 一个示例[ 115.987823] UBIFS: mounted UBI device 0, volume 0, name "rootfs"[ 115.995452] UBIFS: file system size: 8888320 bytes (8680 KiB, 8 MiB, 70 LEBs)[ 116.003082] UBIFS: journal size: 1650688 bytes (1612 KiB, 1 MiB, 13 LEBs)[ 116.010742] UBIFS: media format: w4/r0 (latest is w4/r0)[ 116.016815] UBIFS: default compressor: lzo[ 116.021087] UBIFS: reserved for root: 0 bytes (0 KiB)[ 116.026458] UBIFS DBG msg: compiled on: Jul 9 2016 at 17:19:55[ 116.033355] UBIFS DBG msg: min. I/O unit size: 2048 bytes[ 116.039062] UBIFS DBG msg: max. write size: 2048 bytes[ 116.045440] UBIFS DBG msg: LEB size: 126976 bytes (124 KiB)[ 116.052246] UBIFS DBG msg: data journal heads: 1[ 116.057159] UBIFS DBG msg: UUID: 4EE5BE06-687A-467A-909B-856187011AA9[ 116.065460] UBIFS DBG msg: big_lpt 0[ 116.070343] UBIFS DBG msg: log LEBs: 4 (3 - 6)[ 116.075988] UBIFS DBG msg: LPT area LEBs: 2 (7 - 8)[ 116.081634] UBIFS DBG msg: orphan area LEBs: 1 (9 - 9)[ 116.087249] UBIFS DBG msg: main area LEBs: 70 (10 - 79)[ 116.095458] UBIFS DBG msg: index LEBs: 2[ 116.100341] UBIFS DBG msg: total index bytes: 59504 (58 KiB, 0 MiB)[ 116.107086] UBIFS DBG msg: key hash type: 0[ 116.115447] UBIFS DBG msg: tree fanout: 8[ 116.120361] UBIFS DBG msg: reserved GC LEB: 41[ 116.125335] UBIFS DBG msg: first main LEB: 10[ 116.135467] UBIFS DBG msg: max. znode size 240[ 116.140533] UBIFS DBG msg: max. index node size 192[ 116.145629] UBIFS DBG msg: node sizes: data 48, inode 160, dentry 56[ 116.153076] UBIFS DBG msg: node sizes: trun 56, sb 4096, master 512[ 116.160430] UBIFS DBG msg: node sizes: ref 64, cmt. start 32, orph 32[ 116.167968] UBIFS DBG msg: max. node sizes: data 4144, inode 4256 dentry 312, idx 188[ 116.176513] UBIFS DBG msg: dead watermark: 2048[ 116.185455] UBIFS DBG msg: dark watermark: 6144[ 116.190612] UBIFS DBG msg: LEB overhead: 2656[ 116.195800] UBIFS DBG msg: max. dark space: 430080 (420 KiB, 0 MiB)[ 116.202697] UBIFS DBG msg: maximum bud bytes: 1142784 (1116 KiB, 1 MiB)[ 116.209777] UBIFS DBG msg: BG commit bud bytes: 928512 (906 KiB, 0 MiB)[ 116.216705] UBIFS DBG msg: current bud bytes 55296 (54 KiB, 0 MiB)[ 116.223419] UBIFS DBG msg: max. seq. number: 8756[ 116.228607] UBIFS DBG msg: commit number: 831 [ 54.707519] UBIFS: mounted UBI device 0, volume 1, name "app"[ 54.713500] UBIFS: file system size: 49520640 bytes (48360 KiB, 47 MiB, 390 LEBs)[ 54.721496] UBIFS: journal size: 6729728 bytes (6572 KiB, 6 MiB, 53 LEBs)[ 54.729125] UBIFS: media format: w4/r0 (latest is w4/r0)[ 54.735198] UBIFS: default compressor: lzo[ 54.739471] UBIFS: reserved for root: 0 bytes (0 KiB)[ 54.744812] UBIFS DBG msg: compiled on: Jul 20 2016 at 11:29:21[ 54.751739] UBIFS DBG msg: min. I/O unit size: 2048 bytes[ 54.757446] UBIFS DBG msg: max. write size: 2048 bytes[ 54.763153] UBIFS DBG msg: LEB size: 126976 bytes (124 KiB)[ 54.769958] UBIFS DBG msg: data journal heads: 1[ 54.774871] UBIFS DBG msg: UUID: 7B480369-82F7-49A8-BB09-71B467D8B161[ 54.782958] UBIFS DBG msg: big_lpt 0[ 54.787872] UBIFS DBG msg: log LEBs: 4 (3 - 6)[ 54.793487] UBIFS DBG msg: LPT area LEBs: 2 (7 - 8)[ 54.799102] UBIFS DBG msg: orphan area LEBs: 1 (9 - 9)[ 54.807373] UBIFS DBG msg: main area LEBs: 390 (10 - 399)[ 54.813446] UBIFS DBG msg: index LEBs: 2[ 54.818359] UBIFS DBG msg: total index bytes: 199080 (194 KiB, 0 MiB)[ 54.827362] UBIFS DBG msg: key hash type: 0[ 54.832275] UBIFS DBG msg: tree fanout: 8[ 54.837371] UBIFS DBG msg: reserved GC LEB: 13[ 54.842346] UBIFS DBG msg: first main LEB: 10[ 54.847351] UBIFS DBG msg: max. znode size 240[ 54.852416] UBIFS DBG msg: max. index node size 192[ 54.857513] UBIFS DBG msg: node sizes: data 48, inode 160, dentry 56[ 54.864959] UBIFS DBG msg: node sizes: trun 56, sb 4096, master 512[ 54.872314] UBIFS DBG msg: node sizes: ref 64, cmt. start 32, orph 32[ 54.879852] UBIFS DBG msg: max. node sizes: data 4144, inode 4256 dentry 312, idx 188[ 54.888397] UBIFS DBG msg: dead watermark: 2048[ 54.893554] UBIFS DBG msg: dark watermark: 6144[ 54.898742] UBIFS DBG msg: LEB overhead: 2656[ 54.903900] UBIFS DBG msg: max. dark space: 2396160 (2340 KiB, 2 MiB)[ 54.910980] UBIFS DBG msg: maximum bud bytes: 6221824 (6076 KiB, 5 MiB)[ 54.918060] UBIFS DBG msg: BG commit bud bytes: 5055232 (4936 KiB, 4 MiB)[ 54.927368] UBIFS DBG msg: current bud bytes 63488 (62 KiB, 0 MiB)[ 54.934082] UBIFS DBG msg: max. seq. number: 10239[ 54.939331] UBIFS DBG msg: commit number: 4[ 55.548645] UBIFS: mounted UBI device 0, volume 2, name "db"
[ 55.554565] UBIFS: file system size: 181448704 bytes (177196 KiB, 173 MiB, 1429 LEBs)[ 55.562927] UBIFS: journal size: 9023488 bytes (8812 KiB, 8 MiB, 72 LEBs)[ 55.570556] UBIFS: media format: w4/r0 (latest is w4/r0)[ 55.576629] UBIFS: default compressor: lzo[ 55.580902] UBIFS: reserved for root: 0 bytes (0 KiB)[ 55.586273] UBIFS DBG msg: compiled on: Jul 20 2016 at 11:29:21[ 55.593170] UBIFS DBG msg: min. I/O unit size: 2048 bytes[ 55.598876] UBIFS DBG msg: max. write size: 2048 bytes[ 55.604614] UBIFS DBG msg: LEB size: 126976 bytes (124 KiB)[ 55.611419] UBIFS DBG msg: data journal heads: 1[ 55.617340] UBIFS DBG msg: UUID: 04BD616F-127C-4396-964E-8510279DEA60[ 55.625427] UBIFS DBG msg: big_lpt 0[ 55.630340] UBIFS DBG msg: log LEBs: 5 (3 - 7)[ 55.635955] UBIFS DBG msg: LPT area LEBs: 2 (8 - 9)[ 55.641601] UBIFS DBG msg: orphan area LEBs: 1 (10 - 10)[ 55.647399] UBIFS DBG msg: main area LEBs: 1429 (11 - 1439)[ 55.653656] UBIFS DBG msg: index LEBs: 1[ 55.658569] UBIFS DBG msg: total index bytes: 48 (0 KiB, 0 MiB)[ 55.667358] UBIFS DBG msg: key hash type: 0[ 55.672241] UBIFS DBG msg: tree fanout: 8[ 55.677124] UBIFS DBG msg: reserved GC LEB: 12[ 55.682128] UBIFS DBG msg: first main LEB: 11[ 55.687133] UBIFS DBG msg: max. znode size 240[ 55.692199] UBIFS DBG msg: max. index node size 192[ 55.697296] UBIFS DBG msg: node sizes: data 48, inode 160, dentry 56[ 55.707336] UBIFS DBG msg: node sizes: trun 56, sb 4096, master 512[ 55.717346] UBIFS DBG msg: node sizes: ref 64, cmt. start 32, orph 32[ 55.724884] UBIFS DBG msg: max. node sizes: data 4144, inode 4256 dentry 312, idx 188[ 55.733398] UBIFS DBG msg: dead watermark: 2048[ 55.738586] UBIFS DBG msg: dark watermark: 6144[ 55.743743] UBIFS DBG msg: LEB overhead: 2656[ 55.748931] UBIFS DBG msg: max. dark space: 8779776 (8574 KiB, 8 MiB)[ 55.756011] UBIFS DBG msg: maximum bud bytes: 8388608 (8192 KiB, 8 MiB)[ 55.763092] UBIFS DBG msg: BG commit bud bytes: 6815744 (6656 KiB, 6 MiB)[ 55.770172] UBIFS DBG msg: current bud bytes 0 (0 KiB, 0 MiB)[ 55.776428] UBIFS DBG msg: max. seq. number: 8[ 55.781311] UBIFS DBG msg: commit number: 012. more
参考:
1. http://www.linux-mtd.infradead.org/doc/ubifs.html2. http://www.linux-mtd.infradead.org/doc/ubi.html3. http://blog.csdn.net/xiaosong521/article/details/77646634. A Brief Introduction to the Design of UBIFS