码迷,mamicode.com
首页 > 其他好文 > 详细

Ramdisk驱动的实现

时间:2014-11-25 16:36:54      阅读:142      评论:0      收藏:0      [点我收藏+]

标签:des   io   ar   sp   for   文件   数据   on   bs   

文件gao_rd.c如下

#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>//定义了一些常用的函数原型
#include <linux/fs.h>//
#include <linux/errno.h>//一些出错的常量符号的宏
#include <linux/types.h>//定义了一些基本的数据类型。所有类型均定义为适当的数字类型长度。
#include <linux/fcntl.h>//文件控制选项头文件,
#include <linux/vmalloc.h>
#include <linux/hdreg.h>//定义了一些对硬盘控制器进行编程的一些命令常量符号。
#include <linux/blkdev.h>
#include <linux/blkpg.h>
#include <asm/uaccess.h>


/*设备名称,段大小,设备大小等信息的定义*/
#define GAO_RD_DEV_NAME "gao_rd" //设备名称
#define GAO_RD_DEV_MAJOR 220  //主设备号
#define GAO_RD_MAX_DEVICE 2    //最大设备数
#define GAO_BLOCKSIZE  1024
#define GAO_RD_SECTOR_SIZE 512   //扇区大小
#define GAO_RD_SIZE (4*1024*1024)  //总大小
#define GAO_RD_SECTOR_TOTAL (GAO_RD_SIZE/GAO_RD_SECTOR_SIZE)  //总扇区数

typedef struct
{
   unsigned char *data;
   struct request_queue *queue;
   struct gendisk *gd;
}gao_rd_device;

static char *vdisk[GAO_RD_MAX_DEVICE];

static gao_rd_device device[GAO_RD_MAX_DEVICE];


static int gao_rd_make_request(struct request_queue *q, struct bio *bio)/*制造请求函数*/
{
   gao_rd_device *pdevice;    
   char *pVHDDData;
   char *pBuffer;
   struct bio_vec *bvec;
   int i;
   
   
   if(((bio->bi_sector*GAO_RD_SECTOR_SIZE) + bio-> bi_size) > GAO_RD_SIZE)
   {
       bio_io_error(bio/*, bio->bi_size*/);
       return 0;
   }
   else
   {
       
       pdevice = (gao_rd_device *) bio->bi_bdev->bd_disk-> private_data;
       pVHDDData = pdevice->data + (bio-> bi_sector*GAO_RD_SECTOR_SIZE);
       
       bio_for_each_segment(bvec, bio, i)/*循环遍历的宏*/
       {
           
           pBuffer = kmap(bvec->bv_page) + bvec-> bv_offset;//kmap()函数???
           
           switch(bio_data_dir(bio))//??????????????????????????????
           {
               case READA :    
               case READ : memcpy(pBuffer, pVHDDData, bvec-> bv_len);
               break;
               case WRITE : memcpy(pVHDDData, pBuffer, bvec-> bv_len);
               break;
               default : kunmap(bvec->bv_page);
                   bio_io_error(bio);
                   return 0;            
           }
           
           kunmap(bvec->bv_page);
           pVHDDData += bvec->bv_len;
       }
       /*结束处理,并终止gao_rd_make_request函数*/
       bio_endio(bio, /*bio->bi_size, */0);
       return 0;
   }    
}

int gao_rd_open(struct inode *inode, struct file *filp)
{
   return 0;
}

int gao_rd_release (struct inode *inode, struct file *filp)
{
   return 0;
}

int gao_rd_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,unsigned long arg)
{
   //return -ENOTTY;
   int error;
   struct block_device *bdev = inode->i_bdev;
   if(cmd!= BLKFLSBUF)
   {
       return -ENOTTY;//不适当的I/O控制操作(没有tty终端)
   }
   error = -EBUSY;//资源正忙
   down(&bdev->bd_mount_sem);
   if(bdev->bd_openers <= 2)
   {
       truncate_inode_pages(bdev->bd_inode->i_mapping,0);
       error = 0;
   }
   up(&bdev->bd_mount_sem);
   return error;
}
//block_device_operations 结构体是对块设备操作的集合
static struct block_device_operations vrd_fops =
{
   .owner = THIS_MODULE,
   .open = gao_rd_open,
   .release = gao_rd_release,
   .ioctl = gao_rd_ioctl,
};
int gao_rd_init(void)
{
   int i;    
   int err = -ENOMEM;
   for(i=0; i < GAO_RD_MAX_DEVICE; i++)
   {
       vdisk[i] = vmalloc(GAO_RD_SIZE);
   }    
   /*注册vrd设备驱动程序*/
   if(register_blkdev(GAO_RD_DEV_MAJOR, GAO_RD_DEV_NAME))//对此块设备进行注册
   {
       err = -EIO;
           goto out;
   }
   /**/
   for(i = 0; i < GAO_RD_MAX_DEVICE; i++)
   {
       device[i].data = vdisk[i];    
       /*分配gendisk结构题,gendisk结构题是注册会设备的信息结构体*/
       device[i].gd = alloc_disk(1);

               if (!device[i].gd)
               goto out;

       device[i].queue = blk_alloc_queue(GFP_KERNEL);//GFP_KERNEL 分配正常的内核 
       if (!device[i].queue)
       {
               put_disk(device[i].gd);
               goto out;
           }

       blk_queue_make_request(device[i].queue, &gao_rd_make_request);
       blk_queue_hardsect_size(device[i].queue,GAO_BLOCKSIZE);//盘块大小

       device[i].gd->major = GAO_RD_DEV_MAJOR;
       device[i].gd->first_minor = i;
       device[i].gd->fops = &vrd_fops;//块设备操作结构体
       device[i].gd->queue = device[i].queue;
       device[i].gd->private_data = &device[i];
       sprintf(device[i].gd->disk_name, "gao_rd%c" , 'a'+i);//
       set_capacity(device[i].gd,GAO_RD_SECTOR_TOTAL);
       
       add_disk(device[i].gd);
   }
   printk("RAMDISK driver initialized!");
   return 0;
out:
  while (i--) {
      put_disk(device[i].gd);
      blk_cleanup_queue(device[i].queue);
  }
  return err;
}

void gao_rd_exit(void)
{
   int i;    
   for(i = 0; i < GAO_RD_MAX_DEVICE; i++)
   {
       del_gendisk(device[i].gd);//删除gendisk结构体    
       put_disk(device[i].gd);//减少gendisk结构体的引用计数
       blk_cleanup_queue(device[i].queue);
   }
   unregister_blkdev(GAO_RD_DEV_MAJOR, GAO_RD_DEV_NAME);
   for(i=0;i < GAO_RD_MAX_DEVICE; i++)
   {
       vfree(vdisk[i]);
   }
}
module_init(gao_rd_init);
module_exit(gao_rd_exit);

MODULE_LICENSE("Dual BSD/GPL");


文件Makefile如下

KERNELDIR = /usr/src/kernels/2.6.27.5-117.fc10.i686/

PWD := $(shell pwd)

CC  =gcc
obj-m := gao_rd.o
modules:
    $(MAKE) -C $(KERNELDIR) M=$(PWD) modules

    rm -rf *.o *.mod.c *.mod.o *.o *.order *.symvers

 

编译通过后,再终端依次输入

#mkdir  /root/Desktop/ramdisk/gao_rd

 

#mknod  /dev/gao_rd0 b 220 0

 

#mke2fs /dev/gao_rd0

 

#mount /dev/gao_rd0 /root/Desktop/ramdisk/gao_rd

 

Ramdisk驱动的实现

标签:des   io   ar   sp   for   文件   数据   on   bs   

原文地址:http://blog.csdn.net/xiao_ping_ping/article/details/41481823

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!