Linux下的文件系统结构如下:
MTD(memory technology device内存技术设备)是用于访问memory设备(ROM、flash)的Linux的子系统。MTD的主要目的是为了使新的memory设备的驱动更加简单,为此它在硬件和上层之间提供了一个抽象的接口。MTD的所有源代码在/drivers/mtd子目录下。我将CFI接口的MTD设备分为四层(从设备节点直到底层硬件驱动),这四层从上到下依次是:设备节点、MTD设备层、MTD原始设备层和硬件驱动层。
根文件系统
文件系统
字符设备节点
MTD字符设备
MTD块设备
MTD原始设备
FLASH硬件驱动
块设备节点
一、Flash硬件驱动层:硬件驱动层负责在init时驱动Flash硬件,Linux MTD设备的NOR Flash芯片驱动遵循CFI接口标准,其驱动程序位于drivers/mtd/chips子目录下。NAND型Flash的驱动程序则位于/drivers/mtd/nand子目录下
二、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原始设备,linux系统可以定义出MTD的块设备(主设备号31)和字符设备(设备号90)。MTD字符设备的定义在mtdchar.c中实现,通过注册一系列file operation函数(lseek、open、close、read、write)。MTD块设备则是定义了一个描述MTD块设备的结构 mtdblk_dev,并声明了一个名为mtdblks的指针数组,这数组中的每一个mtdblk_dev和mtd_table中的每一个 mtd_info一一对应。
四、设备节点:通过mknod在/dev子目录下建立MTD字符设备节点(主设备号为90)和MTD块设备节点(主设备号为31),通过访问此设备节点即可访问MTD字符设备和块设备。
五、根文件系统:在Bootloader中将JFFS(或JFFS2)的文件系统映像jffs.image(或jffs2.img)烧到flash的某一个分区中,在/arch/arm/mach-your/arch.c文件的 your_fixup函数中将该分区作为根文件系统挂载。
六、文件系统:内核启动后,通过mount 命令可以将flash中的其余分区作为文件系统挂载到mountpoint上。
设备层和原始设备层的函数调用关系(红色部分需要我们实现):
一个MTD原始设备可以通过mtd_part分割成数个MTD原始设备注册进 mtd_table,mtd_table中的每个MTD原始设备都可以被注册成一个MTD设备,其中字符设备的主设备号为90,次设备号为0、2、4、 6…(奇数次设备号为只读设备),块设备的主设备号为31,次设备号为0、1、2、3…
mtd_notifier mtd_notifier
字符设备 mtd_fops 块设备 mtd_fops
(mtdchar.c) (mtdblock.c) mtdblks
设备层
register_mtd_user()
get_mtd_device()
unregister_mtd_user()
put_mtd_device()
erase_info
mtd_notifiers
mtd_table
mtd_info
mtd_part
(mtdcore.c)
(mtdpart.c)
Your Flash
(your-flash.c)
add_mtd_partitions()
del_mtd_partitions()
原始设备层 add_mtd_device()
del_mtd_device()
mtd_partition
NOR型Flash芯片驱动与MTD原始设备
所有的NOR型Flash的驱动(探测probe)程序都放在 drivers/mtd/chips下,一个MTD原始设备可以由一块或者数块相同的Flash芯片组成。假设由4块devicetype为x8的 Flash,每块大小为8M,interleave为2,起始地址为0x01000000,地址相连,则构成一个MTD原始设备(0x01000000-0x03000000),其中两块interleave成一个chip,其地址从0x01000000到0x02000000,另两块interleave成一个chip,其地址从0x02000000到0x03000000。
请注意,所有组成一个MTD原始设备的Flash芯片必须是同类型的(无论是interleave还是地址相连),在描述MTD原始设备的数据结构中也只是采用了同一个结构来描述组成它的Flash芯片。
0x03000000
0x02000000
0x01000000
每个MTD原始设备都有一个mtd_info 结构,其中的priv指针指向一个map_info结构,map_info结构中的fldrv_priv指向一个cfi_private结构,cfi_private结构的cfiq指针指向一个cfi_ident结构,chips指针指向一个flchip结构的数组。其中mtd_info、 map_info和cfi_private结构用于描述MTD原始设备;因为组成MTD原始设备的NOR型Flash相同,cfi_ident结构用于描述Flash芯片的信息;而flchip结构用于描述每个Flash芯片的专有信息(比如说起始地址)
http://blog.chinaunix.net/u2/65684/showart_681399.html
上面是MTD的标准的解释,由mtd引来的很多概念(大部分都是和硬件flash有关的),这里我只想说说我的理解吧,标准解释网上一堆。
norflash:读很方便,但是写和擦除的时间很长,代码可以直接从中启动,不过速度相对ram来说慢些。
nandflash:不能直接读写,都是通过复杂的IO口操作读写擦除,不过写的速度比nor快,擦除的速度比nor快很多,可控制的最小单元也比nor要小。
关于两者的对比可以看这个帖子:
http://www.eefocus.com/article/09-12/143080021112375M21.html
norflash的两个概念
cfi:这个是一个公开的标准接口,大家可以从flash中读出cfi信息,也就得到了芯片的信息。
jedec:我觉得就是cfi出来之前一个组织,他主要了定义了0x90读出厂商和芯片的ID,然后像查表一样找到那个芯片对应的驱动相关的部分。一般有CFI接口都会建议用CFI,通用性强。
nandflash的几个概念
oob:每一页最后都会多16byte的空间
out-of-band,主要存放ecc,坏块标记等
edc/ecc:错误探测/错误纠正(
EDC/
ECC),保证flash中数据的正确性。
FTL/NFTL:先看下面这段,也许你就清楚了。
当前嵌入式FLASH解决方案多采用:
1. 无文件系统直接使用FLASH:缺点很明显
2. 采用传统文件系统,如ext2,ext3, FAT16/32, dos,Cramfs 等:这些文件系统本来是为传统的磁盘体开发的,他们无法高效的管理以FLASH作为介质的文件系统,特别是在FLASH的使用寿命上。于是出现了第3中方案。
3. 采用FTL/NFTL(flash 转换层/nand flash转换层)+ 传统文件系统:FTL的使用就是针对FLASH的特有属性,通过硬件的方式来实现日志管理、损益均衡等技术。但实践证明,由于各方面因素导致本方案有一定的局限性。
4. FLASH专用文件系统,如JFFS1/2,YAFFS 等,他们从一定程度上缓解了flash使用上的技术瓶颈。但也仍然存在诸多问题:如内存消耗大,对FLASH容量、文件系统大小、内容、访问模式等的线性依赖,损益均衡能力差活过渡损益。随作FLASH容量逐渐暴涨(我见到的资料已经有64GFLASH已经实用化),JFFS,YAFFS几乎无法管理如此大的FLASH——虽然JFFS目前还在改进中,但前途不看好,一个很好的例子JFFS的主要开发者大多倒向了UBIFS。:)
阅读(1122) | 评论(0) | 转发(0) |