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. 【九度OJ】题目1096-二分查找

    题目1069:查找学生信息 这篇文章中提到的问题主要是由于调试平台Visual Studio和测试平台Online Judge的一些小差异,造成在Visual Studio中调试通过的代码,在输入OJ ...

  2. mybatis系列-08-动态sql

    8.1     什么是动态sql mybatis核心 对sql语句进行灵活操作,通过表达式进行判断,对sql进行灵活拼接.组装. 8.2     需求 用户信息综合查询列表和用户信息查询列表总数这两个 ...

  3. Fast Intro To Java Programming (1)

    基本语法 编写Java程序时,应注意以下几点: 大小写敏感:Java是大小写敏感的,这就意味着标识符Hello与hello是不同的. 类名:对于所有的类来说,类名的首字母应该大写.如果类名由若干单词组 ...

  4. SAE 合并图片

    $domain = 'picleader'; //图片库的域名 $stgurl = 'http://lemonluoxing-picleader.stor.sinaapp.com/'; //绝对路径 ...

  5. Struts2运行流程分析

    一.Struts2运行流程图: 二.运行流程分析: 1. 请求发送给StrutsPrepareAndExecuteFilter 2.StrutsPrepareAndExecuteFilter询问Act ...

  6. BestCoder Round #71 (div.2) (hdu 5621)

    KK's Point Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total ...

  7. CABasicAnimation精讲

    前言 本教程写了这个效果图的demo,同时总结CABasicAnimation的使用方法. 看完gif动画完,看到了什么?平移.旋转.缩放.闪烁.路径动画. 实现平移动画 实现平移动画,我们可以通过t ...

  8. BZOJ 2243: [SDOI2011]染色 (树链剖分+线段树合并)

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2243 树链剖分的点剖分+线段树.漏了一个小地方,调了一下午...... 还是要细心啊! 结 ...

  9. 剑指OFFER之二维数组中的查找(九度OJ1384)

    题目描述: 大家都知道斐波那契数列,现在要求输入一个整数n,请你输出斐波那契数列的第n项.斐波那契数列的定义如下: 输入: 输入可能包含多个测试样例,对于每个测试案例, 输入包括一个整数n(1< ...

  10. 用Spring3编写第一个HelloWorld项目

    第一个HelloWorld程序 让我们用Spring来写第一个应用程序吧. 完成这一章要求: 熟悉Java语言 设置好Spring的环境 熟悉简单的Eclipse IDE的操作 如果你还没有设置好环境 ...