在Linux 内核中,将Nandflash抽象为了MTD数据结构,用mtd_info结构体来表示,而每一个原始设备又可以进行分区,每个分区也被抽象为一个mtd_info,比如有两个Nandflash原始设备,每个原始设备各有3个分区,那么就需要6个mtd_info来描述他们。
struct mtd_info {
//在mtd.h中定义
//这里只列出了mtd_info的部分成员
u_int32_t flags;
u_int32_t size;
char *name;
int index;
int (*erase) (struct mtd_info *mtd, struct erase_info *instr);
int (*read) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf);
int (*write) (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf);
}
mtd_info结构体包含了对这个分区的读写以及擦除等成员函数,可以利用这些函数来方便地操作Nandflash.linux,把这些mtd_info保存在其数据结构数组mtd_table中,显然,只要从mtd_table中,获得了要操作的那个分区的mtd_info,那么对这个分区的操作就得心应手。分区表的定义是在drivers/mtd/nand/s3c2410_nand.c中来完成的,在这里可以根据自己的需求重新划分分区。
在这里选取mtd_table[4]作为示范分区,进行读写及擦除操作。
//从这个分区的第0个地址,开始读取512个字节到kbuf缓冲区中
kbuf=kmalloc(512,GFP_KERNEL);
if(!kbuf)
return –ENOMEA;
ret=(*(mtd_table[4]->read))(mtd_table[4],0,512,&retlen,kbuf);
//将kbuf中的数据写入到这个分区中,偏移地址为0
ret=(*(mtd_table[4]->write))(mtd_table[4],0,512,&retlen,kbuf);
//擦除一个块
struct erase_info erase;//erase_info结构体与mtd_info结构体同在mtd.h下定义 DECLARE_WAITQUEUE(wait,curren);//由于擦除数据(特别当需要擦除大量数据时),需要花费较长的一段时间,所以可以将当前进程放入等待队列,以节约cpu的时间
|