IMX257实现Ramblock驱动程序编写

2015-04-12 Lover雪儿

记得以前三月份就开始学习块设备,但是一直弄不出来,今天我们接着以前写的块设备驱动,抱着坚定的信心把它实现.

今天,我们再内存中申请一片内存,模拟作为块设备,程序如下:

程序一:简单的一个小程序

1.定义gendisk结构体与request_queue请求队列结构体,以及file-operation结构体

IMX257实现Ramblock驱动程序编写

gendisk结构体,主要是用于定义与内核,硬件有关的一些重要信息,还有就是,告诉内核定义请求队列的结构体以及操作函数的结构体。

请求队列:主要是提供读写能力,实现读写请求的存储,然后自己调用do_rambloc_request函数来实现读写操作。

操作函数:如字符设备的操作函数一样,不过此处的操作函数暂时不需定义任何函数,但是必须要有.MODULE属性,否则会报错

2.入口函数实现

IMX257实现Ramblock驱动程序编写

如图所示,在入口函数中主要包含了以下几个操作。

1):分般gendisk结构体,并且设备此设备个数为16个

2):分配、初始化队列,并且指定队列读写函数do_ramblock_request函数。

3):设置以下虚拟块设备的一些属性,包括主设备号,次设备号,名字,操作函数,队列,设备容量等。

4):最后就是注册gendisk结构体。

3.读写函数实现

一些都准备就绪之后,当用户对虚拟块设备发出请求时,系统会调用读写函数do_ramblock_request来实现读写功能。但是刚开始,还是简单点,所以此处,我们的函数主要的功能就是打印信息,告诉我们是否进入了这个读写函数。

IMX257实现Ramblock驱动程序编写

4.出口函数实现

和入口函数相反,出口函数主要负责的就是释放前面申请的内存,反注册前面注册的一些信息。

IMX257实现Ramblock驱动程序编写

5.程序测试

加载成功:

IMX257实现Ramblock驱动程序编写

附上驱动程序ramblock1:

 1 /* 参考
 2  * drivers\block\xd.c
 3  * drivers\block\z2ram.c
 4  */
 5 #include <linux/module.h>
 6 #include <linux/errno.h>
 7 #include <linux/interrupt.h>
 8 #include <linux/mm.h>
 9 #include <linux/fs.h>
10 #include <linux/kernel.h>
11 #include <linux/timer.h>
12 #include <linux/genhd.h>
13 #include <linux/hdreg.h>
14 #include <linux/ioport.h>
15 #include <linux/init.h>
16 #include <linux/wait.h>
17 #include <linux/blkdev.h>
18 #include <linux/blkpg.h>
19 #include <linux/delay.h>
20 #include <linux/io.h>
21 
22 #include <asm/system.h>
23 #include <asm/uaccess.h>
24 #include <asm/dma.h>
25 
26 static struct gendisk *ramblock_disk;     //定义gendisk结构体
27 static struct request_queue *ramblock_queue;     //定义请求队列结构体
28 static DEFINE_SPINLOCK(ramblock_lock);    //定义一个自旋锁
29 static int major;                        //主设备号
30 #define RAMBLOCK_SIZE (1024*1024)        //块设备的容量
31 
32 
33 //file_operation结构体
34 static struct block_device_operations ramblock_fops ={
35     .owner        = THIS_MODULE,
36 };
37 
38 //读写处理函数
39 static void do_ramblock_request(struct request_queue *q)
40 {
41     static int cnt = 0;
42     struct request *req;
43     
44     printk("enter do_ramblock_request %d\n",++cnt);
45     
46     req = blk_fetch_request(q);
47     while(req){
48         printk("enter while req %d\n",++cnt);
49         break;
50     }
51 
52     __blk_end_request_cur(req, 0);
53     printk("leave do_ramblock_request %d\n",++cnt);
54 }
55 
56 static int ramblock_init(void)
57 {
58     printk("ramblock_init\n");
59     /* 1.分配一个gendisk结构体 */
60     ramblock_disk = alloc_disk(16); //次设备号个数:分区个数,若为1的话,则意思是只有一个分区
61     
62     /* 2.设置 */
63     /* 2.1 分配/设置队列:函数do_ramblock_request提供读写能力 */
64     ramblock_queue = blk_init_queue(do_ramblock_request, &ramblock_lock);
65     
66     /* 2.2 设置其他属性:比如容量 */
67     major = register_blkdev(0,"ramblock");        //cat /proc/device 动态申请一个主设备号
68     
69     ramblock_disk->major = major;                //主设备号
70     ramblock_disk->first_minor = 0;             //第一个次设备号
71     sprintf(ramblock_disk->disk_name, "ramblock");
72     ramblock_disk->fops = &ramblock_fops;        //操作函数
73     ramblock_disk->queue = ramblock_queue;        //队列
74     set_capacity(ramblock_disk,RAMBLOCK_SIZE/512);    //设置容量,以扇区为单位
75     
76     /* 3.注册 */
77     add_disk(ramblock_disk);    
78     
79     return 0;
80 }
81 
82 static void ramblock_exit(void)
83 {
84     printk("ramblock_exit\n");
85     unregister_blkdev(major, "ramblock");        //卸载主设备号
86     del_gendisk(ramblock_disk);
87     put_disk(ramblock_disk);
88     blk_cleanup_queue(ramblock_queue);
89 }
90 
91 module_init(ramblock_init);
92 module_exit(ramblock_exit);
93 MODULE_LICENSE("GPL");
ramblock1.c

相关文章: