zoukankan      html  css  js  c++  java
  • NAND FLASH驱动程序

    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
      发出命令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

                              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 val=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"

    搜"S3C24XX NAND Driver"
    S3c2410.c (driversmtd and)

    s3c2410_nand_inithw
    s3c2410_nand_init_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_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在哪设置
    // 答. 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
    先看字符设备的mtd_notify_add
    class_device_create
    class_device_create
    再看块设备的blktrans_notify_add
    list_for_each(this, &blktrans_majors) { // 问. blktrans_majors在哪设置
    // 答. driversmtdmdblock.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 (driversmtdmdblock.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

    测试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
      cp arch/arm/boot/uImage /work/nfs_root/uImage_nonand
      使用新内核启动, 并且使用NFS作为根文件系统
      set bootargs console=ttySAC0 root=/dev/nfs nfsroot=192.168.31.202:/work/nfs_root/first_fs ip=192.168.31.203:192.168.31.202:192.168.31.1:255.255.255.0::eth0:off
      nfs 30000000 192.168.31.202:/work/nfs_root/uImage_nonand
      bootm 30000000

    3. insmod s3c_nand.ko

    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-util7.23/util
      修改Makefile:s-05.0

    CROSS=arm-linux-

    改为
    CROSS=arm-linux-
    3. make
    4. cp flash_erase flash_eraseall /work/nfs_root/first_fs/bin/

    版权声明:本文为博主原创文章,转载请注明文章来源,有需要帮忙可加QQ:871263854
  • 相关阅读:
    上传文件至服务器(图片)
    centos7语言更改
    centos7无法访问虚拟机web服务
    Java中四种访问权限总结
    线程和进程、程序、应用程序之间的关系
    kafka
    图文并茂理解iptables
    扩展模块
    根据子网掩码计算最大主机数
    iptables匹配条件总结1
  • 原文地址:https://www.cnblogs.com/Dream998/p/8540747.html
Copyright © 2011-2022 走看看