linux块设备驱动学习(一)

最近在做linux块设备驱动开发,看到ChinaUnix上有一个很好的入门帖子http://bbs.chinaunix.net/thread-2017377-1-1.html 不过代码在Ubuntu10.04的内核上(linux 2.6.32)无法使用.查阅了一些资料,对第一章的代码而言修改如下就可以编译通过了,并能够进行insmod mkfs mount 操作。

insmod之后 用 sudo hdparm -tT /dev/simp_blkdev 测试了一下:

/dev/simp_blkdev:
 Timing cached reads:   2250 MB in  2.00 seconds = 1124.53 MB/sec
 Timing buffered disk reads:   16 MB in  0.03 seconds = 482.63 MB/sec

#include <linux/module.h>
#include <linux/blkdev.h>

#define SIMP_BLKDEV_DEVICEMAJOR		COMPAQ_SMART2_MAJOR
#define SIMP_BLKDEV_DISKNAME		"simp_blkdev"
#define SIMP_BLKDEV_BYTES		(16*1024*1024)  //16MB

unsigned char simp_blkdev_data[SIMP_BLKDEV_BYTES];
static struct request_queue *simp_blkdev_queue;
static struct gendisk *simp_blkdev_disk;

static void simp_blkdev_do_request(struct request_queue *q)
{
        struct request *req;
	sector_t sector = 0;
	unsigned int current_nr_sectors = 0;
	req = blk_fetch_request(q);
        while (req != NULL) {
		int err = 0;
		sector = blk_rq_pos (req); 
       		current_nr_sectors = blk_rq_cur_sectors (req);
                if ((sector + current_nr_sectors)<< 9 > SIMP_BLKDEV_BYTES) {
                        printk(KERN_ERR SIMP_BLKDEV_DISKNAME": bad request: block=%llu, count=%u\n",
				sector,
                                current_nr_sectors);
 			err = -EIO;
                        goto done;
                }

                switch (rq_data_dir(req)) {
                case READ:
                        memcpy(req->buffer,
                                simp_blkdev_data + (sector << 9),
                                current_nr_sectors << 9);
                        break;
                case WRITE:
                        memcpy(simp_blkdev_data + (sector << 9),
                                req->buffer, current_nr_sectors << 9);
                        break;
                default:
                        /* No default because rq_data_dir(req) is 1 bit */
                        break;
                }
	done:
		if (!__blk_end_request_cur(req, err))
			req = blk_fetch_request(q);
        }
}

struct block_device_operations simp_blkdev_fops = {
        .owner                = THIS_MODULE,
};

static int __init simp_blkdev_init(void)
{
        int ret;

        simp_blkdev_queue = blk_init_queue(simp_blkdev_do_request, NULL);
        if (!simp_blkdev_queue) {
                ret = -ENOMEM;
                goto err_init_queue;
        }

        simp_blkdev_disk = alloc_disk(1);
        if (!simp_blkdev_disk) {
                ret = -ENOMEM;
                goto err_alloc_disk;
        }

        strcpy(simp_blkdev_disk->disk_name, SIMP_BLKDEV_DISKNAME);
        simp_blkdev_disk->major = SIMP_BLKDEV_DEVICEMAJOR;
        simp_blkdev_disk->first_minor = 0;
        simp_blkdev_disk->fops = &simp_blkdev_fops;
        simp_blkdev_disk->queue = simp_blkdev_queue;
        set_capacity(simp_blkdev_disk, SIMP_BLKDEV_BYTES>>9);
        add_disk(simp_blkdev_disk);

        return 0;

err_alloc_disk:
        blk_cleanup_queue(simp_blkdev_queue);
err_init_queue:
        return ret;
}

static void __exit simp_blkdev_exit(void)
{
        del_gendisk(simp_blkdev_disk);
        put_disk(simp_blkdev_disk);
        blk_cleanup_queue(simp_blkdev_queue);
}

module_init(simp_blkdev_init);
module_exit(simp_blkdev_exit);

MODULE_LICENSE("GPL");


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值