参考
http://blog.csdn.net/zrm2012/article/details/51840557
MTD设备层:
mtd字符设备接口:
/drivers
/mtd/mtdchar.c文件实现了MTD字符设备接口,通过它,可以直接访问Flash设备,与前面的字符驱动一样,通过
file_operations结构体里面的open()、read()、write()、ioctl()可以读写Flash,通过一系列IOCTL
命令可以获取Flash 设备信息、擦除Flash、读写NAND 的OOB、获取OOB layout 及检查NAND
坏块等(MEMGETINFO、MEMERASE、MEMREADOOB、MEMWRITEOOB、MEMGETBADBLOCK IOCRL)
mtd块设备接口:
/drivers
/mtd/mtdblock.c文件实现了MTD块设备接口,主要原理是将Flash的erase block
中的数据在内存中建立映射,然后对其进行修改,{BANNED}最佳后擦除Flash 上的block,将内存中的映射块写入Flash
块。整个过程被称为read/modify/erase/rewrite
周期。 但是,这样做是不安全的,当下列操作序列发生时,read/modify/erase/poweroff,就会丢失这个block 块的数据。
MTD硬件驱动层:
Linux
内核再MTD层下实现了通用的NAND驱动(/driver/mtd/nand/nand_base.c),因此芯片级的NAND驱动不再需要实现
mtd_info结构体中的read()、write()、read_oob()、write_oob()等成员函数。
MTD使用nand_chip来表示一个NAND FLASH芯片, 该结构体包含了关于Nand Flash的地址信息,读写方法,ECC模式,硬件控制等一系列底层机制
-
struct nand_chip {
-
void __iomem *IO_ADDR_R; /* 读8位I/O线地址 */
-
void __iomem *IO_ADDR_W; /* 写8位I/O线地址 */
-
-
/* 从芯片中读一个字节 */
-
uint8_t (*read_byte)(struct mtd_info *mtd);
-
/* 从芯片中读一个字 */
-
u16 (*read_word)(struct mtd_info *mtd);
-
/* 将缓冲区内容写入芯片 */
-
void (*write_buf)(struct mtd_info *mtd, const uint8_t *buf, int len);
-
/* 读芯片读取内容至缓冲区/ */
-
void (*read_buf)(struct mtd_info *mtd, uint8_t *buf, int len);
-
/* 验证芯片和写入缓冲区中的数据 */
-
int (*verify_buf)(struct mtd_info *mtd, const uint8_t *buf, int len);
-
/* 选中芯片 */
-
void (*select_chip)(struct mtd_info *mtd, int chip);
-
/* 检测是否有坏块 */
-
int (*block_bad)(struct mtd_info *mtd, loff_t ofs, int getchip);
-
/* 标记坏块 */
-
int (*block_markbad)(struct mtd_info *mtd, loff_t ofs);
-
/* 命令、地址、数据控制函数 */
-
void (*cmd_ctrl)(struct mtd_info *mtd, int dat,unsigned int ctrl);
-
/* 设备是否就绪 */
-
int (*dev_ready)(struct mtd_info *mtd);
-
/* 实现命令发送 */
-
void (*cmdfunc)(struct mtd_info *mtd, unsigned command, int column, int page_addr);
-
int (*waitfunc)(struct mtd_info *mtd, struct nand_chip *this);
-
/* 擦除命令的处理 */
-
void (*erase_cmd)(struct mtd_info *mtd, int page);
-
/* 扫描坏块 */
-
int (*scan_bbt)(struct mtd_info *mtd);
-
int (*errstat)(struct mtd_info *mtd, struct nand_chip *this, int state, int status, int page);
-
/* 写一页 */
-
int (*write_page)(struct mtd_info *mtd, struct nand_chip *chip,
-
const uint8_t *buf, int page, int cached, int raw);
-
-
int chip_delay; /* 由板决定的延迟时间 */
-
/* 与具体的NAND芯片相关的一些选项,如NAND_NO_AUTOINCR,NAND_BUSWIDTH_16等 */
-
unsigned int options;
-
-
/* 用位表示的NAND芯片的page大小,如某片NAND芯片
-
* 的一个page有512个字节,那么page_shift就是9
-
*/
-
int page_shift;
-
/* 用位表示的NAND芯片的每次可擦除的大小,如某片NAND芯片每次可
-
* 擦除16K字节(通常就是一个block的大小),那么phys_erase_shift就是14
-
*/
-
int phys_erase_shift;
-
/* 用位表示的bad block table的大小,通常一个bbt占用一个block,
-
* 所以bbt_erase_shift通常与phys_erase_shift相等
-
*/
-
int bbt_erase_shift;
-
/* 用位表示的NAND芯片的容量 */
-
int chip_shift;
-
/* NADN FLASH芯片的数量 */
-
int numchips;
-
/* NAND芯片的大小 */
-
uint64_t chipsize;
-
int pagemask;
-
int pagebuf;
-
int subpagesize;
-
uint8_t cellinfo;
-
int badblockpos;
-
nand_state_t state;
-
uint8_t *oob_poi;
-
struct nand_hw_control *controller;
-
struct nand_ecclayout *ecclayout; /* ECC布局 */
-
-
struct nand_ecc_ctrl ecc; /* ECC校验结构体,里面有大量的函数进行ECC校验 */
-
struct nand_buffers *buffers;
-
struct nand_hw_control hwcontrol;
-
struct mtd_oob_ops ops;
-
uint8_t *bbt;
-
struct nand_bbt_descr *bbt_td;
-
struct nand_bbt_descr *bbt_md;
-
struct nand_bbt_descr *badblock_pattern;
-
void *priv;
-
};
{BANNED}最佳后,我们来用图表的形式来总结一下,MTD设备层、MTD原始设备层、FLASH硬件驱动层之间的联系。
阅读(1755) | 评论(0) | 转发(0) |