块设备驱动----------代码(2)

#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/init.h>

#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/types.h> /* size_t */
#include <linux/fcntl.h> /* O_ACCMODE */
#include <linux/vmalloc.h>
#include <linux/genhd.h>
#include <linux/blkdev.h>
#include <linux/buffer_head.h> /* invalidate_bdev */
#include <linux/bio.h>
#include<linux/hdreg.h>
#include<linux/slab.h>

#define MY_BLOCK_NAME "demo2_blodev"//需要设置块设备的名称,添加宏定义:
#define MY_DEVICE_MAJOR COMPAQ_SMART2_MAJOR//设置主从驱动号,这里使用的是操作系统已存在的驱动号,添加宏定义:
#define MY_BLOCK_CAPACITY (512*1024)//设置块设备的磁盘容量,添加宏定义:

struct block_device_operations blodev_fops={//设置块设备的文件操作函数,添加一个结构体:
	.owner=THIS_MODULE
};

static unsigned int do_request(struct request_queue *q,struct bio * bio);//设置io请求队列,请求队列的处理函数便是这个驱动的核心内容,这里采用的无队列和全局变量存储的方式。
static struct request_queue *blodev_queue;//定义一个全局的块设备

unsigned char blodev_data[MY_BLOCK_CAPACITY];//全局数据存储数组

static struct gendisk *blodev; 


static int __init my_init(void){
	int ret;
	
	blodev_queue=blk_alloc_queue(GFP_KERNEL);
	blk_queue_make_request(blodev_queue,do_request);
	if(!blodev_queue){
		ret=-ENOMEM;
		return ret;
	}

	blodev = alloc_disk(1);	//为这个块设备申请资源、配置、加入系统
	if(!blodev){
		ret=-ENOMEM;
		blk_cleanup_queue(blodev_queue);
		return ret;
	}


	strcpy(blodev->disk_name,MY_BLOCK_NAME);
	blodev->major=MY_DEVICE_MAJOR;
	blodev->first_minor=0;
	blodev->fops=&blodev_fops;
	blodev->queue=blodev_queue;
 	set_capacity(blodev,MY_BLOCK_CAPACITY>>9);
	
	add_disk(blodev);

	return 0;

}

static void __exit my_exit(void){
        put_disk(blodev);
	//del_gentrcpy(blodev->disk_name,MY_BLOCK_NAME);
        blodev->major=MY_DEVICE_MAJOR;
        blodev->first_minor=0;
        blodev->fops=&blodev_fops;
        blodev->queue=blodev_queue;
        set_capacity(blodev,MY_BLOCK_CAPACITY>>9);
	//isk(blodev);
	blk_cleanup_queue(blodev_queue);
}

static unsigned int do_request(struct request_queue *q,struct bio*bio){
	unsigned long offset=bio->bi_iter.bi_sector << 9;
	char *buffer;
	struct bio_vec bvec;
	struct bvec_iter iter;
	int ret=0;
		
	bio_for_each_segment(bvec,bio,iter){
		if(((iter.bi_sector << 9) + iter.bi_size ) > MY_BLOCK_CAPACITY ){
       			printk("Beyond-end write (%ld %d)\n",offset,iter.bi_size);
			ret=-EIO;
			return ret;
		}
		buffer=kmap(bvec.bv_page) + bvec.bv_offset;
		if(bio_data_dir(bio)==READ){
			memcpy(buffer,blodev_data+offset,bvec.bv_len);
			flush_dcache_page(bvec.bv_page);
		}else if(bio_data_dir(bio)==WRITE){
			flush_dcache_page(bvec.bv_page);
			memcpy(blodev_data+offset,buffer,bvec.bv_len);		
		}else{
			kunmap(bvec.bv_page);
			goto out;
		}
		kunmap(bvec.bv_page);
		offset += bvec.bv_len;	
                
	}
	
	out:
		bio_endio(bio);
		return 0;
}

module_init(my_init);
module_exit(my_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("lvbin");
MODULE_DESCRIPTION("this is a ostest demo2");

添加块设备文件

为块设备建立文件系统

说明文件读取成功。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值