/
ramdisk.c
118 lines (97 loc) · 2.67 KB
/
ramdisk.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
#include <linux/module.h>
#include <linux/errno.h>
#include <linux/interrupt.h>
#include <linux/mm.h>
#include <linux/fs.h>
#include <linux/kernel.h>
#include <linux/timer.h>
#include <linux/genhd.h>
#include <linux/hdreg.h>
#include <linux/ioport.h>
#include <linux/init.h>
#include <linux/wait.h>
#include <linux/blkdev.h>
#include <linux/blkpg.h>
#include <linux/delay.h>
#include <linux/io.h>
#include <asm/system.h>
#include <asm/uaccess.h>
#include <asm/dma.h>
static struct gendisk *ramblock_disk;
static struct request_queue *ramblock_queue;
static int major;
static DEFINE_SPINLOCK(ramblock_lock);
#define RAMBLOCK_SIZE (1024*1024)
static unsigned char *ramblock_buf;
static int ramblock_getgeo(struct block_device *bdev, struct hd_geometry *geo)
{
/*容量 = heads * sectors * cylinders *512*/
geo->heads = 2;
geo->sectors = 32;
geo->cylinders = RAMBLOCK_SIZE/2/32/512;
return 0;
}
static struct block_device_operations ramblock_fops = {
.owner = THIS_MODULE,
.getgeo = ramblock_getgeo,
};
static void do_ramdisk_request (request_queue_t * q)
{
static int r_cnt = 0;
static int w_cnt = 0;
struct request *req;
// printk("do_ramdisk_request = %d \n",++cnt);
while ((req = elv_next_request(q)) != NULL)
{
/*数据传输3要素 : 源,目的,长度*/
/*源/目的*/
unsigned long offset = req->sector *512;
/*目的/源*/
//req->buffer
/*长度*/
unsigned long len = req->current_nr_sectors *512;
if (rq_data_dir(req) == READ)
{
printk("do_ramdisk_request read = %d \n",++r_cnt);
memcpy(req->buffer, ramblock_buf+offset, len);
}
else
{
printk("do_ramdisk_request wirte = %d \n",++w_cnt);
memcpy(ramblock_buf+offset,req->buffer, len);
}
end_request(req, 1); /* wrap up, 0 = fail, 1 = success */
}
}
static int ramblock_init(void )
{
/*1. 分配一个gendisk结构体*/
ramblock_disk = alloc_disk(16); /*次设备号 : 分区个数+1 */
/*2. 设置*/
/*2.1 分配/设置队列,提供读写能力*/
ramblock_queue = blk_init_queue(do_ramdisk_request, &ramblock_lock);
ramblock_disk->queue = ramblock_queue;
/*2.2 设置其他属性 比如容量*/
major = register_blkdev(0 , "ramblock");
ramblock_disk->major = major;
ramblock_disk->first_minor =0;
sprintf(ramblock_disk->disk_name, "ramblock");
ramblock_disk->fops = &ramblock_fops;
set_capacity(ramblock_disk, RAMBLOCK_SIZE/512);
/*3. 硬件相关操作*/
ramblock_buf = kzalloc(RAMBLOCK_SIZE, GFP_KERNEL);
/*4. 注册*/
add_disk(ramblock_disk);
return 0;
}
static void ramblock_exit(void)
{
unregister_blkdev(major,"ramblock");
del_gendisk(ramblock_disk);
put_disk(ramblock_disk);
blk_cleanup_queue( ramblock_queue );
kfree(ramblock_buf);
}
module_init(ramblock_init);
module_exit(ramblock_exit);
MODULE_LICENSE("GPL");