分类: LINUX
2012-10-04 17:49:04
FLASH在嵌入式系统中是必不可少的,它是bootloader、linux内核和文件系统的最佳载体。在Linux内核中引入了MTD子系统为NOR FLASH和NAND FLASH设备提供统一的接口,从而使得FLASH驱动的设计大为简化。
在引入MTD后Linux系统中FLASH设备驱动可分为四层:
1. 硬件驱动层:FLASH硬件驱动层负责FLASH硬件设备的读、写、擦出,LINUX MTD设备的NOR FLASH驱动位于/driver/mtd/chips子目录下,NAND FLASH驱动则位于/driver/mtd/nand子目录下。
2. MTD原始设备层:MTD原始设备层由两部分构成,一部分是MTD原始设备的通用代码(mtdcore.c、mtdpart.c),另一部分是各个特定的FLASH的数据,在map目录下,例如分区。
3. MTD设备层:基于MTD原始设备,LINUX系统可以定义出MTD的块设备(主设备号31)和字符设备(设备号90),构成设备层。MTD字符设备在mtdchar.c实现,MTD块设备在mtdblock.c实现。
4. 设备节点:通过mknod在/dev子目录下建立MTD字符设备节点(主设备号为90)和块设备节点(主设备号为31),用户通过访问此设备节点即可访问MTD字符设备和块设备。
基本的调用关系如下图:
一个MTD原始设备可以通过mtd_part分割成数个MTD原始设备注册进mtd_table,mtd_table中的每个MTD原始设备都可以被注册成一个MTD设备,有两个函数可以完成这个工作,即add_mtd_device函数和add_mtd_partitions函数。其中add_mtd_device函数是把整个NAND FLASH注册进MTD Core,而add_mtd_partitions函数则是把NAND FLASH的各个分区分别注册进MTD Core。
当MTD原始设备调用add_mtd_partitions()的时候它会对每一个新建分区建立一个struct mtd_part 结构将其加入mtd_partitions中并调用add_mtd_device()将此分区做为MTD设备注册进MTD Core,成功的时返回0。重点关注一下add_mtd_partitions(struct mtd_info *master,struct mtd_partitions*parts,int nbparts)其中master就是这个MTD原始设备,parts即NAND的分区信息,nbparts指有几个分区。那么parts和nbparts怎么来的呢,其实上面有一句话已经说了。。举个例子在我们移植Linux内核到我们的开发板的时候我们会对NANDFLASH进行分区。
几个重要的数据结构:
struct mtd_info; 用于描述原始设备的数据结构是mtd_info,这其中定义了大量的关于MTD的数据和操作函数。
struct mtd_partion;一个分区
struct mtd_map;
struct mad_party;一个分区对应一个
struct mtd_notifier
每个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芯片的专有信息(比如说起始地址)
一个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。