应该注意版本更新函数的变化。
内核版本:2.6.32-24-generic
-
#include <linux/module.h>
-
#include <linux/fs.h>
-
#include <linux/types.h>
-
#include <linux/genhd.h>
-
#include <linux/blkdev.h>
-
-
#define BLKDEV_DISKNAME "blkdev"
-
/*
-
使用的一个并不常用的设备号,也可动态申请
-
dev_major = register_blkdev(0, BLKDEV_DISKNAME); //在/proc/devices/下面的名称
-
需检查申请是否成功
-
*/
-
#define BLKDEV_DEVICEMAJOR COMPAQ_SMART2_MAJOR
-
#define BLKDEV_BYTES (16*1024*1024) //16M
-
-
unsigned char blkdev_data[BLKDEV_BYTES];
-
-
static struct gendisk *blkdev_disk;
-
static struct request_queue *blkdev_queue;
-
-
struct block_device_operations blkdev_fops = {
-
.owner = THIS_MODULE,
-
};
-
-
static void blkdev_do_request(struct request_queue *q)
-
{
-
struct request *req;
-
req = blk_fetch_request(q); //函数链blk_fetch_request()->blk_peek_request()->__elv_next_request()->...
-
-
while(req) {
-
unsigned long start = blk_rq_pos(req) << 9;
-
unsigned long len = blk_rq_cur_sectors(req) << 9; //此处等同于len = blk_rq_cur_bytes(req);
-
int err = 0;
-
-
if(start + len > BLKDEV_BYTES) {
-
printk(KERN_ERR BLKDEV_DISKNAME ":bad access:block=%lu,count=%un",blk_rq_pos(req), blk_rq_cur_sectors(req));
-
err = -EIO;
-
goto done;
-
}
-
if(rq_data_dir(req) == READ)
-
memcpy(req->buffer, blkdev_data+start,len);
-
else
-
memcpy(blkdev_data+start, req->buffer, len);
-
done:
-
if(!__blk_end_request_cur(req, err))
-
req = blk_fetch_request(q);
-
}
-
}
-
-
static int __init blkdev_init(void)
-
{
-
int ret;
-
-
blkdev_queue = blk_init_queue(blkdev_do_request, NULL); //每个块设备关联请求处理函数
-
if(!blkdev_queue) {
-
ret = -ENOMEM;
-
goto err_init_queue;
-
}
-
-
blkdev_disk = alloc_disk(1);
-
if(!blkdev_disk) {
-
goto err_alloc_disk;
-
}
-
strcpy(blkdev_disk->disk_name, BLKDEV_DISKNAME); //在/dev/下面的名称
-
blkdev_disk->major = BLKDEV_DEVICEMAJOR; //如果是动态申请的话就是dev_major
-
blkdev_disk->first_minor = 0;
-
blkdev_disk->fops = &blkdev_fops;
-
blkdev_disk->queue = blkdev_queue;
-
set_capacity(blkdev_disk, BLKDEV_BYTES>>9); //扇区大小512B
-
add_disk(blkdev_disk);
-
-
return 0;
-
-
err_alloc_disk:
-
blk_cleanup_queue(blkdev_queue);
-
err_init_queue:
-
return ret;
-
-
}
-
-
static void __exit blkdev_exit(void)
-
{
-
blk_cleanup_queue(blkdev_queue);
-
del_gendisk(blkdev_disk);
-
put_disk(blkdev_disk);
-
}
-
-
module_init(blkdev_init);
-
module_exit(blkdev_exit);
2012-02-18 23:15 发表于百度空间,今搬至CU。
阅读(673) | 评论(0) | 转发(0) |