ram_flash驱动

20150418 ram_flash驱动

2015-04-18 Lover雪儿

    参考linux内核中的device/mtdram.c,编写了一个ram_flash驱动程序,说实在主要就是分配mtd_info结构体,初始化mtd_info结构体,以及提交结构体三步。

  1 /* 利用内存来模拟flash操作  
  2  * 参考devices\mtdram.c
  3  */
  4 #include <linux/module.h>
  5 #include <linux/slab.h>
  6 #include <linux/ioport.h>
  7 #include <linux/vmalloc.h>
  8 #include <linux/init.h>
  9 #include <linux/mtd/compatmac.h>
 10 #include <linux/mtd/mtd.h>
 11 #include <linux/mtd/mtdram.h> 
 12 
 13 
 14 #define RAM_FLASH_SIZE    (10 * 1024 * 1024)    //定义ram_flash的大小为10M
 15 unsigned char *ram_flash_addr;        //用于保存为ram_flash申请的内存的指针,也保存在mtd_info->priv中
 16 
 17 //构建一个mtd_info结构体
 18 static struct mtd_info *mtd_info;
 19 
 20 //内存擦除函数
 21 static int ram_erase(struct mtd_info *mtd, struct erase_info *instr){
 22     if (instr->addr + instr->len > mtd->size)
 23         return -EINVAL;
 24 
 25     memset((char *)mtd->priv + instr->addr, 0xff, instr->len);
 26 
 27     instr->state = MTD_ERASE_DONE;
 28     mtd_erase_callback(instr);
 29 
 30     return 0;
 31 }
 32 
 33 static int ram_point(struct mtd_info *mtd, loff_t from, size_t len,size_t *retlen, void **virt, resource_size_t *phys){
 34     if (from + len > mtd->size)
 35         return -EINVAL;
 36 
 37     /* can we return a physical address with this driver? */
 38     if (phys)
 39         return -EINVAL;
 40 
 41     *virt = mtd->priv + from;
 42     *retlen = len;
 43     return 0;
 44 }
 45 
 46 static void ram_unpoint(struct mtd_info *mtd, loff_t from, size_t len){
 47     
 48 }
 49 
 50 //重映射函数
 51 static unsigned long ram_flash_get_unmapped_area(struct mtd_info *mtd,unsigned long len,unsigned long offset,unsigned long flags){
 52     return (unsigned long) mtd->priv + offset;
 53 }
 54 
 55 //读函数
 56 static int ram_flash_read(struct mtd_info *mtd, loff_t from, size_t len,size_t *retlen, u_char *buf){
 57     if (from + len > mtd->size)
 58         return -EINVAL;
 59 
 60     memcpy(buf, mtd->priv + from, len);
 61 
 62     *retlen = len;
 63     return 0;
 64 }
 65 
 66 //写函数
 67 static int ram_flash_write(struct mtd_info *mtd, loff_t to, size_t len,size_t *retlen, const u_char *buf){
 68     if(to + len > mtd->size)
 69         return -EINVAL;
 70     memcpy((char *)mtd->priv + to, buf, len);
 71     *retlen = len;        //返回已经成功写入的大小
 72     return 0;
 73 }
 74 
 75 //入口函数
 76 static int ram_flash_init(void){
 77     // 1.分配mtd_Info结构体
 78     mtd_info = kmalloc(sizeof(struct mtd_info),GFP_KERNEL); 
 79     if(!mtd_info)
 80         return -ENOMEM;
 81     
 82     // 2.申请ram_flash的内存大小
 83     ram_flash_addr = vmalloc(RAM_FLASH_SIZE);    //申请内存
 84     
 85     // 3.初始化mtd_info结构体
 86     mtd_info->name = "ram_flash_device";    //名字
 87     mtd_info->type = MTD_RAM;                //1设备类型为RAM,定义在 mtd\mtd-abi.h中
 88     mtd_info->flags = MTD_CAP_RAM;            //标志,通用
 89     mtd_info->size = RAM_FLASH_SIZE;        //大小
 90     mtd_info->writesize = 1;
 91     mtd_info->erasesize = RAM_FLASH_SIZE;
 92     mtd_info->priv = ram_flash_addr;        //内存地址
 93     
 94     mtd_info->owner = THIS_MODULE;            
 95     mtd_info->erase = ram_flash_erase;        //从此开始关联一些操作函数
 96     mtd_info->point = ram_flash_point;
 97     mtd_info->unpoint = ram_flash_unpoint;
 98     mtd_info->get_unmapped_area = ram_flash_get_unmapped_area;
 99     mtd_info->read = ram_flash_read;
100     mtd_info->write = ram_flash_write;
101     
102     // 4.注册mtd结构体
103     add_mtd_device(mtd_info); //整块flash只作为一个分区,使用add_mtd_device就够了
104     
105     // 5.清除,初始化ram_flash,内容全部为FF表示初始化成功
106     memset(mtd_info->priv,0xff,RAM_FLASH_SIZE);
107     
108     return 0;
109 }
110 //出口函数 
111 static void ram_flash_exit(void){
112     if(mtd_info){
113         del_mtd_device(mtd_info);
114         vfree(mtd_info->priv);
115         kfree(mtd_info);
116     }
117 }
118  
119 module_init(ram_flash_init);
120 module_exit(ram_flash_exit);
121 MODULE_AUTHOR("Lover雪儿");
122 MODULE_LICENSE("GPL");
ram_flash1.c

测试:

ram_flash驱动_第1张图片

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

增加flash的分区:

    由于前面程序总注册mtd结构体使用的是add_mtd_device函数,它是将整块flash当做一个分区,为了为了实现多分区,我们此处须使用add_mtd_partitions函数来注册mtd_info结构体。

  1 /* 利用内存来模拟flash操作  
  2  * 参考devices\mtdram.c
  3  */
  4 #include <linux/module.h>
  5 #include <linux/slab.h>
  6 #include <linux/ioport.h>
  7 #include <linux/vmalloc.h>
  8 #include <linux/init.h>
  9 #include <linux/mtd/compatmac.h>
 10 #include <linux/mtd/mtd.h>
 11 #include <linux/mtd/mtdram.h> 
 12 
 13 
 14 #define RAM_FLASH_SIZE    (10 * 1024 * 1024)    //定义ram_flash的大小为10M
 15 unsigned char *ram_flash_addr;        //用于保存为ram_flash申请的内存的指针,也保存在mtd_info->priv中
 16 
 17 //构建一个mtd_info结构体
 18 static struct mtd_info *mtd_info;
 19 
 20 
 21 //定义分区表
 22 static struct mtd_partition ram_flash_part[] = {
 23     [0] = {
 24         .name     = "first_part",
 25         .offset = 0,
 26         .size    = 0x200000,                //2M
 27     },
 28     [1] = {
 29         .name     = "second_part",
 30         .offset = MTDPART_OFS_APPEND,    //紧跟着上一个分区
 31         .size    = 0x200000,                //2M
 32     },
 33     [2] = {
 34         .name     = "third_part",
 35         .offset = MTDPART_OFS_APPEND,    //紧跟着上一个分区
 36         .size    = MTDPART_SIZ_FULL,        //6M
 37     },
 38 };
 39 
 40 
 41 //内存擦除函数
 42 static int ram_erase(struct mtd_info *mtd, struct erase_info *instr){
 43     if (instr->addr + instr->len > mtd->size)
 44         return -EINVAL;
 45 
 46     memset((char *)mtd->priv + instr->addr, 0xff, instr->len);
 47 
 48     instr->state = MTD_ERASE_DONE;
 49     mtd_erase_callback(instr);
 50 
 51     return 0;
 52 }
 53 
 54 static int ram_point(struct mtd_info *mtd, loff_t from, size_t len,size_t *retlen, void **virt, resource_size_t *phys){
 55     if (from + len > mtd->size)
 56         return -EINVAL;
 57 
 58     /* can we return a physical address with this driver? */
 59     if (phys)
 60         return -EINVAL;
 61 
 62     *virt = mtd->priv + from;
 63     *retlen = len;
 64     return 0;
 65 }
 66 
 67 static void ram_unpoint(struct mtd_info *mtd, loff_t from, size_t len){
 68     
 69 }
 70 
 71 //重映射函数
 72 static unsigned long ram_flash_get_unmapped_area(struct mtd_info *mtd,unsigned long len,unsigned long offset,unsigned long flags){
 73     return (unsigned long) mtd->priv + offset;
 74 }
 75 
 76 //读函数
 77 static int ram_flash_read(struct mtd_info *mtd, loff_t from, size_t len,size_t *retlen, u_char *buf){
 78     if (from + len > mtd->size)
 79         return -EINVAL;
 80 
 81     memcpy(buf, mtd->priv + from, len);
 82 
 83     *retlen = len;
 84     return 0;
 85 }
 86 
 87 //写函数
 88 static int ram_flash_write(struct mtd_info *mtd, loff_t to, size_t len,size_t *retlen, const u_char *buf){
 89     if(to + len > mtd->size)
 90         return -EINVAL;
 91     memcpy((char *)mtd->priv + to, buf, len);
 92     *retlen = len;        //返回已经成功写入的大小
 93     return 0;
 94 }
 95 
 96 //入口函数
 97 static int ram_flash_init(void){
 98     // 1.分配mtd_Info结构体
 99     mtd_info = kmalloc(sizeof(struct mtd_info),GFP_KERNEL); 
100     if(!mtd_info)
101         return -ENOMEM;
102     
103     // 2.申请ram_flash的内存大小
104     ram_flash_addr = vmalloc(RAM_FLASH_SIZE);    //申请内存
105     
106     // 3.初始化mtd_info结构体
107     mtd_info->name = "ram_flash_device";    //名字
108     mtd_info->type = MTD_RAM;                //1设备类型为RAM,定义在 mtd\mtd-abi.h中
109     mtd_info->flags = MTD_CAP_RAM;            //标志,通用
110     mtd_info->size = RAM_FLASH_SIZE;        //大小
111     mtd_info->writesize = 1;
112     mtd_info->erasesize = RAM_FLASH_SIZE;
113     mtd_info->priv = ram_flash_addr;        //内存地址
114     
115     mtd_info->owner = THIS_MODULE;            
116     mtd_info->erase = ram_flash_erase;        //从此开始关联一些操作函数
117     mtd_info->point = ram_flash_point;
118     mtd_info->unpoint = ram_flash_unpoint;
119     mtd_info->get_unmapped_area = ram_flash_get_unmapped_area;
120     mtd_info->read = ram_flash_read;
121     mtd_info->write = ram_flash_write;
122     
123     // 4.注册mtd结构体
124     //add_mtd_device(mtd_info); //整块flash只作为一个分区,使用add_mtd_device就够了
125     add_mtd_partitions(mtd_info,ram_flash_part,3);    //三个分区
126     // 5.清除,初始化ram_flash,内容全部为FF表示初始化成功
127     memset(mtd_info->priv,0xff,RAM_FLASH_SIZE);
128     
129     return 0;
130 }
131 //出口函数 
132 static void ram_flash_exit(void){
133     if(mtd_info){
134         //del_mtd_device(mtd_info);
135         del_mtd_partitions(mtd_info);
136         vfree(mtd_info->priv);
137         kfree(mtd_info);
138     }
139 }
140  
141 module_init(ram_flash_init);
142 module_exit(ram_flash_exit);
143 MODULE_AUTHOR("Lover雪儿");
144 MODULE_LICENSE("GPL");
ram_flash2.c

 

使用mtd的flash-erase

下载: mtd-utils_1.5.1.orig.tar.gz

http://ftp.debian.org/debian/pool/main/m/mtd-utils/

 

在编译的过程中,你或许会遇到下面的问题:

 

 1 (In compile process, you will meet the following problem.)
 2 
 3 1. sys/acl.h: No such file or directory
 4 --> sudo apt-get install libacl1-dev
 5 
 6 2. compr_lzo.c:29:23: error: lzo/lzo1x.h: No such file or directory
 7 --> sudo apt-get install liblzo-dev (Maybe use liblzo2-dev replace it)
 8 
 9 3. uuid/uuid.h: No such file or directory
10 --> sudo apt-get install uuid-dev

 

 

 

 

 

你可能感兴趣的:(Flash)