nandsim模拟mtd测试UBI模块

利用nandsim挂载ubi文件系统

MTD设备及JFFS2, UBIFS文件系统的使用简介

首先需要安装mtd_utils工具:

sudo apt-get install mtd-utils

nandsim是在PC机上模拟nand flash设备的一个小模块,本文使用这个工具,在pc机器上模拟一块nand flash.
然后在虚拟的nand flash上对UBI相关的操作进行测试。这样操作的好处就是不需要搭建开发板的环境,在PC
机环境下,快速测试UBI模块。

1、载入相关模块
PC机上不一定有mtd和mtdblock模块,要进行整个实验必须先保证PC机上已经安装了这两个模块,并使用下面的
命令载入这两个模块:

  1. modprobe mtd
  2. modprobe mtdblock

2、载入nandsim模拟一个flash设备

  1. andy@andy-desktop:~/test$ sudo modprobe nandsim
  2. andy@andy-desktop:~/test$
  3. andy@andy-desktop:~/test$
  4. andy@andy-desktop:~/test$ mtdinfo /dev/mtd0
  5. mtd0
  6. Name: NAND simulator partition 0
  7. Type: nand
  8. Eraseblock size: 16384 bytes, 16.0 KiB
  9. Amount of eraseblocks: 8192 (134217728 bytes, 128.0 MiB)
  10. Minimum input/output unit size: 512 bytes
  11. Sub-page size: 256 bytes
  12. OOB size: 16 bytes
  13. Character device major/minor: 90:0
  14. Bad blocks are allowed: true
  15. Device is writable: true
  16. andy@andy-desktop:~/test$ ls /dev/mtd
  17. mtd0 mtd0ro mtdblock0
  18. andy@andy-desktop:~/test$ ls /dev/mtd

从上面执行的命令可以看到在dev下面存在了mtd0 和mtdblock0两个设备

3、载入ubi和gluebi两个模块
这里需要说明一下gluebi这个模块实际上是ubi系统下面的一个子系统,它的作用就是对ubi系统下面建立起来的
每一个卷(volume)再建立一个块设备,块设备名字一般为mtdblockx.这样ubi中的每一个卷就可以当成一个块
设备被上层的软件(主要是文件系统)来操作了

  1. andy@andy-desktop:~/test$ sudo modprobe ubi mtd=0
  2. andy@andy-desktop:~/test$ sudo modprobe gluebi
  3. andy@andy-desktop:~/test$
  4. andy@andy-desktop:~/test$
  5. andy@andy-desktop:~/test$
  6. andy@andy-desktop:~/test$ ls /dev/mtd*
  7. /dev/mtd0 /dev/mtd0ro /dev/mtdblock0
  8. andy@andy-desktop:~/test$ ls /dev/ubi*
  9. /dev/ubi0 /dev/ubi_ctrl
  10. andy@andy-desktop:~/test$

4、创建ubi卷

  1. andy@andy-desktop:~/test$ sudo ubimkvol /dev/ubi0 -N ubi-vol0 -s 60MiB
  2. Volume ID 0, size 3964 LEBs (62916608 bytes, 60.0 MiB), LEB size 15872 bytes (15.5 KiB), dynamic, name "ubi-vol0", alignment 1
  3. andy@andy-desktop:~/test$ ls /dev/mtd*
  4. /dev/mtd0 /dev/mtd1 /dev/mtdblock0
  5. /dev/mtd0ro /dev/mtd1ro /dev/mtdblock1
  6. andy@andy-desktop:~/test$ ls /dev/ubi*
  7. /dev/ubi0 /dev/ubi0_0 /dev/ubi_ctrl
  8. andy@andy-desktop:~/test$

5、把/dev/mtdblock1格式化为vfat格式并挂载

  1. andy@andy-desktop:~/test$ sudo mkfs.vfat /dev/mtdblock1
  2. mkfs.vfat 3.0.7 (24 Dec 2009)
  3. unable to get drive geometry, using default 255/63
  4. andy@andy-desktop:~/test$ sudo mount -t vfat /dev/mtdblock1 ./ubimount
  5. andy@andy-desktop:~/test$ cd ./ubimount/
  6. andy@andy-desktop:~/test/ubimount$ ls
  7. andy@andy-desktop:~/test/ubimount$ cp ../
  8. hello/ hello.txt jffs.img ubimount/
  9. andy@andy-desktop:~/test/ubimount$ cp ../hello
  10. hello/ hello.txt
  11. andy@andy-desktop:~/test/ubimount$ cp ../hello/hello.txt ./hello
  12. cp: 无法创建普通文件"./hello": 权限不够
  13. andy@andy-desktop:~/test/ubimount$ sudo cp ../hello/hello.txt ./hello
  14. andy@andy-desktop:~/test/ubimount$ ls
  15. hello
  16. andy@andy-desktop:~/test/ubimount$ cat hello
  17. hello
  18. andy@andy-desktop:~/test/ubimount$

6、制作jffs2的镜像文件并挂载
首先查看一下虚拟出来的ubi卷的信息,ubi卷的mtd设备是mtd1,mtd0是nandsim虚拟的mtd设备

  1. andy@andy-desktop:~/test$ mtdinfo /dev/mtd1
  2. mtd1
  3. Name: ubi-vol0
  4. Type: ubi
  5. Eraseblock size: 15872 bytes, 15.5 KiB
  6. Amount of eraseblocks: 3964 (62916608 bytes, 60.0 MiB)
  7. Minimum input/output unit size: 512 bytes
  8. Sub-page size: 512 bytes
  9. Character device major/minor: 90:2
  10. Bad blocks are allowed: false
  11. Device is writable: true

然后将./hello目录作为根目录制作一个jffs2的镜像

  1. andy@andy-desktop:~/test$ sudo mkfs.jffs2 -e 0x3e00 -s 0x200 -p 0x500000 -d ./hello
  2. hello/ hello.txt
  3. andy@andy-desktop:~/test$ sudo mkfs.jffs2 -e 0x3e00 -s 0x200 -p 0x500000 -d ./hello -o jffs.img
  4. andy@andy-desktop:~/test$ ls
  5. hello hello.txt jffs_bak.img jffs.img ubimount

使用dd命令将镜像写入到/dev/mtdblock1设备中

  1. andy@andy-desktop:~/test$ dd if=jffs.img of=/dev/mtdblock1
  2. dd: 正在打开"/dev/mtdblock1": 权限不够
  3. andy@andy-desktop:~/test$ sudo dd if=jffs.img of=/dev/mtdblock1
  4. 记录了31+0 的读入
  5. 记录了31+0 的写出
  6. 15872字节(16 kB)已复制,0.0078479 秒,2.0 MB/秒

使用jffs2格式挂载/dev/mtdblock1这个设备

    1. andy@andy-desktop:~/test$ sudo mount -t jffs2 /dev/mtdblock1 ./ubimount/
    2. andy@andy-desktop:~/test$ cd ./ubimount/
    3. andy@andy-desktop:~/test/ubimount$ ls
    4. hello.txt
    5. andy@andy-desktop:~/test/ubimount$ cat hello.txt
    6. hello
    7. andy@andy-desktop:~/test/ubimount$

开发环境:Fedora15

开发工具:mtd-utils-1.4.6

注意:在linux2.6.28后才加入对ubifs的支持,开发环境主机要求至少是在linux2.6.28后的内核,且已经有nandsim,ubi等相关模块。

步骤:

1.虚拟出NANDFLASH

#modprobe mtd

#modprobe mtdblock

#modprobe nandsim first_id_byte=0xec second_id_byte=0xa1 third_id_byte=0x00 fourth_id_byte=0x15

#chmod 660 /dev/mtd0*

#ls -lah /dev/mtd*

crw-------. 1 root root 90, 0 Oct 18 15:07 /dev/mtd0         mtd字符设备

crw-------. 1 root root 90, 1 Oct 18 15:07 /dev/mtd0ro

brw-rw----. 1 root disk 31, 0 Oct 18 15:07 /dev/mtdblock0    mtd块设备,与mtd0对应

# cat /proc/mtd

dev:    size   erasesize  name

mtd0: 08000000 00020000 "NAND simulator partition 0"

大小为128MiB,擦除单元大小(一般即为块大小)为128KiB,名字是"NAND simulator partition 0"。

NandFlash擦除是以块(block)为单位,读写是以页(page)为单位。

查看nand的基本信息

# ./mtd-utils/ubi-utils/mtdinfo /dev/mtd0

mtd0

Name:                           NAND simulator partition 0

Type:                           nand

Eraseblock size:                131072 bytes, 128.0 KiB      擦除单元大小

Amount of eraseblocks:          1024 (134217728 bytes, 128.0 MiB)  块数*块大小=总容量

Minimum input/output unit size: 2048 bytes    最小输入输出单元

Sub-page size:                  512 bytes  子页大小

OOB size:                       64 bytes  Out-of-bank

Character device major/minor:   90:0        主,次设备号

Bad blocks are allowed:         true

Device is writable:             true

现在的nandflash一般页大小为(512+16)Bytes,(2048+64)Bytes。

大小为512Bytes的可用页对应有16Bytes的OOB信息

大小为2048Byte的可用页对应有64Bytes的OOB信息

2.制作ubi文件系统

我是参照google到的一个创建ubi.img的脚本来生成ubi image的。

./create_ubifs.sh 页大小 每块的页数 分区大小 分区包含的块数 文件夹

例:

#./create_ubifs.sh 2048 64 134217728 1024 ./rootfs

这个是与上面加载的nandsim对应的.

3.写入镜像到nandflash中

#dd if=ubi.img of=/dev/mtd0 bs=2048

4.加载文件系统并attach MTD设备

#modprobe ubi

#./ubiattach /dev/ubi_ctrl -m 0 -O 2048

-m指定挂在在mtd0上

-O参数用来指定VID header offset,默认是512。

5.mount文件系统

#mount -t ubifs ubi0_0 ./mntdir

即可将文件系统挂上.

错误处理

mount时出错:

mount: wrong fs type, bad option, bad superblock on ubi0_0,

missing codepage or helper program, or other error

(for several filesystems (e.g. nfs, cifs) you might

need a /sbin/mount.<type> helper program)

In some cases useful info is found in syslog - try

dmesg | tail  or so

#dmesg

[40278.359982] UBIFS error (pid 11094): validate_sb: LEB size mismatch: 520192 in superblock, 126976 real

[40278.359987] UBIFS error (pid 11094): validate_sb: bad superblock, error 1

很明显能看出是由于LEB size不对造成的,而LED size是我们在mkfs.ubifs时指定的。

重新修改脚本对应命令:

./create_ubifs.sh 2048 64 134217728 1024 ./rootfs

我之前用的命令是

./create_ubifs.sh 2048 256 134217728 1024 ./rootfs

生成新的ubi.img再重新写入nandflash.

注意此时需要重新挂载mtdblock,nandsim模块。

附:创建分卷命令

ubimkvol /dev/ubi0 -N ubi-vol0 -s 32MiB


MTD设备

MTD (Memory Technology Devices) 更多的代表Flash设备,它提供了统一接口来处理各种裸Flash设备,例如NAND, NOR, OneNAND等。对于使用FTL技术模拟成块设备的Flash,并不属于MTD设备。例如MMC, eMMC, SD等。
/dev/mtdN, MTD字符设备,代表MTD设备,可以进行各种ioctl操作
/proc/mtd, 过时的proc接口
sysfs接口是正在使用的接口,包括 /sys/devices,/sys/class,/sys/module 接口
mtdram, mtdblock,mtdram模拟NOR flash设备,而mtdblock将NOR flash模拟成块设备,但是它并不高级,远没有提供FTL的功能,例如写均衡,坏块管理等,它只是一个简单的模拟块设备的接口。通过对象的/dev/mtdblockN 可以以访问块设备的方式访问NOR flash。

mtdram 用内存模拟NOR Flash
block2mtd 用块设备模拟NOR Flash
nandsim 用内存会文件模拟NAND Flash
1. 首先要编译内核支持MTD相关选项,不管是内置还是编译为模块。
2. 安装mtd-utils工具
3.1. mtdram, mtdblock
#modinfo mtdram
可以看出mtdram有两个参数,total_size, erase_size,都以KiB为单位,下面创建一个32MiB的MTD设备,擦除块大小为128KiB
#modprobe mtdram total_size=$((32*1024)) erase_size=128
#cat /proc/mtd // 查看当前的mtd设备,另外,还可以通过/sys/devices/virtual/mtd/目录来查看MTD设备
#ls -l /dev/mtd* // 自动创建了 /dev/mtd0/dev/mtd0ro 设备节点
#modprobe mtdblock
#ls -l /dev/mtd* // 自动创建了和 /dev/mtd0 对应的块设备节点 /dev/mtdblock0
3.2. block2mtd
block2mtd顾名思义使用块设备模拟MTD设备,这里的块设备既可以是真正的块设备,也可以是使用losetup模拟的块设备。
#dd if=/dev/zero of=block.img bs=4K count=8096 // 创建一个32M大小的文件
#losetup /dev/loop0 block.img // 模拟块设备文件,可以使用 losetup -f block.img, losetup -a,如果/dev/loop0已经被占用。
#modinfo block2mtd
可以看出block2mtd模块有一个参数block2mtd,设置块设备文件和擦除块大小
#modprobe block2mtd block2mtd=/dev/loop0,128KiB
#cat /proc/mtd
#ls -l /dev/mtd*
3.3. nandsim
nandsim模拟NAND flash设备,前两种都是模拟NOR flash设备,也可以使用mtdinfo <device>来查看,可以看出,通过mtdram,block2mtd模拟的flash设备最小输入输出单位是字节。
#modinfo nandsim
nandsim有一堆参数,其中first_id_byte, second_id_byte分别指明设备制造商ID和芯片ID,如果不指明,会创建一个默认128M大小的flash设备
#modprobe nandsim first_id_byte=0x20 second_id_byte=0x33
#cat /proc/mtd
#ls -l /dev/mtd*
#mtdinfo /dev/mtdN // 查看MTD的信息,例如这里创建的NAND flash信息为
Name: NAND simulator partition 0
Type: nand
Eraseblock size: 16384 bytes, 16.0 KiB
Amount of eraseblocks: 1024 (16777216 bytes, 16.0 MiB)
Minimum input/output unit size: 512 bytes
Sub-page size: 256 bytes
OOB size: 16 bytes
Character device major/minor: 90:4
Bad blocks are allowed: true
Device is writable: true
4. Flash文件系统
现在,有了MTD设备,还没有合适的文件系统,JFFS2和UBIFS是两个比较流行的flash文件系统。
4.1. JFFS2
JFFS2文件系统用户空间工具为mtd-utils,提供创建jffs2的工具mkfs.jffs2和jffs2dump。创建jffs2文件系统映像后可以用nand工具烧写到flash上。
#mkfs.jffs2 --root=jffs2.dir --pagesize=4KiB --eraseblock=128KiB --pad=$((32*1024))KiB --output=jffs2.img
上面命令以目录jffs2.dir为根创建了一个jffs2.img文件系统映像,--pad表示使用0xFF填充剩余的空间,如果没有参数表示填充到最后一块即止。这里填充到32MiB大小。
在Linux上,可以通过mtdram/mtdblock来查看修改jffs2.img。但是不能直接通过loop back来挂载,因为它工作在MTD之上,而不是块设备之上。
#modprobe mtdram total_size=$((1024*32)) erase_size=128
#modprobe mtdblock
#dd if=jffs2.img of=/dev/mtdblock0
#mount -t jffs2 /dev/mtdblock0 /mnt
或者使用nandsim模拟,然后使用nandwrite将jffs2.img写入MTD设备
#modprobe nandsim // 默认模拟一个128MiB的nand flash
#nandwrite -j /dev/mtd1 jffs2.img
#mount -t jffs2 /dev/mtdblock1 /mnt

UBIFS
UBIFS工作在UBI层之上,UBI是对MTD设备的又一层抽象。首先,要将MTD设备加入UBI池,然后再在UBI之上创建UBIFS,有点类似LVM的概念。
#modprobe nandsim // 创建一个nand flash设备,128MiB
#mtdinfo /dev/mtd0 // flash的物理擦除块大小为16KiB
#modprobe ubi mtd=0 // 将 /dev/mtd0 加入ubi设备池
或者
#modprobe ubi
#ubiattach /dev/ubi_ctrl -m 0 // 现在将会生成/dev/ubi0 设备
#ubinfo /dev/ubi0 // ubi设备的逻辑擦除块大小为15.5KiB, 15872B,这是因为创建ubi设备时需要在每个物理擦除块写入头。
#ubimkvol /dev/ubi0 -N ubi-vol0 -s 32MiB // 创建一个32MiB的volume,/dev/ubi0_0
#ubinfo /dev/ubi0_0
#mount -t ubifs ubi0:ubi-vol0 /mnt
#echo "hello ubifs" > /mnt/hello.txt
#mkfs.ubifs -r /mnt -m 512 -e 15782 -c 2115 -o ubifs.img
上面命令中的最小IO单位512字节,逻辑擦除块大小,以及文件系统最大可扩展至2115个逻辑块,这些信息可以使用如下命令获得
#ubinfo /dev/ubi0 // 获得最小IO单位,逻辑擦除块大小
#ubinfo /dev/ubi0_0 // 文件系统包含的逻辑块数
#cat ubinize.cfg
[ubifs]
mode=ubi
image=ubifs.img
vol_id=0
vol_size=32MiB
vol_type=dynamic
vol_name=ubi-vol0
vol_flags=autoresize
#ubinize -o ubi.img -m 512 -s 256 -p 16KiB ubinize.cfg
这里和mkfs.ubifs的参数不同,-p的参数为物理擦除块大小,也就是ubi工作在MTD层之上,所以需要MTD的参数,即物理参数,而ubifs工作在ubi之上,所以需要ubi的参数,即逻辑参数。
现在,ubi设备映像已经被保存在了ubi.img中,不仅包含ubifs信息,还包含ubi信息,所以可以直接烧写到MTD设备上即可。
#modprobe nandsim
#dd if=ubi.img /dev/mtd0
#modprobe ubi mtd=0
#mount -t ubifs ubi0_0 /mnt
#ls /mnt

hello.txt

注意:如果出现ubiattach错误,很可能是使用了block2mtd模拟MTD设备,因为这时设备是没有格式化的,所以会出现ubi_read_volume_table: the layout volume was not found,通过dmesg查看。那么,首先需要格式化MTD设备
#ubiformat /dev/mtd0
#ubiattach /dev/ubi_ctrl -m 0

nandsim ubi nand nor的更多相关文章

  1. ubi问题总结

    一.挂载成功后,使用正常.有时会出现:UBIFS error (pid 76): ubifs_read_node: bad node type (255 but expected 1)UBIFS er ...

  2. 使用ubifs格式的根文件系统

    配置内核,使其支持ubifs文件系统 1)Device Drivers  --->Memory Technology Device (MTD) support  --->UBI - Uns ...

  3. 使用ubifs格式的根文件系统---过程记录

    配置内核,使其支持ubifs文件系统 1)Device Drivers  --->Memory Technology Device (MTD) support  --->UBI - Uns ...

  4. 提升Android编译速度

    Android codebase都非常大.编译一次都须要花非常多时间.假设是preloader/lk/bootimage还好,可是Android的话都是非常久. 实际上这个编译时间还是能够进一步缩短! ...

  5. page size == 4096 , nand size == 1GB, block size == 256kb 的ubi 文件系统制作

    mkubiimg.sh 2 sudo mkfs.ubifs -F -q -r rootfs_ecm_5410 -m 4096 -e 253952 -c 3600 -o ubifs.img 3 4 ec ...

  6. UBI FAQ and HOWTO

    转:http://www.linux-mtd.infradead.org/faq/ubi.html UBI FAQ and HOWTO Table of contents How do I enabl ...

  7. 基于MTD的NAND驱动开发、K9F1G08 2K page、Yaffs2 Files System

    转载:http://hi.baidu.com/cui1206/item/1d4119e376132513585dd886 基于MTD的NAND驱动(linux-2.6.22.10内核),目前已可以在该 ...

  8. Linux UBI子系统设计初探

    问题领域 flash存储设备存在如下特点: 存在坏块 使用寿命较短 存储介质不稳定 读写速度慢 不支持随机访问(nand) 只能通过擦除将0改成1 最小读写单位为page or sub-page 便宜 ...

  9. NAND flash sub-pages

    http://www.linux-mtd.infradead.org/doc/ubi.html#L_subpage NAND flash sub-pages As it is said here, a ...

随机推荐

  1. 多校1005 HDU5785 Interesting (manacher)

    // 多校1005 HDU5785 Interesting // 题意:给你一个串,求相邻两个回文串左边端点*右边端点的和 // 思路:马拉车算出最长回文半径,求一个前缀和,既得到每个点对答案的贡献. ...

  2. mongoDB 3.0 安全权限访问控制 -摘自网络

    "E:\Program Files\MongoDB\Server\3.0\bin\mongod.exe" --logpath E:\mongodb\log\mongodblog.l ...

  3. codeforces 630R Game

    R. Game time limit per test 0.5 seconds memory limit per test 64 megabytes input standard input outp ...

  4. 嵌入式LINUX入门到实践(一)

    MINI2440 IIC协议 IIC协议在工程中应用广泛,在我看来,此协议的优势就在于其硬件及其简单,结构清晰. 首先来解读一下S3C2440A这款芯片的IIC协议. 一.一个协议的解读从如上结构图中 ...

  5. ThinkPHP框架的网站url重写

    nginx location / { root /var/www; index index.html index.htm index.php; if (!-e $request_filename) { ...

  6. ActiveMQ学习笔记(二) JMS与Spring

    上文可见,JMS Native API使用起来不是特别方便.好在Spring提供了很好的JMS支持. (一)配置ConnectionFactory 如果使用连接池的话,不要忘记activemq-poo ...

  7. Eclipse查找类路径快捷方式

    直接ctrl+shift+t查找这个类,下面会显示类的路径,包括jar名

  8. C#学习笔记(十二):正则表达式

    Regex 正则表达式的类,我们可以通过该类来使用正则表达式. 比如下面我们使用Regex来判断输入的字符串是否符合指定的格式: using System; using System.Text.Reg ...

  9. easyUI之tree

    转自:http://www.cnblogs.com/CoreCaiNiao/archive/2010/08/20/1804387.html http://blog.csdn.net/l27775918 ...

  10. C#中的where从句

    C#中的where从句 2011-07-03 13:07OrphousV | 分类:C#/.NET | 浏览8443次 能解释一下下面两段代码中where的作用吗?using System;publi ...