Chinaunix首页 | 论坛 | 博客
  • 博客访问: 3167996
  • 博文数量: 685
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 5303
  • 用 户 组: 普通用户
  • 注册时间: 2014-04-19 14:17
个人简介

文章分类

全部博文(685)

文章存档

2015年(116)

2014年(569)

分类: LINUX

2014-10-27 12:30:54

原文地址:http://my.oschina.net/shelllife/blog/123482
# ls /dev | grep mtd*
mtd0
mtd0ro
mtd1
mtd1ro
mtd2
mtd2ro
mtd3
mtd3ro
mtdblock0
mtdblock1
mtdblock2
mtdblock3

今天做升级方案用到了mtd-utils中的flash_eraseall和flash_cp两个工具,在进行方案验证的时候,遭遇到各种不解和疑惑,因对MTD的原理不熟悉,所以只能多次尝试,虽然最后把方案搞定了,不过觉得MTD中的mtd和mtdblock区别这块还是值得总结学习一下。这里先说明一下问题现象,然后在进行具体的区别原理解释。

MTD设备(Nor Flash)使用中的问题现象表现

  1. mtd-utils工具对mtd和mtdblock分区设备的区别处理
  2. ?
    1
    2
    3
    4
    5
    6
    7
    / $ flash_eraseall/dev/mtdblock/2
    flash_eraseall:/dev/mtdblock/2: unable to get MTD device info
    / $ flash_eraseall/dev/mtdblock/2
    flash_eraseall:/dev/mtdblock/2: unable to get MTD device info
    / $ flash_eraseall/dev/mtd/2
    Erasing 128 Kibyte @ 8e0000 -- 98 % complete.
    / $ls
    ?
    1
    2
    3
    4
    5
    6
    / $ flashcp rootfs_version/dev/mtdblock2
    This doesn't seem to be a valid MTD flash device!
    / $ flashcp rootfs_version/dev/mtdblock/2
    This doesn't seem to be a valid MTD flash device!
    / $ flashcp rootfs_version/dev/mtd2
    / $ls
  3. mtd和mtdblock分区设备mount时的区别
  4. ?
    1
    2
    3
    4
    5
    6
    / $mount-t jffs2/dev/mtd/2qqzm/
    mount: Mounting/dev/mtd/2on qqzm/ failed: Invalid argument
    / $mount-t jffs2/dev/mtd2qqzm/
    mount: Mounting/dev/mtd2on qqzm/ failed: Invalid argument
    / $mount-t jffs2/dev/mtdblock/2qqzm/
    / $ls
  5. mtdblock挂载成功,单擦除后卸载失败
  6. ?
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    / $ flash_eraseall/dev/mtd/2 Erasing 128 Kibyte @ 8e0000 -- 98 % complete.
    /qqzm$mount
    /dev/rooton /typejffs2 (rw,noatime)
    proc on/proctypeproc (rw,nodiratime)
    sysfs on/systypesysfs (rw)
    devfs on/devtypedevfs (rw)
    devpts on/dev/ptstypedevpts (rw)
    /dev/mmcblk0p1on/mnt/sdtypevfat (rw,nodiratime,fmask=0022,dmask=0022,codepage=cp437,iocharset=iso8859-1)
    /dev/mtdblock/2on/qqzmtypejffs2 (rw,noatime)
    none on/qqzm/www/cgi-bin/tmptyperamfs (rw)
    /qqzm$cd..
    / $umount/qqzm
    umount: Couldn'tumount/qqzm: Inappropriate ioctlfordevice
    / $umount/dev/mtdblock/2
    umount: Couldn'tumount/dev/mtdblock/2: Inappropriate ioctlfordevice
    / $

通过上面的不断尝试和错误反馈,我把方案基本验证通过了,只是对其中的原理不清楚:

  • 为什么mtd和mtdblock明明是同一个设备分区却有不同的操作?
  • mount命令只能挂载块设备吗?
  • 卸载mtdblock设备时,Inappropriate ioctl for device是什么意思?
  • unable to get MTD device info,又是什么意思?

MTD技术的基本原理

MTD(memory technology device内存技术设备)是用于访问memory设备(ROM、flash)的Linux的子系统。MTD的主要目的是为了使新的memory设备的驱动更加简单,为此它在硬件和上层之间提供了一个抽象的接口,并进行了一个层次划分,层次从上到下大致为:设备文件、MTD设备层、MTD原始设备层、硬件驱动层。MTD的所有源代码在/drivers/mtd子目录下。

系统中的MTD设备文件

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
~ $ls/dev/mtd* -l
crw-rw----    1 root     root      90,   0 Jan  1 00:00/dev/mtd0
crw-rw----    1 root     root      90,   1 Jan  1 00:00/dev/mtd0ro
crw-rw----    1 root     root      90,   2 Jan  1 00:00/dev/mtd1
crw-rw----    1 root     root      90,   3 Jan  1 00:00/dev/mtd1ro
crw-rw----    1 root     root      90,   4 Jan  1 00:00/dev/mtd2
crw-rw----    1 root     root      90,   5 Jan  1 00:00/dev/mtd2ro
crw-rw----    1 root     root      90,   6 Jan  1 00:00/dev/mtd3
crw-rw----    1 root     root      90,   7 Jan  1 00:00/dev/mtd3ro
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
 
/dev/mtd:
crw-rw-rw-    1 root     root      90,   0 Jan  1 00:00 0
cr--r--r--    1 root     root      90,   1 Jan  1 00:00 0ro
crw-rw-rw-    1 root     root      90,   2 Jan  1 00:00 1
cr--r--r--    1 root     root      90,   3 Jan  1 00:00 1ro
crw-rw-rw-    1 root     root      90,   4 Jan  1 00:00 2
cr--r--r--    1 root     root      90,   5 Jan  1 00:00 2ro
crw-rw-rw-    1 root     root      90,   6 Jan  1 00:00 3
cr--r--r--    1 root     root      90,   7 Jan  1 00:00 3ro
 
/dev/mtdblock:
brw-------    1 root     root      31,   0 Jan  1 00:00 0
brw-------    1 root     root      31,   1 Jan  1 00:00 1
brw-------    1 root     root      31,   2 Jan  1 00:00 2
brw-------    1 root     root      31,   3 Jan  1 00:00 3
~ $
可以看到有mtdN和对应的/dev/mtd/N、mtdblockN和对应的/dev/mtdblock/N两类MTD设备,分别是字符设备,主设备号90和块设备,主设备号31。其中/dev/mtd0和/dev/mtd/0是完全等价的,/dev/mtdblock0和/dev/mtdblock/0是完全等价的,而/dev/mtd0和/dev/mtdblock0则是同一个MTD分区的两种不同应用描述,操作上是有区别的。

/dev/mtdN设备

/dev/mtdN 是MTD架构中实现的mtd分区所对应的字符设备(将mtd设备分成多个区,每个区就为一个字符设备),其里面添加了一些ioctl,支持很多命令,如MEMGETINFO,MEMERASE等。

mtd-utils中的flash_eraseall等工具,就是以这些ioctl为基础而实现的工具,实现一些关于Flash的操作。比如,mtd 工具中 flash_eraseall中:

?
1
2
3
4
5
if(ioctl(fd, MEMGETINFO, &meminfo) != 0)
{
   fprintf(stderr,"%s: %s: unable to get MTD device info\n",exe_name, mtd_device);
   return1;
}
MEMGETINFO是Linux MTD中的drivers/mtd/mtdchar.c中的ioctl命令,使用mtd字符设备需要加载mtdchar内核模块。该代码解释了上面的第一个现象。

/dev/mtdblockN设备

/dev/mtdblockN,是Flash驱动中用add_mtd_partitions()添加MTD设备分区,而生成的对应的块设备。MTD块设备驱动程序可以让flash器件伪装成块设备,实际上

阅读(2000) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~