Nor Flash和Nand Flash的不同:
类型 | NOR Flash | Nand Flash |
接口 | RAM-like,引脚多 | 引脚少 |
容量 | 小(1M、2M...) | 大(512M、1G) |
读 | 简单 | 复杂 |
写 | 复杂 | 复杂 |
价格 | 贵 | 便宜 |
无坏块、位反转 | 有位反转、坏块 | |
存储一些重要的文件 | 可以出错的文件比如视频 | |
xip | 可以 | 不可以 |
使用uboot来体验nor Flash操作。(Nor的A0接到Soc的A1上。所以地址应该左移1位。)
1. 读数据(NOR Flash可以像内存一样直接来读)
md.b <address>
2. 读ID
NOR手册上 往地址555H写入AA。往2AA写入55,往555H写入90H。读0地址得到厂家IDC2H。读1地址得带22DAH或225dH。退出读ID状态
OpenJTAG> mw.w aaa aa OpenJTAG> mw.w 554 55 OpenJTAG> mw.w aaa 90 OpenJTAG> md.w 0 1 00000000: 00c2 .. OpenJTAG> md.w 2 1 00000002: 2249 I"
OpenJTAG> mw.w 0 90
一般Nor有两种规范:jedec和cfi(common Flash interface);
jedec不包含硬件信息,是一种老的规范。
cfi包含内存大小,承受电压等信息。
Linux内核中Flash框架:
APP | open、write、read | |||||
虚拟文件系统 | sys_open、sys_write、sys_read | |||||
字符设备驱动 | 块设备驱动 | |||||
RAMBLOCK | 硬盘 | MTD | ||||
Nand Flash |
Nor Flash | |||||
jedec | cfi |
Nand Flash协议层知道发什么信息来擦除、读写、识别。硬件相关层知道怎么发命令/地址。
Nor Flash协议层知道如何发送读写、擦除命令。硬件相关层有一些微小差异来让用户做修改。
通过配置内核支持NOR FLASH
Device Drivers --->
<*> Memory Technology Device (MTD) support --->
Mapping drivers for chip access --->
[ ] Support non-linear mappings of flash chips │ │
<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 //位宽
cp drivers/mtd/maps/physmap.ko /home/jz2440/fsroot
启动开发板。
insmod physmap.ko
然后会在相应的目录中增加设备文件:/dev/mtd*
这是内核中自带的驱动程序。
下面是自己编写的驱动程序代码:
/************************************************************************* > File Name: s3c_nor.c > Author: > Mail: > Created Time: 2016年11月08日 星期二 15时41分05秒 ************************************************************************/ #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 <linux/mtd/physmap.h> #include <asm/io.h> static struct map_info *s3c_nor_map; static struct mtd_info *s3c_nor_mtd; 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) { /* 分配map_info结构体 */ s3c_nor_map = kzalloc(sizeof(struct map_info), GFP_KERNEL); /* 设置:物理基地址,大小,位宽,虚拟基地址 */ 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); /* 调用NOR FLASH协议层提供的函数来识别 */ s3c_nor_mtd = do_map_probe( "cfi_probe", s3c_nor_map); if(!s3c_nor_mtd) { printk("jedec probe "); s3c_nor_mtd = do_map_probe("jedec_probe",s3c_nor_map); } else printk("use cfi_probe "); if(!s3c_nor_mtd) { iounmap(s3c_nor_map->virt); kfree(s3c_nor_map); return -EIO; } /* 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");
Nor Flash识别过程:
struct mtd_info *do_map_probe(const char *name, struct map_info *map)
-drv = get_mtd_chip_driver(name);
-ret = drv->probe(map); // struct mtd_info *cfi_probe(struct map_info *map) //name=“cfi_probe”
--struct mtd_info *mtd_do_chip_probe(struct map_info *map, struct chip_probe *cp)
---static struct cfi_private *genprobe_ident_chips(struct map_info *map, struct chip_probe *cp)
----static int genprobe_new_chip(struct map_info *map, struct chip_probe *cp,struct cfi_private *cfi)
-----cp->probe_chip(map, 0, NULL, cfi) //进入cfi模式,看看是否支持cfi
-ret = drv->probe(map); // struct mtd_info *jedec_probe(struct map_info *map) //name=“jedec_probe”
--struct mtd_info *mtd_do_chip_probe(struct map_info *map, struct chip_probe *cp)
---static struct cfi_private *genprobe_ident_chips(struct map_info *map, struct chip_probe *cp)
----static int genprobe_new_chip(struct map_info *map, struct chip_probe *cp,struct cfi_private *cfi)
-----cp->probe_chip(map, 0, NULL, cfi) //static int jedec_probe_chip(struct map_info *map, __u32 base,unsigned long *chip_map, struct cfi_private *cfi)
------进行和Nor Flash相关的一系列操作
sd