
本文共 3575 字,大约阅读时间需要 11 分钟。
驱动程序之 Nor Flash 部分
Nor Flash 作为一种可编程存储设备,与 Nand Flash 在协议层有着相似的实现,但硬件接口和工作方式存在区别。本文将详细介绍 Nor Flash 驱动的编写流程。
Nor Flash 驱动架构
Nor Flash 的驱动框架与 Nand Flash 类似,核心协议层实现保持一致。主要区别体现在硬件接口的差异,特别是在地址空间和总线配置上。Nor Flash 可以像内存一样进行读取操作,但写入操作与Nand Flash类似。为此,协议层需要为读写操作提供相应的接口,并根据硬件特性进行适配。
Physmap.c 驱动实现
Nor Flash 的硬件驱动通常位于 drivers/mtd/maps/Physmap.c
中。驱动实现的关键步骤包括:
分配 physmap_flash_info 结构:初始化相应的硬件参数,包括物理地址、段大小、总线宽度和虚拟地址。
设置驱动参数:配置物理映射信息,包括区域名称、物理起始地址、大小以及相应的虚拟地址。
实现操作函数:定义用于读取和写入操作的方法。
设备识别:通过提供相应的探测函数,确保驱动能够与特定的Nor Flash 芯片相匹配。
划分分区:将设备划分为若干个分区,确保每个分区可以独立使用。
在 Physmap.c
中的典型实现如下:
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类似。主要区别在于硬件相关参数的设置,以下是总结性的编写步骤:
创建 physmap_flash_info 结构体,配置硬件参数。
初始化映射信息,包括名称、物理地址、虚拟地址等。
配置操作函数,确保读写操作与硬件接口一致。
添加探测支持,确保驱动能够与Nor Flash 芯片兼容。
划分和配置分区,根据需求将存储设备划分为多个可用的区段。
测试与格式化
与 Nand Flash 驱动的测试方法大致相同。由于 Nor Flash 通常采用 jffs2 格式,格式化时需特别注意以下几点:
- 如果使用
flash_eraseall
格式化工具,默认会选择 yaffs 格式,因此需指定格式:
flash_eraseall -j /dev/mtd5
- 挂载时需指定文件系统类型:
mount -t jffs2 /dev/mtd5 /mnt
Nor Flash 驱动示例代码
以下为一个典型的 Nor Flash 驱动示例代码,用于实现与 S3C2440 SoC 相关的 Nor Flash 存储器支持:
#include#include #include #include 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) { 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 (int i = 0; i < 2; i++) { nor_info->mtd = do_map_probe(rom_probe_types[i], &nor_info->map); if (!nor_info->mtd) { 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");
结论
通过以上实现,可以看出 Nor Flash 驱动的编写工作与 Nand Flash 相关 girlfriends affairs 类似,主要操作流程和配置参数有所不同。编写驱动程序时,需仔细校准硬件参数和驱动协议,以确保最佳性能和可靠性。
发表评论
最新留言
关于作者
