mini2440 入门块设备驱动(用RAM缓存模拟磁盘)代码记录(内核用的是2.6.32.2)

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

#include 
#include 
#include 

#define		RAMBLOCK_SIZE	(1024*1024)

static struct gendisk *grh_gendisk;
static struct request_queue *grh_queue;
static DEFINE_SPINLOCK(grh_spin_lock);
static int major;
static unsigned char *ramblock_buf;


//对队列中的请求进行处理的函数
static void grh_do_ramblock_req(struct request_queue *q){
	struct request *req;
	static int read_count=0, write_count=0;
	unsigned long offset, count;
	
	req = blk_fetch_request(q);
	while (req) {

		//真正的数据操作
		offset = blk_rq_pos(req); //req对应的扇区的偏移量
		count = blk_rq_cur_sectors(req); //req对应的数据传输量,以扇区为单位
		offset <<= 9;
		count <<= 9;
		if(rq_data_dir(req) == READ){ //读操作
			printk(KERN_EMERG"read count=%d\n", ++read_count);
			memcpy(req->buffer, ramblock_buf+offset, count); /*从ramdisk把需要搬移的扇区数据移动到req的buffer里面*/
		}
		else{ //写操作
			printk(KERN_EMERG"write count=%d\n", ++write_count);
			memcpy(ramblock_buf+offset, req->buffer, count);
		}

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

}


//获取柱面和扇区信息的函数,用于向分区工具提供参数
static int grh_getgeo(struct block_device *bdev, struct hd_geometry *geo){
	geo->heads = 2; //假设2个面
	geo->cylinders = 32; //假设32个柱面
	geo->sectors = RAMBLOCK_SIZE/512/2/32; //算出扇区个数
	return 0;
}

static struct block_device_operations grh_bdops = {
	.owner = THIS_MODULE,
	.getgeo = grh_getgeo,
};

static int ram_block_init(void){
	//分配gendisk
	grh_gendisk = alloc_disk(16); //分区个数为16

	//设置gendisk
	grh_queue = blk_init_queue(grh_do_ramblock_req, &grh_spin_lock); //创建操作队列
	grh_gendisk->queue = grh_queue;
	major = register_blkdev(0, "grh_ramblock");
	grh_gendisk->major = major;
	grh_gendisk->first_minor = 0;
	sprintf(grh_gendisk->disk_name, "ramblock");
	grh_gendisk->fops = &grh_bdops;
	set_capacity(grh_gendisk, RAMBLOCK_SIZE/512); //设置块设备大小为1M

	ramblock_buf = kzalloc(RAMBLOCK_SIZE, GFP_KERNEL);
	if(NULL == ramblock_buf){
		printk(KERN_EMERG"allocate buffer error!\n");
	}

	//注册gendisk
	add_disk(grh_gendisk);

	return 0;
}

static void ram_block_exit(void){
	unregister_blkdev(major, "grh_ramblock");
	del_gendisk(grh_gendisk);
	put_disk(grh_gendisk);
	blk_cleanup_queue(grh_queue);
	kfree(ramblock_buf);
	return;
}


module_init(ram_block_init);
module_exit(ram_block_exit);

MODULE_AUTHOR("GRH");
MODULE_VERSION("1.0");
MODULE_DESCRIPTION("RAM BLOCK DRIVER");
MODULE_LICENSE("GPL");

你可能感兴趣的:(mini2440)