- 论坛徽章:
- 0
|
本人最近想学习linux驱动程序的编写,网上正好有一篇与此相关的精彩文章,有zhaolei前辈写的《写一个块设备驱动
》(原帖地址http://bbs.chinaunix.net/thread-2017377-1-1.html)。
按照上述第一章的内容,编写了下述程序。原文章中使用的一些结构和函数比较老,在新内核中有所变化(sectors调用blk_rq_pos得到, current_nr_sectors调用blk_rq_sectors得到, elv_next_request换成blk_peek_request, end_request换成blk_end_request_cur)。
可是我make完了之后,insmod的时候悲剧了,机器直接卡那不受控制了。我baidu了下,网上有的说是在处理request的时候加锁了,但blk_end_request_cur时没正确释放。(参考帖地址http://bbs.chinaunix.net/viewthr ... p;extra=&page=2)
我参照了网上的修改意见修改了我的程序,把blk_end_request_cur改成了__blk_end_request_cur , blk_end_request_all, __blk_end_request_all,都未能解决问题,还是一样的,insmod之后就死在那了,悲催了。。。。
有哪位高人能指出其中错误之处阿!
下面是我的代码- #include <linux/module.h>
- #include <linux/slab.h>
- #include <linux/kernel.h>
- #include <linux/list.h>
- #include <linux/fs.h>
- #include <linux/blkdev.h>
- #include <linux/blkpg.h>
- #include <linux/elevator.h>
- #define SIMP_BLKDEV_DEVICEMAJOR COMPAQ_SMART2_MAJOR
- #define SIMP_BLKDEV_DISKNAME "simp_blkdev"
- #define SIMP_BLKDEV_BYTES (16*1024*1024)
- unsigned char simp_blkdev_data[SIMP_BLKDEV_BYTES];
- static struct gendisk *simp_blkdev_disk;
- struct block_device_operations simp_blkdev_ops = {
- .owner = THIS_MODULE
- };
- static struct request_queue *simp_blkdev_queue;
- static void simp_blkdev_do_request(struct request_queue *q);
- static int __init simp_blk_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_ops;
- 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);
- return ret;
- err_init_queue:
- return ret;
- }
- static void __exit simp_blk_exit(void)
- {
- del_gendisk(simp_blkdev_disk);
- put_disk(simp_blkdev_disk);
- blk_cleanup_queue(simp_blkdev_queue);
- }
- static void simp_blkdev_do_request(struct request_queue *q)
- {
- struct request *req;
- while( (req = blk_fetch_request(q)) != NULL )
- {
- if( (blk_rq_pos(req) + blk_rq_sectors(req))<<9
- > SIMP_BLKDEV_BYTES )
- {
- printk(KERN_ERR SIMP_BLKDEV_DISKNAME ": bad request: block = %llu, count = %u\n", (unsigned long long)(blk_rq_pos(req)),blk_rq_sectors(req));
- __blk_end_request_all(req, 0);
- continue;
- }
-
- switch(rq_data_dir(req))
- {
- case READ:
- memcpy(req->buffer, simp_blkdev_data + ( blk_rq_pos(req) << 9) , blk_rq_sectors(req)<<9);
- __blk_end_request_all(req, 1);
- break;
- case WRITE:
- memcpy(simp_blkdev_data + (blk_rq_pos(req)<< 9), req->buffer, blk_rq_sectors(req)<<9);
- __blk_end_request_all(req , 1);
- break;
- default:
- /*No default, because the return value is 1 bit*/
- break;
- }
-
- }
- }
- module_init(simp_blk_init);
- module_exit(simp_blk_exit);
复制代码 |
|