zoukankan      html  css  js  c++  java
  • 块设备驱动2

      1 #include <linux/module.h>
      2 #include <linux/blkdev.h>
      3 
      4 #define SIMP_BLKDEV_DISKNAME "simp_blkdev"          //块设备名
      5 #define SIMP_BLKDEV_DEVICEMAJOR COMPAQ_SMART2_MAJOR //主设备号
      6 #define SIMP_BLKDEV_BYTES (1*1024*1024)            // 块设备大小为50MB
      7 #define SECTOR_SIZE_SHIFT 9
      8 
      9 static struct gendisk *simp_blkdev_disk;// gendisk结构表示一个简单的磁盘设备
     10 static struct block_device_operations simp_blkdev_fops = { //块设备操作,gendisk的一个属性
     11     .owner = THIS_MODULE,
     12 };
     13 static struct request_queue *simp_blkdev_queue;//指向块设备请求队列的指针
     14 unsigned char simp_blkdev_data[SIMP_BLKDEV_BYTES];// 虚拟磁盘块设备的存储空间
     15 
     16 
     17 /******************************************************
     18 *
     19 *   磁盘块设备数据请求的处理函数
     20 *
     21 ******************************************************/
     22 static void simp_blkdev_do_request(struct request_queue *q){
     23     struct request *req;// 正在处理的请求队列中的请求
     24     struct bio *req_bio;// 当前请求的bio
     25     struct bio_vec *bvec;// 当前请求的bio的段(segment)链表
     26     char *disk_mem;      // 需要读/写的磁盘区域
     27     char *buffer;        // 磁盘块设备的请求在内存中的缓冲区
     28     int i = 0;
     29 
     30     while((req = blk_fetch_request(q)) != NULL){
     31         // 判断当前req是否合法
     32         if((blk_rq_pos(req)<<SECTOR_SIZE_SHIFT) + blk_rq_bytes(req) > SIMP_BLKDEV_BYTES){
     33             printk(KERN_ERR SIMP_BLKDEV_DISKNAME":bad request:block=%llu, count=%u
    ",(unsigned long long)blk_rq_pos(req),blk_rq_sectors(req));
     34             blk_end_request_all(req, -EIO);
     35             continue;
     36         }
     37         //获取需要操作的内存位置
     38         disk_mem = simp_blkdev_data + (blk_rq_pos(req) << SECTOR_SIZE_SHIFT);
     39         req_bio = req->bio;// 获取当前请求的bio
     40 
     41         switch (rq_data_dir(req)) {  //判断请求的类型
     42         case READ:
     43             // 遍历req请求的bio链表
     44             while(req_bio != NULL){
     45                 // for循环处理bio结构中的bio_vec结构体数组(bio_vec结构体数组代表一个完整的缓冲区)
     46                 for(i=0; i<req_bio->bi_vcnt; i++){
     47                     bvec = &(req_bio->bi_io_vec[i]);
     48                     buffer = kmap(bvec->bv_page) + bvec->bv_offset;
     49                     memcpy(buffer, disk_mem, bvec->bv_len);
     50                     kunmap(bvec->bv_page);
     51                     disk_mem += bvec->bv_len;
     52                 }
     53                 req_bio = req_bio->bi_next;
     54             }
     55             __blk_end_request_all(req, 0);
     56             break;
     57         case WRITE:
     58             while(req_bio != NULL){
     59                 for(i=0; i<req_bio->bi_vcnt; i++){
     60                     bvec = &(req_bio->bi_io_vec[i]);
     61                     buffer = kmap(bvec->bv_page) + bvec->bv_offset;
     62                     memcpy(disk_mem, buffer, bvec->bv_len);
     63                     kunmap(bvec->bv_page);
     64                     disk_mem += bvec->bv_len;
     65                 }
     66                 req_bio = req_bio->bi_next;
     67             }
     68             __blk_end_request_all(req, 0);
     69             break;
     70         default:
     71             /* No default because rq_data_dir(req) is 1 bit */
     72             break;
     73         }
     74     }
     75 }
     76 
     77 
     78 /******************************************************
     79 *
     80 *   模块的入口函数
     81 *
     82 ******************************************************/
     83 static int __init simp_blkdev_init(void){
     84     int ret;
     85 
     86     //1.添加设备之前,先申请设备的资源
     87     simp_blkdev_disk = alloc_disk(1);
     88     if(!simp_blkdev_disk){
     89         ret = -ENOMEM;
     90         goto err_alloc_disk;
     91     }
     92 
     93     //2.设置设备的有关属性(设备名,设备号,fops指针,请求队列,512B的扇区数)
     94     strcpy(simp_blkdev_disk->disk_name,SIMP_BLKDEV_DISKNAME);
     95     simp_blkdev_disk->major = SIMP_BLKDEV_DEVICEMAJOR;
     96     simp_blkdev_disk->first_minor = 0;
     97     simp_blkdev_disk->fops = &simp_blkdev_fops;
     98     // 将块设备请求处理函数的地址传入blk_init_queue函数,初始化一个请求队列
     99     simp_blkdev_queue = blk_init_queue(simp_blkdev_do_request, NULL);
    100     if(!simp_blkdev_queue){
    101         ret = -ENOMEM;
    102         goto err_init_queue;
    103     }
    104     simp_blkdev_disk->queue = simp_blkdev_queue;
    105     set_capacity(simp_blkdev_disk, SIMP_BLKDEV_BYTES>>9);
    106 
    107     //3.入口处添加磁盘块设备
    108     add_disk(simp_blkdev_disk);
    109     return 0;
    110 
    111     err_alloc_disk:
    112         return ret;
    113     err_init_queue:
    114         return ret;
    115 }
    116 
    117 
    118 /******************************************************
    119 *
    120 *   模块的出口函数
    121 *
    122 ******************************************************/
    123 static void __exit simp_blkdev_exit(void){
    124     del_gendisk(simp_blkdev_disk);// 释放磁盘块设备
    125     put_disk(simp_blkdev_disk);   // 释放申请的设备资源
    126     blk_cleanup_queue(simp_blkdev_queue);// 清除请求队列
    127 }
    128 
    129 
    130 module_init(simp_blkdev_init);// 声明模块的入口
    131 module_exit(simp_blkdev_exit);// 声明模块的出口

    Makefile文件:

     1 ifneq ($(KERNELRELEASE),) 
     2 MODULE_NAME := blk_ko
     3 OBJGMAC := simp_blkdev.o
     4 
     5 $(MODULE_NAME)-objs := $(OBJGMAC)
     6 obj-m := $(MODULE_NAME).o 
     7 
     8 else
     9 
    10 DRIVERDIR := $(shell pwd)
    11 KERNELDIR = /home/rayhe/share/rk3288_sdk/rk3288_rt
    12 
    13 all: 
    14     $(MAKE) -C $(KERNELDIR) M=$(DRIVERDIR) modules
    15 
    16 clean:
    17     rm -rf *.o  ./build/*.ko ./gmac/*.o  ./gmac/*.ko *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions modules.order Module.symvers
    18 endif

    参考网址:https://blog.csdn.net/cxy_chen/article/details/80998510

  • 相关阅读:
    JavaScript操作符instanceof揭秘
    Linux打开txt文件乱码的解决方法
    Working copy locked run svn cleanup not work
    poj 2299 UltraQuickSort 归并排序求解逆序对
    poj 2312 Battle City 优先队列+bfs 或 记忆化广搜
    poj2352 stars 树状数组
    poj 2286 The Rotation Game 迭代加深
    hdu 1800 Flying to the Mars
    poj 3038 Children of the Candy Corn bfs dfs
    hdu 1983 Kaitou Kid The Phantom Thief (2) DFS + BFS
  • 原文地址:https://www.cnblogs.com/debruyne/p/9437138.html
Copyright © 2011-2022 走看看