NAND ACCESS(四)UBIFS操作

本文深入探讨UBIFS(Unsorted Block Image File System)及其在固态存储设备上的应用,作为JFFS2的后继者,UBIFS在u-boot和Linux中得到广泛支持。文章详细介绍了UBI设备、卷和文件系统的概念,解析了UBI Header结构,指导如何在Linux中创建UBI镜像,以及在u-boot中写入和设置Linux启动参数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

UBIFS是Unsorted Block Image File System的简写,用于固态存储设备上,是JFFS2的后继文件系统之一。目前u-boot和Linux中都提供了很好的支持。

一. ubi的几个概念

在阅读ubi相关的文档时,需要区分几个不同的名称

ubi device(设备)

这是指绑定了某个MTD分区的ubi逻辑设备,一般简称ubi。

系统中使用ubi0表示第一个ubi设备,ubi1表示第二个设备。

ubi volume(卷)

这是指在ubi设备上创建的文件卷 (volume),每个ubi设备可以创建1个或多个卷。一个ubi卷的表示方法是ubi0:0或ubi0:volume。

ubifs(文件系统)

这是指在ubi卷上建立的文件系统。

二. ubi的Header

ubi在每个block中存放了2个Header结构,一个存放了物理擦写块(PEB)擦写计数的信息,称为Erase Counter Header(EC),另一个存放了卷标和这个物理擦写块(PEB)所属的逻辑擦写块(LEB)信息,称为Volume Identifier Header(VID)。

EC通常放在每个块最开始的位置上,也就是offset 0的位置,使用64字节,而VID存放在第二个I/O操作的单位上,也占据64字节。具体来说:

如果是NOR Flash且最小I/O单位是1 byte的话,则VID存放在Offset=64的位置上;

如果是NAND Flash且没有子页的话,VID存放在第2个页上,offset=2048 (假定一页是2048字节)。

如果是NAND Flash且支持子页的话,VID存放在第2个子页上,offset=512 (通常每个子页512字节)。

三. Linux中创建ubi镜像

如果在嵌入系统中使用ubifs作为根文件系统,通常在Linux中创建ubi的镜像文件,然后在uboot中使用ubi命令将镜像文件写入NAND。

Linux中创建ubi镜像文件的命令是

mkfs.ubifs -r <源目录> -o <目标文件> -m <页大小> -e <LEB大小> -c <LEB个数>

源目录是已经准备好的根文件系统所在的目录;

目标文件是需要生成的镜像文件名称;

页的大小是NAND芯片Page的大小;

LEB大小是逻辑块的大小,等于物理块的大小减去存放Header信息页的大小。

LEB个数等于NAND分区中物理块的个数。

举例来说,

假定NAND芯片每个Page 2048字节,每个Block 128Kb,支持子页,NAND分区176M(1408 Block),则Head信息占据1个Page,LEB的大小 = 128K – 2048 = 129024,镜像生成命令是

mkfs.ubifs –r ./rootfs –o rootfs.img –m 2048 –e 129024 –c 1408

同样参数,但不支持子页,则Head信息需要占用2个Page,LEB的大小 = 128K – 4096 = 126976,镜像生成命令是

mkfs.ubifs –r ./rootfs –o rootfs.img –m 2048 –e 126976 –c 1408

上面涉及到的一些重要参数,可在Linux或uboot中通过挂载MTD分区获得

uboot使用ubi命令

ubi part <MTD分区>

显示内容:

Creating 1 MTD partitions on "nand0":
0x000005000000-0x000010000000 : "mtd=6"
ubi0: attaching mtd1
ubi0: scanning is finished
ubi0: empty MTD device detected
ubi0: attached mtd1 (name "mtd=6", size 176 MiB)
ubi0: PEB size: 131072 bytes (128 KiB), LEB size: 129024 bytes
ubi0: min./max. I/O unit sizes: 2048/2048, sub-page size 512
ubi0: VID header offset: 512 (aligned 512), data offset: 2048
ubi0: good PEBs: 1407, bad PEBs: 1, corrupted PEBs: 0
ubi0: user volume: 0, internal volumes: 1, max. volumes count: 128
ubi0: max/mean erase counter: 1/0, WL threshold: 4096, image sequence number: 0
ubi0: available PEBs: 1364, total reserved PEBs: 43, PEBs reserved for bad PEB handling: 39

Linux中使用

ubiattach /dev/ubi_ctrl -m 6

ubi1: attaching mtd6
ubi1: scanning is finished
ubi1: empty MTD device detected
ubi1: attached mtd6 (name "NAND.User-space", size 176 MiB)
ubi1: PEB size: 131072 bytes (128 KiB), LEB size: 129024 bytes
ubi1: min./max. I/O unit sizes: 2048/2048, sub-page size 512
ubi1: VID header offset: 512 (aligned 512), data offset: 2048
ubi1: good PEBs: 1407, bad PEBs: 1, corrupted PEBs: 0
ubi1: user volume: 0, internal volumes: 1, max. volumes count: 128
ubi1: max/mean erase counter: 0/0, WL threshold: 4096, image sequence number: 3078332594
ubi1: available PEBs: 1364, total reserved PEBs: 43, PEBs reserved for bad PEB handling: 39
ubi1: background thread "ubi_bgt1d" started, PID 77

可以看到显示的内容与u-boot中基本一样。

其中

PEB size: 物理擦写块的大小,物理上块的字节数

LEB size: 逻辑擦写块的大小,物理擦写块的大小 减去 两个 Header 后剩余的大小

I/O unit sizes: 输入输出大小,也就是一个Page的大小

sub-page size: 说明能够支持sub-page的访问

VID header offset: VID (Volume IDentifier) 的偏移位置

data offset: 块中开始存放数据的偏移位置

四. uboot中写入镜像

在上一节Linux中生成的ubifs.img文件,可以在uboot中通过ubi命令写入NAND分区

首先将ubifs.img文件读入内存,假定存放的位置是0x82000000,长度2E000。

然后绑定MTD分区NAND.rootfs

ubi part NAND.rootfs

在ubi的分区上创建文件卷rootfs

ubi create rootfs -

后面使用”-“表示将创建的卷使用整个ubi的分区。如果想在这个ubi分区上建立两个或两个以上的文件卷,需要指定size大小。

最后将已载入内存的镜像文件写入ubi的卷中

ubi write 0x82000000 rootfs 2e000

五. 设置Linux启动命令

将Linux的启动参数设置为

bootargs = "console=ttyO0,115200n8 root=ubi0:rootfs ubi.mtd=5 rootfstype=ubifs rw";

关于上面与ubi有关的参数中,

root=ubi0:rootfs

表示根文件系统是ubi0设备的rootfs卷中,这个rootfs的名称与上一节使用ubi create命令创建ubi文件卷时设置的名称相对应。

ubi.mtd=5

表示ubi0设备使用的是MTD分区中第5个设备,也就是在上一节ubi part命令绑定分区时所对应的分区。

有些文档的这个参数写为

ubi.mtd=5,2048

这是在不支持subpage的ubi中,VID偏移位置在2048(第2个page处)。如果不写则表示缺省偏移位置在512(第2个subpage处)。

rootfstype=ubifs

这是指定根文件系统的类型是ubifs

六. u-boot中ubi的命令

ubi detach

detach ubi from a mtd partition

将ubi从MTD分区上分离。

ubi part [part] [offset]

显示当前ubi绑定的mtd分区,或设置ubi需要绑定的MTD分区。在设置分区时,可以同时指定VID头的偏移位置。

ubi info [l[ayout]]

显示当前卷的信息,以及ubi中卷的布局信息

ubi check <volumename>

检查volumename名称的卷是否存在

ubi create[vol] <volume> [size] [type] [id]

create volume name with size ('-' for maximum available size)

创建一个名称为volume的卷,这个卷的大小为size,如果使用“-”则使用最大可能的大小。

ubi write[vol] <address> <volume> <size>

Write volume from address with size

将内存地址address开始的size字节写入名称为volume的卷中

ubi read[vol] <address> <volume> [size]

Read volume to address with size

将volume卷中的内容,读取到内存address开始处,长度是size。如果不指定size则读取整个volume的内容

ubi remove[vol] <volume>

Remove volume

移除volume卷

ubifsmount <volume-name>

mount UBIFS volume

加载ubi create创建的文件卷。卷名的形式有

  • ubiX_Y    - 加载 ubi设备号X 卷号Y 的文件卷;
  • ubiY         - 加载 ubi设备号0 卷号Y 的文件卷;
  • ubiX:NAME - 加载 ubi设备号X 卷名NAME 的文件卷;
  • ubi:NAME  - 加载 ubi设备号0 卷名NAME 的文件卷

ubifsload <addr> <filename> [bytes]

load file from an UBIFS filesystem

从加载的ubifs卷中读取filename文件,写入addr开始的内存地址,如果不指定bytes,则读取整个文件,否则读取bytes字节数。

ubifsls [directory]

list files in a directory

显示ubifs卷中的文件,如果不指定directory,则显示根目录下的文件,否则显示指定目录的文件

ubifsumount

unmount UBIFS volume

卸载当前的ubifs卷

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值