驱动可以参考At91_nand.c,这个比S3c2410.c (drivers\mtd\nand)简单多了

NAND FLASH是一个存储芯片
那么: 这样的操作很合理"读地址A的数据,把数据B写到地址A"

问1. 原理图上NAND FLASH和S3C2440之间只有数据线,
怎么传输地址?
答1.在DATA0~DATA7上既传输数据,又传输地址
当ALE为高电平时传输的是地址,

问2. 从NAND FLASH芯片手册可知,要操作NAND FLASH需要先发出命令
怎么传入命令?
答2.在DATA0~DATA7上既传输数据,又传输地址,也传输命令
当ALE为高电平时传输的是地址,
当CLE为高电平时传输的是命令
当ALE和CLE都为低电平时传输的是数据

问3. 数据线既接到NAND FLASH,也接到NOR FLASH,还接到SDRAM、DM9000等等
那么怎么避免干扰?
答3. 这些设备,要访问之必须"选中",
没有选中的芯片不会工作,相当于没接一样

问4. 假设烧写NAND FLASH,把命令、地址、数据发给它之后,
NAND FLASH肯定不可能瞬间完成烧写的,
怎么判断烧写完成?
答4. 通过状态引脚RnB来判断:它为高电平表示就绪,它为低电平表示正忙

问5. 怎么操作NAND FLASH呢?
答5. 根据NAND FLASH的芯片手册,一般的过程是:
发出命令
发出地址
发出数据/读数据

NAND FLASH                                     S3C2440
发命令   选中芯片
             CLE设为高电平                                    NFCMMD=命令值
             在DATA0~DATA7上输出命令值
             发出一个写脉冲

发地址    选中芯片                                              NFADDR=地址值
               ALE设为高电平
               在DATA0~DATA7上输出地址值
                发出一个写脉冲

发数据     选中芯片                                              NFDATA=数据值
                ALE,CLE设为低电平
                在DATA0~DATA7上输出数据值
                发出一个写脉冲

读数据     选中芯片                                               val=NFDATA
               发出读脉冲
               读DATA0~DATA7的数据

用UBOOT来体验NAND FLASH的操作:

1. 读ID
                                                               S3C2440                                   u-boot
选中                                                        NFCONT的bit1设为0                  md.l 0x4E000004 1; mw.l 0x4E000004 1(memory display读 ;memory write写)
发出命令0x90                                         NFCMMD=0x90                           mw.b 0x4E000008 0x90
发出地址0x00                                         NFADDR=0x00                           mw.b 0x4E00000C 0x00
读数据得到0xEC                                     val=NFDATA                               md.b 0x4E000010 1
读数据得到device code                           val=NFDATA                              md.b 0x4E000010 1
                  0xda
退出读ID的状态                                        NFCMMD=0xff                         mw.b 0x4E000008 0xff

2. 读内容: 读0地址的数据
使用UBOOT命令:
nand dump 0
Page 00000000 dump:
17 00 00 ea 14 f0 9f e5 14 f0 9f e5 14 f0 9f e5

(nandflash用五个字节表示地址)

S3C2440                              u-boot
选中                                         NFCONT的bit1设为0            md.l 0x4E000004 1; mw.l 0x4E000004 1
发出命令0x00                           NFCMMD=0x00                    mw.b 0x4E000008 0x00
发出地址0x00                          NFADDR=0x00                      mw.b 0x4E00000C 0x00
发出地址0x00                           NFADDR=0x00                     mw.b 0x4E00000C 0x00
发出地址0x00                          NFADDR=0x00        mw.b 0x4E00000C 0x00
发出地址0x00                          NFADDR=0x00        mw.b 0x4E00000C 0x00
发出地址0x00                           NFADDR=0x00        mw.b 0x4E00000C 0x00
发出命令0x30                          NFCMMD=0x30        mw.b 0x4E000008 0x30
读数据得到0x17        val=NFDATA          md.b 0x4E000010 1
读数据得到0x00        val=NFDATA          md.b 0x4E000010 1
读数据得到0x00        val=NFDATA          md.b 0x4E000010 1
读数据得到0xea v      al=NFDATA          md.b 0x4E000010 1
退出读状态         NFCMMD=0xff          mw.b 0x4E000008 0xff

NAND FLASH驱动程序层次

看内核启动信息
S3C24XX NAND Driver, (c) 2004 Simtec Electronics
s3c2440-nand s3c2440-nand: Tacls=3, 30ns Twrph0=7 70ns, Twrph1=3 30ns
NAND device: Manufacturer ID: 0xec, Chip ID: 0xda (Samsung NAND 256MiB 3,3V 8-bit)
Scanning device for bad blocks
Bad eraseblock 256 at 0x02000000
Bad eraseblock 257 at 0x02020000
Bad eraseblock 319 at 0x027e0000
Bad eraseblock 606 at 0x04bc0000
Bad eraseblock 608 at 0x04c00000
Creating 4 MTD partitions on "NAND 256MiB 3,3V 8-bit":
0x00000000-0x00040000 : "bootloader"
0x00040000-0x00060000 : "params"
0x00060000-0x00260000 : "kernel"
0x00260000-0x10000000 : "root"

sourceinsight工程中搜"S3C24XX NAND Driver"
S3c2410.c (drivers\mtd\nand)

s3c2410_nand_inithw   //初始化硬件,主要关于时钟频率计算及启用nand flash控制器,设置TACLS 、TWRPH0、TWRPH1通信时序等

s3c2410_nand_init_chip  //初始化芯片,设置nand_chip结构体的一些参数,比如读写寄存器或者函数
nand_scan // drivers/mtd/nand/nand_base.c 根据nand_chip的底层操作函数识别NAND FLASH,构造mtd_info
  nand_scan_ident
    nand_set_defaults
      if (!chip->select_chip)
        chip->select_chip = nand_select_chip; // 默认值不适用

      if (chip->cmdfunc == NULL)
        chip->cmdfunc = nand_command;
          chip->cmd_ctrl(mtd, command, ctrl);
      if (!chip->read_byte)
        chip->read_byte = nand_read_byte;
          readb(chip->IO_ADDR_R);
      if (chip->waitfunc == NULL)
        chip->waitfunc = nand_wait;
          chip->dev_ready

    nand_get_flash_type
      chip->select_chip(mtd, 0);
      chip->cmdfunc(mtd, NAND_CMD_READID, 0x00, -1);
      *maf_id = chip->read_byte(mtd);
      dev_id = chip->read_byte(mtd);

      //接下来在nand_flash_ids这个数字中根据dev_id找到一项,打印,在内核启动信息中可以发现这项信息
  nand_scan_tail
     mtd->erase = nand_erase;
     mtd->read = nand_read;
     mtd->write = nand_write;
s3c2410_nand_add_partition  //添加分区
  add_mtd_partitions
    add_mtd_device
      list_for_each(this, &mtd_notifiers) { // 问. mtd_notifiers在哪设置(对mtd_notifiers链表里的每一项调用add函数)(在本.c文件中找mtd_notifiers,看其在哪里被设置,发现是在register_mtd_user函数中,在找工程中这个函数被谁调用)
                      // 答. 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_notify_add 和 blktrans_notify_add(这两个就是add函数,包含着两个函数的结构体作为参数被register_mtd_user调用)
        先看字符设备的mtd_notify_add
          class_device_create
          class_device_create
        再看块设备的blktrans_notify_add
          list_for_each(this, &blktrans_majors) { // 问. blktrans_majors在哪设置(对blktrans_majors链表里的每一项调用add_mtd函数)
                           // 答. 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

在驱动了的开发板上运行 ls /dev/mtd* 指令,可以看到nand flash既可以当做字符设备,也可以作为块设备

怎么写驱动

1、分配一个nand_chip结构体

2、设置nand_chip结构体

3、硬件相关设置

4、使用核心层提供的nand_scan和add_mtd_partitions函数(add_mtd_device可以代替add_mtd_partitions,但是该函数使用后nandflash不能分区了)

(mtd_info结构体必须使用kzalloc申请,用kmalloc在驱动安装的时候会产生段错误,原因还不清楚)

(nand_scan会根据nand_chip设置一个mtd_info结构体,里面有读写、擦除等函数,drivers/mtd/mtdchar.c中当通过字符设备方式访问块设备时,比如read,就是找到这个mtd_info结构体里面的读函数)

测试4th:
1. make menuconfig去掉内核自带的NAND FLASH驱动
-> Device Drivers
-> Memory Technology Device (MTD) support
-> NAND Device Support
< > NAND Flash support for S3C2410/S3C2440 SoC
2. make uImage
使用新内核启动, 并且使用NFS作为根文件系统
3. insmod s3c_nand.ko

  ls -l /dev/mtd*
4. 格式化 (参考下面编译工具)
flash_eraseall /dev/mtd3 // 查完就是yaffs文件系统

5. 挂接
mount -t yaffs /dev/mtdblock3 /mnt
6. 在/mnt目录下建文件

编译工具:
1. tar xjf mtd-utils-05.07.23.tar.bz2
2. cd mtd-utils-05.07.23/util
修改Makefile:
#CROSS=arm-linux-
改为
CROSS=arm-linux-
3. make
4. cp flash_erase flash_eraseall /work/nfs_root/first_fs/bin/

15、NAND FLASH驱动程序框架的更多相关文章

  1. 【驱动】linux系统下nand flash驱动程序框架

    linux操作系统下nand flash驱动框架 当我们需要在操作系统上读写普通文件的时候,总是需要一层层往下,最终到达硬件相关操作,当然底层设备大多数都是块设备 NAND FLASH就作为一个最底层 ...

  2. NAND FLASH驱动框架以及程序实现

    1.NAND FLASH的硬件连接: 实验用的NAND FLASH芯片为K9F2G08U0C,它是三星公司的存储芯片,它的大小为256M.它的接线图如下所示: 它的每个引脚的分别为LDATA0-LDA ...

  3. NAND FLASH驱动程序

    NAND FLASH是一个存储芯片那么: 这样的操作很合理"读地址A的数据,把数据B写到地址A" 问1. 原理图上NAND FLASH和S3C2440之间只有数据线,     怎么 ...

  4. 嵌入式Linux驱动学习之路(二十三)NAND FLASH驱动程序

    NAND FLASH是一个存储芯片. 在芯片上的DATA0-DATA7上既能传输数据也能传输地址. 当ALE为高电平时传输的是地址. 当CLE为高电平时传输的是命令. 当ALE和CLE都为低电平时传输 ...

  5. 15.1 linux操作系统下nand flash驱动框架2

    当我们需要在操作系统上读写普通文件的时候,总是需要一层层往下,最终到达硬件相关操作,当然底层设备大多数都是块设备 NAND FLASH就作为一个最底层的块设备. 而写驱动,就是要构建硬件与操作系统之间 ...

  6. 块设备驱动之NAND FLASH驱动程序

    转载请注明出处:http://blog.csdn.net/ruoyunliufeng/article/details/25240909 一.框架总结 watermark/2/text/aHR0cDov ...

  7. Nand Flash 驱动框架

    框架入口源文件:s3c_nand.c (可根据入口源文件,再按着框架到内核走一遍) 内核版本:linux_2.6.22.6   硬件平台:JZ2440 以下是驱动框架: 以下是驱动代码 s3c_nan ...

  8. 驱动09.nand flash

    1 nand flash的操作 目的:读地址A的数据,把数据B写到地址A. 问1. 原理图上NAND FLASH和S3C2440之间只有数据线,怎么传输地址?答1.在DATA0-DATA7上既传输数据 ...

  9. NOR FLASH驱动程序

    NOR                                  NAND接口:    RAM-Like,引脚多                 引脚少,复用容量:  小 1M 2M 3M   ...

随机推荐

  1. HDU 1495 很可乐(BFS 倒水问题)

    题意  将体积为s的可乐  利用容积分别为n和m的两个杯子平均分为两份  至少须要倒多少次可乐 能够把容器s,n,m中装的可乐量看成一种状态 容器都是没有刻度的  所以每次倒可乐要么把自己倒完 要么把 ...

  2. android-LinearLayout 控件占满父容器位置实现

    经常碰到需要把一个控件放在手机底部的情况,以前都是在LinearLayout尝试使用gravity="bottom" ,但是,没有效果,后来在网上查到了方法,如下 <Line ...

  3. PHP和JSON

    PHP和JSON 一.总结 1.php中json的使用方法:php中json的使用超级简单啦,主要是两个函数json_encode(编码)和json_decode(解码),像md5加密 2.json的 ...

  4. PHP盛宴——经常使用函数集锦

    近期写了蛮多PHP,也接触到挺多经常使用的函数,大多都记了笔记,发个博客出来.共同学习.事实上感觉学习一门语言,语法逻辑是软素养.而对语言的熟悉程度仅仅能随着使用时间的增长而慢慢增长,当对一门语言的函 ...

  5. HTML的SEO(搜索引擎优化)标准

    HTML的SEO(搜索引擎优化)标准 一.总结 这个做seo的时候要多看,做网站优化的时候 1. SEO(搜索引擎优化):通过总结搜索引擎的排名规律,对网站进行合理优化,使你的网站在百度和Google ...

  6. nuxt使用QRCode.js 生成二维码

    QRCode.js 是一个用于生成二维码图片的插件, 官方文档 . 我是在nuxt.js(vue官方的服务端渲染方式)项目里使用的QRCode.js: 第一步:看官方文档: 第二步:下载QRCode. ...

  7. USB串行端口

    USB-SERIAL CH341A(COM22)USB串行端口

  8. LoadRunner--录制手机APP脚本

    通过LR录制手机脚本的方式有三种: 1)通过安卓模拟器录制: 2)通过抓包录制: 3)通过代理方式录制: 本文使用第二种方式进行录制,首先需要先安装LoadRunner11测试工具,然后安装lr录制A ...

  9. 【hdu 6214】Smallest Minimum Cut

    [链接] 我是链接,点我呀:) [题意] 求最小割中最少的边数. [题解] 模板题 [代码] const int INF = 1e9; const int maxn = 1e3 + 7; const ...

  10. 【 2017 Multi-University Training Contest - Team 9 && hdu 6162】Ch’s gift

    [链接]h在这里写链接 [题意] 给你一棵树,每个节点上都有一个权值. 然后给你m个询问,每个询问(x,y,a,b); 表示询问x->y这条路径上权值在[a,b]范围内的节点的权值和. [题解] ...