驅動開發硬核特訓 · Day 11(下篇):從 virtio_blk 看虛擬總線驅動模型的真實落地

🔍

B站相應的視屏教程
📌 內核:博文+視頻 - 總線驅動模型實戰全解析
敬請關注,記得標為原始粉絲。


🔧

在上篇中,我們已經從理論視角分析了“虛擬總線驅動模型”在 Linux 驅動體系中的獨特定位。本篇我們聚焦實戰:深入分析一個真實的內核子系統 —— virtio_blk 虛擬塊設備驅動,完整講清虛擬總線模型的運行機制、設備匹配、驅動注冊、驅動結構體組織方式、probe 流程、VQ(virtqueue)使用方式等。我們將對照 platform_driver、i2c_driver,總結異同點,幫助你徹底理解這個典型的虛擬驅動模型。


1. virtio_blk 簡介與實戰目標

virtio_blk 是 Linux 內核中 VirtIO 虛擬設備框架的一部分,模擬了一個塊設備(類似硬盤),用于 KVM 虛擬機中的磁盤訪問、容器虛擬塊設備等場景。它不對應具體硬件,但提供了完整的設備模型。

我們實戰目標是:

  • 看懂 virtio_blk 驅動如何注冊。
  • 理解它是如何匹配“虛擬設備”的。
  • 弄清 virtio 總線下設備與驅動之間的綁定機制。
  • 對比 platform_drivervirtio_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_driverof_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_resource
probe 中行為初始化 VQ / 隊列注冊申請 IO 內存、中斷、寄存器
特點無真實硬件,支持熱插拔通常為靜態資源

6. 真實代碼結構分析:virtio_blk 是怎樣注冊塊設備的?

從注冊 gendiskblk_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. 總結與核心問答

Q1:virtio_driver 和 platform_driver 最大區別是什么?
A:總線不同、匹配機制不同、資源獲取不同。virtio 無真實硬件,匹配依賴 virtio_device_id。

Q2:virtqueue 相當于 platform 驅動中的什么?
A:類似于 platform 驅動中通過 ioremap 得到的寄存器,但更加抽象,是“通用的數據傳輸管道”。

Q3:是否可以將 virtio_driver 看成虛擬平臺驅動?
A:從使用方式看類似,但從總線層來看,是完全不同的子系統。


小結

本篇我們通過對 virtio_blk 的深入剖析,完整講解了虛擬總線驅動模型在 Linux 內核中的真實落地。它不是一個“子集”或“附屬”模型,而是一個獨立存在、擁有自己總線匹配機制與通信方式的驅動模型。

下一篇(Day 12),我們將繼續拓展——深入理解 virtio_consolevirtio_net 等設備的實現方式,幫助你逐步掌握虛擬設備開發的核心技能。

如有任何問題,歡迎在評論區留言討論!

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/901380.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/901380.shtml
英文地址,請注明出處:http://en.pswp.cn/news/901380.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

音視頻轉換器 AV 接口靜電保護方案

方案簡介 音視頻轉換器是將音視頻(AV)信號轉換成其他格式或信號類型的設備或軟件。 它能夠實現大多數視頻、音頻以及圖像格式之間的轉換,包括但不限于 RMVB、AVI、 MP4、MOV 等常見格式,同時也支持將不同采樣率、位深度、聲道數…

AI agents系列之全從零開始構建

在我們上一篇博客文章中,我們全面介紹了智能代理,討論了它們的特性、組成部分、演變過程、面臨的挑戰以及未來的可能性。 這篇文章,咱們就來聊聊怎么用 Python 從零開始構建一個智能代理。這個智能代理能夠根據用戶輸入做出決策,…

【Python爬蟲】詳細工作流程以及組成部分

目錄 一、Python爬蟲的詳細工作流程 確定起始網頁 發送 HTTP 請求 解析 HTML 處理數據 跟蹤鏈接 遞歸抓取 存儲數據 二、Python爬蟲的組成部分 請求模塊 解析模塊 數據處理模塊 存儲模塊 調度模塊 反爬蟲處理模塊 一、Python爬蟲的詳細工作流程 在進行網絡爬蟲工…

Kotlin 集合過濾全指南:all、any、filter 及高級用法

在 Kotlin 中,集合過濾是數據處理的核心操作之一。無論是簡單的條件篩選,還是復雜的多條件組合,Kotlin 都提供了豐富的 API。本文將詳細介紹 filter、all、any、none 等操作符的用法,并展示如何在實際開發中靈活運用它們。 1. 基礎…

爬蟲:一文掌握 curl-cffi 的詳細使用(支持 TLS/JA3 指紋仿真的 cURL 庫)

更多內容請見: 爬蟲和逆向教程-專欄介紹和目錄 文章目錄 一、curl-cffi 概述1.1 curl-cffi介紹1.2 主要特性1.3 適用場景1.4 使用 curl-cffi 的注意事項1.5 與 requests 和 pycurl 對比1.6 curl-cffi 的安裝二、基本使用2.1 同步請求2.2 異步請求三、高級功能3.1 模擬瀏覽器指…

AllData數據中臺升級發布 | 支持K8S數據平臺2.0版本

🔥🔥 AllData大數據產品是可定義數據中臺,以數據平臺為底座,以數據中臺為橋梁,以機器學習平臺為中層框架,以大模型應用為上游產品,提供全鏈路數字化解決方案。 ?杭州奧零數據科技官網&#xf…

dnf install openssl失敗的原因和解決辦法

網上有很多編譯OpenSSL源碼(3.x版本)為RPM包的文章,這些文章在安裝RPM包時都是執行rpm -ivh openssl-xxx.rpm --nodeps --force 這個命令能在缺少依賴包的情況下能強行執行安裝 其實根據Centos的文檔,安裝RPM包一般是執行yum install或dnf install。后者…

從入門到進階:React 圖片輪播 Carousel 的奇妙世界!

全文目錄: 開篇語🖐 前言? 目錄🎯 什么是圖片輪播組件?🔨 初識 React 中的輪播實現示例代碼分析 📦 基于第三方庫快速實現輪播示例:用 react-slick優勢局限性 🛠? 自己動手實現一個…

2025第十六屆藍橋杯PythonB組部分題解

一、攻擊次數 題目描述 小藍操控三個英雄攻擊敵人,敵人初始血量2025: 第一個英雄每回合固定攻擊5點第二個英雄奇數回合攻擊15點,偶數回合攻擊2點第三個英雄根據回合數除以3的余數攻擊:余1攻2點,余2攻10點&#xff0…

新手寶塔部署thinkphp一步到位

目錄 一、下載對應配置 二、加載數據庫 三、添加FTP? 四、上傳項目到寶塔? 五、添加站點? 六、配置偽靜態 七、其他配置 開啟監控 八、常見錯誤 一、打開寶塔頁面,下載對應配置。 二、加載數據庫 從本地導入數據庫文件 三、添加FTP 四、上傳項目到寶塔…

2025年,HarmonyOS認證學習及考試

HarmonyOS應用開發者認證考試 基礎認證 通過系統化的課程學習,熟練掌握 DevEco Studio,ArkTS,ArkUI,預覽器,模擬器,SDK 等 HarmonyOS 應用開發的關鍵概念,具備基礎的應用開發能力。 高級認證…

3-1 Git分布式版本控制特性探討

Git 的分布式版本控制特性是其核心優勢之一,它使 Git 在版本管理方面具有高度的靈活性、可靠性和高效性。以下從多個方面來理解這一特性: 分布式存儲 在 Git 中,每個開發者的本地機器上都擁有完整的版本庫,包含了項目的所有歷史記錄和元數據。這與集中式版本控制系統(如…

flutter 桌面應用之右鍵菜單

?在 Flutter 桌面應用開發中,context_menu 和 contextual_menu 是兩款常用的右鍵菜單插件,各有特色。以下是對它們的對比分析:? context_menu 集成方式:?通過 ContextMenuArea 組件包裹目標組件,定義菜單項。?掘金…

Tips:用proxy解決前后端分離項目中的跨域問題

在前后端分離項目中,"跨域問題"是瀏覽器基于同源策略(Same-Origin Policy)對跨域請求的安全限制。當你的前端(如運行在 http://localhost:3000 )和后端(如運行在 http://localhost:8080 &#…

基于 Qt 的圖片處理工具開發(一):拖拽加載與基礎圖像處理功能實現

一、引言 在桌面應用開發中,圖片處理工具的核心挑戰在于用戶交互的流暢性和異常處理的健壯性。本文以 Qt為框架,深度解析如何實現一個支持拖拽加載、亮度調節、角度旋轉的圖片處理工具。通過嚴謹的文件格式校驗、分層的架構設計和用戶友好的交互邏輯&am…

設計模式:依賴倒轉原則 - 依賴抽象,解耦具體實現

一、為什么用依賴倒轉原則? 在軟件開發中,類與類之間的依賴關系是架構設計中的關鍵。如果依賴過于緊密,系統的擴展性和維護性將受到限制。為了應對這一挑戰,依賴倒轉原則(Dependency Inversion Principle,…

vue+d3js+fastapi實現天氣柱狀圖折線圖餅圖

說明: vued3jsfastapi實現天氣柱狀圖折線圖餅圖 效果圖: step0:postman 1. 生成天氣數據(POST請求):URL: http://localhost:8000/generate-data/?year2024&month3&seed42 方法: POST Headers:Content-Type:…

UE5,LogPackageName黃字警報處理方法

比如這個場景,淘寶搜索,ue5 T臺,轉為ue5.2后,選擇物體,使勁冒錯。 LogPackageName: Warning: DoesPackageExist called on PackageName that will always return false. Reason: 輸入“”為空。 2. 風險很大的刪除法&…

量子代理簽名:量子時代的數字授權革命

1. 量子代理簽名的定義與核心原理 量子代理簽名(Quantum Proxy Signature, QPS)是經典代理簽名在量子信息領域的延伸,允許原始簽名者(Original Signer)授權給代理簽名者(Proxy Signer)代為簽署文…

【ESP32-C6】Base on esptool commands to enable Flash Encryption and Secure Boot

Please refer to Security Guides Security Overview Flash Encryption Secure Boot v2 Security Features Enablement Workflows Vulnerabilities You can base on “esp-idf/examples/security/flash_encryption” example for testing. Partition Table setting&#…