块设备驱动程序

转载块设备驱动程序详解

实现原理:
1. 把"读写"放入队列,先不执行;
2. 优化后再执行(优化/调顺序/合并)。

块设备驱动程序实现:

  1. 分配gendisk: alloc_disk
  2. 设置
    2.1 分配/设置队列: request_queue// 它提供读写能力
    blk_init_queue
    2.2 设置gendisk其他信息 // 它提供属性: 比如容量
  3. 注册: add_disk

使用内存(SDRAM)来构造一个块设备:
源码

#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)//1M

static struct gendisk *ramblock_disk;
static struct request_queue *ramblock_queue;
static int major;
static u8 *ramblock_buf;

static DEFINE_SPINLOCK(ramblock_lock);//自旋锁
/*虚拟的*/
static int ramblock_getgeo(struct block_device *bdev, struct hd_geometry *geo)
{	/*容量=面x环x扇区x512*/
	geo->heads =2;//盘面(柱头)
	geo->cylinders =32;//环(柱面)
	geo->sectors = RAMBLOCK_SIZE/2/32/512;//扇区
	
	return 0;
}

static struct block_device_operations ramblock_fops = {
	.owner	= THIS_MODULE,
	.getgeo = ramblock_getgeo,//获得几何属性
};
	
/*队列处理函数*/
static void do_ramblock_request(struct request_queue * q )
{
	static int w_cnt=0;
  static int r_cnt=0;
	struct request *req;

	/*获得列队中第一个未完成的请求,没有请求处理时,返回NULL*/
	req=blk_fetch_request(q);
	while(req!=NULL)//获得列队中第一个未完成的请求
	{	
		/*数据传输三要素:源,目的,长度*/
		u32 offset=blk_rq_pos(req) << 9;//源/目的:下一个要提交的扇区*512
		u32 len=blk_rq_cur_bytes(req);//长度:当前处理的扇区个数*512

		if(rq_data_dir(req)==READ)//读
		{		
       printk("do_ramblock_request read %d\n",++r_cnt);
	   				/*从源读到buff*/	
			memcpy(req->buffer,ramblock_buf+offset,len);
		}
		else//rq_data_dir(req)==WRITE
		{		
       printk("do_ramblock_request write %d\n",++w_cnt);
	   				/*从buff写到目的*/
			memcpy(ramblock_buf+offset,req->buffer,len);
		}

			/*结束请求,获取下一个请求*/
		if (!__blk_end_request_cur(req, 0))/* 1 = success */
		{
			req = blk_fetch_request(q);
		}
		else
		{
			printk("__blk_end_request_cur error!\n");
		}
	}
}

static int ramblock_init(void)
{	
	 /*分配一个gendisk结构体-》设置-》注册*/
	ramblock_disk=alloc_disk(16);//次设备号个数:分区个数+1

	 /*分配/设置列队:提供读写能力*/
	ramblock_queue=blk_init_queue(do_ramblock_request, &ramblock_lock);
	 ramblock_disk->queue = ramblock_queue;

	major=register_blkdev(0,"ramblock");//注册 得到主设备号
	
	/*设置其他属性*/
	ramblock_disk->major = major;
	ramblock_disk->first_minor = 0;//第一个次设备号
	sprintf(ramblock_disk->disk_name, "ramblock");
	ramblock_disk->fops = &ramblock_fops;
	/*设置容量    				  磁盘扇区的个数   	扇区(512B)为单位*/
	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)
{  
	unregister_blkdev(major,"ramblock");
	del_gendisk(ramblock_disk);
	put_disk(ramblock_disk);
	blk_cleanup_queue(ramblock_queue);
	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、付费专栏及课程。

余额充值