| 1. 前言 |
因工作上項目的需要,筆者需要做驅動相關的開發,之前並沒有接觸過相關的知識,折騰一段時間下來,功能如需實現了,也積累了一些經驗和看法,所以在此做番總結。
對於驅動開發的開發指引,微軟官方文檔網站已經提供了很詳細的教程文檔,並且在Github上提供了一系列典型的例程源碼用於開發人員參考。開發人員在具備一定的驅動概念知識后,通過參考官方例程可以很容易實現擁有特定功能的驅動應用程序。
Windows驅動程序入門: https://docs.microsoft.com/zh-cn/windows-hardware/drivers/gettingstarted/
Github: https://github.com/Microsoft/Windows-driver-samples
| 2. 驅動類型 |
驅動分為如下幾種類型:
- 設備函數驅動程序
- 設備篩選器驅動程序
- 軟件驅動程序
- 文件系統篩選器驅動程序
- 文件系統驅動程序
驅動程序不是一定需要與硬件通訊,如果需要訪問操作系統核心數據,往往應用程序沒有足夠的權限,這種情況則需要在內核模式下進行訪問。就上面5種驅動類型,筆者參考着微軟的驅動例子開發過 鼠標鍵盤設備過濾驅動 和 網絡過濾軟件驅動程序,所以對驅動開發的理解仍在淺水區,如在閱讀過程中發現有誤的地方,還請不吝指出。
采用的驅動類型關乎到代碼的實現(需不需要考慮PNP和電源管理)和驅動的安裝( NT式驅動程序以 service 的形式運行,其他驅動需要采用通用的INF文件安裝),微軟的官方文檔這樣提到:
有關軟件驅動程序,你的兩個選項為 KMDF 和內核模式 Windows NT 驅動程序模型。 使用 KMDF 和內核模式 Windows NT 模型,你可以編寫驅動程序,而無需考慮即插即用 (PnP) 和電源管理。 你可以改為專心於驅動程序的首要任務上。 使用 KMDF,你不必考慮 PnP 和電源,因為框架會為你處理 PnP 和電源。 使用內核模式 Windows NT 模型,你不必考慮 PnP 和電源,因為內核模式服務在與 PnP 和電源管理完全無關的環境中運行。
| 3. 開發環境 |
Visual Studio + WDK(Windows Driver Kit)
其中WDK需要自己手動下載安裝
筆者是在Windows平台上開發,使用的開發環境為 Visual Studio 2013 + WDK 8.1
| 4. 實現方式 |
WDM vs WDF
對於剛接觸驅動開發的新手來說,筆者不建議采用WDM(Windows 驅動程序模型)進行開發。目前在網上能找到的關於驅動開發的中文書籍基本上都是圍繞WDM模式進行講述的,而關於WDF(Windows 驅動框架)開發的書籍寥寥無幾,《竹林溪徑——深入淺出Window驅動開發》和《Developing Drivers with the Windows Driver Foundation》算是兩本講述基於WDF開發驅動的書籍,兩者都能在網上找到電子書資源。
基於WDF的驅動開發
WDF的開發需要遵循一定的規則,開發實現時需要考慮較多的細節,由於篇幅有限,筆者憑着自己的經驗暫且稍做列舉,后續將寫一篇針對WDF驅動開發的文章。
- PNP和電源管理(WDF已經幫忙封裝了大部分的接口);
- 各種對象:驅動對象,設備對象,WDF對象,文件對象,隊列對象;
- 驅動上下文:有時稱為設備擴展,用於存儲特定設備對象的相關信息的數據結構;
- 對象的釋放:需要考慮不同性質對象釋放的時機;
- 中斷請求級別:處理不當易導致藍屏;
- 分頁與非分頁內存;
- 同步鎖:回調同步鎖、框架等待鎖、自旋鎖、中斷鎖等;
- 日志跟蹤記錄: 調試的必備,可以采用
WPP(Windows軟件追蹤預處理器)或簡單的DebugPrint輸出 - 與應用程序的通訊:控制代碼、IRQ,請求隊列
| 5. 驅動安裝 |
測試環境下安裝驅動前
開發的驅動程序沒有進行簽名或者采用測試簽名,則需要在設備上開啟測試模式,具體操作為:打開控制台,輸入:
bcdedit /set testsigning on
回車,會提示:操作成功完成。 然后重啟設備,開機后會在電腦桌面右下方顯示有“測試模式”字樣內容的水印。
如果要關閉測試模式,則需在控制台輸入:
bcdedit /set testsigning off
回車,同樣會提示:操作成功完成。 重啟設備后則會發現桌面右下角的水印消失。
以服務的形式運行
NT式的驅動程序允許以 service 的形式運行, 服務安裝的例程可以參考 WDF Sample 中的 Eventdrv 工程,或者參考我寫的關於進程網絡監控的驅動例程的開源代碼
使用INF文件安裝
設備相關的驅動安裝可以選擇INF進行安裝,INF安裝文件的編寫建議從 WDF Sample 中找到合適的INF文件進行修改,如果你想了解INF的語法,可以參考這里
- 通過設備管理器手工安裝
打開控制台,輸入 devmgmt 回車,這是打開設備管理器的其中一種方式,其他方式比如右鍵系統菜單欄圖標均可以打開任務管理器,只是使用命令行的方式比較少見,這里特意記錄一下。找到感興趣的 設備節點,右鍵 屬性(或更新驅動程序軟件),切換到 驅動程序,可以進行感興趣的操作。這里所看到所提供的選項,后續等你熟悉了驅動安裝的接口后,你會發現都有對應的接口對應每個功能選項。
- 通過程序實現自動安裝
可以參考 WDF Sample 中的Driver Install Frameworks API (DIFxAPI) Sample 和Device Console (DevCon) Tool 兩個工程,分別提供了不同調用接口的驅動安裝方式,Device Console (DevCon) Tool 生成的devcon.exe 是一個功能強大的工具,不僅可用於驅動(包)的安裝和卸載,還可以獲取設備的硬件ID,描述符以及設備所安裝的驅動列表等信息,開發人員可以從中一窺究竟。
在驅動的安裝過程中,系統會自動記錄安裝的日志,在INF目錄(路徑一般在 C:\Windows\inf下)下可以找到兩個日志文件 setupapi.app.log 和 Setupapi.dev.log ,查看這兩個日志文件有利於理解驅動安裝的執行過程,同時也有利於排查驅動安裝過程中出現的異常。
驅動的安裝涉及到驅動文件的校驗(保證驅動文件的完整性和合法性),驅動的優先級計算(選擇最優的驅動去匹配當前識別到的新的設備),驅動的放置目錄(Driver Store)等內容。開發人員熟悉驅動安裝邏輯有利於驅動的開發,感興趣可以通過此處進行了解。
| 6. 驅動簽名 |
測試環境
通過VS集成開發環境創建 Driver 解決方案后會生成兩個項目,右鍵屬性打開 XXX Package,左側選中 Driver Signing ,在右側欄 Sign Mode 選擇 Test Sign,在 Test Certificate選擇 <Create test certificate...>,則在編譯時會自動生成測試簽名證書。
生產環境
從Win10開始,驅動文件包不僅需要進行擴展驗證 (EV) 代碼簽名,還需要提交到硬件開發中心儀表盤,具體操作指南可以參考此處,你可以在該文檔上找到驅動簽名所需的任何內容。
