块设备驱动2:一个实际的设备驱动代码分析

由于真实的块设备如nand,sd卡等读写访问操作比较麻烦,分析起来难度也较大,所以这里我们使用系统中的内存虚拟出一个硬件设备,然后对这个使用块设备驱动对这份内存进行读写。

驱动的详细分析在前面的博客中已经分析过,这里只对块设备相关的,特有的部分也就是驱动入口代码进行一个分析,对驱动中都有的部分就不做解释了。

 

驱动的入口:

module_init(my_ramblock_init);
static int my_ramblock_init(void)
{
	major = register_blkdev(0, "my_ramblock");
	if (major < 0)
	{
		printk("fail to regiser my_ramblock\n");
		return -EBUSY;
	}
	
	// 实例化
	my_ramblock_disk = alloc_disk(1);		//次设备个数 ,分区个数 +1
	
	//分配设置请求队列,提供读写能力
	my_ramblock_queue = blk_init_queue(do_my_ramblock_request, &my_ramblock_lock);
	//设置硬盘属性 
	my_ramblock_disk->major = major;
	my_ramblock_disk->first_minor = 0;
	my_ramblock_disk->fops = &my_ramblock_fops;
	sprintf(my_ramblock_disk->disk_name, "my_ramblcok");		// /dev/name
	my_ramblock_disk->queue = my_ramblock_queue;
	set_capacity(my_ramblock_disk, RAMBLOCK_SIZE / 512);
	/* 硬件相关操作 */
	my_ramblock_buf = kzalloc(RAMBLOCK_SIZE, GFP_KERNEL);
	add_disk(my_ramblock_disk);				// 向驱动框架注册一个disk或者一个partation的接口
	
	return 0;
}

1.驱动的注册:

0表示系统动态的分配主设备号,另一个参数为设备名。

major = register_blkdev(0, "my_ramblock");

 

2.实例化一个结构体指针,将内存分成alloc_disk(1)参数+1个分区;

my_ramblock_disk = alloc_disk(1);		//次设备个数 ,分区个数 +1
static struct gendisk *my_ramblock_disk;		// 磁盘设备的结构体

而这个结构体是磁盘设备的独有一个设备结构体。

 

3.实例化请求队列:

my_ramblock_queue = blk_init_queue(do_my_ramblock_request, &my_ramblock_lock);

用来实例化产生一个等待队列,也就是my_ramblock_queue

static struct request_queue *my_ramblock_queue;	// 等待队列

将来应用层对本块设备所做的所有的读写操作,都会生成一个request然后被加到这个等待队列。

blk_init_queue函数接收的2个参数,第一个是等待队列的回调函数,这个函数是驱动提供的用来处理等待队列中的request的函数(IO调度层通过电梯算法从等待队列中取出一个request,就会调用这个回调函数来处理这个请求),第二个参数是一个自旋锁,这个自旋锁是要求我们驱动提供给等待队列去使用的。

 

4.进行设备结构体变量的填充,设置硬件的属性:

填充、设置主设备号;

my_ramblock_disk->major = major;

填充、设置次设备号从0开始设置:

my_ramblock_disk->first_minor = 0;

填充、设置块设备的block_device_operations结构体:

my_ramblock_disk->fops = &my_ramblock_fops;

填充、设置等待队列:

my_ramblock_disk->queue = my_ramblock_queue;

设置块设备的大小:

set_capacity(my_ramblock_disk, RAMBLOCK_SIZE / 512);

这里的大小以扇区为单位,第一个参数是前面填充设置的设备结构体变量。

 

5.给虚拟的设备进行内存的分配:(实际驱动中无此步骤)

my_ramblock_buf = kzalloc(RAMBLOCK_SIZE, GFP_KERNEL);

在前面只是定义了一个内存指针,并未进行实例化:

static unsigned char *my_ramblock_buf;

在这里使用堆内存,动态的分配内存 ,分配的大小就是RAMBLOCK_SIZE=1M

#define RAMBLOCK_SIZE (1024*1024)

 

6.调用接口注册一个块设备文件:

add_disk(my_ramblock_disk);

 

代码来源于ldd3书中,特别鸣谢!

End。。。。。。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值