驱动程序之_2_块设备_5_Nor Flash_3_驱动编写

 驱动程序之_2_块设备_5_Nor Flash_3_驱动编写

Nor Flash的驱动框架与Nand Flash类似,协议层基本一样,都是分配一个mtd_info结构体,主要区别在于硬件层,Nor Flash和Nand Flash的地址、总线位宽不同;Nor Flash可以像内存一样读,但不能像内存一样写,写操作类似Nand Flash,协议层提供读写接口,需要根据硬件特性完善

内核Nor Flash驱动的硬件层位于drivers/mtd/maps/Physmap.c

1、分配physmap_flash_info

2、设置physmap_flash_info(物理地址、大小、位宽、虚拟地址)

3、设置操作函数

4、识别

5、添加分区

static int physmap_flash_probe(struct platform_device *dev)
{
    struct physmap_flash_info *info;
/*****************************************/
    info = kzalloc(sizeof(struct physmap_flash_info), GFP_KERNEL);
/*****************************************/
	info->map.name = dev->dev.bus_id;
	info->map.phys = dev->resource->start;
	info->map.size = dev->resource->end - dev->resource->start + 1;
	info->map.bankwidth = physmap_data->width;
/*****************************************/
	info->map.virt = ioremap(info->map.phys, info->map.size);
/*****************************************/
	simple_map_init(&info->map);
/*****************************************/
    info->mtd = do_map_probe(*probe_type, &info->map);
/*****************************************/
    add_mtd_partitions(info->mtd, info->parts, err);
/*****************************************/
}

参考Physmap.c编写代码,步骤同上面类似,明显的改动在地址、大小等硬件相关参数上

测试方法基本与Nand Flash驱动相同

区别:Nor Flash一般使用jffs2格式、Nand Flash一般使用yaffs格式

使用flash_eraseall格式化时,默认格式化为yaffs格式

本例是Nor Flash驱动,格式化时应加上-j选项,使之格式化为jffs2格式

挂载时,加上-t jffs2,指定格式

flash_eraseall -j /dev/mtd5

mount -t jffs2 /dev/mtd5 /mnt

附上完整代码

#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>

struct physmap_flash_info {
	struct mtd_info		*mtd;
	struct map_info		map;
	struct resource		*res;
#ifdef CONFIG_MTD_PARTITIONS
	int			nr_parts;
	struct mtd_partition	*parts;
#endif
};



static const char *rom_probe_types[] = { "cfi_probe", "jedec_probe", "map_rom", NULL };

static struct mtd_partition s3c2440_nor_parts[] = {
	[0] = {
        .name   = "part1",
        .size   = 0x00040000,
		.offset	= 0,
	},
	[1] = {
        .name   = "part2",
        .offset = MTDPART_OFS_APPEND,
        .size   = MTDPART_SIZ_FULL,
	}
};

static struct physmap_flash_info *nor_info;

static int nor_init(void)
{
	int i;
	
	nor_info = kzalloc(sizeof(struct physmap_flash_info), GFP_KERNEL);

	nor_info->map.name      = "s3c_nor";
	nor_info->map.bankwidth = 2;
	nor_info->map.phys      = 0x00000000;
	nor_info->map.size      = 0x1000000;
	nor_info->map.virt      = ioremap(nor_info->map.phys, nor_info->map.size);	
	nor_info->parts			= s3c2440_nor_parts;

	simple_map_init(&nor_info->map);
	
	for(i = 0;i < 2;i++)
	{
		nor_info->mtd = do_map_probe(rom_probe_types[i], &nor_info->map);	
		if(nor_info->mtd)
			break;
		else
		{
			if(i != 1)
			{
				continue;
			}
			else
			{
				iounmap(nor_info->map.virt);	
				kfree(nor_info);
				printk("probe failed \r\n");
				return -1;
			}
		}
	}
	printk("\r\n%s probe\r\n\r\n",rom_probe_types[i]);

	add_mtd_partitions(nor_info->mtd, nor_info->parts, 2);

	return 0;
}

static void nor_exit(void)
{
	del_mtd_partitions(nor_info->mtd);
	iounmap(nor_info->map.virt);	
	kfree(nor_info);
}

module_init(nor_init);
module_exit(nor_exit);
MODULE_LICENSE("GPL");
发布了71 篇原创文章 · 获赞 4 · 访问量 7242

猜你喜欢

转载自blog.csdn.net/floatinglong/article/details/86586526