MTD技术的基本原理
MTD技术的基本原理MTD(memory technology device内存技术设备)是用于访问memory设备(ROM、flash)的Linux的子系统。MTD的主要目的是为了使新的memory设备的驱动更加简单,为此它在硬件和上层之间提供了一个抽象的接口,并进行了一个层次划分,层次从上到下大致为:设备文件、MTD设备层、MTD原始设备层、硬件驱动层。MTD的所有源代码在/drivers
MTD技术的基本原理
MTD(memory technology device内存技术设备)是用于访问memory设备(ROM、flash)的Linux的子系统。MTD的主要目的是为了使新的memory设备的驱动更加简单,为此它在硬件和上层之间提供了一个抽象的接口,并进行了一个层次划分,层次从上到下大致为:设备文件、MTD设备层、MTD原始设备层、硬件驱动层。MTD的所有源代码在/drivers/mtd子目录下。
MTD字符驱动程序允许直接访问flash器件,通常用来在flash上创建文件系统,也可以用来直接访问不频繁修改的数据。
MTD块设备驱动程序可以让flash器件伪装成块设备,实际上它通过把整块的erase block放到ram里面进行访问,然后再更新到flash,用户可以在这个块设备上创建通常的文件系统。
参考:http://blog.csdn.net/bugouyonggan/article/details/9167213
系统中的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); return 1; } |
MEMGETINFO是Linux MTD中的drivers/mtd/mtdchar.c中的ioctl命令,使用mtd字符设备需要加载mtdchar内核模块。该代码解释了上面的第一个现象。
/dev/mtdblockN设备
/dev/mtdblockN,是Flash驱动中用add_mtd_partitions()添加MTD设备分区,而生成的对应的块设备。MTD块设备驱动程序可以让flash器件伪装成块设备,实际上它通过把整块的erase block放到ram里面进行访问,然后再更新到flash,用户可以在这个块设备上创建通常的文件系统。
而对于MTD块设备,MTD设备层是不提供ioctl的实现方法的,也就不会有对应的MEMGETINFO命令之类,因此不能使用nandwrite,flash_eraseall,flash_erase等工具去对/dev/mtdblockN去进行操作,否则就会出现上面的现象一,同时也解释了现象3——用mtd2擦除分区后,在用mtdblock2进行umount就会造成混乱。
1 2 3 4 5 6 7 8 9 10 | ~ $ cat /proc/partitions major minor #blocks name
31 0 512 mtdblock0 31 1 1024 mtdblock1 31 2 5632 mtdblock2 31 3 9216 mtdblock3 254 0 30760960 mmcblk0 254 1 30756864 mmcblk0p1 ~ $ |
后面的两个是SD块设备的分区大小。每个block的大小是1KB。
MTD设备分区和总结
1 2 3 4 5 6 7 | ~ $ cat /proc/mtd dev: size erasesize name mtd0: 00080000 00020000 "boot" mtd1: 00100000 00020000 "kernel" mtd2: 00580000 00020000 "roofs70" mtd3: 00900000 00020000 "app" ~ $ |
可以发现,实际上mtdN和mtdblockN描述的是同一个MTD分区,对应同一个硬件分区,两者的大小是一样的,只不过是MTD设备层提供给上层的视图不一样,给上层提供了字符和块设备两种操作视图——为了上层使用的便利和需要,比如mount命令的需求,你只能挂载块设备(有文件系统),而不能对字符设备进行挂载,否则会出现上面的现象2:无效参数。
这里对于mtd和mtdblock设备的使用场景进行简单总结:
1. mtd-utils工具只能应用与/dev/mtdN的MTD字符设备
2. mount、umount命令只对/dev/mtdblockN的MTD块设备有效
3. /dev/mtdN和/dev/mtdblockN是同一个MTD设备的同一个分区(N一样)
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)