Norflash 驱动

对jz2440上norflash的情况需要先查看之前uboot中norflash的介绍:https://blog.csdn.net/qqliyunpeng/article/details/51134567

 

1. norflash 接口

norflash 存储器接口有两个标准:CFI和JEDEC。

CFI为公共Flash接口(Common Flash Interface),程序从Flash芯片中获取操作方式信息(发送命令,从nor flash的芯片里获取器件的各种参数,换芯片时,不需修改内核代码)。

JEDEC,程序通过读取Flash的制造商ID和设备ID,通过内核中预先存储的信息来确定flash的大小和算法,也就是说当换另外一款芯片时,如果内核里没有这个nor flash 的信息,需手动添加该器件的各种参数,以确定Flash的大小和算法。当然如果芯片不支持CFI,就需使用JEDEC了。

 

2. 在uboot阶段体验

拨动拨码开关从norflash启动,如果norflash中没有uboot,需要根据之前的章节,将uboot烧写到norflash中,然后,启动。

 

读写的命令:

md 读 (md.l 读4字节 md.b 读1字节 )

mw 写(md.l 读4字节 md.b 读1字节 )

几个测试:

1)读 0 地址上的数据

> md.b 0

 

2)读ID

手册上说明的步骤如下

往地址555H写AAH

往地址2AAH写55H

往地址555H写90H

读0地址得到厂家ID: C2H

读1地址得到设备ID: 22DAH或225BH

退出读ID状态: 给任意地址写F0H

对于实际硬件上2440的A1对应 norflash上的A0,uboot的应该如何操作?

地址应该左移1位。即

 

往地址AAAH写AAH mw.w aaa aa

往地址554写55H mw.w 554 55

往地址AAAH写90H mw.w aaa 90

读0地址得到厂家ID: C2H md.w 0 1

读2地址得到设备ID: 22DAH或225BH md.w 2 1

退出读ID状态: mw.w 0 f0

 

3)NOR有两种规范, jedec, cfi(common flash interface)的操作

通过cfi读取芯片信息

norflash手册上操作方法

进入CFI模式 往55H写入98H

读数据: 读10H得到0051

读11H得到0052

读12H得到0059

读27H得到容量

由于引脚,地址需要左移一位

进入CFI模式 往AAH写入98H mw.w aa 98

读数据: 读20H得到0051 md.w 20 1

读22H得到0052 md.w 22 1

读24H得到0059 md.w 24 1

读4EH得到容量 md.w 4e 1

退出CFI模式 mw.w 0 f0

 

4)写数据:在地址0x100000写入0x1234

NOR手册:

往地址555H写AAH

往地址2AAH写55H

往地址555H写A0H

往地址PA写PD

2440的A1接到NOR的A0,因此,地址左移1位

往地址AAAH写AAH mw.w aaa aa

往地址554H写55H mw.w 554 55

往地址AAAH写A0H mw.w aaa a0

往地址0x200000写1234h mw.w 200000 1234

 

3. 例子

①测试1:配置内核支持norflash

1)

make menuconfig

-> Device Drivers

-> Memory Technology Device (MTD) support

-> Mapping drivers for chip access

<M> CFI Flash device in physical memory map

(0x0) Physical start address of flash mapping // 物理基地址

(0x1000000) Physical length of flash mapping // 长度

(2) Bank width in octets (NEW) // 位宽

 

2)

> make modules

> cp drivers/mtd/maps/physmap.ko /work/nfs_root/first_fs

3)启动开发板

> ls /dev/mtd*

> insmod physmap.ko

> ls /dev/mtd*

> cat /proc/mtd

 

②使用自己写的驱动程序:


/*
 * 参考 drivers\mtd\maps\physmap.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\n");
	s3c_nor_mtd = do_map_probe("cfi_probe", s3c_nor_map);
	if (!s3c_nor_mtd)
	{
		printk("use jedec_probe\n");
		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);
	mtd_device_parse_register(s3c_nor_mtd, NULL, NULL, s3c_nor_parts, 2);
	
	return 0;
}

static void s3c_nor_exit(void)
{
	//del_mtd_partitions(s3c_nor_mtd);
	mtd_device_unregister(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. ls /dev/mtd*

2. insmod s3c_nor.ko

3. ls /dev/mtd*

4. 格式化: f

lash_eraseall -j /dev/mtd1

5. mount -t jffs2 /dev/mtdblock1 /mnt

在/mnt目录下操作文件

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值