首页 > 其他 > 详细

块设备驱动

时间:2019-11-17 21:59:36      阅读:94      评论:0      收藏:0      [点我收藏+]

技术分享图片?

for (i = 0; i < nr; i++) {

struct buffer_head *bh = bhs[i];

submit_bh(rw, bh);

struct bio *bio; // 使用bh来构造bio (block input/output)

submit_bio(rw, bio);

// 通用的构造请求: 使用bio来构造请求(request)

generic_make_request(bio);

__generic_make_request(bio);

request_queue_t *q = bdev_get_queue(bio->bi_bdev); // 找到队列

?

// 调用队列的"构造请求函数"

ret = q->make_request_fn(q, bio);

// 默认的函数是__make_request

__make_request

// 先尝试合并

elv_merge(q, &req, bio);

?

// 如果合并不成,使用bio构造请求

init_request_from_bio(req, bio);

?

// 把请求放入队列

add_request(q, req);

?

// 执行队列

__generic_unplug_device(q);

// 调用队列的"处理函数"

q->request_fn(q);

? ?

驱动程序

1 /*
2 * 块设备驱动程序:内存用作磁盘
3 * 参考:
4 * .\linux-2.6.22.6\drivers\block\xd.c
5 * .\linux-2.6.22.6\drivers\block\z2ram.c
6 */
7
8 #include <linux/module.h>
9 #include <linux/errno.h>
10 #include <linux/interrupt.h>
11 #include <linux/mm.h>
12 #include <linux/fs.h>
13 #include <linux/kernel.h>
14 #include <linux/timer.h>
15 #include <linux/genhd.h>
16 #include <linux/hdreg.h>
17 #include <linux/ioport.h>
18 #include <linux/init.h>
19 #include <linux/wait.h>
20 #include <linux/blkdev.h>
21 #include <linux/blkpg.h>
22 #include <linux/delay.h>
23 #include <linux/io.h>
24
25 #include <asm/system.h>
26 #include <asm/uaccess.h>
27 #include <asm/dma.h>
28
29 /* 1M */
30 #define RAMBlock_SIZE (1024*1024)
31
32 static unsigned char *ramBlock_buf;
33
34 static struct gendisk *ramBlock_disk;
35 static request_queue_t *ramBlock_queue;
36
37 static int major;
38
39 /* 自旋锁 */
40 static DEFINE_SPINLOCK(ramBlock_lock);
41
42 //为了使用fdisk分区工具,假装自己是磁盘,
43 //有2个面,32个环,RAMBlock_SIZE/heads/cylinders/512个扇区
44 //容量:RAMBlock_SIZE = heads*cylinders*sectors*512
45 //1 disk ????????????????= 2 heads
46 //1 heads ???????? ????????= 32 cylinders
47 //1 cylinders????????= RAMBlock_SIZE/heads/cylinders/512 sectors = 32 sectors
48 static int ramBlock_getgeo(struct block_device *bdev, struct hd_geometry *geo)
49 {
50 ????????geo->heads ????????????????= 2;
51 ????????geo->cylinders ????????= 32;
52 ????????geo->sectors ????????= 32;
53 ????????return 0;
54 }
55
56
57 static struct block_device_operations ramBlock_fops = {
58 ????????.owner = THIS_MODULE,
59 ????????.getgeo = ramBlock_getgeo,
60 };
61
62 static void do_ramBlock_request(request_queue_t *q)
63 {
64 ????????static int r_cnt = 0;
65 ????????static int w_cnt = 0;
66 ????????struct request *req;
67
68 ????????//以电梯调度算法,取出下一个请求
69 ????????while ((req = elv_next_request(q)) != NULL) {
70 ????????????????/* 6 读写 */
71 ????????????????//数据传输三要素:源、目的、长度
72 ????????????????//源/目的????????(要操作第几个扇区)
73 ????????????????unsigned long offset = req->sector << 9;????????//<< 9 相当于 * 512
74
75 ????????????????//目的/源????????(读、写缓冲区)
76 ????????????????//req->buffer
77
78 ????????????????//长度????????(缓冲区长度(sector的倍数))
79 ????????????????unsigned long len = req->current_nr_sectors << 9;
80
81 ????????????????//读数据
82 ????????????????if (rq_data_dir(req) == READ)
83 ????????????????{
84 ????????????????????????printk("do_ramblock_request read %d\n", ++r_cnt);
85 ????????????????????????memcpy(req->buffer, ramBlock_buf+offset, len);
86 ????????????????}
87 ????????????????else {????????//写数据
88 ????????????????????????printk("do_ramblock_request read %d\n", ++r_cnt);
89 ????????????????????????memcpy(ramBlock_buf+offset, req->buffer, len);
90 ????????????????}
91
92 ????????????????/******** 6 end ********/
93 ????????????????end_request(req, 1);
94 ????????}
95 ????????return;
96 }
97
98
99 /* 1 出入口函数 */
100 static int ramBlock_init(void)
101 {
102 ????????/* 2 分配一个gendisk结构体 */
103 ????????ramBlock_disk = alloc_disk(16); //次设备号个数:分区个数+1
104 ????????/******** 2 end ********/
105
106 ????????/* 3 设置 */
107 ????????//3.1 分配/设置队列(提供读写功能)
108 ????????ramBlock_queue = blk_init_queue(do_ramBlock_request, &ramBlock_lock);????????
109 ????????
110 ????????//3.2 设置其他属性:如容量
111 ????????ramBlock_disk->queue????????????????= ramBlock_queue;
112
113 ????????major = register_blkdev(0, "ramBlock_disk");????????????????//cat /proc/devices
114 ????????ramBlock_disk->major????????????????= major;
115
116 ????????ramBlock_disk->first_minor????????= 0;
117 ????????sprintf(ramBlock_disk->disk_name, "ramBlock_disk");
118 ????????ramBlock_disk->fops????????????????????????= &ramBlock_fops;
119 ????????set_capacity(ramBlock_disk, RAMBlock_SIZE/512);????????????????//第二个参数表示扇区个数,相对于内核而言,一个扇区为512字节
120 ????????/******** 3 end ********/
121
122 ????????/*
123 ???????? * 除了第4、第6、及以后的操作外,实际已经完成了块设备驱动框架的编写;????????
124 ???????? */
125
126 ????????/* 4 硬件相关的操作 */
127 ????????ramBlock_buf = kzalloc(RAMBlock_SIZE, GFP_KERNEL);
128 ????????/******** 4 end ********/
129
130 ????????/* 5 注册 */
131 ????????add_disk(ramBlock_disk);
132 ????????/******** 5 end ********/
133 ????????return 0;
134 }
135
136
137 static void ramBlock_exit(void)
138 {
139 ????????unregister_blkdev(major, "ramBlock_disk");
140 ????????del_gendisk(ramBlock_disk);
141 ????????put_disk(ramBlock_disk);
142 ????????blk_cleanup_queue(ramBlock_queue);
143 ????????kfree(ramBlock_buf);
144 ????????return;
145 }
146
147 module_init(ramBlock_init);
148 module_exit(ramBlock_exit);
149 MODULE_LICENSE("GPL");
150 /******** 1 end ********/

? ?

? ?

调试

1. insmod ramBlock.ko

? ?

2. 格式化:

mkdosfs /dev/ramBlock_disk

? ?

3. 挂接:

mount /dev/ramBlock_disk /tmp

? ?

4. 读写文件:

cd /tmp

vi 1.txt

? ?

(分区:fdisk /dev/ramBlock_disk)

? ?

5. 卸载

cd /

umount /tmp/

? ?

6. 把/dev/ramBlock_disk目录下的文件,以镜像的形式保存到/mnt下

cat /dev/ramBlock_disk > /mnt/ramBlock_disk.bin

? ?

7. 在PC上查看ramBlock_disk.bin(把ramBlock_disk.bin作为回环设备挂接到/mnt)

sudo mount -o loop ramBlock_disk.bin /mn

??

块设备驱动

原文:https://www.cnblogs.com/lilto/p/11878255.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!