广州模板网站,黄石建设网站公司,国家企业信息系统公示查询,哪些公司网站建设好#x1f50d; B站相应的视屏教程#xff1a; #x1f4cc; 内核#xff1a;博文视频 - 总线驱动模型实战全解析 敬请关注#xff0c;记得标为原始粉丝。 #x1f527;
在上篇中#xff0c;我们已经从理论视角分析了“虚拟总线驱动模型”在 Linux 驱动体系中的独特定位。… B站相应的视屏教程 内核博文视频 - 总线驱动模型实战全解析 敬请关注记得标为原始粉丝。 在上篇中我们已经从理论视角分析了“虚拟总线驱动模型”在 Linux 驱动体系中的独特定位。本篇我们聚焦实战深入分析一个真实的内核子系统 —— virtio_blk 虚拟块设备驱动完整讲清虚拟总线模型的运行机制、设备匹配、驱动注册、驱动结构体组织方式、probe 流程、VQvirtqueue使用方式等。我们将对照 platform_driver、i2c_driver总结异同点帮助你彻底理解这个典型的虚拟驱动模型。 1. virtio_blk 简介与实战目标
virtio_blk 是 Linux 内核中 VirtIO 虚拟设备框架的一部分模拟了一个块设备类似硬盘用于 KVM 虚拟机中的磁盘访问、容器虚拟块设备等场景。它不对应具体硬件但提供了完整的设备模型。
我们实战目标是
看懂 virtio_blk 驱动如何注册。理解它是如何匹配“虚拟设备”的。弄清 virtio 总线下设备与驱动之间的绑定机制。对比 platform_driver 和 virtio_driver理解它们的核心区别。 2. virtio 驱动注册机制总览
在 drivers/block/virtio_blk.c 中驱动最终通过以下结构注册
static struct virtio_driver virtio_blk {.feature_table features,.feature_table_size ARRAY_SIZE(features),.driver.name KBUILD_MODNAME,.id_table id_table,.probe virtblk_probe,.remove virtblk_remove,
};通过
module_virtio_driver(virtio_blk);内核完成注册最终宏会展开为 module_init() 和 module_exit() 自动注册。
这非常类似于 platform_driver 的注册过程
module_platform_driver(my_platform_driver);区别在于总线类型不同
platform_driver 注册到 platform 总线上匹配 platform_device。virtio_driver 注册到 virtio 总线上匹配 virtio_device。 3. virtio 设备和驱动匹配机制
virtio 的匹配方式不基于设备树也可以配合使用而是通过 virtio_device_id 表完成。
static const struct virtio_device_id id_table[] {{ VIRTIO_ID_BLOCK, VIRTIO_DEV_ANY_ID },{ 0 },
};VIRTIO_ID_BLOCK 是预定义的设备类型标识代表块设备。系统在虚拟机启动时比如 QEMU会注入 virtio_device并调用驱动的 probe。
匹配过程
virtio_bus.c→ virtio_register_driver()→ __register_driver()→ bus_add_driver()→ driver_match_device() // 比较 virtio_id和 platform_driver 的 of_match_table 匹配方式略有不同virtio_driver 更偏向于“协议栈类型匹配”。 4. 重点函数分析virtblk_probe()
static int virtblk_probe(struct virtio_device *vdev) {// 关键分配 virtio_blk 结构体挂载到 vdev-privvdev-priv vblk kmalloc(...);// 初始化 virtqueueinit_vq(vblk);// 分配 gendisk注册 blk-mq 调度器vblk-disk blk_mq_alloc_disk(...);// 注册设备device_add_disk(...);
}vdev-priv 与 platform_driver 中的 dev_set_drvdata() 类似保存上下文。virtqueue 是 virtio 驱动的关键数据通道。使用 blk-mq 接口建立请求调度与提交。 5. virtqueue 与传统 platform 驱动的差异
项目virtio_blkplatform_driver总线类型virtio 总线platform 总线匹配机制virtio_device_idof_match_table / id_table资源传递virtqueue virtio_config设备树 platform_resourceprobe 中行为初始化 VQ / 队列注册申请 IO 内存、中断、寄存器特点无真实硬件支持热插拔通常为静态资源 6. 真实代码结构分析virtio_blk 是怎样注册块设备的
从注册 gendisk 到 blk_mq 调度器配置
vblk-tag_set.ops virtio_mq_ops;
blk_mq_alloc_tag_set(vblk-tag_set);
vblk-disk blk_mq_alloc_disk(vblk-tag_set, vblk);重点在于
virtio_mq_ops 提供了 .queue_rq、.poll、.map_queues 等接口。驱动注册时通过 device_add_disk() 向 block subsystem 注册。
再看看 .queue_rq 实现
virtio_queue_rq() {struct virtblk_req *vbr blk_mq_rq_to_pdu(req);virtblk_add_req(...) // 将请求挂到 virtqueue
}即使没有真实硬件virtqueue 就相当于“虚拟的 DMA ring”请求通过它发送到对端。 7. 与软件工程中的“适配器”模式对比分析
设备模型是内核层次的一种“适配机制”
驱动与设备解耦device 和 driver 通过总线进行匹配。匹配后注册调用 probe相当于运行时建立适配连接。通过统一接口调用函数如 probe()、remove()、suspend()。
在 virtio 中这种适配机制更为纯粹因为
驱动和设备都是“运行时注入”的没有真实硬件不需要解析物理寄存器映射强依赖 virtqueue 来传递数据适配的是协议数据格式。
因此virtio 驱动更像是“运行时适配器 抽象接口定义”的组合非常符合软件工程中 Adapter 模式的精髓。 8. 总结与核心问答
Q1virtio_driver 和 platform_driver 最大区别是什么 A总线不同、匹配机制不同、资源获取不同。virtio 无真实硬件匹配依赖 virtio_device_id。
Q2virtqueue 相当于 platform 驱动中的什么 A类似于 platform 驱动中通过 ioremap 得到的寄存器但更加抽象是“通用的数据传输管道”。
Q3是否可以将 virtio_driver 看成虚拟平台驱动 A从使用方式看类似但从总线层来看是完全不同的子系统。 小结
本篇我们通过对 virtio_blk 的深入剖析完整讲解了虚拟总线驱动模型在 Linux 内核中的真实落地。它不是一个“子集”或“附属”模型而是一个独立存在、拥有自己总线匹配机制与通信方式的驱动模型。
下一篇Day 12我们将继续拓展——深入理解 virtio_console、virtio_net 等设备的实现方式帮助你逐步掌握虚拟设备开发的核心技能。
如有任何问题欢迎在评论区留言讨论