免费注册 查看新帖 |

Chinaunix

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

一个块设备驱动 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2012-04-15 11:41 |只看该作者 |倒序浏览
各位大神,我用2.6.32的内核仿照LDD的块设备驱动程序例程写了一个自己的块设备驱动,在/dev/下能看到相应的块设备文件,我写了一个简单的测试程序,结果是打开块设备文件成功,写块设备文件成功,可是读块设备文件就失败了,strace显示:read(3,        ;就这样一直停住,由于整个文件系统层次太多,又没有太多经验,对问题产生的原因琢磨不透,望各位大神指点迷津!queue队列的函数如下
static void myblock_queue( struct request_queue *q  )
{
  struct request *req;
  struct bio_vec *vctt;
  struct bio *bios;
  unsigned short i;
  
  while( (req = blk_fetch_request(q  )) != NULL )
  {
      if( !blk_fs_request( req ) )
      {
          printk( KERN_EMERG "this is the file information request, return\n" );
          __blk_end_request_cur( req, -1 );
          continue;

      }
      //each bio
     __rq_for_each_bio(bios, req )
     {
          // get the direction
          int dir ;
          dir = bio_data_dir(bios);
          //position
          unsigned long sectors = bios->bi_sector;
          //each segment
          bio_for_each_segment( vctt , bios, i )
          {
              char *buf;
              //get the size, bytes
              unsigned long size = bio_cur_bytes( bios );
       
              buf = __bio_kmap_atomic( bios, i, KM_USER0 );
             
              if( dir == 1 )      //write
              {
                  printk( KERN_EMERG "buf =  %s\n", buf );
                  memcpy((myblock.ptr + sectors*512), buf, size );
              }
              else
              {
                  //read
                  memcpy( buf, (myblock.ptr + sectors*512), size );
                  printk( KERN_EMERG "into to the read request\n" );
              }
              __bio_kunmap_atomic( buf, KM_USER0 );
            }
        }
   
      __blk_end_request_cur( req, 0 );
    }
         

  *((int *  )0) = 5;    //测试用的,用来产生oop
  printk( KERN_EMERG "request has end\n" );
  
}

论坛徽章:
0
2 [报告]
发表于 2012-04-16 14:35 |只看该作者
  1. # echo 1 > /proc/sys/kernel/sysrq
  2. # echo t > /proc/sysrq-trigger
  3. # dmesg
复制代码
看看卡在哪

论坛徽章:
0
3 [报告]
发表于 2012-04-17 20:56 |只看该作者
后来仔细看了块设备api,才知道问题出现在__blk_end_request_cur( req, 0 ),在结束请求的时候,必须要通过结束请求函数传递你处理了多少个字节的数据,这个函数的实现为:
bool __blk_end_request_cur(struct request *rq, int error)
{
        return __blk_end_request(rq, error, blk_rq_cur_bytes(rq));
}
其中blk_rq_cur_bytes(rq)的意义是当前bio的当前vec页缓冲的字节数,在我的函数里传的字节数因该是request的数据量,这样握就少传了很多字节数,这样造成内核以为数据没读完,所以read一直阻塞(read一般是同步操作)
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP