块设备 和 字符设备是并行的概念

 

可以参考内核源码:z2ram.c  

 

总结来说,

gendisk 负责注册一个块设备

gendisk->queue = z2_queue; //负责指向请求队列

blk_init_queue(do_z2_request, &z2ram_lock); //负责把请求队列和处理函数绑定起来

 

static void do_z2_request(struct request_queue *q) //负责处理请求

函数原型可以参考源码 z2ram.c  

 

=======================================================

块设备:

 

block_device_operations 结构体,是对块设备操作的集合

 

gendisk 表示一个独立的磁盘设备。同一个磁盘的各个分区共享一个主设备号,而此设备号不一样

 

struct gendisk *alloc_disk(int minors);

分配一个 gendisk 结构体

 

void add_disk(struct gendisk *disk);

添加进内核

 

void del_gendisk(struct gendisk *gp);

释放

=====================================================

 

bio request request_queue

bio 对应了上层传递给 块区的 IO 请求

bio 中包含了 bvec_iter bio_vec 描述了IO请求开始的扇区、数据方向、数据写入的页等

 

初始化请求队列

struct request_queue *blk_init_queue(request_fn_proc *, spinlock_t *);

 

清除请求队列

void blk_cleanup_queue(struct request_queue *);

 

分配请求队列

struct request_queue *blk_alloc_queue(gfp_t);

 

对于ramdisk 完全随机访问的,使用这个函数绑定请求队列和制作请求函数

void blk_queue_make_request(struct request_queue *, make_request_fn *);

 

提取请求

struct request *blk_peek_request(struct request_queue *q);

 

启动请求

blk_start_request(struct request * rq)

 

报告完成

blk_end_request_all(struct request * rq,int error,unsigned int nr_bytes)

__blk_end_request_all(struct request * rq,int error,unsigned int nr_bytes)

==================================================================

 

块设备驱动初始化

int register_blkdev(unsigned int, const char *);

块设备驱动初始化的时候通常还要完成分配、初始化请求队列、绑定请求队列和请求处理函数等工作

并且可能会分配、初始化 gendisk 给 gendisk 的major 、fops 、queue 等成员复制,最后添加 gendisk