参考此文,把难懂的表述整理了下,做简化总结:http://blog.csdn.net/binghuiliang/article/details/2060794

红色部分是我阅读文章后的修改,还没查看源码,不太确定的修改准确性,可能理解有误。


MTD(Memory Technology Device)是用于访问Memory的linux子系统,MTD的主要目的是为了使新的memory设备的驱动更加简单,为此它在硬件和上层之间提供了一个抽象的接口。MTD的所有源代码在/drivers/mtd子目录下。CFI接口的MTD设备可分为4层(从设备节点直到底层硬件驱动),这4层从下到上依次是(这样顺序有利于理解)


 1.硬件驱动层—— CFI接口标准

Linux MTD设备的NOR Flash芯片驱动遵循CFI接口标准,其驱动程序位于drivers/mtd/chips子目录下。NANDFlash的驱动程序则位于/drivers/mtd/nand子目录下。

   

2.MTD原始设备层——封装了一些基本操作

原始设备层有两部分组成,一部分是MTD原始设备的通用代码,另一部分是各个特定的Flash的数据,例如分区。

用于描述MTD原始设备的数据结构是mtd_info,这其中定义了大量的关于MTD的数据和操作函数。mtd_table(mtdcore.c)则是所有MTD原始设备的列表,mtd_part(mtd_part.c)是用于表示MTD原始设备分区的结构,其中包含了mtd_info,因为每一个分区都是被看成一个MTD原始设备加在mtd_table中的,mtd_part.mtd_info中的大部分数据都从该分区的主分区mtd_part->master中获得。

 drivers/mtd/maps/子目录下存放的是特定的flash的数据,每一个文件都描述了一块板子上的flash。其中调用add_mtd_device()del_mtd_device()建立/删除mtd_info结构并将其加入/删除mtd_table。或者调用add_mtd_partition()del_mtd_partition()mtdpart.c)建立/删除mtd_part结构并将mtd_part.mtd_info加入/删除mtd_table 中)。

小结:MTD原始设备层就是根据MTD系统的标准,把驱动层提供的API,封装成了常用的MTD设备操作,如在mtd_table中增加、删除MTD设备,或者在mtd_info中增删MTD分区信息。这样,上层操作一个NandFlash设备时,操作的就不再是具体的Flash驱动,而是操作MTD系统,如:增删MTD设备。不知道有么有读写操作,其它功能有待我研究源码再下定论。 

mtd_info表示MTD原始设备的结构,每个分区也被实现为一个mtd_info,如果有两个MTD原始设备,每个上有三个分区,在系统中就一共有6个mtd_info结构,这些mtd_info的指针被存放在名为mtd_table的数组里。详情,可参见后面的源码


3.MTD设备层——基于通用的基本操作,设计出特别的设备接口,如字符设备、块设备。

     基于MTD原始设备,linux系统可以定义出MTD的块设备(主设备号31)和字符设备(设备号90)。MTD字符设备的定义在mtdchar.c中实现,通过注册一系列file operation函数(lseekopenclosereadwrite)。

MTD块设备则是定义了一个描述MTD块设备的结构mtdblk_dev,并声明了一个名为mtdblks的指针数组,这个数组用来存放块设备(mtdblk_dev)。且一个mtd_table中的每一个mtd_info对应一个块设备(mtdblk_dev),可以通过设备节点查询信息。

小结:与MTD原始设备层有什么不同呢?原始设备层是MTD系统的抽象统一的特性,像增删设备,各种芯片都是遵循统一标准的。而MTD设备层要根据这些基本操作,封装出不同的读写操作。这是我猜测的,因为块设备和字符设备的读取方式不同,字符设备可以读取单个字符,而块设备只能按页进行操作。两种设备的读写、擦除操作不一样,使得必须在共通的部分加上特性的部分。

但是,加了特性部分后,就有了不同的操作了,假设有block_read,char_read这样的函数,所以,这一层应该还实现了把xx_read,xx_write,xx_erase进行统一封装,根据设备节点提供的统一接口,统一封装为标准的read/write/open/close/lseek。


4.设备节点——dev/mtdblk. 用于上层访问硬件信息

另外,如何调用上面的CFI接口设备呢?通过下面两系统。

5、根文件系统:在Bootloader中将JFFS(或JFFS2)的文件系统映像jffs.image(或jffs2.img)烧到flash的某一个分区中,在/arch/arm/mach-your/arch.c文件的your_fixup函数中将该分区作为根文件系统挂载。

6、文件系统:内核启动后,通过mount 命令可以将flash中的其余分区作为文件系统挂载到mountpoint上。

最下面的mtdchar.c和mtdblock.c是我后来加上去的,是用来描述MTD设备层的(mtd字符设备和mtd块设备)


Nor型Flash芯片驱动与MTD原始设备

所有的NOR型Flash的驱动(探测probe)程序都放在drivers/mtd/chips下,一个MTD原始设备可以由一块或者数块相同的Flash芯片组成。所有组成一个MTD原始设备的Flash芯片必须是同类型的(无论是interleave(串接,增加容量),还是地址相连(并联,增加数据位宽)),共用一个“MTD原始设备”数据结构来描述组成它的Flash芯片。

每个MTD原始设备都有一个mtd_info结构,

mtd_info.priv(成员,私有数据)->指向map_info(内存映射信息)

map_info.fldrv_priv                  ->指向cfi_private结构CFI接口信息

cfi_private.cfiq           -> 指向cfi_ident(描述芯片信息,我猜这个ident是identity,指符合CFI的具体设备的身份)

cfi_ident.chips           -> 指向flchip(描述每个Flash芯片的专有信息(比如说起始地址)


源码部分太多了,分篇显示比较好索引。

MTD结构体源码

http://blog.csdn.net/xzongyuan/article/details/29822879


Logo

开源、云原生的融合云平台

更多推荐