Nand Flash 的分析,我们需要看datasheet,一般分析一个 READ ID,就知道。 就知道厂家ID 和设备ID.
U-BOOT里面也提供了操作Nand Flash 的 operation。md 是read,mw是write 以四字节读写
1. read ID
可以看一个read ID operation s3c2440 u-boot
选中芯片 NFCONT bit1 设置为0 0x4E000004 md.l 0x4E000004 1(四字节读取) mw.l 0x4E000004 1(写)
1.发送0x90命令 NFCMMD = 0X90; mw.b 0x4E000008 0X90 b 以1字节来读取,1字节就是8bits 0XdcH
2.发送0x00地址 NFADDR = 0X00; mw.b 0x4E00000C 0x00
3.然后读0xEC Value = NFDATA md.b 0x4E000010 1
4.然后读device code Value = NFDATA md.b 0x4E000010 1
5 退出read id模式 NFCMMD = 0xff mw.b 0x4E000008 0xff
Nand Flash 在linux种的框架分析
可以分析下面两个文件at91_nand.C 文件会简单一点 但是都是一样的。
linux/drivers/mtd/nand/s3c2410.c
drivers/mtd/nand/at91_nand.c
分析:
platform_driver_register(&at91_nand_driver);//首先 platform_driver_register 平台注册一个驱动
接下来看probe函数
主要需要构造 mtd_info nand_chip 这个两个结构体, nand_chip 就是硬件操作函数,发0X90命令函数
需要根据platform_device 的resource 进行映射,得到虚拟地址
host->io_base = ioremap(pdev->resource[0].start,
pdev->resource[0].end - pdev->resource[0].start + 1);
s3c2410_nand_inithw
s3c2410_nand_init_chip
nand_scan
nand_scan_ident
nand_set_defaults
nand_get_flash_type
chip->select_chip(mtd, i);
nand_scan_tail
s3c2410_nand_add_partition
add_mtd_device
list_for_each(this, &mtd_notifiers) { //mtd_notifiers 需要设置
//drivers/mtd/mtdchar.c,mtd_blkdev.c调用register_mtd_user
struct mtd_notifier *not = list_entry(this, struct mtd_notifier, list);
not->add(mtd);
这个mtd_notifiers 会有下面两个函数,
static struct mtd_notifier notifier = {
.add = mtd_notify_add,
.remove = mtd_notify_remove,
};
再看块设备的blktrans_notify_add
list_for_each(this, &blktrans_majors) { // 问. blktrans_majors在哪设置
// 答. drivers\mtd\mdblock.c或mtdblock_ro.c register_mtd_blktrans
struct mtd_blktrans_ops *tr = list_entry(this, struct mtd_blktrans_ops, list);
tr->add_mtd(tr, mtd);
mtdblock_add_mtd (drivers\mtd\mdblock.c)
add_mtd_blktrans_dev
alloc_disk
gd->queue = tr->blkcore_priv->rq; // tr->blkcore_priv->rq = blk_init_queue(mtd_blktrans_request, &tr->blkcore_priv->queue_lock);
add_disk
总结::
nand_chip 结构体知道发0x90命令 在nand_scan扫描之前,需要注册这些 nand_chip结构体里面的 发命令
选中芯片 读字节这些函数。
2440是在s3c2410_nand_init_chip这里面实现这些函数。在这s3c2410_nand_init_chip函数之前,是需要和硬件打交道,
就是需要映射ioremap,这也就是platform里面的res的虚拟地址映射。
mtd_info 结构体的初始化是在nand_scan初始化, 这里面有涉及到 MTD的问题,就是把Nand Flash 当作磁盘来用。
struct nand_chip *chip = mtd->priv;
需要设置
CLE 的 ALED的时间,需要配置nfconf这个寄存器