NOR_FLASH分析和启动流程

先来看看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目录里面新建 文件 取消挂接 重新挂接后 文件还在

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值