ubi子系统FAQ

文章目录

前言

概述

本文档主要介绍Linux UBI子系统常见FAQ等。

修订记录

日期作者版本修改说明
2023.10.10枫潇潇V1.0.0初始版本
2024.01.22枫潇潇V1.0.1增加ubi使用只读块设备
2024.01.23枫潇潇V1.0.2增加ubifs做rootfs
2024.01.24枫潇潇V1.0.3增加fastmap使用

ubi attach流程及作用

ubi如何attach mtd设备?
启动参数法

参数格式:

Parameter format: mtd=<name|num|path>[,<vid_hdr_offs>[,max_beb_per1024[,ubi_num]]]

在cmdline中加入ubi参数,示例如下:

ubi.mtd=rootfs ubi.mtd=firmware,0,20,1 ubi.mtd=/dev/mtdX,0,20,2 ubi.block=0,rootfs root=/dev/ubiblock0_0 rootfstype=squashfs 

cmdline中mtd分区参数,示例如下:

mtdparts=spi0.1:512k(boot)ro,512k(misc),512k(pstore),512k(factory),1536k(rp),4608k(system)ro,4608k(recovery)ro,5632k(rootfs),40m(firmware),-(data)

参数含义解析:

ubi.mtd=firmware,0,20,1

firmware:mtd分区名,也可以是8,或者是/dev/mtd8

0:vid_hdr_offs

20:每1024块中保留块的数量,当前ubi保留块的数量为:20*nand_size_in_blocks/1024

1:ubi设备号

模块参数法
modprobe ubi mtd=rootfs mtd=firmware,0,20,1
或者:
modprobe ubi mtd=7 mtd=8,0,20,1
mtd-utils工具法
ubiattach -h
ubiattach version 2.0.1 - a tool to attach MTD device to UBI.

Usage: ubiattach [<UBI control device node file name>]
        [-m <MTD device number>] [-d <UBI device number>] [-p <path to device>]
        [--mtdn=<MTD device number>] [--devn=<UBI device number>]
        [--dev-path=<path to device>]
        [--max-beb-per1024=<maximum bad block number per 1024 blocks>]
UBI control device defaults to /dev/ubi_ctrl if not supplied.
Example 1: ubiattach -p /dev/mtd0 - attach /dev/mtd0 to UBI
Example 2: ubiattach -m 0 - attach MTD device 0 (mtd0) to UBI
Example 3: ubiattach -m 0 -d 3 - attach MTD device 0 (mtd0) to UBI
           and create UBI device number 3 (ubi3)
Example 4: ubiattach -m 1 -b 25 - attach /dev/mtd1 to UBI and reserve
           25*C/1024 eraseblocks for bad block handling, where C is the flash
           is total flash chip eraseblocks count, that is flash chip size in
           eraseblocks (including bad eraseblocks). E.g., if the flash chip
           has 4096 PEBs, 100 will be reserved.

-d, --devn=<number>   the number to assign to the newly created UBI device
                      (assigned automatically if this is not specified)
-p, --dev-path=<path> path to MTD device node to attach
-m, --mtdn=<number>   MTD device number to attach (alternative method, e.g
                      if the character device node does not exist)
-O, --vid-hdr-offset  VID header offset (do not specify this unless you really
                      know what you are doing, the default should be optimal)
-b, --max-beb-per1024 maximum expected bad block number per 1024 eraseblock.
                      The default value is correct for most NAND devices.
                      Allowed range is 0-768, 0 means the default kernel value.
-h, --help            print help message
-V, --version         print program version

ubi attach mtd设备的作用

根据mtd_dev_param参数信息,创建ubi设备与对应的mtd设备进行一一对应绑定。整个过程将会根据mtd设备的erasesize、size、writesize等信息,结合mtd设备的扫描信息,初始化好ubi_device、ubi_volume等实例。

ubi attach mtd设备的流程

1)通过 ubi_mtd_param_parse 解析ubi参数配置好mtd_dev_param参数信息;

2)通过 open_mtd_device找到对应的mtd设备实例——mtd_info;

3)通过 io_init函数,根据mtd_info的IO属性对ubi中的IO属性进行初始化;

4)scan_all扫描ubi设备中所有的PEB,判断其是否为bad,同时获取每个PEB的EC、VID等信息;

5)ubi_read_volume_table创建vtbl,并初始化好逻辑卷volume;

6)ubi_wl_init磨损平衡初始化;

7)ubi_eba_init LEB 与 PEB映射关系初始化,实例为eba_tbl;

8)autoresize重新计算卷大小;

ubi_init()
   |--->open_mtd_device()
   |--->ubi_attach_mtd_dev()
   |				|--->io_init()
   |				|--->ubi_attach()
   |				|		|--->scan_all()
   |				|		|		|--->scan_peb()
   |				|		|--->ubi_read_volume_table()
   |				|		|			|--->create_empty_lvol()
   |				|		|			|--->process_lvol()
   |				|		|			|--->init_volumes()
   |				|		|--->ubi_wl_init()
   |				|		|--->ubi_eba_init()
   |				|--->autoresize()
   |				|--->uif_init()
   |				|--->ubi_debugfs_init_dev()
   |--->ubiblock_init()

ubi保留PEB数量如何配置?

默认情况下,大约 2% 的整个芯片大小 (20/1024 PEB) 被保留用于坏块处理。如果坏块的数量超过了分配的数量,就会打印一条错误消息,并且 UBI 将切换到只读模式。

NandFlash设备在出厂时可能包含一些无效块,并且规定了总可用块中的最小有效块数(Minimum number of Valid Blocks ,NVB)约总块数的98%。无效块是指其中至少包含一个页面的错误位数超过最小所需的 ECC 能够纠正的错误位数。在使用过程中可能会出现额外的坏块。然而,在产品的耐久寿命内,总可用块数不会低于 NVB。

  • 1)kernel默认配置
Device Drivers  --->
       <*> Memory Technology Device (MTD) support  --->
                <*>   Enable UBI - Unsorted block images  ---> 
                          --- Enable UBI - Unsorted block images                                     
                            (20)  Maximum expected bad eraseblock count per 1024 eraseblocks

CONFIG_MTD_UBI_BEB_LIMIT:指定UBI在MTD设备上期望的最大坏物理擦除块数(每1024擦除块),默认值:20,即:2%

  • 2)引导参数配置

    详见:《启动参数法》

  • 3)ubiattach工具配置

    详见:《mtd-utils工具法》

ubi内LEB & PEB如何建立映射?

/* linux-4.19.132/drivers/mtd/ubi/ubi.h */
struct ubi_volume {
	......
	struct ubi_device *ubi; // reference to the UBI device description object
	int vol_id;				// volume ID
	......
	int reserved_pebs;		// how many physical eraseblocks are reserved for this volume
	int vol_type;			// volume type (%UBI_DYNAMIC_VOLUME or %UBI_STATIC_VOLUME)
	......
	int name_len;			// volume name length
	char name[UBI_VOL_NAME_MAX + 1];	// volume name
	......
	struct ubi_eba_table *eba_tbl;	// EBA table of this volume (LEB->PEB mapping)
	......
};

ubi_volume结构体中的eba_tbl用于记录volume使用了哪些逻辑擦写块,以及逻辑擦写块到物理擦写块的映射; eba_tbl 的数据类型为struct ubi_eba_table,结构体定义如下所示:

/*
 * struct ubi_eba_entry - structure encoding a single LEB -> PEB association
 */
struct ubi_eba_entry {
	int pnum; // the physical eraseblock number attached to the LEB
};

/*
 * struct ubi_eba_table - LEB -> PEB association information
 */
struct ubi_eba_table {
	struct ubi_eba_entry *entries; // the LEB to PEB mapping (one entry per LEB)
};

ubi_eba_table结构体中的entries是个数组,数组长度为ubi_volume结构体中的reserved_pebs,即为这个volume分配的物理擦写块个数;数组元素类型为 struct ubi_eba_entry,这个结构体只包含一个成员pnum;

问题:逻辑擦写块如何映射到物理擦写块?struct ubi_eba_entry结构体中的pnum是什么?

以nand flash来举例说明,假设nand flash的erase block size=128KB,这个nand flash上有一个96MB的mtd分区,假设这个分区名称为mtd1,ubi attach到mtd1;则mtd1总共包含有 96MB/128KB=768个erase block;

如果要读取pnum=12的物理擦写块的内容,则pnum=12在mtd1分区的offset=12*(erase block size)=12*128KB=1536KB,有了offset后就可以通过mtd提供的接口把这个物理擦写块的内容读出来;

如果给定逻辑擦写块lnum=0,通过ubi_eba_table结构体中的entries[lnum].pnum 获取到对应的pnum(因为mtd1有768个erase block,这个值的取值范围:0~767),假设entries[lnum].pnum=12,则lnum=0被映射到pnum=12,即通过逻辑擦写块lnum=0可以读写物理擦写块pnum=12(mtd1分区offset=1536KB)的数据;

在这里插入图片描述

ubi上如何使用只读块设备?

UBI允许在卷之上创建块设备,但是有以下限制:

Ø 只读操作

Ø 连续的IO操作,请记住NAND驱动核心已经将所有的IO连续了。

尽管有这么多的限制,挂载一个只读的块设备仍然非常有作用。比如被压缩的文件系统(squashfs),它就可以作为一个轻量级的只读根文件系统放在NAND设备上。UBI层将负责管理像bit-flips和损耗均衡这一类的事情。

使用方法

生成和销毁UBI卷之上的块设备和将MTD设备和UBI关联起来有些相似。既可以使用UBI模块参数block,也可以使用用户空间工具“ubiblock”.

为了在启动的时候就创建一个块设备,可以指定block参数为内核启动参数:

ubi.mtd=5 ubi.block=0,0 root=/dev/ubiblock0_0
  • 方式一:引导参数

Ø 使用UBI卷路径

ubi.block=/dev/ubi0_0

Ø 使用UBI设备和卷名:

ubi.block=0,rootfs

Ø 使用UBI设备号和UBI卷号:

ubi.block=0,0
  • 方式二:模块参数

如果已经将UBI创建为一个模块,在模块加载时可以使用以下参数:

$ modprobe ubi mtd=/dev/mtd5 block=/dev/ubi0_0
  • 方式三:ubiblock工具

使用用户空间工具ubiblock,块设备也可以在运行时被动态的创建和移除

$ ubiblock --create /dev/ubi0_0
$ ubiblock --remove /dev/ubi0_0
示例——squashfs做rootfs
ubi.mtd=rootfs  ubi.mtd=firmware ubi.mtd=data ubi.block=0,rootfs root=/dev/ubiblock0_0 rootfstype=squashfs mtdparts=spi0.1:1m(boot)ro,1m(misc),1m(pstore),1m(factory),1m(rp1),1m(rp2),6m(system1)ro,6m(system2)ro,6m(rootfs)ro,32m(firmware),-(data)

参数含义:

  • ubi.mtd=XXX:ubi attach mtd设备

  • ubi.block=0,rootfs:为指定的ubi设备的卷创建块设备,即为ubi0的rootfs卷创建一个ubi块设备

  • root=/dev/ubiblock0_0:指定根文件系统

  • rootfstype=squashfs:根文件系统类型

ubi上如何使用ubifs做rootfs?

用法同上,差异点如下:

ubi.mtd=rootfs  ubi.mtd=firmware ubi.mtd=data root=ubi0:rootfs rw rootwait rootfstype=ubifs 

ubi上如何使用fastmap?

fastmap工作原理

快速映射是一个试验的可选的UBI特征,可以将CONFIG_MTD_UBI_FASTMAP设置为y来使能该功能。一旦被使能,UBI将评估模块参数”fm_autoconvert”。如果它被设置为1(默认为0),UBI将为每一个被关联镜像(attachedimage)自动使能快速映射。这意味着UBI用快速映射的数据创建了一个新的内部卷,以便下次快速关联模式可以使用这些数据。
在默认配置下,UBI将会使用存储在快速映射卷里面的信息,以此来加速关联(attach)过程。如果想测试快速映射,设置fm_autoconver为1并将其关联(attach)到一个卷。

以下是可进行的配置:

CONFIG_MTD_UBI_FASTMAPFm_autoconvertresultn
n0快速映射完全被屏蔽
y0如果镜像上存在一个快速映射,它将附在(attach)UBI上,但是如果没有快速映射,也就不会有快速映射会被安装在镜像上。
y1如果镜像上存在一个快速映射,它将附在(attach)UBI上,快速映射会自动的被安装在所有依附(attach)的镜像上。
技术实现

一个磁盘存储的快速映射包含所有的需要附加到整个镜像的信息,也就是说所有的擦除计数值,所有的PEB列表和他们的状态,所有卷的列表和他们当前的EBA……为了避免对快速映射的太多次的写入,快速映射有一个PEB列表,这些PEB是已经更改过的或者需要在附加时进行全扫描的。这个表叫作快速映射池,并且有一个固定的大小,PEB总数的5%。仅当UBI对快速映射进行写入,并且快速映射池里没有空闲的PEB时,才会使用到这个技术。否则,每当一个卷的EBA改变时,UBI都会写入到快速映射。

快速映射有一个超级块(也叫作PEB锚),并且可以负载任何PEB上的数据。PEB锚必须在MTD设备的前64个PEB中,它有一个指向其它剩余PEB的指针,而这些PEB才是真正的装载实际的快速映射数据。在现在的NAND flash芯片中,整个快速映射是放在一个单独的PEB中的,因此,PEB锚指向它自己。在加载快速映射数据以后,UBI将据此来生成信息结构。

attach 流程如下
Ø UBI试图找到快速映射PEB锚,如果没有找到PEB锚,UBI将进行一个传统的全扫描
Ø 根据存储在PEB锚中的指针读取快速映射的负载数据
Ø 仅把池中的PEB执行一个传统的扫描,而不是所有的PEB。

如果UBI检测到使用的快速映射是无效的,它将自动退回扫描模式并执行一个全扫描。使用CRC32的checksum和一致性来校验内部的UBI结构体,以此来判断快速映射是否有效。

每当快速映射池满,快速映射将会被写入设备,卷层将改变或者镜像被detach。也许会疑问,为什么在detach的时候需要被写入,如果UBI在detach的时候不写一个新的快速映射,所有的擦除计数将发生修改当上一个快速映射写入已丢失。

开销

如果使能了快速映射,UBI将存储足够的PEB来装载两个完整的快速映射。在实际当中,NAND flash芯片有两个PEB是为快速映射预留的。

也有一些运行时的开销,为了确保新的快速映射是有效的,UBI将管理所有那些将导致EBA更改的IO,这将消耗一秒。所以,快速映射在大flash芯片,也就是进行一次全扫描需要较长时间的芯片上使用才会有意义。比如一个4G的NAND flash芯片进行一次全扫描需要好几秒,而一个快速的attach仅需要不到一秒的时间。

备注

启用Fastmap并不保证每个attach过程都会在最短时间内完成。在某些情况下,仍然需要进行完整扫描。这可能发生在两种情况下:

(i) 如果在写入Fastmap到闪存时发生意外重启;

(ii) 在写入Fastmap时UBI用尽了PEBs。

后一种情况可能发生在写入时发生大量I/O错误,并且UBI找不到足够可用的PEBs。

使用方法
  • 使用CONFIG_UBI_FASTMAP配置编译内核

  • 使用ubi.fm_autoconvert = 1内核参数至少引导一次系统。

  • 以干净的方式重启系统

  • 保证正常启动一次系统后可以删除ubi.fm_autoconvert = 1

fastmap优化效果

128MB spinand与32MB spinor测试对比

阶段耗时(uint:S)Spinor启动时间
过程启动fastmap关闭fastmap
Boot阶段Brom0.4——
Spl1.20.4
Uboot1.31.4
总计2.9001.744
Kernel阶段自解压2.8882.8783.091
Nand init1.0211.1030
Ubi attach0.7072.1250
Ubifs mount1.3301.2351.175
总计7.5748.8306.762
[TOC](这里写自定义目录标题)

欢迎使用Markdown编辑器

你好! 这是你第一次使用 Markdown编辑器 所展示的欢迎页。如果你想学习如何使用Markdown编辑器, 可以仔细阅读这篇文章,了解一下Markdown的基本语法知识。

新的改变

我们对Markdown编辑器进行了一些功能拓展与语法支持,除了标准的Markdown编辑器功能,我们增加了如下几点新功能,帮助你用它写博客:

  1. 全新的界面设计 ,将会带来全新的写作体验;
  2. 在创作中心设置你喜爱的代码高亮样式,Markdown 将代码片显示选择的高亮样式 进行展示;
  3. 增加了 图片拖拽 功能,你可以将本地的图片直接拖拽到编辑区域直接展示;
  4. 全新的 KaTeX数学公式 语法;
  5. 增加了支持甘特图的mermaid语法1 功能;
  6. 增加了 多屏幕编辑 Markdown文章功能;
  7. 增加了 焦点写作模式、预览模式、简洁写作模式、左右区域同步滚轮设置 等功能,功能按钮位于编辑区域与预览区域中间;
  8. 增加了 检查列表 功能。

功能快捷键

撤销:Ctrl/Command + Z
重做:Ctrl/Command + Y
加粗:Ctrl/Command + B
斜体:Ctrl/Command + I
标题:Ctrl/Command + Shift + H
无序列表:Ctrl/Command + Shift + U
有序列表:Ctrl/Command + Shift + O
检查列表:Ctrl/Command + Shift + C
插入代码:Ctrl/Command + Shift + K
插入链接:Ctrl/Command + Shift + L
插入图片:Ctrl/Command + Shift + G
查找:Ctrl/Command + F
替换:Ctrl/Command + G

合理的创建标题,有助于目录的生成

直接输入1次#,并按下space后,将生成1级标题。
输入2次#,并按下space后,将生成2级标题。
以此类推,我们支持6级标题。有助于使用TOC语法后生成一个完美的目录。

如何改变文本的样式

强调文本 强调文本

加粗文本 加粗文本

标记文本

删除文本

引用文本

H2O is是液体。

210 运算结果是 1024.

插入链接与图片

链接: link.

图片: Alt

带尺寸的图片: Alt

居中的图片: Alt

居中并且带尺寸的图片: Alt

当然,我们为了让用户更加便捷,我们增加了图片拖拽功能。

如何插入一段漂亮的代码片

博客设置页面,选择一款你喜欢的代码片高亮样式,下面展示同样高亮的 代码片.

// An highlighted block
var foo = 'bar';

生成一个适合你的列表

  • 项目
    • 项目
      • 项目
  1. 项目1
  2. 项目2
  3. 项目3
  • 计划任务
  • 完成任务

创建一个表格

一个简单的表格是这么创建的:

项目Value
电脑$1600
手机$12
导管$1

设定内容居中、居左、居右

使用:---------:居中
使用:----------居左
使用----------:居右

第一列第二列第三列
第一列文本居中第二列文本居右第三列文本居左

SmartyPants

SmartyPants将ASCII标点字符转换为“智能”印刷标点HTML实体。例如:

TYPEASCIIHTML
Single backticks'Isn't this fun?'‘Isn’t this fun?’
Quotes"Isn't this fun?"“Isn’t this fun?”
Dashes-- is en-dash, --- is em-dash– is en-dash, — is em-dash

创建一个自定义列表

Markdown
Text-to- HTML conversion tool
Authors
John
Luke

如何创建一个注脚

一个具有注脚的文本。2

注释也是必不可少的

Markdown将文本转换为 HTML

KaTeX数学公式

您可以使用渲染LaTeX数学表达式 KaTeX:

Gamma公式展示 Γ ( n ) = ( n − 1 ) ! ∀ n ∈ N \Gamma(n) = (n-1)!\quad\forall n\in\mathbb N Γ(n)=(n1)!nN 是通过欧拉积分

Γ ( z ) = ∫ 0 ∞ t z − 1 e − t d t   . \Gamma(z) = \int_0^\infty t^{z-1}e^{-t}dt\,. Γ(z)=0tz1etdt.

你可以找到更多关于的信息 LaTeX 数学表达式here.

新的甘特图功能,丰富你的文章

2014-01-07 2014-01-09 2014-01-11 2014-01-13 2014-01-15 2014-01-17 2014-01-19 2014-01-21 已完成 进行中 计划一 计划二 现有任务 Adding GANTT diagram functionality to mermaid
  • 关于 甘特图 语法,参考 这儿,

UML 图表

可以使用UML图表进行渲染。 Mermaid. 例如下面产生的一个序列图:

张三 李四 王五 你好!李四, 最近怎么样? 你最近怎么样,王五? 我很好,谢谢! 我很好,谢谢! 李四想了很长时间, 文字太长了 不适合放在一行. 打量着王五... 很好... 王五, 你怎么样? 张三 李四 王五

这将产生一个流程图。:

链接
长方形
圆角长方形
菱形
  • 关于 Mermaid 语法,参考 这儿,

FLowchart流程图

我们依旧会支持flowchart的流程图:

Created with Raphaël 2.3.0 开始 我的操作 确认? 结束 yes no
  • 关于 Flowchart流程图 语法,参考 这儿.

导出与导入

导出

如果你想尝试使用此编辑器, 你可以在此篇文章任意编辑。当你完成了一篇文章的写作, 在上方工具栏找到 文章导出 ,生成一个.md文件或者.html文件进行本地保存。

导入

如果你想加载一篇你写过的.md文件,在上方工具栏可以选择导入功能进行对应扩展名的文件导入,
继续你的创作。


  1. mermaid语法说明 ↩︎

  2. 注脚的解释 ↩︎

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值