块设备 和 字符设备是并行的概念
可以参考内核源码: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
本文同步分享在 博客“连志安的博客”(CSDN)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。