一、UBIFS文件系统简介
UBIFS(Unsorted Block Image File System)无序区块镜像文件系统是用于固态存储设备上,UBIFS在设计与性能上均较YAFFS2、JFFS2更适合MLC(Multi-Level Cell) NAND FLASH。例如:UBIFS支持凑数(write-back), 其写入的数据会被缓存起来, 直到有必要写入时才写到flash, 这样大大降低分散小区块数量,并提高读写效率。UBIFS文件系统目录存储在flash上,UBIFS 挂载时不需要扫描整个存储器来重新创建文件目录。支持实时压缩,而且可选择性压缩部份文件。另外UBIFS使用日志(journal),可减少对flash index的更新频率。因为UBIFS是直接工作在Raw Flash设备上(如Nandflash),所以他不能工作在SD卡、U盘这些常用的存储设备上,目前的安卓手机上绝大部分都是使用的UBIFS文件系统。关于UBIFS的更多信息请参考: http://www.linux-mtd.infradead.org/doc/ubifs.html
传统的flash文件系统如Jffs2、yaffs2等是工作在MTD设备层之上,而UBIFS则建立在UBI卷层之上,UBI卷层工作在MTD设备层之上。也可以说,UBIFS涉及三个子系统:
1. MTD 子系统,提供对flash芯片Raw的访问接口。 MTD子系统提供了MTD device的概念,比如/dev/mtdx(字符设备)和/dev/mtdblockX(块设备);
2. UBI Subsystem,它工作在MTD设备之上,提供了UBI逻辑卷(类似于Linux服务器上的LVM概念),对上层屏蔽了一些直接使用MTD设备需要处理的问题,如wear-leveling(磨损平衡算法)和volume management(坏块管理)功能等;
3. UBIFS文件系统,工作于UBI之上。它提供文件的open、read、write等操作;
以下是UBIFS的一些特点:
1、可扩展性:UBIFS对flash 尺寸有着很好的扩展性; 也就是说mount时间,内存消耗以及I/O速度都不依赖于flash 尺寸(对于内存消耗的描述并不完全准确,但是依赖性非常的低); UBIFS可以很好的运行在GB级的 flashe设备; 当然UBI本身还是有扩展性的问题,无论如何 UBI/UBIFS都比JFFS2的可扩展性好,如果UBI成为瓶颈,可以改进UBI而不需改变UBIFS本身。
2、快速mount:不像JFFS2,UBIFS在mount阶段不需要扫描整个文件系统,UBIFS mount的时间只是毫秒级,时间不依赖与flash的尺寸;然而UBI的初始化时间是依赖flash的尺寸的,因此必须把这个时间考虑在内。
3、write-back 支持: 回写或者叫延迟写更准确些吧,同JFFS2的write-through(立即写入内存)相比可以显著的提高文件系统的吞吐量。
4、异常unmount适应度:UBIFS是一个日志文件系统可以容忍突然掉电以及unclean重启; UBIFS 通过replay 日志来恢复unclean unmount,在这种情况下replay会消耗一些时间,因此mount时间会稍微增加,但是replay过程并不会扫描整个flash介质,所以UBIFS的异常mount时间大概在几分之一秒。
5、快速I/O - 即使我们disable write-back(可以在unmount时使用-o sync mount选项), UBIFS的性能仍然接近JFFS2; 记住,JFFS2的同步I/O是非常惊人的,因为JFFS2不需要在flash上维护indexing data结构, 所以就没有因此而带来的负担; 而UBIFS恰恰是有index数据的,UBIFS之所以够快是因为UBIFS提交日志的方式:不是把数据从一个地方移动到另外一个位置,而只是把数据的地址加到文件系统的index,然后选择不同的eraseblock作为新的日志块,此外还有multi-headed日志方式等技巧。
6、on-the_flight compression - 存储在flash介质上的数据是压缩的;同时也可以灵活的针对单个文件来打开关闭压缩。例如,可能需要针对某个特定的文件打开压缩;或者可能缺省方式下支持压缩,但是对多媒体文件则关闭压缩。
7、可恢复性 - UBIFS可以从index破坏后恢复; UBIFS中的每一片信息都用一个header来描述,因此可以通过扫描整个flash介质来重构文件系统,这点和JFFS2非常类似。想像一下,如果你擦除了FAT文件系统的FAT表,对于FAT 文件系统是致命的错误,但是如果擦除UBIFS的index,你仍然可以重构文件系统,当然这需要使用一个用户空间程序来做恢复
8、完整性 - UBIFS通过把checksum写到flash 介质上来保证数据的完整性,UBIFS不会无视损坏的文件数据或meta-data;缺省的情况,UBIFS仅仅检查meta-data的CRC,但是你可以通过mount选项,强制进行data CRC的检查。
二、根文件系统镜像文件制作
使用mtd-utils源码编译出来的mkfs.jffs2工具,将根文件系统树目录制作成jffs2根文件系统镜像。
[wuyujun@wuyujunlocalhost ~]$ cd fl2440/linux/
[wuyujun@wuyujunlocalhost linux]$ mkfs.ubifs -h
Usage: mkfs.ubifs [OPTIONS] target
Make a UBIFS file system image from an existing directory tree
Examples:
Build file system from directory /opt/img, writting the result in the ubifs.img file ubifs根文件系统镜像文件制作可以参照他的例子
mkfs.ubifs -m 512 -e 128KiB -c 100 -r /opt/img ubifs.img
The same, but writting directly to an UBI volume
mkfs.ubifs -r /opt/img /dev/ubi0_0
Creating an empty UBIFS filesystem on an UBI volume
mkfs.ubifs /dev/ubi0_0
Options:
-r, -d, --root=DIR build file system from directory DIR 指定根文件系统目录
树的路径
-m, --min-io-size=SIZE minimum I/O unit size Nand Flash的最小读写单元,一般为page size。
-e, --leb-size=SIZE logical erase block size 逻辑擦除块的大小,Nandflash一写写一页,一擦擦一块,根据开发板所用的NandFlash原理图
-c, --max-leb-cnt=COUNT maximum logical erase block count 最大逻辑擦除块的个数,与分区大小有关
-o, --output=FILE output to FILE 输出的根文件系统镜像文件
-j, --jrn-size=SIZE journal size
-R, --reserved=SIZE how much space should be reserved for the super-user
-x, --compr=TYPE compression type - "lzo", "favor_lzo", "zlib" or
"none" (default: "lzo")
-X, --favor-percent may only be used with favor LZO compression and defines
how many percent better zlib should compress to make
mkfs.ubifs use zlib instead of LZO (default 20%)
-f, --fanout=NUM fanout NUM (default: 8)
-F, --space-fixup file-system free space has to be fixed up on first mount
(requires kernel version 3.0 or greater)
-k, --keyhash=TYPE key hash type - "r5" or "test" (default: "r5")
-p, --orph-lebs=COUNT count of erase blocks for orphans (default: 1)
-D, --devtable=FILE use device table FILE
-U, --squash-uids squash owners making all files owned by root
-l, --log-lebs=COUNT count of erase blocks for the log (used only for
debugging)
-y, --yes assume the answer is "yes" for all questions
-v, --verbose verbose operation
-V, --version display version information
-g, --debug=LEVEL display debug information (0 - none, 1 - statistics,
2 - files, 3 - more details)
-h, --help display this help text
[wuyujun@wuyujunlocalhost linux]$ cat linux-3.0/arch/arm/plat-s3c24xx/common-smdk.c
Fl2440中的Nandflash
[wuyujun@wuyujunlocalhost linux]$ mkfs.ubifs -x lzo -m 2048 -e 129024 -c 300 -r ./rootfs -o rootfs-ubifs.img
参数说明:
-x lzo 指定使用lzo压缩方法,默认是lzo,还支持zlib,zlib压缩率高些,但是lzo压缩解压速度快 。
-m 2048 Nand Flash的最小读写单元,一般为page size,K9F2G08的页大小为2048字节。
-r ./rootfs 指定根文件系统目录树的路径
-o rootfs-ubifs.img 指定制作出的根文件系统镜像文件名
-e 129024 指定LEB(Logical Erase Block,逻辑擦除块)大小。Nandflash读写单位为页,擦除单位为块,一个设备有多个块,一个块有多个页,K9F2G08Nandflash一个块是64个页,而一个页大小为2048字节。这样一个PEB(Physical EraseblockSize,物理擦除块)大小就是2048*64=131072,-e的算法是物理擦除块大小-1*页大小,这里就是131072-1*2048=129024
-c 300 指定该分区最大逻辑擦除块数量,该值随着根文件系统分区的大小和该分区的坏块数调整。该值很重要,不能大也不能小,最小也要大于image大小,太大mount有问题。计算起点是分区的物理块数量,比如40MiB的mtd分区,物理擦除块数量是
40*1024*1024/2048/64 = 320个,需要减去2个volume table的块,1个wear-leveling块,1个atomic LEB change块,以及一些坏块处理的保留块。因为一个分区上有多少个坏块是随机的,一般做法是做一个坏块容忍数,比如16个,不要担心这个会浪费空间,下面的ubinize的autoresize选项就是解决这个问题的。在这里我们最终的逻辑擦除块个数计算公式为: 320-2(volume table)-1(Wear-leveling)-1(atomic LEB change)-16(坏块容量数)=300
UBIFS官方关于逻辑擦除块大小的说明
参考: http://www.linux-mtd.infradead.org/doc/ubi.html#L_overhead
UBIFS是建立在UBI之上的文件系统,因此使用mkfs.ubifs制作的根文件系统镜像不能直接使用u-boot的nand write命令烧录,而需要在u-boot下使用ubi命令在根文件系统所在分区建立ubi卷之后才能烧录。但这种烧录方式比较麻烦,这时我们可以使用另外ubinize命令对rootfs-ubifs.img文件进行处理后就可以在u-boot上直接用nand write命令写入到根文件系统分区了。该命令的使用方法如下:
[wuyujun@wuyujunlocalhost linux]$ ubinize -h
......
Usage: ubinize [-o filename] [-p <bytes>] [-m <bytes>] [-s <bytes>] [-O <num>] [-e <num>]
[-x <num>] [-Q <num>] [-v] [-h] [-V] [--output=<filename>] [--peb-size=<bytes>]
[--min-io-size=<bytes>] [--sub-page-size=<bytes>] [--vid-hdr-offset=<num>]
[--erase-counter=<num>] [--ubi-ver=<num>] [--image-seq=<num>] [--verbose] [--help]
[--version] ini-file
Example: ubinize -o ubi.img -p 16KiB -m 512 -s 256 cfg.ini - create UBI image
'ubi.img' as described by configuration file 'cfg.ini'
-o, --output=<file name> output file name 处理后输出的镜像文件名
-p, --peb-size=<bytes> size of the physical eraseblock of the flash
this UBI image is created for in bytes,
kilobytes (KiB), or megabytes (MiB)
(mandatory parameter)物理擦除块大小
-m, --min-io-size=<bytes> minimum input/output unit size of the flash
in bytes 最小输入输出大小,一般为页大小
-s, --sub-page-size=<bytes> minimum input/output unit used for UBI
headers, e.g. sub-page size in case of NAND
flash (equivalent to the minimum input/output
unit size by default)
-O, --vid-hdr-offset=<num> offset if the VID header from start of the
physical eraseblock (default is the next
minimum I/O unit or sub-page after the EC
header)指定vid header的偏移量
-e, --erase-counter=<num> the erase counter value to put to EC headers
(default is 0)
-x, --ubi-ver=<num> UBI version number to put to EC headers
(default is 1)
-Q, --image-seq=<num> 32-bit UBI image sequence number to use
(by default a random number is picked)
-v, --verbose be verbose
-h, --help print help message
-V, --version print program version
需要创建ubinize的配置文件,然后再使用ubinize命令对image进行处理:
[wuyujun@wuyujunlocalhost linux]$ vim ubinize.ini
[ubifs-volume]
mode=ubi
image=rootfs-ubifs.img
vol_id=0
vol_size=38707200
vol_type=dynamic
vol_name=rootfs
vol_flags=autoresize
vol_alignment=1
配置文件说明:
mode=ubi
image=rootfs-ubifs.img 指定mkfs.ubifs制作生成的根文件系统镜像文件路径;
vol_id=0 指定根文件系统树的卷标为0,u-boot的bootargs参数需要根据它来设置;
vol_size=38707200 指定该UBI逻辑卷的大小,该值计算公式一般为 逻辑擦除块大小*逻辑擦除块个数
=129024*300=38707200。该值一般不用写,默认值是image大小。写了这个作用是帮助检查image是否超过了分区限制,制作时候就提示,否则mount会出错。逻辑擦除块个数的值是经过计算的最大值(前面mkfs.ubifs -c指定的300)了,不过autoresize参数会自适应大小,不会浪费空间的,后面Linux系统内核启动过程中可以看到这个现象。
vol_type=dynamic
vol_name=rootfs 指定UBI卷的名称,u-boot的bootargs参数需要根据它来设置;
vol_flags=autoresize UBI Subsystem在系统启动时自动调整逻辑擦除块的个数
vol_alignment=1
[wuyujun@wuyujunlocalhost linux]$ ubinize -o rootfs-ubifs.bin -m 2048 -p 131072 -s 512 -O 512 ubinize.ini
参数说明:
-o rootfs-ubifs.bin 指定ubinize处理后输出的image文件名,该文件可以由u-boot的nand write命令直接烧录
-m 2048 指定minimum input/output unit大小,为nandflash的页大小。
-p 131072 指定物理擦除块大小: 64 Page*2048 Byte/Page = 131072
-s 512 指定sub-page-size大小,页大小为2048字节的nandflash对应值为512;对于其他的Nandflash可以在Linux内核跑起来后挂载ubifs后查看该值
-O 512 指定vid-hdr-offset值,默认为sub-page-size的值,可以省略不用。
[wuyujun@wuyujunlocalhost linux]$ du -h rootfs-ubifs.bin
8.3M rootfs-ubifs.bin
经过 ubinize 命令处理过后的根文件系统镜像文件rootfs-ubifs.bin 就可以直接在u-boot下使用nand write命令烧录到相应的根文件系统分区上去了。
关于Minim Flash input/output、sub-pages、UBI Header的说明
参考: http://www.linux-mtd.infradead.org/doc/ubi.html#L_min_io_unit
三、内核配置和编译
General setup --->
[ ] Initial RAM filesystem and RAM disk (initramfs/initrd) support 一定
要取消initamfs,否则内核找到initramfs根文件系统的话就直接使用他启动了。
Device Drivers --->
<*> Memory Technology Device (MTD) support --->
< > RedBoot partition table parsing
< > FTL (Flash Translation Layer) support
< > NFTL (NAND Flash Translation Layer) support
<*> Enable UBI - Unsorted block images ---> 因为UBIFS文件系统建立在UBI一层上,所以只有这里选择了UBI之后,下面的文件系统里才会有UBIFS的选项
(4096) UBI wear-leveling threshold (NEW)
(1) Percentage of reserved eraseblocks for bad eraseblocks handling (NEW)
< > MTD devices emulation driver (gluebi) (NEW)
[ ] UBI debugging (NEW)
File systems --->
[*] Miscellaneous filesystems --->
<*> UBIFS file system support 选择支持UBIFS文件系统
[*] Extended attributes support
[*] Advanced compression options
[*] LZO compression support (NEW)
[*] ZLIB compression support (NEW)
[ ] Enable debugging support (NEW)
重新编译生成Linux内核uImage镜像文件:
[wuyujun@wuyujunlocalhost linux-3.0]$ make
[wuyujun@wuyujunlocalhost linux-3.0]$ mkimage -A arm -O linux -T kernel -C none -a 30008000 -e 30008040 -n "Linux Kernel" -d arch/arm/boot/zImage linuxrom-s3c2440.bin
Image Name: Linux Kernel
Created: Thu May 2 15:05:19 2019
Image Type: ARM Linux Kernel Image (uncompressed)
Data Size: 2574808 Bytes = 2514.46 kB = 2.46 MB
Load Address: 30008000
Entry Point: 30008040
[wuyujun@wuyujunlocalhost linux-3.0]$ du -sh linuxrom-s3c2440.bin
2.5M linuxrom-s3c2440.bin
四、u-boot系统烧录和环境变量配置
因为使用UBIFS根文件系统启动的Linux内核不包含根文件系统,所以u-boot烧录Linux系统时需要同时烧录linux内核镜像(linuxrom-s3c2440.bin)和根文件系统镜像(rootfs-ubifs.bin),此外还要通过bootargs环境变量告诉Linux内核根文件系统所在的位置。这里Linux内核、根文件系统的烧录地址、bootargs传参应该与Linux内核里的Nandflash分区表相一致:
u-boot的烧录地址应该是 0,大小不超过1M。该分区对应Linux内核分区表的/dev/mtdblock0;
Linux内核的烧录地址应该是0x100000(1M的偏移量处),大小不超过15M。该分区对应Linux内核分区表的/dev/mtdblock1;
根文件系统镜像的烧录地址应该是0x1000000(16M的偏移量处),大小不超过40M。该分区对应Linux内核分区表的/dev/mtdblock2;
[fl2440@lingyun]# set bootcmd 'nand read 30008000 100000 400000; bootm 30008000'
[fl2440@lingyun]# set blx 'tftp 30008000 linuxrom-s3c2440.bin;nand erase 100000 F00000;nand write 30008000 100000 400000'
[fl2440@lingyun]# set bubifs 'tftp 30008000 rootfs-ubifs.bin;nand erase 1000000 2800000;nand write 30008000 1000000 $filesize'
[fl2440@lingyun]# set bootargs 'console=tty0 console=ttyS0,115200 ubi.mtd=2 root=ubi0:rootfs rootfstype=ubifs mem=64M noinitrd rw loglevel=7'
bootargs的参数解析如下:
console=tty0 指定内核控制终端为LCD,内核启动信息输出到LCD上;console=ttyS0,115200 指定内核控制终端也为第一个串口,使用波特率115200,这样内核启动信息也打印到第一个串口上;
ubi.mtd=2 指定UBI卷建立在mtd2上,该值应该与u-boot烧录位置、Linux内核分区保
持一致;如果错误则Linux内核会因找不到根文件系统而启动失败;
root=ubi0:rootfs 指定根文件系统所在位置:在制作UBIFS的过程中,我们通过ubinize命令对文件系统镜像进行处理时,其配置文件中的vol_id指定为0,vol_name指定rootfs;
rootfstype=jffs2 指定根文件系统类型为jffs2,如果该参数错误则内核启动失败;init=/linuxrc 指定init进程执行/linuxrc这个程序,他会解析并执行/etc/inittab下的命令;
mem=64M u-boot告诉Linux内核有64M的内存;
rw 根文件系统以读写的形式挂载;
noinitrd 没有使用initrd;
loglevel=7 定义内核printk的打印级别为7,即所有信息都通过console打印出来;
[fl2440@lingyun]# save
Saving Environment to NAND...
Erasing Nand...
Erasing at 0x60000 -- 100% complete.
Writing to Nand... done
[fl2440@lingyun]# run blx 烧录内核
-
dm9000 i/o:
0x20000300, id:
0x90000a46
-
-
DM9000: running
in
16 bit mode
-
-
MAC:
08:
00:
3e:
26:
0a:
5b
-
-
could
not establish link
-
-
Using dm9000 device
-
-
TFTP from server
192.168.
137.1; our IP address
is
192.168.
137.3
-
-
Filename
'linuxrom-s3c2440.bin'.
-
-
Load address:
0x30008000
-
-
Loading: T T #################################################################
-
-
#################################################################
-
-
##############################################
-
-
done
-
-
Bytes transferred =
2574872 (
274a18 hex)
-
-
-
-
NAND erase: device
0 offset
0x100000, size
0xf00000
-
-
Skipping bad block at
0x00c40000
-
-
Erasing at
0xfe0000 --
100% complete.
-
-
OK
-
-
-
-
NAND
write: device
0 offset
0x100000, size
0x400000
-
-
4194304 bytes written: OK
[fl2440@lingyun]# run bubifs 烧录根文件系统
-
dm9000 i/o:
0x20000300, id:
0x90000a46
-
-
DM9000: running
in
16 bit mode
-
-
MAC:
08:
00:
3e:
26:
0a:
5b
-
-
could not establish link
-
-
Using dm9000 device
-
-
TFTP from server
192.168
.137
.1; our IP address
is
192.168
.137
.3
-
-
Filename
'rootfs-ubifs.bin'.
-
-
Load address:
0x30008000
-
-
Loading: T #################################################################
-
-
#################################################################
-
-
#################################################################
-
-
#################################################################
-
-
#################################################################
-
-
#################################################################
-
-
#################################################################
-
-
#################################################################
-
-
#################################################################
-
-
#####
-
-
done
-
-
Bytes transferred =
8650752 (
840000 hex)
-
-
-
-
NAND erase: device
0 offset
0x1000000, size
0x2800000
-
-
Skipping bad block at
0x02fe0000
-
-
Erasing at
0x37e0000 --
100% complete.
-
-
OK
-
-
-
-
NAND write: device
0 offset
0x1000000, size
0x840000
-
-
8650752 bytes written: OK
[fl2440@lingyun]# boot 直接使用boot命令启动,或重启开发板将自动启动
NAND read: device 0 offset 0x100000, size 0x400000
4194304 bytes read: OK
## Booting kernel from Legacy Image at 30008000 ...
Image Name: Linux Kernel
Created: 2019-05-02 7:05:19 UTC
Image Type: ARM Linux Kernel Image (uncompressed)
Data Size: 2574808 Bytes = 2.5 MiB
Load Address: 30008000
Entry Point: 30008040
Verifying Checksum ... OK
XIP Kernel Image ... OK
OK
Starting kernel ...
Uncompressing Linux... done, booting the kernel.
Linux version 3.0.0 (wuyujun@wuyujunlocalhost.localdomain) (gcc version 4.4.6 (crosstool-NG 1.16.0) ) #14 Thu May 2 15:03:30 CST 2019
CPU: ARM920T [41129200] revision 0 (ARMv4T), cr=c0007177
CPU: VIVT data cache, VIVT instruction cache
Machine: SMDK2440
Memory policy: ECC disabled, Data cache writeback
CPU S3C2440A (id 0x32440001)
S3C24XX Clocks, Copyright 2004 Simtec Electronics
S3C244X: core 405.000 MHz, memory 101.250 MHz, peripheral 50.625 MHz
CLOCK: Slow mode (1.500 MHz), fast, MPLL on, UPLL on
Built 1 zonelists in Zone order, mobility grouping on. Total pages: 16256
u-boot传给Linux内核的bootargs参数
Kernel command line: console=tty0 console=ttyS0,115200 ubi.mtd=2 root=ubi0:rootfs rootfstype=ubifs mem=64M noinitrd rw loglevel=7
PID hash table entries: 256 (order: -2, 1024 bytes)
Dentry cache hash table entries: 8192 (order: 3, 32768 bytes)
Inode-cache hash table entries: 4096 (order: 2, 16384 bytes)
Memory: 64MB = 64MB total
Memory: 59900k/59900k available, 5636k reserved, 0K highmem
Virtual kernel memory layout:
vector : 0xffff0000 - 0xffff1000 ( 4 kB)
fixmap : 0xfff00000 - 0xfffe0000 ( 896 kB)
DMA : 0xffc00000 - 0xffe00000 ( 2 MB)
vmalloc : 0xc4800000 - 0xf6000000 ( 792 MB)
lowmem : 0xc0000000 - 0xc4000000 ( 64 MB)
modules : 0xbf000000 - 0xc0000000 ( 16 MB)
.init : 0xc0008000 - 0xc0024000 ( 112 kB)
.text : 0xc0024000 - 0xc049d5d4 (4582 kB)
.data : 0xc049e000 - 0xc04c4720 ( 154 kB)
.bss : 0xc04c4744 - 0xc04e4cfc ( 130 kB)
NR_IRQS:85
......
NAND device: Manufacturer ID: 0xec, Chip ID: 0xda (Samsung NAND 256MiB 3,3V 8-bit)
Scanning device for bad blocks
Bad eraseblock 98 at 0x000000c40000
Bad eraseblock 383 at 0x000002fe0000
Bad eraseblock 776 at 0x000006100000
Bad eraseblock 965 at 0x0000078a0000
Bad eraseblock 1131 at 0x000008d60000
Bad eraseblock 1702 at 0x00000d4c0000
Creating 6 MTD partitions on "NAND":
0x000000000000-0x000000100000 : "mtdblock0 u-boot 1MB"
0x000000100000-0x000001000000 : "mtdblock1 kernel 15MB"
0x000001000000-0x000003800000 : "mtdblock2 rootfs 40MB"
0x000003800000-0x000008800000 : "mtdblock3 apps 80MB"
0x000008800000-0x00000d800000 : "mtdblock4 data 80MB"
0x00000d800000-0x000010000000 : "mtdblock5 backup 40MB"
UBI: attaching mtd2 to ubi0
UBI: physical eraseblock size: 131072 bytes (128 KiB) PEB大小为: 64*2048=128KiB
UBI: logical eraseblock size: 129024 bytes 逻辑擦除页大小LEB为: (64-1) *2048 = 129024B
UBI: smallest flash I/O unit: 2048 Nandflash页大小为2K
UBI: sub-page size: 512 sub-page大小:512
UBI: VID header offset: 512 (aligned 512)
UBI: data offset: 2048
UBI: max. sequence number: 0
UBI: volume 0 ("rootfs") re-sized from 300 to 312 LEBs 系统启动UBI初始化时根据Nandflash上的坏块情况动态调整为312个
UBI: attached mtd2 to ubi0
UBI: MTD device name: "mtdblock2 rootfs 40MB"
UBI: MTD device size: 40 MiB
UBI: number of good PEBs: 319
UBI: number of bad PEBs: 1
UBI: number of corrupted PEBs: 0
UBI: max. allowed volumes: 128
UBI: wear-leveling threshold: 4096
UBI: number of internal volumes: 1
UBI: number of user volumes: 1
UBI: available PEBs: 0
UBI: total number of reserved PEBs: 319
UBI: number of PEBs reserved for bad PEB handling: 3
UBI: max/mean erase counter: 1/0
UBI: image sequence number: 218683373
dm9000 Ethernet Driver, V1.31
......
drivers/rtc/hctosys.c: unable to open rtc device (rtc0)
UBIFS: mounted UBI device 0, volume 0, name "rootfs"
UBIFS: file system size: 37416960 bytes (36540 KiB, 35 MiB, 290 LEBs)
UBIFS: journal size: 5160960 bytes (5040 KiB, 4 MiB, 40 LEBs)
UBIFS: media format: w4/r0 (latest is w4/r0)
UBIFS: default compressor: lzo
UBIFS: reserved for root: 0 bytes (0 KiB)
usb 1-1: new full speed USB device number 2 using s3c2410-ohci
VFS: Mounted root (ubifs filesystem) on device 0:12. Linux内核找到并以UBIFS格式挂载根文件系统,如果bootargs传参有误则Linux内核将死在这里
......
Copyright (C) 2012 LingYun I.o.T Studio< iot-yun.com >
2019/4/23 WuYujun Demo
Default Logon Username: root Password: 123456
LingYunFL2440_WYJ login: root
Password:
~ >: mount
五、普通分区ubifs挂载
~ >: cat /proc/mtd 查看MTD设备的分区情况
dev: size erasesize name
mtd0: 00100000 00020000 "mtdblock0 u-boot 1MB"
mtd1: 00f00000 00020000 "mtdblock1 kernel 15MB"
mtd2: 02800000 00020000 "mtdblock2 rootfs 40MB"
mtd3: 05000000 00020000 "mtdblock3 apps 80MB"
mtd4: 05000000 00020000 "mtdblock4 data 80MB"
mtd5: 02800000 00020000 "mtdblock5 backup 40MB"
~ >: cat /proc/partitions 查看Linux内核分区表
major minor #blocks name
31 0 1024 mtdblock0
31 1 15360 mtdblock1
31 2 40960 mtdblock2
31 3 81920 mtdblock3
31 4 81920 mtdblock4
31 5 40960 mtdblock5
~ >: ls -l /dev/mtdblock* 查看分区对应的块设备
brw-rw---- 1 root root 31, 0 Jan 1 00:00 /dev/mtdblock0
brw-rw---- 1 root root 31, 1 Jan 1 00:00 /dev/mtdblock1
brw-rw---- 1 root root 31, 2 Jan 1 00:00 /dev/mtdblock2
brw-rw---- 1 root root 31, 3 Jan 1 00:00 /dev/mtdblock3
brw-rw---- 1 root root 31, 4 Jan 1 00:00 /dev/mtdblock4
brw-rw---- 1 root root 31, 5 Jan 1 00:00 /dev/mtdblock5
这里以 mtdblock3 为例将其以ubifs文件系统格式挂载到 /apps 挂载点上:
~ >: flash_eraseall /dev/mtd3 使用flash_eraseall命令将mtd3所在分区全部擦除
Erasing 128 Kibyte @ 28e0000 - 51% complete.
Skipping bad block at 0x02900000
Erasing 128 Kibyte @ 4080000 - 80% complete.
Skipping bad block at 0x040a0000
Erasing 128 Kibyte @ 5000000 - 100% complete.
在MTD上建立UBI卷:
~ >: ls /dev/ubi* 列出当前存在的ubi设备
/dev/ubi0 /dev/ubi0_0 /dev/ubi_ctrl
~ >: ubiattach 查看ubiattach的使用方法
BusyBox v1.27.1 (2019-05-01 20:12:50 CST) multi-call binary.
Usage: ubiattach -m MTD_NUM [-d UBI_NUM] [-O VID_HDR_OFF] UBI_CTRL_DEV
Attach MTD device to UBI
-m MTD_NUM MTD device number to attach
-d UBI_NUM UBI device number to assign
-O VID_HDR_OFF VID header offset
~ >: ubiattach -m 3 -d 3 /dev/ubi_ctrl 在mtd3上关联ubi3
~ >: ls /dev/ubi* 再查看ubi设备信息,将会多一个ubi3
/dev/ubi0 /dev/ubi0_0 /dev/ubi3 /dev/ubi_ctrl
~ >: ubimkvol 查看ubimkvol的帮助信息
BusyBox v1.27.1 (2019-05-01 20:12:50 CST) multi-call binary.
Usage: ubimkvol -N NAME [-s SIZE | -m] UBI_DEVICE
Create UBI volume
-a ALIGNMENT Volume alignment (default 1)
-m Set volume size to maximum available
-n VOLID Volume ID. If not specified,
assigned automatically
-N NAME Volume name
-s SIZE Size in bytes
-t TYPE Volume type (static|dynamic)
~ >: ubimkvol -m -n 0 -N apps /dev/ubi3 在ubi3上建立UBI卷
~ >: ls /dev/ubi* 再查看ubi设备信息,将会多一个ubi3_0
/dev/ubi0 /dev/ubi0_0 /dev/ubi3 /dev/ubi3_0 /dev/ubi_ctrl
UBIFS文件系统挂载:
~ >: mount -t ubifs -o sync,noatime,rw ubi3:apps /apps/
UBIFS: default file-system created
UBIFS: mounted UBI device 3, volume 0, name "apps"
UBIFS: file system size: 79865856 bytes (77994 KiB, 76 MiB, 619 LEBs)
UBIFS: journal size: 3999744 bytes (3906 KiB, 3 MiB, 31 LEBs)
UBIFS: media format: w4/r0 (latest is w4/r0)
UBIFS: default compressor: lzo
UBIFS: reserved for root: 3772261 bytes (3683 KiB)
~ >: mount
UBIFS文件系统卸载及重新挂载测试:
~ >: umount /apps/ 卸载ubifs
UBIFS: un-mount UBI device 3, volume 0
~ >: ubidetach -d 3 /dev/ubi_ctrl 解除ubi和mtd之间的关联
UBI: mtd3 is detached from ubi3
~ >: ls /dev/ubi* 查看UBI设备,现在ubi3相关的设备都消除
/dev/ubi0 /dev/ubi0_0 /dev/ubi_ctrl
~ >: ubiattach -m 3 -d 3 /dev/ubi_ctrl 之前已经建立了卷,现在ubiattach之后就会存在ubi卷设备ubi3_0。
~ >: ls /dev/ubi*
/dev/ubi0 /dev/ubi0_0 /dev/ubi3 /dev/ubi3_0 /dev/ubi_ctrl
~ >: ubimkvol -m -n 0 -N apps /dev/ubi3
ubimkvol: UBI_IOCMKVOL: Invalid argument
我们再次关联ubi3到mtd3下的时候,因为之前已经在该分区上建立过UBI卷,所以再次建立UBI卷的话将会出错。这也意味着,如果之前已经用ubimkvol建立UBI卷的分区再次挂载时不需要在执行该命令,也即ubimkvol针对一个分区只能做一次,除非使用flash_eraseall重新格式化。
系统启动时自动将/dev/mtdblock3以ubifs文件系统格式挂载到/apps路径下:
重启之后ubi3和mtd3之间的关联解除,但是在该分区上建立过UBI卷,只需建立ubi和mtd之间的关联然后挂载即可。
[wuyujun@wuyujunlocalhost init.d]$ cd fl2440/linux/rootfs/etc/init.d/
[wuyujun@wuyujunlocalhost init.d]$ vim S11_mount_mtdblock3_apps_ubifs
-
#!/bin/sh
-
-
ubiattach -m 3 -d 3 /dev/ubi_ctrl
-
-
mount -t ubifs -o sync,noatime,rw ubi3:apps /apps/
[wuyujun@wuyujunlocalhost init.d]$ sudo chmod a+x S11_mount_mtdblock3_apps_ubifs
[wuyujun@wuyujunlocalhost init.d]$ cd ~/fl2440/linux
[wuyujun@wuyujunlocalhost linux]$ mkfs.ubifs -x lzo -m 2048 -e 129024 -c 300 -r ./rootfs -o rootfs-ubifs.img
[wuyujun@wuyujunlocalhost linux]$ ubinize -o rootfs-ubifs.bin -m 2048 -p 131072 -s 512 -O 512 ubinize.ini
[fl2440@lingyun]# run bubifs 烧录到开发板
[fl2440@lingyun]# boot