zoukankan      html  css  js  c++  java
  • 块设备驱动之NOR FLASH驱动

    转载请注明出处:http://blog.csdn.net/ruoyunliufeng/article/details/25240947

    一.硬件原理


    从原理图中我们能看到NOR FLASH有地址线,有数据线,能向内存一样读,不能向内存一样写(要发出某些命令)。

    这也使得NOR的数据很可靠,所以一般用来存储bootloader。当然如今手机上都仅仅有nand flash了。节约成本嘛。下节我会带大家去分析nand flash驱动,并进行总结。

    二.驱动程序

    /*
     * 參考 driversmtdmapsphysmap.c
     */
    
    #include <linux/module.h>
    #include <linux/types.h>
    #include <linux/kernel.h>
    #include <linux/init.h>
    #include <linux/slab.h>
    #include <linux/device.h>
    #include <linux/platform_device.h>
    #include <linux/mtd/mtd.h>
    #include <linux/mtd/map.h>
    #include <linux/mtd/partitions.h>
    #include <asm/io.h>
    
    static struct map_info *s3c_nor_map;
    static struct mtd_info *s3c_nor_mtd;
    
    /*分区数组*/
    static struct mtd_partition s3c_nor_parts[] = {
    	[0] = {
            .name   = "bootloader_nor",
            .size   = 0x00040000,
    		.offset	= 0,
    	},
    	[1] = {
            .name   = "root_nor",
            .offset = MTDPART_OFS_APPEND,      //紧接着上一个
            .size   = MTDPART_SIZ_FULL,         //到最后
    	}
    };
    
    
    static int s3c_nor_init(void)  //入口函数
    {
    	/* 1. 分配map_info结构体 */
    	s3c_nor_map = kzalloc(sizeof(struct map_info), GFP_KERNEL);;
    	
    	/* 2. 设置: 物理基地址(phys), 大小(size), 位宽(bankwidth), 虚拟基地址(virt) */
    	s3c_nor_map->name = "s3c_nor";
    	s3c_nor_map->phys = 0;          //物理地址
    	s3c_nor_map->size = 0x1000000; /* >= NOR的真正大小 */
    	s3c_nor_map->bankwidth = 2;     //位宽
    	s3c_nor_map->virt = ioremap(s3c_nor_map->phys, s3c_nor_map->size);  //虚拟地址
    
    	simple_map_init(s3c_nor_map);    //简单初始化
    	
    	/* 3. 使用: 调用NOR FLASH协议层提供的函数来识别 */
    	printk("use cfi_probe
    ");
    	s3c_nor_mtd = do_map_probe("cfi_probe", s3c_nor_map);
    	/*假设没识别就用jedec*/
    	if (!s3c_nor_mtd)
    	{
    		printk("use jedec_probe
    ");
    		s3c_nor_mtd = do_map_probe("jedec_probe", s3c_nor_map);
    	}
            /*假设仍然没事别就释放掉。返回错误*/
    	if (!s3c_nor_mtd)
    	{		
    		iounmap(s3c_nor_map->virt);
    		kfree(s3c_nor_map);
    		return -EIO;
    	}
    	
    	/* 4. add_mtd_partitions (加入分区)*/
    	add_mtd_partitions(s3c_nor_mtd, s3c_nor_parts, 2);
    	
    	return 0;
    }
    
    static void s3c_nor_exit(void)         //出口函数
    {
    	del_mtd_partitions(s3c_nor_mtd);  
    	iounmap(s3c_nor_map->virt);         
    	kfree(s3c_nor_map);
    }
    
    module_init(s3c_nor_init);
    module_exit(s3c_nor_exit);
    
    MODULE_LICENSE("GPL");
    


    三.驱动分析

       1. 分配map_info结构体

       2. 设置: 物理基地址(phys), 大小(size), 位宽(bankwidth), 虚拟基地址(virt)

       3. 使用: 调用NOR FLASH协议层提供的函数来识别

       4. add_mtd_partitions (加入分区)

    事实上我们的这个驱动。主要把硬件上的差异性写出来就能够了,大部分的工作内核已经帮我们做了。如今我主要来分析第三步。cfi和jedec,这里主要分析cfi

    /*NOR FLASH识别过程*/
    do_map_probe("cfi_probe", s3c_nor_map);
        drv = get_mtd_chip_driver(name)
        ret = drv->probe(map);  // cfi_probe.c
                cfi_probe
                    mtd_do_chip_probe(map, &cfi_chip_probe);
                        cfi = genprobe_ident_chips(map, cp);
                                    genprobe_new_chip(map, cp, &cfi)
                                        cp->probe_chip(map, 0, NULL, cfi)
                                                cfi_probe_chip
                                                    // 进入CFI模式
                                                    cfi_send_gen_cmd(0x98, 0x55, base, map, cfi, cfi->device_type, NULL);
                                                    // 看能否读出"QRY"
                                                    qry_present(map,base,cfi)


    我们进行的操作事实上在协议层已经帮我们写好了。我们须要提供的事实上就是硬件上的差异。由于全部的nor都是支持这套协议的。


    參考:韦东山视频第二期

  • 相关阅读:
    paip.提升性能并行多核编程哈的数据结构list,set,map
    paip.网页右键复制菜单限制解除解决方案
    paip.java swt 乱码问题解决
    paip.哈米架构CAO.txt
    paip.提升性能协程“微线程”的使用.
    paip.最省内存的浏览器评测 cah
    paip.云计算以及分布式计算的区别
    paip.提升性能string split
    paip.提升分词准确度常用量词表
    paip.提升中文分词准确度新词识别
  • 原文地址:https://www.cnblogs.com/brucemengbm/p/6763566.html
Copyright © 2011-2022 走看看