综述
UBI全称Unsor te d Block Images,是一种原始flash设备的卷管理系统。这个系统能在一个物理的flash设备上管理操纵多个卷并且能在整个flash芯片上实现损耗均衡。
从某种意义上说,UBI和LVM有点相似,LVM将逻辑扇区映射到物理扇区上面,UBI映射逻辑擦除块到物理擦除块。但是除了映射,UBI还实现了全局的损耗均衡和透明的I/O错误处理。
一个UBI卷就是一串连续的逻辑擦除块。每一个逻辑擦除块可以被映射到任何一个物理擦除块上面。这个映射是由UBI管理,这种映射对用户是透明的,同时这种映射也是UBI实现全局的损耗均衡的基础。通过每一个物理擦除块记录的擦除计数,可以将数据从损耗严重的物理块转移到损耗较少的擦除块。
UBI卷的大小在卷被创建的时候被指定,这个大小也可以动态的被改变。有用户空间工具可以用来操作UBI卷。
总共有两种类型的UBI卷,一种是动态卷,一种是静态卷。静态卷是只读的,内容被CRC-32校验保护。动态卷可读可写,上层软件负责数据完整性。
UBI能管理flash的坏块,这样上层软件可以不需要考虑坏块。UBI有一个预留的物理块池,当一个物理擦除块坏掉了,UBI会利用预留的块来替代这个坏块。UBI将数据从新出现的坏块上转移到预留的好块上面。这个功能的好处就是应用层软件不会感知到底层的I/O错误。
NAND Flash在读写的时候可能会出现bit翻转,bit翻转可以被ECC校验来纠正,但是这种现象长期积累会导致数据丢失。UBI将出现bit翻转块上的数据转移到其它块上面。这种机制叫做冲刷,冲刷过程在后台完成,对上层软件是透明的。
下面是UBI特性的列表
1. UBI提供一种卷的机制,可以动态创建、删除、重设置卷大小等操作
2. UBI在整个Flash设备上提供了损耗平衡的机制,你可以不断的对某一个逻辑擦除块进行擦除,UBI会将你的操作均匀分散到其它各个物理块上面。
3. UBI透明的处理Flash上面的坏块
4. UBI通过冲刷机制最大限度的减小数据丢失的几率
5. UBI和MTD分析对比,有如下的特点。
6. 两者都由擦除块组成,在UBI中是逻辑擦除块,在MTD分区中是物理擦除块。
7. 两者都支持三种基本的擦做,read、write和erase
8. UBI卷没有擦除块损耗均衡的限制,用户层软件不需要关注损耗均衡,简化了用户层软件的设计
9. UBI卷没有坏块的情况需要考虑,这也使得上层软件设计简单
10. UBI卷可以被动态创建、删除和重新分配大小,而MTD分区是静态的。
11. UBI能处理bit翻转的情况,用户层软件不需要考虑bit翻转
12. UBI提供了卷升级操作,这样可以简单的探测软件升级的中断并且予以恢复
13. UBI提供了原子逻辑擦除块更换操作,这个操作允许更改逻辑擦除块中的内容过程中如果遇到了断电重启等情况不会丢失原来逻辑擦除块中的内容。这个功能对上层软件比如文件系统特别有用。
14. UBI提供un-map操作,这种操作只是将逻辑块和物理块之间的映射去除掉,然后调度物理块进行后台擦除操作,这个过程非常迅速,上层软件不需要等待较长的擦除时间。
UBI 对外提供一种块设备,允许随机访问,块适应的文件系统挂载在UBI卷上面。实现这种功能的主要原因是UBI卷不需要考虑坏块。
另外UBI还额外提供一种叫做gluebi的驱动来在UBI卷上模拟MTD设备,这种做法看起来有一点奇怪,因为UBI本身工作在MTD设备上面,而gluebi又要在UBI上模拟一个MTD设备。但是这种做法实际是可行的,这样可以在UBI上运行诸如jffs2之类的软件。尽管如此,新软件还是能充分利用UBI的特性,让UBI来处理Flash技术引入的一些问题。
UBI用户空间工具
下面列举了UBI相关的一些工具 ubinfo - 提供从系统中找到的UBI设备、UBI卷的相关信息
1. ubiattach - 链接MTD设备(MTD设备描述原始Flash设备)到UBI并且创建相应的UBI设备;
2. ubidetach - ubiattach相反的操作,将MTD设备从UBI设备上去链接;
3. ubimkvol - 从UBI设备上创建UBI卷;
4. ubirmvol - 从UBI设备上删除UBI卷;
5. ubiblock - 管理UBI卷上的block;
6. ubinize - 制作UBI镜像;
7. ubiformat - 格式化恐的Flash设备,擦除Flash,保存擦除计数,写入UBI镜像到Flash;
8. mtdinfo - 报告从系统中找到的UBI设备的信息.
UBI头
UBI存储两个64字节的文件头在每一个非坏块的起始位置
1. 擦除计数头(或者称为EC头)包含物理擦除块的擦除次数以及其它一些不太重要的信息
2. 卷 标记 头(或者称为VID头)包含了属于这块物理擦除块的卷ID和逻辑块号,另外包含了其它一些不太重要的信息
所有的UBI头都使用CRC-32校验来保护,用户可以参考/drive rs /mtd/ubi/ubi-media.h文件获得更加详细的文件头内容的信息。
当UBI链接一个MTD设备时,UBI系统会扫描整个MTD设备,读取所有的文件头,并且校验CRC-32的校验值。之后UBI系统会记录每个物理擦除块的擦除操作计数,同时建立逻辑块到物理块的映射到内存中。用户可以参考后面相关的章节了解这个过程的详细描述。
当UBI系统擦除了一个物理块,它会在这个物理块上写入一个EC头并且增加擦除计数。这意味着物理擦除块除了在擦除物理块到写入EC头的这段短暂时间内总有一个EC头,如果在上述短暂时间内系统发生了断电等情况,EC头会丢失或者损坏,这种情况下UBI系统重新写入一个EC头并且使用一个整个扫描计算得到的UBI的平均擦除计数作为EC头的擦除计数。
逻辑擦除块的去映射操作只是将逻辑块从映射的物理块去映射然后调度物理块进行擦除操作。擦除操作中EC头会被直接写入物理块中,而VID头并不写入物理块
逻辑擦除块的映射操作以及当往一个还没有映射的逻辑块中写入内容的时候。UBI寻找一个合适的物理块并且向其中写入VID头(此前EC头已经被写入到物理块中了)。需要注意的是如果向一个已经映射的逻辑块中写入内容的话只直接写入数据到映射到的物理块而不需要操作UBI头。
UBI系统为每一个物理块维护了两个文件头,主要的原因是UBI需要在不同的时间向Flash中写入不同的信息。这两个不同的时间点如下面所述。
当一个物理块被擦除后,UBI需要迅速向物理块中写入EC头记录这个物理块的擦除次数。以免这个擦除计数由于断电重启而被丢失的概率。
1. 当UBI映射一个物理块到逻辑块时,VID头会被写入到物理块中。
2. 当EC头被写入到物理块中的时候,UBI还不清楚这个物理块将要对应的卷ID和以后将要被映射的逻辑块号。这就是UBI需要使用两个分立的文件头的原因。
UBI 卷表
卷表示UBI系统保存在Flash上的一个数据结构,这个数据结构保存了一个UBI设备上面每一个卷的信息。一个卷表是每个卷记录信息的数组。每个卷记录信息包含了下面的具体内容:
卷大小,卷名称,卷类型(静态卷或者动态卷),卷对齐,升级标识(如果这个标记被设置标识在卷升级操作中操作被打断),自动重分配大小标记,这个卷记录的CRC-32校验。
每一条记录描述一个UBI卷,卷表上记录的索引表示卷ID。比如说卷0由卷表的第0条表项来描述,以此类推。卷表中的表项由逻辑卷的大小来限制,但是最大不能超过128条表项。这就是说UBI设备不能创建超过128卷。
每次创建、删除、重新分配卷大小、重新命名卷名、升级操作都会改变相应的卷表项。UBI维护了相同的两份卷表来增加UBI系统的可靠性。
具体实现细节
在UBI系统内部,卷表存储在特殊用途的卷上面,这个特殊用途的卷被叫做层卷。这个卷只包含了两个逻辑块,每一个中都包含了一个卷表的拷贝。层卷是一种UBI系统的"内部"卷,用户不能访问到这个卷,当UBI系统读写卷表时,使用和普通卷相同的机制。
UBI使用下面的算法来更新卷表记录项。
1. 将卷表的内容在内存中准备好。
2. 将层卷中的LEB0逻辑块进行去映射操作。
3. 将新的卷表项写入到层卷的LEB0逻辑块中。
4. 将层卷中的LEB1逻辑块进行去映射操作。
5. 将新的卷表项写入到层卷的LEB1逻辑块中。
6. 刷新UBI的工作队列确保之前去映射的逻辑块被擦除掉了
当UBI链接MTD设备的时候,必须确保两份卷表内容一致。如果两份卷表的内容不一致,就用LEB0逻辑块的卷标拷贝覆盖LEB1逻辑块的内容。如果其中某一份的内容损坏了,就用那份完整的拷贝覆盖损坏的内容。
Flash最小的输入/输出单位
UBI使用了一种抽象的Flash模型,简而言之就是,UBI将MTD设备看成事由一个个擦除块组成的,擦除块分为好块和坏块。好块可以进行读取,写入,擦除操作。
对Flash的读写操作都只能以最小擦除块的大小进行,这个大小取决于Flash的类型
NOR Flash通常的最小IO大小事1字节,NOR Flash通常允许单字节的对Flash进行读写操作,NOR Flash甚至可以对设备上单比特进行操作
NAND Flash通常以512、2048、4096字节作为设备IO的最小单位,一般这个最小单位就是NAND Flash的一页的大小。NAND Flash将每一页的ECC校验值存储到OOB区中,这就意味着整个NAND Flash的一页内容必须一次写入从而可以计算出整个页的ECC校验值。整个页的内容页必须一次性读出以校验ECC校验值。Flash设备的最小IO大小是一个很重要的概念,对UBI系统有很多影响,比如说:
UBI系统中VID头部的位置就取决于Flash设备的最小IO大小,还有UBI系统中逻辑擦除块的大小也取决于Flash设备的最小IO大小。一般来说,最小IO值越大,逻辑擦除块反而会越小,原因是UBI头占用的空间会越大。
所有对逻辑擦除块的写操作都必须是和最小IO值对齐的,必须是最小IO值的整数倍。对于读操作没有这样的限制,事实上在MTD设备层面也是按照最小IO值大小进行读取的,读入到一个缓冲空间后,最后只拷贝了用户请求的字节数目给用户。