1. 程式人生 > >Windows驅動開發之入門篇(一)

Windows驅動開發之入門篇(一)

        本文主要介紹“如何入門Windows驅動開發”和“新手需要掌握哪些知識和動手技能”,大部分是本人探索Windows驅動開發近一月時間的經驗之談。大致包括如下幾個方面:

1,開發工具、除錯工具和除錯手段;

2,Windows驅動開發框架;

3,驅動程式基本知識;

4,PCIE驅動程式;

5,學習資料

        以上內容在本文僅做簡單介紹,後續隨著本人經驗的增加,將經常更新本文,並對有些內容單獨開篇進行講解。

        參考MSDN文件:點選開啟連結

一、開發工具

1,虛擬機器和作業系統

        本人使用的win10作業系統,並安裝了“VMware Station11”,在虛擬機器中暫時只安裝了一個“win7 x64”作業系統,後續將安裝一個win10虛擬機器系統。一般情況下,我都是在虛擬機器操作進行驅動的安裝和除錯,這樣可以防止將本機的作業系統弄亂。

        後續將嘗試“通過本機winDbg來除錯虛擬機器中的驅動”。這是一個比較高階的除錯方法,點選開啟連結

2,開發工具

        本人主要使用“WDK7600”(點選開啟連結)和"VS2015+wdk10"(點選開啟連結)。我把前者安裝在“win7 X64”虛擬機器中安裝,把後者安裝在本機和實驗室電腦上。由於我使用的教材《Windows驅動開發詳解》和學習部落格都是用wdk7這個版本開發,為了環境一致,故選擇了在虛擬機器上試驗這些教材上的示例程式碼。

        關於wdk7,參考部落格:點選開啟連結

        關於“VS2015+wdk10”,需要在win10系統下,先安裝VS2015,再安裝wdk10,此外還要安裝VS2015的update。(winDbg整合到了wdk10下,路徑:C:\Program Files (x86)\Windows Kits\10\Debuggers\x64)。

注意事項:

1)VS2015預設安裝,是不安裝c++和sdk的,需要選擇自定義安裝;

2)如果已經預設安裝了,這個時候再安裝wdk10,會給出警告;

3)此時,可以選擇先用VS2015新建一個c++專案,然後會提示你安裝c++部分的模組;

4)安裝好後,就可以正常安裝wdk10了,如果wdk10安裝好後,還有編譯問題,也需要先去VS下看看是否卻c++相關模組,並按上述3安裝完整。

另一個需要注意的是,編譯報“Inf2Cat error -2: "Inf2Cat, signability test failed. "Double click to see the tool output”,

是因為inf檔案的“DriverVer”的時間不對,VS2015預設的“Inf2cat”中的時間為UTF,需要在工程屬性-》“inf2cat”選擇中,將local時間開啟。

3,除錯工具

1)debugview

        在驅動程式中,呼叫KdPrint函式(類似C語言中printf),然後通過debugview檢視列印資訊。這是最常用的一種除錯方法。

需要注意的是:首先要在“capture”選單中勾選“kernel”相關的選項,表示抓取核心的資訊。然後,需要使用“管理員身份”執行該軟體。Debugview在win10下經常報錯:


需要到“C:\Windows\System32\drivers”中找到“dbgv.sys”,刪除它,再使用“管理員身份”執行該軟體。

2)

4,除錯手段

1)驅動安裝階段,可以到“C:\Windows\System32\drivers”目錄下看相應的“sys”檔案是否到位。

2)cmd->regedit開啟登錄檔,再在“編輯”選單下“查詢”對應的裝置資訊。

3)使用KdPrint函式列印log和DebugView軟體抓取log(最常用的手段);

4)在驅動程式碼中寫log檔案(理論上可行,待探索);

5)儲存dump資訊。所謂dump資訊,就是在系統奔潰之前,作業系統會將當前的呼叫堆疊記錄成一個dump檔案。(詳細設定系統轉存dump資訊,可以參考《Windows驅動開發技術詳解》最後一章,或部落格:點選開啟連結)。設定好dump檔案後,遇到藍屏,再將dump檔案放到WinDbg中檢視,這也是一箇中常用的除錯手段。

6)IRPTrace,這個軟體可以跟蹤IRP,但是win7及後續版本都不可用,可以嘗試自己寫程式跟蹤。

7)PCITree,檢視裝置掛載;

8)WinObject,檢視驅動中的各種物件資訊。

9)WinDbg除錯虛擬機器,這是一個高階應用。配合VS2015可以檢視“記憶體”、“呼叫堆疊”、“執行緒”和“反彙編”。

注:在驅動的開發過程,需要逐漸掌握各種工具和除錯手段。

二、開發框架

        從我最近的瀏覽的資料來看,Windows驅動程式大致有三種類型:NT驅動、WDM驅動和WDF驅動。其中,NT驅動是非即插即用(Plug-in-and-Play,PNP)式的,它是一項系統服務,目前的裝置類驅動大都不是這種型別,不是我的關注點,後面將不展開介紹。WDM驅動和WDF驅動都是即插即用的驅動,後者是前者的升級版。

1,WDM框架

        WDM是早前的Windows驅動開發框架,雖然現在微軟推薦用WDF,但是,學習WDM一是能夠更對地瞭解作業系統的內部機制(WDF是對WDM更高層次的封裝),二是《Windows驅動開發技術詳解》以及網上的很多博文都是用的WDM,從學習角度出發也需要掌握一定的WDM知識。

        WDM框架的基本知識,可以參考博文:點選開啟連結。後續我也用單獨的博文來講解這方面的內容,主要包括:

1)驅動物件與裝置物件(DriverObject vs Device Object);

2)物理裝置物件(PDO)和功能裝置物件(FDO);

3)驅動的層次結構:水平層次(eg:FDO之間)和垂直層次(FDO到PDO);

4)入口函式(DriverEntry);

5)裝置擴充套件(DRIVER_EXTENSION);

6)重要的例程(routine):AddDevice

7)IRP機制(I/O Request Package):MajorFunction(MJ))和MinorFunction(MN);

2,WDF框架

        對於WDF框架,可以參考《Window7裝置驅動開發》這本書。WDF框架可以分為KMDF(Kernel Model Driver Frame)和UMDF(User Model Driver Frame),其驅動模型如下:

1)WDF物件(屬性、方法和事件);

2)即插即用和電源管理的整合;

3)整合的I/O排隊和取消(queue);

4)I/O模型。在Windows中,IRP的功能不僅僅是向驅動程式提供傳統的I/O請求(讀、寫、建立等)。它是作業系統和驅動程式、驅動程式和驅動程式之間一種基於資料包的通訊機制。

3,一個典型的KMDF驅動程式

        通過VS2015新建一個專案,選擇“KMDF”,它會產生如下檔案:


1)public.h中定義GUID和CTL_CODE,並提供給應用程式使用;

2)trace.h定義的除錯巨集和函式,暫不關注;

3)driver.h和driver.c定義了主要的框架程式碼。包括:入口函式(DriverEntry)、載入裝置的例程(KMDFDriver1EvtDeviceAdd)和清理上下文區的函式。該檔案都是框架性的程式碼,在驅動開發的過程中,可以選擇一個框架,選定框架後,一般不在該檔案中新增功能,而是放到“device.c”和“queue.c”。

4)device.h和device.c,主要處理裝置相關的功能,與裝置互動的實現放在該檔案中。主要包括裝置初始化和資源釋放;

5)queue.h和queue.c,主要處理IRP,包括KMDFDriver1EvtIoDeviceControl;