块设备驱动

AIchatOS

#include<linux/kernel.h>
#include<linux/module.h>
#include<linux/fs.h>
#include<linux/init.h>
#include<linux/errno.h>
#include<linux/moduleparam.h>
#include<linux/vmalloc.h>
#include<linux/blkdev.h>
#include<linux/genhd.h>
#include<linux/hdreg.h>
#include<linux/version.h>

#define VDISK_SIZE 10*1024*1024    //扇区容量
#define SECTOR_SIZE 512    //扇区大小

static int ramdisk_major = 0;
static struct gendisk *gdisk;
static spinlock_t ramdisksplock;
unsigned char* vmem;

static int demo_open(struct block_device *dev, fmode_t mod)
{
    printk(KERN_WARNING "L%d->%s()\n",__LINE__,__FUNCTION__);
    return 0;
}

static int demo_getgeo(struct block_device *blk,struct hd_geometry *geo)
{
    printk(KERN_WARNING "L%d->%s()\n",__LINE__,__FUNCTION__);
    geo->heads = 4;
    geo->sectors = 16;
    gep->start = 0;
    geo->cylinders = VDISK_SIZE/SECTOR_SIZE/4/16;
    return 0;
}


static struct block_device_operations ramdisk_fops = {
    .owner = THIS_MODULE,
    .open = demo_open,
    .getgo =demo_getgeo, //设置柱面,扇区等,从而可以使用磁盘工具而分区
};

static void ramdisk_request(struct request_queue *q)
{
    struct request *req;
    unsigned int size; //大小
    unsigned int off; //偏移量

    printk(KERN_WARNING "L%d->%s()\n",__LINE__,__FUNCTION__);
    req = blk_fetch_request(q);//得到一个请求
    while(req){
        size = blk_rq_cur_bytes(req);
        off = req->sector*SECTOR_SIZE ;

        if((rq_data_dir(req) == READ))//读
            memcpy(req->buffer,vem+off,size);

        else if((rq_data_dir(req) == WRITE))  //写      
            memcpy(vem+off,size,req->buffer);

        if(!__blk_end_request_cur(req,0))
            req = blk_fetch_request(q);
    }

}


static int __init ramdisk_init(void){
    printk(KERN_WARNING "L%d->%s()\n",__LINE__,__FUNCTION__);
vmen = vmalloc(VDISK_SIZE);//在内存里申请空间,作为我们虚拟磁盘的空间
If(!vmem)

    // 1、申请主设备号
    ramdisk_major = register_blkdev(ramdisk_major,"ramdisk");
    //2、注册 gendisk
    gdisk = alloc_disk(3); 
    //3、填充 gendisk
    gdisk->major = ramdisk_major;//填充主设备号
    gdisk->first_minor = 0;//起始从设备号
    gdisk->fops = &ramdisk_fops;//块设备操作函数
    strcpy(gdisk->disk_name,"ramdiska");
    spin_lock_init(&ramdisksplock);//初始化自旋锁
    gdisk->queue = blk_init_queue(ramdisk_request,&ramdisksplock);//请求队列 回调函数,自旋锁
    set_capacity(gdisk,VDISK_SIZE /SECTOR_SIZE )//扇区数量 容量/大小
    //4、注册 gendisk
    add_disk(gdisk);
    return 0;   

}

static void __exit my_exit(void)
{
    printk(KERN_WARNING "L%d->%s()\n",__LINE__,__FUNCTION__);
    del_gendisk(gdisk);    //注销
    put_disk(gdisk);    //释放
    unregister_blkdev(ramdisk_major,"ramdisk");
    vfree(vmem);//虚拟空间释放
}

MODULE_LICENSE(“GPL v2”);
module_init( ramdisk_init);
module_exit(my_exit);
BASEINCLUDE ?= /lib/modules/$(shell uname -r)/build

oops-objs := ramdisk-driver.o 
KBUILD_CFLAGS +=-g -00

obj-m:= ramdisk_driver.o
all : 
	$(MAKE) -C $(BASEINCLUDE) SUBDIRS=$(PWD) modules;

install:
	$(MAKE) -C $(BASEINCLUDE) SUBDIRS=$(PWD) modules_install;
	
clean:
	$(MAKE) -C $(BASEINCLUDE) SUBDIRS=$(PWD) clean;
	rm -f *.ko;
编译:
make
sudo insmod ramdisk_driver.ko
sudo mkfs ext4 /dev/ramdiska  对ramdisk这个块设备进行格式化
dmesg     查看系统信息
sudo mount /dev/myramdisk   /mnt/    安装文件系统
cd /mnt
ls
df  用df命令查看一下文件系统挂载的分区
sudo mkdir mytest  创建一个文件夹
dmesg   查看创建mytest文件夹时引起的块设备I/O操作

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值