2014-04-19 块设备驱动程序(模拟内存)__

实验描述:

块设备驱动程序(模拟内存)


内核版本:

Linux 2.6.38


开发板: 

Mini 6410


程序实现:

#include <linux/init.h>  
#include <linux/module.h>  
#include <linux/device.h>
#include <linux/cdev.h> 
#include <linux/fs.h> 
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/clk.h>
#include <asm/irq.h>
#include <asm/uaccess.h>
#include <linux/time.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/err.h>
#include <linux/blkdev.h>
#include <linux/blkpg.h>
#include <linux/genhd.h>
#include <linux/hdreg.h>

#define PRINTK printk
//#define PRINTK(...) 

#define DEVICE_NAME "6410_ram_block"
#define RAMBLOCK_SIZE (1024*1024)

static int major;
static DEFINE_SPINLOCK(s3c6410_ram_lock);
static struct gendisk *s3c6410_ram_gendisk;
static struct request_queue *ramblock_queue;
static unsigned char *ramblock_buf;

static void do_ram_blk_request(struct request_queue *queue)
{
	struct request *req;
	static int r_cnt = 0;
	static int w_cnt = 0;
	while((req = blk_fetch_request(queue))){
		int err = 0;
		unsigned long offset = blk_rq_pos(req) << 9;	//address
		unsigned long len = blk_rq_cur_bytes(req);//len

		if (rq_data_dir(req) == READ)
		{	
			printk("do_ramblock_request read %d\n", ++r_cnt);
			memcpy(req->buffer, ramblock_buf+offset, len);
		}
		else
		{	
			printk("do_ramblock_request write %d\n", ++w_cnt);
			memcpy(ramblock_buf+offset, req->buffer, len);
		}	
		
		if (!__blk_end_request_cur(req, err))
			req = blk_fetch_request(queue);
	}
	PRINTK(KERN_ALERT"do_ram_blk_request!\n");
}

static int ram_blk_getgeo(struct block_device *block_device, struct hd_geometry *hd_geometry)
{
	hd_geometry->heads     = 2;	//fdisk
	hd_geometry->cylinders = 32;
	hd_geometry->sectors   = RAMBLOCK_SIZE/2/32/512;
	PRINTK(KERN_ALERT"ram_blk_getgeo!\n");
	return 0;
}

static const struct block_device_operations s3c6410_ram_fops =
{
	.owner = THIS_MODULE,
	.getgeo = ram_blk_getgeo,
};

static int blk_driver_init(void)  
{   
	int ret;
	ret = -EBUSY;
   	if ((major = register_blkdev(0, DEVICE_NAME)) < 0)
		goto out_err;

	ret = -ENOMEM;
	s3c6410_ram_gendisk = alloc_disk(16);//this will alloc minors
	if (!s3c6410_ram_gendisk)
		goto out_err;

	ramblock_queue = blk_init_queue(do_ram_blk_request, &s3c6410_ram_lock);
	  if (!ramblock_queue)
		goto out_err;

	s3c6410_ram_gendisk->major = major;
	s3c6410_ram_gendisk->first_minor = 2;
	s3c6410_ram_gendisk->fops = &s3c6410_ram_fops;
	s3c6410_ram_gendisk->queue = ramblock_queue;
	sprintf(s3c6410_ram_gendisk->disk_name, "my_blk_ram");

	ret = -ENOMEM;  
	ramblock_buf = kzalloc(RAMBLOCK_SIZE, GFP_KERNEL);	//this will do handware settings, as we only do some request mem
	if(!ramblock_buf){  
     		goto out_err;  
   	}

	add_disk(s3c6410_ram_gendisk);
	
	PRINTK(KERN_ALERT"init!\n");
	return 0;
out_err:
	if(major)
		unregister_blkdev(major, DEVICE_NAME);
	
	if (s3c6410_ram_gendisk)
		put_disk(s3c6410_ram_gendisk);

	if(ramblock_buf)
		kfree(ramblock_buf);

	if(ramblock_queue)
		blk_cleanup_queue(ramblock_queue);
	return ret;
}  

static int blk_driver_exit(void)  
{   
	if(major)
		unregister_blkdev(major, DEVICE_NAME);
	
	if (s3c6410_ram_gendisk){
		del_gendisk(s3c6410_ram_gendisk);
		put_disk(s3c6410_ram_gendisk);
	}
		
	if(ramblock_buf)
		kfree(ramblock_buf);
	
	if(ramblock_queue)
		blk_cleanup_queue(ramblock_queue);

	PRINTK(KERN_ALERT"exit!\n");
	return 0;  
}  
 
module_init(blk_driver_init);  
module_exit(blk_driver_exit);
MODULE_LICENSE("GPL");  
MODULE_DESCRIPTION("S3C6410 block device driver");
MODULE_AUTHOR("Books, <uppour@sina.cn>");


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值