分类: 嵌入式
2015-06-09 12:53:49
NOR FLASH驱动程序
15年6月8日20:44:35
程序如下:
1
2
#include
3
#include
4
#include
5
#include
6
#include
7
#include
8
#include
9
#include
10
#include
11
#include
12
#include
13
#include
14
15 static struct map_info *s3c_nor_info;
16 static struct mtd_info *s3c_mtd;
17
18 static struct mtd_partition s3c_nor_parts[] = {
19 [0] = {
20 .name = "bootloader_nor",
21 .size = 0x00040000,
22 .offset = 0,
23
24 },
25 [1] = {
26 .name = "root_nor",
27 .offset = MTDPART_OFS_APPEND,
28 .size = MTDPART_SIZ_FULL,
29 }
30 };
31
32 static int s3c_nor_init(void)
33 {
34 s3c_nor_info = kzalloc(sizeof(struct map_info), GFP_KERNEL);
35
36 s3c_nor_info->name = "s3c_nor";
37 s3c_nor_info->phys = 0;
38 s3c_nor_info->size = 0x1000000;
39 s3c_nor_info->bankwidth = 2;
40 s3c_nor_info->virt = ioremap(s3c_nor_info->phys, s3c_nor_info->size);
41
42 simple_map_init(s3c_nor_info);
43
44 s3c_mtd = do_map_probe("cfi_probe", s3c_nor_info);
45
46 add_mtd_partitions(s3c_mtd, s3c_nor_parts, 2);
47
48 return 0;
49 }
50
51 static void s3c_nor_exit(void)
52 {
53 del_mtd_partitions(s3c_mtd);
54 iounmap(s3c_nor_info->virt);
55 kfree(s3c_nor_info);
56 }
57
58 module_init(s3c_nor_init);
59 module_exit(s3c_nor_exit);
60
61 MODULE_LICENSE("GPL");
62
上一章学习了NAND FLASH驱动程序的编写,再对比这一章的NOR FLASH的编写。
在linux系统中,实现了针对CFI和JEDEC等接口的通用NOR驱动,这一层的驱动直接面向mtd_info的成员函数,这使得NOR的驱动程序非常简单,只需要定义具体的内存映射情况结构体map_info并使用指定接口类型调用do_map_probe()即可。
NOR FLASH驱动程序的核心结构体就是map_info结构体,它指定了nor flash的基址,位宽,大小等信息,原型如下所示:
struct map_info {
char *name;
unsigned long size;
resource_size_t phys;
#define NO_XIP (-1UL)
void __iomem *virt;
void *cached;
int bankwidth; /* in octets. This isn't necessarily the width
of actual bus cycles -- it's the repeat interval
in bytes, before you are talking to the first chip again.
*/
#ifdef CONFIG_MTD_COMPLEX_MAPPINGS
map_word (*read)(struct map_info *, unsigned long);
void (*copy_from)(struct map_info *, void *, unsigned long, ssize_t);
void (*write)(struct map_info *, const map_word, unsigned long);
void (*copy_to)(struct map_info *, unsigned long, const void *, ssize_t);
/* We can perhaps put in 'point' and 'unpoint' methods, if we really
want to enable XIP for non-linear mappings. Not yet though. */
#endif
/* It's possible for the map driver to use cached memory in its
copy_from implementation (and _only_ with copy_from). However,
when the chip driver knows some flash area has changed contents,
it will signal it to the map driver through this routine to let
the map driver invalidate the corresponding cache as needed.
If there is no cache to care about this can be set to NULL. */
void (*inval_cache)(struct map_info *, unsigned long, ssize_t);
/* set_vpp() must handle being reentered -- enable, enable, disable
must leave it enabled. */
void (*set_vpp)(struct map_info *, int);
unsigned long map_priv_1;
unsigned long map_priv_2;
void *fldrv_priv;
struct mtd_chip_driver *fldrv;
};
初始化map_info结构体以后,通过 do_map_probe(函数)来探测flash得到mtd_info结构体,函数原型如下:
struct mtd_info *do_map_probe(const char *name, struct map_info *map);
第一个参数为探测的接口类型,常见的调用方法如下:
do_map_probe("cfi_probe", &xxx_map_info);
do_map_probe("jedec_probe", &xxx_map_info);
下面总结写NOR FLASH驱动程序的步骤:
(1)定义并分配一个map_info结构体,初始化其中的成员,如name, size, bankwidth, phys, virt等。注意virt需要映射。
(2)调用simple_map_init()函数,进行简单的初始化。
(3)调用 do_map_probe(函数)来探测flash得到mtd_info结构体。
(4) 写出mtd_partition结构体,其中包含分区信息,然后调用add_mtd_partitions()函数来分区即可。