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

本文档详细记录了使用Linux内核2.6.32.2版本,通过RAM缓存来模拟块设备驱动的过程。代码涵盖了gendisk、request_queue的初始化,以及读写操作的处理。此外,还提供了获取磁盘几何信息的函数,以供分区工具使用。
摘要由CSDN通过智能技术生成
#include <linux/module.h>
#include <linux/errno.h>
#include <linux/interrupt.h>
#include <linux/mm.h>
#include <linux/fs.h>
#include <linux/kernel.h>
#include <linux/timer.h>
#include <linux/genhd.h>
#include <linux/hdreg.h>
#include <linux/ioport.h>
#include <linux/init.h>
#include <linux/wait.h>
#include <linux/blkdev.h>
#include <linux/blkpg.h>
#include <linux/delay.h>
#include <linux/io.h>

#include <asm/system.h>
#include <asm/uaccess.h>
#include <asm/dma.h>

#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");

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值