本章為您提供設備驅動程序的一般介紹,並帶您瀏覽設備驅動程序的結構元素。
⚠注意
使用WinDriver時,您不需要熟悉驅動程序開發的內部工作。如中所述
1.1.導言,WinDriver使您能夠與您的硬件進行通信,並從用户模式為您的設備開發驅動程序,僅使用WinDriver的簡單api,而無需任何驅動程序或內核開發知識。
2.1.設備驅動程序概述
設備驅動程序是在操作系統和特定硬件設備 (如終端、磁盤、磁帶驅動器、視頻卡和網絡介質) 之間提供接口的軟件部分。設備驅動程序使設備進入和退出服務,在設備中設置硬件參數,將數據從內核傳輸到設備,從設備接收數據並將其傳遞迴內核,並處理設備錯誤。
驅動程序就像設備和使用該設備的程序之間的轉換器。每個設備都有自己的專用命令集,只有其驅動程序知道。相反,大多數程序通過使用通用命令來訪問設備。因此,驅動程序接受來自程序的通用命令,然後將它們轉換為設備的專用命令。
2.2.根據功能對驅動程序進行分類
有許多驅動程序類型,其功能不同。本小節簡要介紹了三種最常見的驅動程序類型。
2.2.1.單片驅動器
單片驅動器是體現支持硬件設備所需的所有功能的設備驅動器。單片驅動器由一個或多個用户應用訪問,並且直接驅動硬件設備。驅動程序通過I/O控制命令 (ioctl) 與應用程序通信,並通過調用不同的WDK、ETK、DDI/DKI函數來驅動硬件。
包括所有Windows平台和所有Unix平台在內的所有操作系統都支持單片驅動程序。
2.2.2.分層驅動程序
分層驅動程序是設備驅動程序,它們是一起處理I/O請求的設備驅動程序堆棧的一部分。分層驅動程序的示例是攔截對盤的調用並加密/解密傳送到盤/從盤傳送的所有數據的驅動程序。在該示例中,驅動程序將被掛鈎到現有驅動程序的頂部,並且將僅進行加密/解密。
分層驅動程序有時也稱為過濾器驅動程序,在所有操作系統 (包括所有Windows平台和所有Unix平台) 中都受支持。
2.2.3.微型端口驅動程序
微型端口驅動程序是支持微型端口驅動程序的類驅動程序的附加組件。使用它微型端口驅動程序不必實現該類驅動程序所需的所有功能。類驅動程序為微型端口驅動程序提供基本的類功能。類驅動程序是支持一組具有通用功能的設備 (例如所有HID設備或所有網絡設備) 的驅動程序。
微型端口驅動程序也稱為miniclass驅動程序或minidrivers,並在Windows 7及更高版本的操作系統中受支持。
Windows 7及更高版本的操作系統提供了幾個驅動程序類 (稱為端口),用於處理其類的常見功能。然後由用户決定僅添加與特定硬件的內部工作有關的功能。NDIS微型端口驅動器是這種驅動器的一個示例。NDIS微型端口框架用於創建連接到Windows通信堆棧的網絡驅動程序,因此可以訪問應用程序使用的常見通信調用。Windows內核為各種通信堆棧和通信卡通信的其他代碼提供驅動程序。由於NDIS框架,網卡開發人員不必編寫所有這些代碼,只需編寫特定於他正在開發的網卡的代碼即可。
2.3.操作系統的驅動程序分類
2.3.1.WDM驅動程序
Windows驅動程序模型 (WDM) 驅動程序是Windows操作系統中的內核模式驅動程序。WDM通過將設備驅動程序的一些工作引入集成到操作系統中的代碼部分來工作。這些代碼部分處理所有低級緩衝區管理,包括DMA和即插即用 (Pnp) 設備枚舉。WDM驅動程序是支持電源管理協議的PnP驅動程序,包括單片驅動程序、分層驅動程序和微型端口驅動程序。
2.3.2.WDF驅動程序
Windows Driver Foundation (WDF) 是Microsoft Windows Driver Model (WDM) 接口的包裝,是當今實現Windows驅動程序的首選方式。WDF是一組Microsoft工具和庫,可幫助創建Windows設備驅動程序。它抽象了編寫Windows驅動程序的大部分複雜性。
⚠注意
從版本5.2.0到14.1.1,WinDriver是WDM驅動程序。從版本14.1.1 WinDriver是一個完整的WDF驅動程序。
2.3.3.Unix設備驅動程序
在經典的Unix驅動程序模型中,設備屬於以下三類之一: 字符 (char) 設備,塊設備和網絡設備。實現這些設備的驅動程序相應地稱為char驅動程序、塊驅動程序或網絡驅動程序。在Unix下,驅動程序是鏈接到以特權內核模式運行的內核的代碼單元。通常,驅動程序代碼代表用户模式應用程序運行。通過文件系統提供從用户模式應用程序對Unix驅動程序的訪問。換句話説,設備在應用程序中顯示為可以打開的特殊設備文件。
Unix設備驅動程序是分層或單片驅動程序。單片驅動器可以被視為一層分層驅動器。
2.3.4.Linux設備驅動程序
Linux設備驅動程序基於經典的Unix設備驅動程序模型。此外,Linux還引入了一些新的特性。
在Linux下,塊設備可以像字符設備一樣被訪問,就像在Unix中一樣,但也有一個面向塊的接口,對用户或應用程序是不可見的。
傳統上,在Unix下,設備驅動程序與內核鏈接,並且系統在安裝新驅動程序後被關閉並重新啓動。Linux引入了稱為模塊的可動態加載驅動程序的概念。Linux模塊可以動態加載或刪除,而無需關閉系統。可以編寫Linux驅動程序,使其靜態鏈接或以允許其動態加載的模塊化形式編寫。這使得Linux內存使用非常高效,因為可以編寫模塊來探測它們自己的硬件,如果它們找不到它們正在尋找的硬件,則可以自行卸載。
與Unix設備驅動程序一樣,Linux設備驅動程序是分層驅動程序或單片驅動程序。
2.4.驅動程序的入口點
每個設備驅動程序必須有一個主入口點,如main()C控制枱應用程序中的函數。此入口點稱為DriverEntry()在Windows和init_module()在Linux中。當操作系統加載設備驅動程序時,將調用此驅動程序輸入過程。
有一些全局初始化,每個驅動程序在第一次加載時只需要執行一次。此全局初始化由DriverEntry()/init_module()例行公事。entry函數還記錄操作系統將調用哪些驅動程序回調。這些驅動程序回調是來自驅動程序的對服務的操作系統請求。在Windows中,這些回調被稱為調度例程,在Linux中,它們被稱為文件操作。每個註冊的回調由操作系統調用,作為一些標準的結果,例如硬件的斷開。
2.5.將硬件與驅動程序關聯
操作系統在將設備與特定驅動程序關聯的方式上有所不同。
在Windows中,硬件驅動程序關聯是通過INF文件執行的,該文件註冊設備以與驅動程序一起使用。此關聯是在DriverEntry()例行程序被調用。操作系統識別設備,檢查其數據庫以識別哪個INF文件與設備相關聯,並根據INF文件調用驅動程序的入口點。
在Linux中,硬件-驅動程序關聯定義在驅動程序的init_module()例行公事。該例程包括回調,該回調指示指定驅動程序處理哪個硬件。操作系統根據代碼中的定義調用驅動程序的入口點。
2.6.與驅動通信
對於不同操作系統,使用定製OS應用編程接口 (api),實現用户模式應用和驅動硬件的驅動程序之間的通信。
在Windows和Linux上,應用程序可以使用OS文件訪問API打開驅動程序的句柄 (例如,Windows使用CreateFile()函數或Linux使用open()函數),然後通過將句柄傳遞給相關的OS文件訪問函數 (例如,Windows使用ReadFile()和WriteFile()函數,或Linux使用read()和write()功能)。
應用程序通過I/O控制 (IOCTL) 調用向驅動程序發送請求,使用為此目的提供的自定義操作系統api (例如,Windows使用DeviceIoControl()函數,或Linux使用ioctl()功能)。
通過IOCTL調用在驅動程序和應用程序之間傳遞的數據使用自定義OS機制進行封裝。例如,在Windows上,數據通過I/O請求包 (IRP) 結構傳遞,並由I/O管理器封裝。