8.Nor Flash块设备驱动

一:nor flash原理及硬件
在这里插入图片描述
1.NOR 的接口与内存的接口是一样的,而 NAND(数据线只有 7 条,发地址又发命令和数据等)。
NOR 可以像内存一样的来读,但不能像内存一样的去写。
NOR 的烧写要发出某些特定的命令,在某地址上写某个值就称为命令

2.NOR 存放关键性的代码,如 bootload\内核或文件系统。而 NADN 有位反转的缺点,如存一些海量数据如视频监控文件等

3.用 NOR 启动时,CPU 看到的“0”地址是“NOR”FLASH。
若为 NAND 启动,则 CPU 看到的“0”地址是 2440 片的 4K 内存。
用 NAND 启动时 CPU 完全看不到 NOR,只有用 NOR 启动时,CPU 看到的“0”地址才是 NOR。

代码可以直接在 NOR 上运行,在 NAND 上不行。CPU 可以直接从 NOR 上取到指令来运行。而用 NAND 启动,2440 是有将 NAND 的前 4K 数据自动拷贝到 2440 的 4K 片内内存里,这时 CPU再从片内 4K 内存中取指令运行

4.NOR有两种规范, jedec, cfi(common flash interface)

jedec

就是和nandflash的一样,通过读ID来匹配linux内核中drivers/mtd/chips/jedec_probe.c里的jedec_table[]数组,来确定norflash的各个参数(名称、容量、位宽等),如下图所示:

cfi

就是将这些参数保存在cfi模式下指定地址中, 往nor的0x55地址写入0x98,即可进入cfi模式,
当我们在cfi模式下,比如:读取nor地址0x27处的数据,便能读到nor的容量

二:驱动编写
所以注册一个块设备驱动,需要以下步骤:

  1. 分配mtd_info结构体和map_info结构体
  2. 设置map_info 结构体
    物理基地址(phys), 大小(size), 位宽(bankwidth), 虚拟基地址(virt) 。
    内核看到不同开发板 NOR 的最小差别
  3. 设置mtd_info 结构体
  4. 使用add_mtd_partitions()或者add_mtd_device()来创建MTD字符/块 设备
#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 mtd_info        *mynor_mtd_info;
static struct map_info         *mynor_map_info;


static struct mtd_partition mynor_partitions[] = {
       [0] = {
        .name   = "bootloader",
        .size   = 0x00040000,
        .offset     = 0,
       },
       [1] = {
        .name   = "root",
        .offset = MTDPART_OFS_APPEND,
        .size   = MTDPART_SIZ_FULL,
       }
};
 
static const char *mynor_probe_types[] = { "cfi_probe", "jedec_probe",NULL};


static int mynor_init(void)
{
    int val;

/*1. 分配map_info 结构体和mtd_info结构体*/
    mynor_mtd_info=kzalloc(sizeof(struct mtd_info), GFP_KERNEL);
    mynor_map_info=kzalloc(sizeof(struct map_info), GFP_KERNEL);

/*2. 设置map_info 结构体*/
    mynor_map_info->name="my_nor";
    mynor_map_info->phys=0x0;                          //物理地址
    mynor_map_info->size=0x1000000;                 //=16M,长度必须大于等于norflash的2M容量
    mynor_map_info->bankwidth=2;                     //16位宽
    mynor_map_info->virt = ioremap(0x0, mynor_map_info->size);   //虚拟地址
    simple_map_init(mynor_map_info);

/*3. 设置mtd_info 结构体*/
   mynor_mtd_info = do_map_probe("cfi_probe", mynor_map_info);
   if (!mynor_mtd_info)
   {
     mynor_mtd_info = do_map_probe("jedec_probe", mynor_map_info);
    }
     if (!mynor_mtd_info)
	    {		
		    printk("not  available  norflash !!!\r\n");
		    goto err_out;
	    }
         mynor_mtd_info->owner=THIS_MODULE;
 
/*4. 使用add_mtd_partitions()或者add_mtd_device()来创建MTD字符/块 设备*/
       add_mtd_partitions(mynor_mtd_info,mynor_partitions,2);
       return 0;

       
err_out:
       iounmap(mynor_map_info->virt);                      //取消虚拟地址映射
       kfree(mynor_map_info);
       kfree(mynor_mtd_info);      
       return 0;
}


static  void mynor_exit(void)
{
    del_mtd_partitions(mynor_mtd_info);                  //卸载分区
    iounmap(mynor_map_info->virt);                      //取消虚拟地址映射
    kfree(mynor_map_info);
    kfree(mynor_mtd_info);       
}

module_init(mynor_init);
module_exit(mynor_exit);
MODULE_LICENSE("GPL");

三,nor 驱动实验
(一定要在nor启动下挂载才行,因为2440使用nand启动时,是访问不了nor的前4k地址)
1.重新编译内核(去掉默认nor flash驱动)
2.insmod 挂载驱动
在这里插入图片描述
3. 接下来便来对root分区(mtd1)来试验(使用flash之前最好擦除一次)

./flash_eraseall -j /dev/mtd1                      //使用mtd-util工具的flash_eraseal命令来擦除root分区(mtd1)

mount -t jffs2 /dev/mtdblock1 /mnt/                //使用mount挂载文件系统, -t:文件系统类型(type)

接下来就可以在/mnt目录下来任意读写文件了,最终会保存在flash的mtdblock1块设备中

**2.**利用内核自带的 NORFLASH 底层驱动程序
Physmap.c”做测试:
内核里有这一个底层的 NORFLASH 驱动程序,这时可以直接拿来做实验:
测试 1:通过配置内核支持 NOR FLASH

1. make menuconfig
-> Device Drivers
 -> Memory Technology Device (MTD) support //内存技术设备支持
 -> Mapping drivers for chip access
 <M> CFI Flash device in physical memory map //M作为模块
 (0x0) Physical start address of flash mapping // 物理基地址 写为0
 (0x1000000) Physical length of flash mapping // 长度 这里写大些为16M,此长度要大于等于
NORFLASH的真实长度即可。因为它要ioremap。设置长度的意思是让它ioremap映射得到虚拟地址。
 (2) Bank width in octets (NEW) // 位宽 16,单位是 octets(8
的意思).故设为 2
  1. make modules(不需 make uImage)得到“physmap.ko”。
  2. cp drivers/mtd/maps/physmap.ko /work/nfs_root/first_fs
  3. 启动开发板
    ls /dev/mtd*
    insmod physmap.ko
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值