免费注册 查看新帖 |

Chinaunix

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

求助:块设备驱动程序 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2010-06-18 15:47 |只看该作者 |倒序浏览
本帖最后由 seadragonzhl 于 2010-06-18 15:49 编辑

小弟新手,最近在学习块设备驱动。
但是下面的程序能编译通过,但是加载模块后就死机,请高手指点!
内核是linux-2.6.32.1。
代码如下:
  1. #include <linux/module.h>
  2. #include <linux/init.h>
  3. #include <linux/sched.h>
  4. #include <linux/kernel.h>
  5. #include <linux/fs.h>
  6. #include <linux/types.h>
  7. #include <linux/buffer_head.h>
  8. #include <linux/blkdev.h>
  9. #include <linux/msdos_fs.h>
  10. #include <linux/fcntl.h>
  11. #include <linux/delay.h>
  12. #include <linux/elevator.h>

  13. #define SIMP_BLKDEV_DEVICEMAJOR        COMPAQ_SMART2_MAJOR7
  14. #define SIMP_BLKDEV_DISKNAME        "simp_blkdev"
  15. #define SIMP_BLKDEV_BYTES        (16*1024*1024)

  16. static struct request_queue *simp_blkdev_queue;
  17. static struct gendisk *simp_blkdev_disk;
  18. static void simp_blkdev_do_request(struct request_queue *q);
  19. unsigned char simp_blkdev_data[SIMP_BLKDEV_BYTES];

  20. struct block_device_operations simp_blkdev_fops = {
  21.     .owner                = THIS_MODULE,
  22. };

  23. static int __init simp_blkdev_init(void)
  24. {
  25.     int ret;
  26.     simp_blkdev_queue = blk_init_queue(simp_blkdev_do_request, NULL);
  27.     if (!simp_blkdev_queue) {
  28.         ret = -ENOMEM;
  29.         goto err_init_queue;
  30.     }
  31.     simp_blkdev_disk = alloc_disk(1);
  32.     if (!simp_blkdev_disk) {
  33.         ret = -ENOMEM;
  34.         goto err_alloc_disk;
  35.     }
  36.     strcpy(simp_blkdev_disk->disk_name, SIMP_BLKDEV_DISKNAME);
  37.     simp_blkdev_disk->major = SIMP_BLKDEV_DEVICEMAJOR;
  38.     simp_blkdev_disk->first_minor = 0;
  39.     simp_blkdev_disk->fops = &simp_blkdev_fops;
  40.     simp_blkdev_disk->queue = simp_blkdev_queue;
  41.     set_capacity(simp_blkdev_disk, SIMP_BLKDEV_BYTES>>9);
  42.     add_disk(simp_blkdev_disk);
  43.     return 0;

  44. err_alloc_disk:
  45.     blk_cleanup_queue(simp_blkdev_queue);

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

  49. static void simp_blkdev_do_request(struct request_queue *q)
  50. {
  51.     struct request *req;
  52.     //while ((req = elv_next_request(q)) != NULL) {
  53.          while ((req = blk_fetch_request(q)) != NULL) {
  54.         if ((blk_rq_pos(req) + blk_rq_cur_sectors(req)) << 9
  55.              > SIMP_BLKDEV_BYTES) {
  56.              printk(KERN_ERR SIMP_BLKDEV_DISKNAME
  57.                  ": bad request: block=%llu, count=%u\n",
  58.                  (unsigned long long)blk_rq_pos(req),
  59.                  blk_rq_cur_sectors(req));
  60.              blk_end_request_cur(req, 0);
  61.              continue;
  62.         }
  63.         switch (rq_data_dir(req)) {
  64.     case READ:
  65.              memcpy(req->buffer,
  66.                  simp_blkdev_data + (blk_rq_pos(req) << 9),
  67.                  blk_rq_cur_sectors(req) << 9);
  68.              blk_end_request_cur(req, 1);
  69.              break;
  70.     case WRITE:
  71.         memcpy(simp_blkdev_data + (blk_rq_pos(req) << 9),
  72.              req->buffer, blk_rq_cur_sectors(req) << 9);
  73.         blk_end_request_cur(req, 1);
  74.         break;
  75.     default:
  76.         /* No default because rq_data_dir(req) is 1 bit */
  77.         break;
  78.     }
  79.   }
  80. }

  81. static void __exit simp_blkdev_exit(void)
  82. {
  83.     del_gendisk(simp_blkdev_disk);
  84.     put_disk(simp_blkdev_disk);
  85.     blk_cleanup_queue(simp_blkdev_queue);
  86. }
  87. module_init(simp_blkdev_init);
  88. module_exit(simp_blkdev_exit);
复制代码

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
2 [报告]
发表于 2010-06-18 23:30 |只看该作者
在可疑的代码处打印信息,既然死机,可能就无法执行dmesg命令了,那么你可以试一下这个:
用netconsole从网络上收集Kernel Panic信息详细方法
http://linux.chinaunix.net/bbs/thread-811116-1-225.html

论坛徽章:
0
3 [报告]
发表于 2010-06-21 15:19 |只看该作者
回复 2# jinxinxin163

多谢楼上,问题已经解决了,是一个函数用错了,谢谢!
但是我现在还是有个问题不太明白:我的这个模块使用insmod加载后,没有应用程序去调用它,但引用计数就成了1。这是为什么呢?
我用ps -e查看进程,果然多了一个blkid的进程,这个进程不知道是怎么来的?(模块名字叫blk)

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
4 [报告]
发表于 2010-06-21 17:36 |只看该作者
回复 3# seadragonzhl


    我觉的这个很有可能阿,因为说不定你上面调用的某个函数创建了一个内核线程

论坛徽章:
0
5 [报告]
发表于 2010-06-23 15:11 |只看该作者
回复 4# jinxinxin163


    嗯,问题暂时解决了,是__blk_end_request函数的问题,不过还不太清楚为什么整个系统会因为这个原因hang住。

论坛徽章:
0
6 [报告]
发表于 2010-12-11 20:25 |只看该作者
回复  jinxinxin163


    嗯,问题暂时解决了,是__blk_end_request函数的问题,不过还不太清楚为什么 ...
seadragonzhl 发表于 2010-06-23 15:11

我写了个也hang个住了 进入blk_end_request就死机了!
这个到底是什么问题呢?

论坛徽章:
0
7 [报告]
发表于 2010-12-24 11:59 |只看该作者
  1.         struct request *req;
  2.         req = blk_fetch_request(q);
  3.         while (req != NULL)
  4.         {
  5.                 if (! blk_fs_request(req)) {
  6.                         blk_end_request_all(req, -EIO);
  7.                         continue;
  8.                 }
  9.                 switch(rq_data_dir(req))
  10.                 {
  11.                 case READ:
  12.                                 memcpy(req->buffer, blkdev_data + (blk_rq_pos(req) << 9), blk_rq_cur_sectors(req) << 9);
  13.                                 break;
  14.                 case WRITE:
  15.                                 memcpy(blkdev_data + (blk_rq_pos(req) << 9), req->buffer, blk_rq_cur_sectors(req) << 9);
  16.                                 break;
  17.                 }
  18.                         if(!blk_end_request_cur(req, 0)) {
  19.                         req = blk_fetch_request(q);
  20.                 }
  21.         }
复制代码
在request函数里写成这样就行了

论坛徽章:
0
8 [报告]
发表于 2010-12-28 11:21 |只看该作者
源码分析版有个fujisu的大牛写的教你编写块设备驱动的文章,推荐你可以看看
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP