块设备之设备驱动层

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了块设备之设备驱动层相关的知识,希望对你有一定的参考价值。

  块设备是通过generic_make_request提交请求给I/O调度层,然后驱动层通过调用blk_init_queue来准备请求,这节来看看怎么样写一个块设备驱动程序。一个块设备的是由一个gendisk结构体来描述,每一个gendisk可以支持多个分区,内核对于块设备的访问,都是基于这个结构体展开

struct gendisk {
    int major;                                           //主设备号
    int first_minor;                                  //第一个次设备号
    int minors;                                             //次设备个数,每个分区都需要一个次设备号
                                        
    char disk_name[DISK_NAME_LEN];                           //块设备名字,可以通过/proc/partions获取
    char *(*devnode)(struct gendisk *gd, umode_t *mode);            
unsigned
int events;                           //supported events unsigned int async_events;                          // async events, subset of all struct disk_part_tbl __rcu *part_tbl; struct hd_struct part0;                             //分区表 const struct block_device_operations *fops;                 //块设备操作集 struct request_queue *queue;                          //请求队列 void *private_data;                               //私有成员变量 int flags; struct device *driverfs_dev; // FIXME: remove struct kobject *slave_dir; struct timer_rand_state *random; atomic_t sync_io; /* RAID */ struct disk_events *ev; #ifdef CONFIG_BLK_DEV_INTEGRITY struct blk_integrity *integrity;       #endif int node_id; }

其实驱动就是构造这个结构体,并且提供一个驱动程序的访问队列即可。由通用层,如果驱动程序没有提供处理等待队列的处理函数,就会使用内核提供的默认的等待队列的处理函数,那么就分为两种情况,来看看怎么写一个块设备的驱动程序。

1. 对于没有提供等待队列的处理函数情况

  1. 分配一个请求队列:blk_alloc_queue

  2. 分配一个 gendisk 结构:alloc_disk

  3. 设置 gendisk 主要结构成员:置主次设备号,设置操作函数集,设置容量等

  4. 向内核注册块设备驱动:add_disk

2. 对于提供等待队列的处理函数的情况

  1. 分配一个请求队列:blk_alloc_queue

  2. 为请求队列绑定 make_request_fn 方法:blk_queue_make_request

  3. 分配一个 gendisk 结构:alloc_disk

  4. 设置 gendisk 主要结构成员:置主次设备号,设置操作函数集,设置容量等

  5. 向内核注册块设备驱动:add_disk

 

以上是关于块设备之设备驱动层的主要内容,如果未能解决你的问题,请参考以下文章

块设备驱动之I/O调度层之调度器

《Linux内核设计与实现》读书笔记(十四)- 块I/O层

块设备驱动框架

块设备驱动框架详解

Linux块设备加密之dm-crypt分析

linux驱动开发之块设备学习笔记