块设备驱动(内存模拟硬盘)

时间:2021-10-13 19:43:27

搜索“blk_init_queut()”参考“drivers\block\xd.c”和“drivers\block\z2ram.c”两个文件。

看一个驱动程序从“入口函数”开始看。

处理函数>>放到队列>>放到gendisk

其他属性()>>gengdisk

最终效果,文件系统通过处理函数来实现相应的功能.

块设备驱动框架

块设备驱动(内存模拟硬盘)

块设备驱动(内存模拟硬盘)

之前分析把“文件读写”转成“扇区读写”,对“扇区的读写”会放入个队列里面:
把“buffer_head”构造为“bio”,把“bio”放入到队列里面,调用队列里面的“q->make_request_fn”函数,这个“make_request_fn”构造请求的函数有默认的函数
“__make_request”。
当我们初始化队列时,给我们提供了一个默认构造请求的函数“__make_request”。当它把这个“请求”放入到“队列”之后,以后会用这个队列里的“q->request_fn()”来处理。这个“request_fn()”就等于“blk_init_queue_node()”函数传进来的参数“形参1:request_fn_proc *rfn”。这个形参 1 会赋给“request_fn”,最后就是我们要定义的一个处理请求的函数。request_queue_t *blk_init_queue(request_fn_proc *rfn, spinlock_t *lock)-->blk_init_queue_node(rfn, lock, -1);-->blk_queue_make_request(q, __make_request);提供了默认构造请求的函数。对于我们这里这个把内存模拟成硬盘的驱动来说,最终会是我们这里定义的
do_rambloc_request”来处理请求。

*****************************************************************************************

块设备驱动程序编写步骤

A. 使用alloc_disk分配gendisk结构体
B. 设置gendisk
B.1 blk_init_queue(分配/设置)队列request_queue_t
B.2 设置gendisk其他信息
// 它提供属性: 如容量

C. 注册: add_disk

**********************************************************************************************

具体流程

设置其他属性

0alloc_disk():

1主设备号

2第一个次设备号是什么 和 块设备的名字。

3,fops :操作函数。即使是空的操作函数,这个 fops 也要提供。(经过实验,即使这个函数里什么也没有(如没有".ioctl"和".getgeo"),也要提供这个结构体。不然会出错。)

4容量:设置容量时,是以扇区为单位

5设置队列:

6注册:add_disk().

7设置处理函数()

{1. 设置数据传输的3要素 : 目的/源 + 长度

2. 用电梯调度算法处理读写请求
3. 如果有请求 : 先判断是读还是写?,然后在调用

memcopy进行数据的拷贝

}

*************************************************************************************************

主要围绕gendisk结构题展开,给gendisk结构体分配空间,分配队列,队列也是gendisk其中的一项

在队列初始化的时候声明了队列处理函数。

//入口函数
static int ramblock_init(void)
{
//1,分配一个 gendisk 结构体
//2,设置
//2.1,分配/设置队列:提供读写能力
//2.2,设置其他属性:比如容量等等.
//3,注册
}

关键词:请求队列request_queue;gendisk结构体

注意   : 对于一个块设备,次设备号为“0”时,表示整个磁盘。如“/dev/sda”。次设备号“1,

2,、”表示是磁盘的第几个 主 分区。次设备号从 5 开始是“扩展分区”

*************************************************************************************************

static struct gendisk *ramblock_disk;

static struct request_queue *ramblock_queue;

/*获得主设备号*/

ramblock_disk = alloc_disk(16) //次设备号个数/分区个数+1

ramblock_queue = blk_init_queue(do_ramblock_request, &ramdisk_lock)

ramblock_disk->queue = ramblock_queue;