






















首先UBI的擦除并不需要“使用多少,清0多少”,只要破坏这个分区块的头部记录即可;
UBI提供了一系列用户空间工具(通常包含在 mtd-utils 或 ubi-utils 软件包中),用于执行卷的创建、删除、更新等操作。与覆盖和清除相关的核心命令如下表所示:
| 命令 | 主要功能 | 对应操作类型 |
|---|---|---|
ubiupdatevol |
更新(覆盖)UBI卷的内容 | 数据覆盖 |
ubirmvol |
删除(清除)指定的UBI卷 | 卷清除 |
ubimkvol |
创建新的UBI卷 | 卷创建(为覆盖做准备) |
ubiupdatevolubiupdatevol 是用于更新(即覆盖)UBI卷内容的核心命令。它可以将文件、数据流或全零写入指定的UBI卷,实现卷内容的完全替换。
Bash
ubiupdatevol [options] <UBI volume node> [<input file>]
常用参数解析:
| 参数 | 说明 |
|---|---|
-t, --truncate |
截断卷。将卷大小设置为0,即清空卷内所有数据(逻辑清除)。 |
-s <bytes>, --size=<bytes> |
指定要写入的数据大小。如果输入文件小于卷大小,未指定部分将保持原内容不变(部分覆盖)。常与 -t 联用实现精确写入。 |
<UBI volume node> |
目标UBI卷的设备节点,格式为 /dev/ubiX_Y (X为设备号,Y为卷号) 或 ubiX:Y。 |
<input file> |
输入文件。如果省略或为 -,则从标准输入读取数据。 |
这是最常见的用法,用于更新卷内的固件、配置文件或Logo等。
Bash
此命令会用量为 new_kernel.bin 文件的大小覆盖卷的起始部分。如果文件小于卷容量,剩余空间保留原数据。
# 示例:将新的内核镜像 `new_kernel.bin` 写入 UBI设备0上的卷1
ubiupdatevol /dev/ubi0_1 new_kernel.bin
# 基本语法:ubiupdatevol <目标UBI卷设备节点> <镜像文件>
sudo ubiupdatevol /dev/ubi0_1 rootfs.squashfs
使用 -t 参数可以快速将卷大小截断为0,实现逻辑上的清除。这对于需要重置卷状态或准备接收新数据流非常有用。
Bash
# 示例:清空 UBI设备0上的卷2
ubiupdatevol -t /dev/ubi0_2
注释:该操作并非物理擦除Flash块,而是更新UBI内部元数据,将卷标记为空。后续写入操作将从逻辑起始地址开始。
适用于通过管道接收数据并直接写入UBI卷的场景,例如在OTA升级中解压后直接写入。
Bash
# 示例:解压一个归档文件并将其内容直接写入UBI卷
tar -xOzf rootfs.tar.gz | ubiupdatevol /dev/ubi0_0 -s $(tar -tzf rootfs.tar.gz | wc -c)
注释:通过 -s 指定精确的数据大小,确保写入操作正确完成。
有时为了安全或调试,需要将整个卷用特定数据填充。
Bash
# 示例:使用全零填充整个UBI设备0上的卷1
dd if=/dev/zero bs=1K count=<volume_size_in_KB> | ubiupdatevol /dev/ubi0_1 -
# 或者使用 `truncate` 创建全零文件后再写入
truncate -s <volume_size> zero.bin
ubiupdatevol /dev/ubi0_1 zero.bin
ubirmvolubirmvol 命令用于从UBI设备上永久删除一个逻辑卷。这是一种更彻底的“清除”,卷被删除后,其占用的物理擦除块(PEB)将被释放回UBI设备池,可用于创建新卷。
Bash
ubirmvol [options] <UBI device node> -n <volume ID>
常用参数解析:
| 参数 | 说明 |
|---|---|
-n <ID>, --name=<ID> |
指定要删除的卷的ID(卷编号)。卷ID可通过 ubinfo /dev/ubiX 命令查看。 |
<UBI device node> |
UBI设备节点,格式为 /dev/ubiX。 |
Bash
# 1. 首先,查看UBI设备上的卷信息,确认要删除的卷ID
ubinfo /dev/ubi0
# 输出示例:
# Present UBI devices: ubi0
# ubi0
# Volumes count: 2
# Logical eraseblock size: 126976 bytes, 124.0 KiB
# ...
# Volume ID: 0 (on ubi0)
# Type: dynamic
# Alignment: 1
# Size: 100 LEBs, 12697600 bytes, 12.1 MiB
# Name: boot
# ...
# Volume ID: 1 (on ubi0)
# Name: rootfs
# ...
# 2. 删除卷ID为1的卷(例如名为rootfs的卷)
ubirmvol /dev/ubi0 -n 1
重要提示:
卷删除操作是不可逆的,该卷上的所有数据将丢失。
确保没有进程正在访问或挂载该卷,否则删除操作会失败。
删除卷后,其逻辑空间被释放,但底层Flash的物理擦除操作由UBI子系统在后台的损耗均衡和垃圾回收过程中异步完成。
为了更清晰地理解何时使用覆盖 (ubiupdatevol) 和何时使用清除 (ubirmvol),可以参考下表:
| 操作需求 | 推荐命令 | 说明与示例 |
|---|---|---|
| 更新卷内容 | ubiupdatevol |
系统升级时更新rootfs:ubiupdatevol /dev/ubi0_0 new_rootfs.ubifs |
| 清空卷数据 | ubiupdatevol -t |
快速重置一个配置卷:ubiupdatevol -t /dev/ubi0_2 |
| 彻底删除卷 | ubirmvol |
移除一个不再需要的旧日志卷:ubirmvol /dev/ubi0 -n 3 |
| 安全擦除 | ubiupdatevol + dd |
用随机数据覆盖整个卷后再删除,增强安全性:`dd if=/dev/urandom bs=1M count=X |
高级场景:OTA升级中的组合使用
在嵌入式系统OTA升级中,常结合使用这些命令:
准备阶段:可能使用 ubirmvol 删除旧的备份卷。
更新阶段:使用 ubiupdatevol 将新固件写入目标卷。
回滚准备:在更新主卷前,先用 ubiupdatevol 将当前运行系统备份到另一个卷。
Bash
# 假设 ubi0_0 是主系统卷,ubi0_1 是备份卷
# 1. 将当前运行系统备份到备份卷 (假设已通过其他方式生成镜像)
# 2. 更新主系统卷
ubiupdatevol /dev/ubi0_0 new_firmware.bin
# 3. 如果更新失败,从备份卷恢复
# ubiupdatevol /dev/ubi0_0 backup_firmware.bin
磨损均衡:无论是 ubiupdatevol 的写入还是 ubirmvol 删除后的空间回收,UBI都会在底层执行磨损均衡操作,将数据迁移到擦除次数较少的物理块上,从而延长Flash寿命。
坏块管理:这些命令在执行时,UBI会自动避开坏块,用户无需关心物理坏块的存在。
原子性操作:ubiupdatevol 的写入操作是原子的。如果更新过程意外中断(如断电),卷将包含完整的旧数据或完整的新数据,不会处于损坏的中间状态。
空间预留:UBI卷在创建时通常会预留少量空间(由 -b 参数在 ubiattach 时设置)用于坏块替换和损耗均衡。因此,卷的可用逻辑大小会略小于物理MTD分区的大小。
性能考虑:频繁地对整个UBI卷进行 ubiupdatevol 覆盖操作会产生大量的Flash擦写,可能影响寿命。在设计系统时,应考虑增量更新或日志结构化文件系统(如UBIFS)来管理频繁变化的数据。
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。