Chinaunix首页 | 论坛 | 博客
  • 博客访问: 62268
  • 博文数量: 28
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 10
  • 用 户 组: 普通用户
  • 注册时间: 2014-11-30 01:24
文章分类
文章存档

2017年(1)

2016年(5)

2015年(22)

我的朋友

分类: LINUX

2015-04-30 12:59:10

应该注意版本更新函数的变化。

内核版本:2.6.32-24-generic

点击(此处)折叠或打开

  1. #include <linux/module.h>
  2. #include <linux/fs.h>
  3. #include <linux/types.h>
  4. #include <linux/genhd.h>
  5. #include <linux/blkdev.h>

  6. #define BLKDEV_DISKNAME "blkdev"
  7. /*
  8.  使用的一个并不常用的设备号,也可动态申请
  9.  dev_major = register_blkdev(0, BLKDEV_DISKNAME); ///proc/devices/下面的名称
  10.  需检查申请是否成功
  11. */
  12. #define BLKDEV_DEVICEMAJOR COMPAQ_SMART2_MAJOR
  13. #define BLKDEV_BYTES (16*1024*1024) //16M

  14. unsigned char blkdev_data[BLKDEV_BYTES];

  15. static struct gendisk *blkdev_disk;
  16. static struct request_queue *blkdev_queue;

  17. struct block_device_operations blkdev_fops = {
  18.  .owner = THIS_MODULE,
  19. };

  20. static void blkdev_do_request(struct request_queue *q)
  21. {
  22.  struct request *req;
  23.  req = blk_fetch_request(q); //函数链blk_fetch_request()->blk_peek_request()->__elv_next_request()->...

  24.  while(req) {
  25.   unsigned long start = blk_rq_pos(req) << 9;
  26.   unsigned long len = blk_rq_cur_sectors(req) << 9; //此处等同于len = blk_rq_cur_bytes(req);
  27.   int err = 0;

  28.   if(start + len > BLKDEV_BYTES) {
  29.    printk(KERN_ERR BLKDEV_DISKNAME ":bad access:block=%lu,count=%un",blk_rq_pos(req), blk_rq_cur_sectors(req));
  30.    err = -EIO;
  31.    goto done;
  32.   }
  33.   if(rq_data_dir(req) == READ)
  34.    memcpy(req->buffer, blkdev_data+start,len);
  35.   else
  36.    memcpy(blkdev_data+start, req->buffer, len);
  37.  done:
  38.   if(!__blk_end_request_cur(req, err))
  39.    req = blk_fetch_request(q);
  40.  }
  41. }

  42. static int __init blkdev_init(void)
  43. {
  44.  int ret;

  45.  blkdev_queue = blk_init_queue(blkdev_do_request, NULL); //每个块设备关联请求处理函数
  46.  if(!blkdev_queue) {
  47.   ret = -ENOMEM;
  48.   goto err_init_queue;
  49.  }
  50.  
  51.  blkdev_disk = alloc_disk(1);
  52.  if(!blkdev_disk) {
  53.   goto err_alloc_disk;
  54.  }
  55.  strcpy(blkdev_disk->disk_name, BLKDEV_DISKNAME); ///dev/下面的名称
  56.  blkdev_disk->major = BLKDEV_DEVICEMAJOR; //如果是动态申请的话就是dev_major
  57.  blkdev_disk->first_minor = 0;
  58.  blkdev_disk->fops = &blkdev_fops;
  59.  blkdev_disk->queue = blkdev_queue;
  60.  set_capacity(blkdev_disk, BLKDEV_BYTES>>9); //扇区大小512B
  61.  add_disk(blkdev_disk);

  62.  return 0;
  63.  
  64. err_alloc_disk:
  65.  blk_cleanup_queue(blkdev_queue);
  66. err_init_queue:
  67.  return ret;

  68. }

  69. static void __exit blkdev_exit(void)
  70. {
  71.  blk_cleanup_queue(blkdev_queue);
  72.  del_gendisk(blkdev_disk);
  73.  put_disk(blkdev_disk);
  74. }

  75. module_init(blkdev_init);
  76. module_exit(blkdev_exit);

2012-02-18 23:15 发表于百度空间,今搬至CU。


阅读(673) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~