linux设备驱动——ram_as_block

块设备的学习可以对照字符设备

字符设备:当应用程序调用open,read,write时,会调用到驱动程序的open,read,write函数,这样联系就建立起来啦

块设备:当应用程序调用open,read,write时,文件系统会转化成对扇区的读写请求,并且把请求优化后放入一个队列中,然后调用队列的处理函数用电梯调度算法从队列中取出请求进行处理。

驱动程序要做的事情就是,1.创建这个队列    2.构造这个处理函数  3.其他的参数

内核中已经把这三步的东西集中在了一个结构体中,我们只要

1.分配gendisk结构体

2.设置

3.add_disk



/* 参考:
 * drivers\block\xd.c
 * drivers\block\z2ram.c
 */

#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>

struct block_device_operations ramblock_ops={
	.owner		= THIS_MODULE,

};

#define RAMBLOCK_SIZE (1024*1024)
static struct gendisk *ramblock_disk;
static unsigned int major;
static request_queue_t *ramblock_queue;
static DEFINE_SPINLOCK(ramblock_lock);
static unsigned char *ramblock_buf;


static void do_ramblock_request(request_queue_t *q)
{
	struct request *req;
	int r_cnt;
	int w_cnt;
	while ((req = elv_next_request(q)) != NULL) {


		
		unsigned long offset = req->sector * 512;

		unsigned long len = req->current_nr_sectors * 512;
		

		if(rq_data_dir(req) == READ)	
		{
			printk("read %d",++r_cnt);
			memcpy(req->buffer, ramblock_buf+offset, len);
		}
		
		else	
		{
			
			memcpy(ramblock_buf+offset, req->buffer, len);
			printk("wirte %d",++w_cnt);
			
		}
	}
}

static int ramblock_init(void)
{
 	ramblock_disk = alloc_disk(16);

	major = register_blkdev(0,"ramblock");
	ramblock_disk->major = major;
	ramblock_disk->first_minor = 0;
    	sprintf(ramblock_disk->disk_name, "ramblock");
	ramblock_disk->fops = &ramblock_ops;
	ramblock_queue = blk_init_queue(do_ramblock_request, &ramblock_lock);
	ramblock_disk->queue = ramblock_queue;
	set_capacity(ramblock_disk, RAMBLOCK_SIZE/512);

	
	ramblock_buf = kzalloc(RAMBLOCK_SIZE, GFP_KERNEL);
	
    	add_disk(ramblock_disk);
	return 0;
}


static void ramblock_exit(void)
{
	
	put_disk(ramblock_disk);
	blk_cleanup_queue(ramblock_queue);
  	unregister_blkdev( major, "ramblock" ) ;
	del_gendisk(ramblock_disk);
	kfree(ramblock_buf);

}


module_init(ramblock_init);
module_exit(ramblock_exit);

MODULE_LICENSE("GPL");







评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值