免费注册 查看新帖 |

Chinaunix

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

[内核模块] 块设备驱动在add_disk的时候出问题了…… [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2014-05-18 22:09 |只看该作者 |倒序浏览
本帖最后由 小菜虎 于 2014-05-18 22:15 编辑

我编写的块设备驱动加载不上,经测试,程序卡在运行add_disk函数的时候。麻烦大大们帮我找下BUG谢谢{:3_194:} demsg日志和源代码如下:

[  174.489539] MyBlk init done.
[  174.489542] bop init done.
[  174.489548] bdisk alloc done.
[  174.489549] bdisk init done.
[  174.489571] bqueue alloc done.
[  174.489573] bqueue make request done.
[  174.489580] Register blkdev done.
[  174.489586] BUG: unable to handle kernel NULL pointer dereference at 0000021c
[  174.489599] IP: [<c11305b0>] bdi_register+0x10/0x100
[  174.489608] *pdpt = 0000000030d40001 *pde = 0000000000000000
[  174.489614] Oops: 0000 [#1] SMP
[  174.489619] Modules linked in: hello(OF+) bnep rfcomm bluetooth snd_hda_codec_hdmi x86_pkg_temp_thermal intel_powerclamp coretemp kvm_intel(F) kvm(F) crc32_pclmul(F) ppdev(F) eeepc_wmi asus_wmi sparse_keymap cdc_acm nouveau microcode(F) snd_hda_codec_realtek mxm_wmi ttm lpc_ich drm_kms_helper serio_raw(F) snd_hda_intel mei_me snd_hda_codec parport_pc(F) video(F) snd_hwdep(F) snd_pcm(F) drm snd_seq_midi(F) snd_seq_midi_event(F) snd_rawmidi(F) snd_page_alloc(F) snd_seq(F) snd_seq_device(F) snd_timer(F) i2c_algo_bit mei snd(F) wmi mac_hid soundcore(F) lp(F) parport(F) hid_generic usbhid hid r8169 mii(F)
[  174.489700] CPU: 1 PID: 2404 Comm: insmod Tainted: GF          O 3.11.0-12-generic #19-Ubuntu
[  174.489704] Hardware name: System manufacturer System Product Name/P8H61-M LX, BIOS 0601 08/31/2011
[  174.489709] task: f1813380 ti: f0cec000 task.ti: f0cec000
[  174.489713] EIP: 0060:[<c11305b0>] EFLAGS: 00010296 CPU: 1
[  174.489717] EIP is at bdi_register+0x10/0x100
[  174.489720] EAX: 000000d0 EBX: 000000d0 ECX: 00000000 EDX: 000000f8
[  174.489724] ESI: f1b4fc5c EDI: 00000000 EBP: f0cedd8c ESP: f0cedd78
[  174.489728]  DS: 007b ES: 007b FS: 00d8 GS: 00e0 SS: 0068
[  174.489732] CR0: 80050033 CR2: 0000021c CR3: 30d4e000 CR4: 000407f0
[  174.489735] Stack:
[  174.489738]  00000330 00000015 00000001 f1b4fc00 f1b4fc5c f0cedda8 c11306d6 000000d0
[  174.489750]  00000000 c1871a1e 000000f8 00000000 f0cedde8 c12d9b8e 00000001 00000246
[  174.489761]  00000000 00000000 f1b4fc0c 00000001 0f800000 c1621d72 00000000 00000001
[  174.489773] Call Trace:
[  174.489778]  [<c11306d6>] bdi_register_dev+0x36/0x40
[  174.489784]  [<c12d9b8e>] add_disk+0x11e/0x430
[  174.489789]  [<c1621d72>] ? printk+0x50/0x52
[  174.489794]  [<ff6ff000>] ? 0xff6fefff
[  174.489798]  [<ff6ff14f>] init_module+0x14f/0x1000 [hello]
[  174.489804]  [<c10020ca>] do_one_initcall+0xca/0x190
[  174.489808]  [<ff6ff000>] ? 0xff6fefff
[  174.489813]  [<c104871f>] ? set_memory_nx+0x5f/0x70
[  174.489818]  [<c10b4a8e>] load_module+0x10ce/0x18d0
[  174.489824]  [<c10b531f>] SyS_init_module+0x8f/0xf0
[  174.489831]  [<c1632ccd>] sysenter_do_call+0x12/0x28
[  174.489835] Code: 5d c3 c7 45 b8 00 00 00 00 e9 83 fe ff ff 8d b6 00 00 00 00 8d bc 27 00 00 00 00 55 89 e5 56 53 83 ec 0c 66 66 66 66 90 8b 5d 08 <8b> 83 4c 01 00 00 85 c0 74 0e 31 c0 83 c4 0c 5b 5e 5d c3 90 8d
[  174.490116] EIP: [<c11305b0>] bdi_register+0x10/0x100 SS:ESP 0068:f0cedd78
[  174.490164] CR2: 000000000000021c
[  174.512496] ---[ end trace 66605d80150e4d51 ]---

  1. /*hello.c*/
  2. #include <linux/init.h>
  3. #include <linux/module.h>
  4. #include <linux/fs.h>
  5. #include <linux/blkdev.h>
  6. #include <linux/genhd.h>
  7. #include <linux/bio.h>
  8. #include "myblk.h"

  9. #define MYBLK_DEV_SIZE 200
  10. #define MYBLK_DEV_MAJOR 248
  11. #define MYBLK_DEV_NAME "MyBlkDev"

  12. struct MyBlk *blk;
  13. struct block_device_operations bop;
  14. struct gendisk *bdisk;
  15. struct request_queue *bqueue;

  16. int open(struct inode *node, struct file *fp)
  17. {
  18.         return 0;
  19. }

  20. int release(struct inode *node, struct file *fp)
  21. {
  22.         return 0;
  23. }

  24. void myblk_make_request(struct request_queue *q, struct bio *bio)
  25. {
  26.         int i;
  27.         char *buf;
  28.         char *mem;
  29.         struct bio_vec *bvl;
  30.         if(((bio->bi_sector)<<9) + bio->bi_size > (MYBLK_DEV_SIZE<<9))
  31.         {
  32.                 bio_io_error(bio);
  33.                 //return 0;
  34.         }
  35.         mem = blk->mem + ((bio->bi_sector)<<9);
  36.         bio_for_each_segment(bvl, bio, i)
  37.         {
  38.                 buf = __bio_kmap_atomic(bio,i/*,KM_USER0*/);
  39.                 switch(bio_data_dir(bio))
  40.                 {
  41.                         case READ:
  42.                         case READA:
  43.                                 memcpy(buf, mem, bvl->bv_len);
  44.                                 break;
  45.                         case WRITE:
  46.                                 memcpy(mem, buf, bvl->bv_len);
  47.                                 break;
  48.                         default:
  49.                                 break;
  50.                 }
  51.                 __bio_kunmap_atomic(buf/*, KM_USER0*/);
  52.                 mem += bvl->bv_len;
  53.         }
  54.         bio_endio(bio, /*bio->bi_size,*/ 0);
  55.         //return 0;
  56. }

  57. int __init hello_init(void)
  58. {
  59.         blk = MyBlk_init(MYBLK_DEV_SIZE);
  60.         if(blk == NULL)
  61.         {
  62.                 printk(KERN_ALERT"Error init MyBlk.\n");
  63.                 return -1;
  64.         }
  65.         printk(KERN_ALERT"MyBlk init done.\n");
  66.         //bop.open = open;
  67.         //bop.release = release;
  68.         bop.owner = THIS_MODULE;
  69.         printk(KERN_ALERT"bop init done.\n");
  70.         bdisk = alloc_disk(1);
  71.         if(bdisk == NULL)
  72.         {
  73.                 printk(KERN_ALERT"bdisk alloc error.\n");
  74.                 return -1;
  75.         }
  76.         printk(KERN_ALERT"bdisk alloc done.\n");
  77.         bdisk->major = MYBLK_DEV_MAJOR;
  78.         bdisk->first_minor = 0;
  79.         bdisk->fops = &bop;
  80.         set_capacity(bdisk, MYBLK_DEV_SIZE);
  81.         strcpy(bdisk->disk_name, MYBLK_DEV_NAME);
  82.         printk(KERN_ALERT"bdisk init done.\n");
  83.         /*************************/
  84.         bqueue = blk_alloc_queue(GFP_KERNEL);
  85.         if(bqueue == NULL)
  86.         {
  87.                 printk(KERN_ALERT"Error blk_alloc_queue\n");
  88.                 return -1;
  89.         }
  90.         printk(KERN_ALERT"bqueue alloc done.\n");
  91.         blk_queue_make_request(bqueue, myblk_make_request);
  92.         printk(KERN_ALERT"bqueue make request done.\n");
  93.         //blk_queue_max_sectors(bqueue, MYBLK_DEV_SIZE);
  94.         /*************************/
  95.         if(0 > register_blkdev(MYBLK_DEV_MAJOR, MYBLK_DEV_NAME))
  96.         {
  97.                 printk(KERN_ALERT"Register_blkdev error\n");
  98.                 return -1;
  99.         }
  100.         printk(KERN_ALERT"Register blkdev done.\n");
  101.         add_disk(bdisk);
  102.         printk(KERN_ALERT"Hello world!\n");
  103.         return 0;
  104. }
  105. void __exit hello_exit(void)
  106. {
  107.         MyBlk_uninit(blk);
  108.         blk_cleanup_queue(bqueue);
  109.         del_gendisk(bdisk);
  110.         unregister_blkdev(MYBLK_DEV_MAJOR, MYBLK_DEV_NAME);
  111.         printk(KERN_ALERT"Goodbye world!\n");
  112. }

  113. module_init(hello_init);
  114. module_exit(hello_exit);

  115. MODULE_LICENSE("Dual BSD/GPL");
  116. MODULE_AUTHOR("Xiaocaihu");
  117. MODULE_VERSION("1.0");
复制代码

  1. /*myblk.h*/
  2. #include <linux/slab.h>
  3. struct MyBlk
  4. {
  5.         char* mem;
  6.         sector_t size;
  7. };

  8. struct MyBlk* MyBlk_init(sector_t size)
  9. {
  10.         struct MyBlk *blk;
  11.         blk = kmalloc(sizeof(struct MyBlk), GFP_KERNEL);
  12.         if(blk == NULL)
  13.         {
  14.                 printk(KERN_ALERT"blk alloc error!\n");
  15.                 return NULL;
  16.         }
  17.         blk->size = size;
  18.         blk->mem = kmalloc(size<<9, GFP_KERNEL);
  19.         if(blk->mem == NULL)
  20.         {
  21.                 printk(KERN_ALERT"Mem alloc error!\n");
  22.                 kfree(blk);
  23.                 return NULL;
  24.         }
  25.         return blk;
  26. }

  27. void MyBlk_uninit(struct MyBlk *blk)
  28. {
  29.         if(blk && blk->mem)
  30.                 kfree(blk->mem);
  31.         if(blk)
  32.                 kfree(blk);
  33. }
复制代码

论坛徽章:
15
射手座
日期:2014-02-26 13:45:082015年迎新春徽章
日期:2015-03-04 09:54:452015年辞旧岁徽章
日期:2015-03-03 16:54:15羊年新春福章
日期:2015-02-26 08:47:552015年亚洲杯之卡塔尔
日期:2015-02-03 08:33:45射手座
日期:2014-12-31 08:36:51水瓶座
日期:2014-06-04 08:33:52天蝎座
日期:2014-05-14 14:30:41天秤座
日期:2014-04-21 08:37:08处女座
日期:2014-04-18 16:57:05戌狗
日期:2014-04-04 12:21:33技术图书徽章
日期:2014-03-25 09:00:29
2 [报告]
发表于 2014-05-19 08:42 |只看该作者
非法地址访问,需要反汇编看看具体出错的代码行和具体变量,确认变量的来源,看看是不是你传入的参数有问题。

论坛徽章:
0
3 [报告]
发表于 2014-05-19 23:52 |只看该作者
回复 2# humjb_1983


    谢谢你的回复,可我还是不知道问题出在哪儿……

论坛徽章:
0
4 [报告]
发表于 2014-05-20 00:41 |只看该作者
本帖最后由 小菜虎 于 2014-05-20 00:42 编辑

回复 2# humjb_1983


    找到问题了。我忘了把请求队列赋值给gendisk,低级失误啊{:3_204:}

在hello.c文件的第99行和第100行之间插入代码:

  1. bdisk->queue = bqueue;
复制代码
问题解决{:3_200:}

再次感谢你的回复

论坛徽章:
15
射手座
日期:2014-02-26 13:45:082015年迎新春徽章
日期:2015-03-04 09:54:452015年辞旧岁徽章
日期:2015-03-03 16:54:15羊年新春福章
日期:2015-02-26 08:47:552015年亚洲杯之卡塔尔
日期:2015-02-03 08:33:45射手座
日期:2014-12-31 08:36:51水瓶座
日期:2014-06-04 08:33:52天蝎座
日期:2014-05-14 14:30:41天秤座
日期:2014-04-21 08:37:08处女座
日期:2014-04-18 16:57:05戌狗
日期:2014-04-04 12:21:33技术图书徽章
日期:2014-03-25 09:00:29
5 [报告]
发表于 2014-05-20 08:42 |只看该作者
呵呵,找到问题就好,此类问题通常是自己编写的代码所致,内核中稍不留神就这样~,坑踩多了就好了
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP