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


可以参考内核源码: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