免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 4097 | 回复: 2
打印 上一主题 下一主题

写一个块设备驱动 insmod后机器死了(完全控制不了) [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2011-12-06 18:25 |只看该作者 |倒序浏览
本人最近想学习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之后就死在那了,悲催了。。。。

有哪位高人能指出其中错误之处阿!

下面是我的代码
  1. #include <linux/module.h>
  2. #include <linux/slab.h>
  3. #include <linux/kernel.h>
  4. #include <linux/list.h>
  5. #include <linux/fs.h>
  6. #include <linux/blkdev.h>
  7. #include <linux/blkpg.h>
  8. #include <linux/elevator.h>


  9. #define SIMP_BLKDEV_DEVICEMAJOR         COMPAQ_SMART2_MAJOR
  10. #define SIMP_BLKDEV_DISKNAME                 "simp_blkdev"
  11. #define SIMP_BLKDEV_BYTES                (16*1024*1024)


  12. unsigned char simp_blkdev_data[SIMP_BLKDEV_BYTES];

  13. static struct gendisk *simp_blkdev_disk;

  14. struct block_device_operations simp_blkdev_ops = {
  15.         .owner        = THIS_MODULE
  16. };

  17. static struct request_queue *simp_blkdev_queue;

  18. static void simp_blkdev_do_request(struct request_queue *q);

  19. static int __init simp_blk_init(void)
  20. {
  21.         int ret;

  22.         simp_blkdev_queue = blk_init_queue(simp_blkdev_do_request, NULL);
  23.         if(!simp_blkdev_queue)
  24.         {
  25.                 ret = -ENOMEM;
  26.                 goto err_init_queue;
  27.         }       

  28.         simp_blkdev_disk = alloc_disk(1);
  29.         if(!simp_blkdev_disk)
  30.         {
  31.                 ret = -ENOMEM;
  32.                 goto err_alloc_disk;
  33.         }
  34.        
  35.         strcpy(simp_blkdev_disk->disk_name, SIMP_BLKDEV_DISKNAME);
  36.         simp_blkdev_disk->major = SIMP_BLKDEV_DEVICEMAJOR;
  37.         simp_blkdev_disk->first_minor = 0;
  38.         simp_blkdev_disk->fops = &simp_blkdev_ops;
  39.         simp_blkdev_disk->queue = simp_blkdev_queue;
  40.         set_capacity(simp_blkdev_disk, SIMP_BLKDEV_BYTES>>9);       

  41.         add_disk(simp_blkdev_disk);
  42.         return 0;

  43.         err_alloc_disk:
  44.                 blk_cleanup_queue(simp_blkdev_queue);
  45.                 return ret;

  46.         err_init_queue:
  47.                 return ret;
  48. }

  49. static void __exit simp_blk_exit(void)
  50. {
  51.         del_gendisk(simp_blkdev_disk);
  52.         put_disk(simp_blkdev_disk);
  53.         blk_cleanup_queue(simp_blkdev_queue);
  54. }

  55. static void simp_blkdev_do_request(struct request_queue *q)
  56. {
  57.         struct request *req;
  58.         while( (req = blk_fetch_request(q)) != NULL )
  59.         {
  60.         if( (blk_rq_pos(req) + blk_rq_sectors(req))<<9
  61.             > SIMP_BLKDEV_BYTES         )
  62.                 {
  63.                 printk(KERN_ERR SIMP_BLKDEV_DISKNAME ": bad request: block = %llu, count = %u\n", (unsigned long long)(blk_rq_pos(req)),blk_rq_sectors(req));       
  64.                 __blk_end_request_all(req, 0);
  65.                 continue;
  66.                 }       
  67.        
  68.         switch(rq_data_dir(req))
  69.         {
  70.         case READ:
  71.                 memcpy(req->buffer, simp_blkdev_data + ( blk_rq_pos(req) << 9) , blk_rq_sectors(req)<<9);
  72.                 __blk_end_request_all(req, 1);
  73.                 break;

  74.         case WRITE:
  75.                 memcpy(simp_blkdev_data + (blk_rq_pos(req)<< 9), req->buffer, blk_rq_sectors(req)<<9);       
  76.                 __blk_end_request_all(req , 1);
  77.                 break;

  78.         default:
  79.                 /*No default, because the return value is 1 bit*/
  80.                 break;
  81.         }
  82.        
  83.         }


  84. }

  85. module_init(simp_blk_init);
  86. module_exit(simp_blk_exit);
复制代码

论坛徽章:
0
2 [报告]
发表于 2013-08-22 16:22 |只看该作者
你把所有__blk_end_request_all(req , 1);改为 __blk_end_request_cur(req , 0);注意参数也要改为0  。。试试。。。有问题qq联系,1193533825

论坛徽章:
0
3 [报告]
发表于 2013-08-22 22:37 |只看该作者
本帖最后由 鬼鬼一哈 于 2013-08-22 22:41 编辑

你的内核多新,blk_rq_pos(req) + blk_rq_sectors(req)换为req->sector + req->current_nr_sectors。
在2.6.27上测试通过。。insmod无异常

insmod死机,kdum不好么,定位一下
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP