先来看看NAND_FLASH 和 NOR_FLASH 的不同点
使用uboot操作nor_flash
先把开发板设置为nor 启动
看看nor_flash的操作手册
看完操作手册 之后 我们尝试读出id
往地址555H写AAH --> 往地址2AAH写55H —> 往地址555H写入90H ---->读0地址得到厂家ID: C2H ----->读1地址得到设备ID:22DAH
但是由于2440soc的A1接到 A0 所以2440的地址要左移1位 ,nor才能收到
所以更改
往地址AAAH写AAH --> 往地址554H写55H —> 往地址AAAH写入90H ---->读0地址得到厂家ID: C2H ----->读2地址得到设备ID:22DAH
变成在uboot上面的操作
mw.w aaa aa —> mw.w 554 55 —> mw.w aaa 90 ------> md.w 0 1 ------> md.w 2 1
进行驱动的编写
1 分配map_info结构体
在init函数里面 进行分配
2 设置 : 物理基地址(phys),大小(size),位宽(bankwidth),虚拟地址(virt)
名字随意 ,物理启动地址分配为0 ,大小 超过真实大小即可,位宽是16位(单位是字节,就是8*2,所以填2)
3 使用 :调用NOR_FLASH协议层提供的函数来识别
从之前别人原有的协议中调用函数 ,来对我们的nor_flash 来进行识别
4 add_mtd_parttitions
构造出分区
在init函数里面,加上自己的分区,有两个数组
下面是完整代码
/*
* 参考 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);
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");
makefile:
KERN_DIR = /work/system/linux-2.6.22.6
all:
make -C $(KERN_DIR) M=`pwd` modules
clean:
make -C $(KERN_DIR) M=`pwd` modules clean
rm -rf modules.order
obj-m += s3c_nor.o
开始测试
测试1 :尝试用内核自带的驱动程序 由于在之前的nand_flash 已经去掉驱动 所以这次只编译模块
编译内核
这个模块选择m
并且物理起始地址选择为0
长度设置为16兆 只要大于等于真实长度就行,因为写驱动要ioremap进行映射
位宽 是16 也就是28bit
这时候就能进行 make modules
把编译出来的驱动文件拷贝到网络的文件系统里面
ls /dev/mtd 好想就是多了一些东西 也不知道多的是啥
cat proc/mtd 我们的nor_falsh 作为一块 已经进来
测试2: 用自己写的驱动程序
进行编译后加载进入模块
ls /dev/mtd* 经过装载和不装载驱动的对比
开始进行格式化
flash_eraseall -j /dev/mtd5 //对比上面的文件多了mtd5 ,4 就是自己建的两个nor_falsh 分区
mount -t jffs2 /dev/mtdblock5 /mnt //在mnt目录里面挂接我们的nor_falsh
对于nor_flash 我们用jfss2文件系统 对于nand_falsh 我们用yaffs2 文件系统
现在在mnt目录里面新建 文件 取消挂接 重新挂接后 文件还在