Buildroot下UBI mkfs&volume介绍
- Tools
Buildroot调用如下的tools来制作UBI fs及volume image,代码源代码在如下package。
Buildroot/output/build/host-mtd-1.5.2
源代码打印非常友好,makefile中开启-v选项可以很有效的调试;
- mkfs.ubifs ------ for ubi fs/usr.mnt_app.ubifs
ubinize基于mkfs.ubifs生成UBI分区image
- ubinize ------ for volume image/usr.mnt_app.ubi
以下工具用来协助调试
- mtdinfo ------ 查看mtd device 信息
- ubinfo ------ 查看ubi分区信息
buildroot打开如下选项会编译生成这些工具:
Target packages >
Filesystem and flash utilities>
[*] mtd, jffs2 and ubi/ubifs tools
- UBI flash空间开销(overhead)
UBI使用了一部分的flash空间用于它自身功能的实现,因此UBI用户所获得的空间会比实际的flash空间要少。也就是说:
Ø 两个PEB用来存储卷表
Ø 一个PEB被保留,用以损耗均衡
Ø 一个PEB被保留,用以原子LEB改变操作
Ø 一定数量的PEB被保留,用以处理坏PEB;这个是用于NANDflash而不是NOR flash;保留的数量是可配置的,默认情况是每1024块保留20块。
Ø 在每个PEB的开头存储EC头和VID头;这个所占用的字节数因flash类型的不同而不同。
Ø 如果支持FASTMAP功能,需要额外的block来支持,一般一个FASTMAP BLOCK小于一个LEB,因此需要保留两个LEB给FASTMAP使用;具体的空间消耗,参考kernel中的如下函数:
接下来将会进行解释。
符号解释:
Ø W--flash芯片上的PEB总数(注意:是整块芯片,而不是MTD分区)
Ø P—MTD分区上PEB总数
Ø SP--PEB大小
Ø SL –LEB大小
Ø BB –MTD分区坏块数
Ø BR –为处理坏PEB而预留的PEB数。对于NANDflash默认等于20*W/1024,NOR flash为0
Ø B—MAX(BR,BB)
Ø O—存储EC和VID头的开销,单位为字节。例如O = SP – SL
这样UBI的开销为(B +4) * SP + O * (P – B – 4)。这就是用户所不能获得的总字节数。O因flash的类型的不同而不同。
Ø 对于NOR flash来说,O是128字节
Ø 对于没有子页的NANDflash,O是两个NAND页,如果一个NAND页是2k,那么O就等于4k
Ø 对于有子页的NANDflash,UBI将优化它的flash层,EC头和VID头将被放在同一个NAND页里面,但是不同的子页里面。这种情况下,O等于一个NAND页的字节数
注意:以上的公式是将坏块也作为了UBI的开销,实际上UBI的开销其实是:(B - BB + 4) * SP + O * (P - B - 4)
在buildroot环境中,buildroot/fs/ubifs/ calc-ubi.sh脚本提供了自动生成最小overhead的参数(没有考虑FASTMAP空间开销);
对应上述说明的计算公式如下:
# SP = block_size
# SL = block_size - 2 * page_size
# O = SP - SL
# P = mtd_partition_size / SP
# W = flash_size / SP
# BR = (20 * W) / 1024
((BR=20*(W+1023)/1024))
# BB = (20 * P) / 1024
# B = MAX(BB, BR)
# overhead = (B + 4) * SP + O * (P - B - 4)
# vol_size = mtd_partition_size - overhead
# max_leb_cnt = vol_size / SL
- buildroot ubi分区config
以usr/mnt_app分区为例:
说明如下:
- MTD Partition size 因为UBI本身存在flash开销,所以分区不宜过小,最好大于10M
- Logical eraseblock size 当这个值为0的时候,会使用上述的calc-ubi.sh自动生成参数。
- Mimimum I/O unit size(page size) 必须与mtdinfo中获取到的信息一致;
- Embed into an UBI image 会生成ubi image volume,UBI挂载时会根据参数自动修改volume。否则UBI挂载后没有volume,user需要自己创建volume。
手动创建UBI Volume的action item如下:
ubiformat /dev/mtd19
ubiattach /dev/ubi_ctrl -m 19
ubimkvol /dev/ubi0 -s 18538496 -N my_ubi_vol //volume size/volume name
mount -t ubifs ubi0_0 /mnt/ubi
//进入目录,可以成功创建一个文本文件
cd /mnt/ubi
vi test.txt
umount /mnt/ubi
ubidetach /dev/ubi_ctrl -m 19
- Buildroot(7.6.0.6)环境中存在的issue
- buildroot/fs/ubifs/ calc-ubi.sh脚本自动计算参数错误,红色部分;
overhead=0
#calc ubi device overhead
if [ $partition_size = 0 ] || [ "$stored_flag" = "mtd" ] ; then
# echo "calc overhead..."
((O=SP-SL))
if [ "$stored_flag" = "ubi" ]; then
((P=(UbiResetSize+UsedVolSize)/SP))
else
((P=UbiResetSize/SP))
fi
((W=flash_size/SP))
((BR=20*((W+1023)/1024)))
((BB=20*((P+1023)/1024)))
## ((BR=20*(W+1023)/1024))
## ((BB=20*(P+1023)/1024))
((B=BR))
if [ $BB -gt $BR ] ; then
((B=BB))
fi
- 没有考虑支持FASTMAP功能,红色部分,kernel默认开启了FASTMAP,可以在此基础上减掉FASTMAP需要使用的两个LEB;
if [ $arg_leb_cnt = 0 ]; then
((vol_size=UbiResetSize-overhead-2*SL))
#((vol_size=UbiResetSize-overhead))
((vol_leb_cnt=vol_size/SL))
[ $vol_leb_cnt -lt 0 ] && message "($BASH_SOURCE:$FUNCNAME:$LINENO) Error: max_leb_cnt < 0, please increase $2 partition size!" && exit 1
else
((vol_leb_cnt=arg_leb_cnt))
((vol_size=vol_leb_cnt*SL))
fi