全部博文(685)
分类: LINUX
2014-10-27 12:30:54
今天做升级方案用到了mtd-utils中的flash_eraseall和flash_cp两个工具,在进行方案验证的时候,遭遇到各种不解和疑惑,因对MTD的原理不熟悉,所以只能多次尝试,虽然最后把方案搞定了,不过觉得MTD中的mtd和mtdblock区别这块还是值得总结学习一下。这里先说明一下问题现象,然后在进行具体的区别原理解释。
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
|
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
|
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(memory technology device内存技术设备)是用于访问memory设备(ROM、flash)的Linux的子系统。MTD的主要目的是为了使新的memory设备的驱动更加简单,为此它在硬件和上层之间提供了一个抽象的接口,并进行了一个层次划分,层次从上到下大致为:设备文件、MTD设备层、MTD原始设备层、硬件驱动层。MTD的所有源代码在/drivers/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
~ $
|
/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;
}
|
/dev/mtdblockN,是Flash驱动中用add_mtd_partitions()添加MTD设备分区,而生成的对应的块设备。MTD块设备驱动程序可以让flash器件伪装成块设备,实际上