Windows2000裝置驅動程式的研製開發

才智咖 人氣:4.94K

引言:

Windows2000裝置驅動程式的研製開發

由於工作關係,我經常涉及PC機與外圍裝置介面的工作,從PC機這方面要做的工作看來,主要是通過介面處理外圍裝置的中斷,通過I/O埠或記憶體地址與外設互相傳遞資料。從計算機原理的角度看,所要達到的目的很簡單,那麼如何編寫程式完成上述功能呢?

目前國內流行的PC作業系統有三種:DOS,Win95/98系列,WindowsNT。DOS是單使用者、單任務作業系統,由於PC機硬體處理速度不斷提高,基於單使用者、單任務的作業系統越來越不能充分發揮硬體的功能,現在只應用於一些老式PC及其它個別場合,有逐漸被淘汰的趨勢;Win95/98系列和WindowsNT屬於多工作業系統,不論從其原理還是介面上看,這兩種作業系統都比DOS有著無可比擬的優越性,這兩種作業系統雖然在介面和操作上及其相似,但其內部實現的諸多方面有許多區別,有些區別是本質上的。Win95/98設計目標是針對一般家庭使用者,安全性及可靠性存在許多薄弱環節,就可靠性而言,Win95/98系列不能很好的防止多工環境中某個程序的非法操作導致系統中其它程式甚至整個系統的崩潰,而WindowsNT在這方面及其它諸多方面設計的相當嚴謹。這兩種作業系統是Microsoft公司同一時期的產品,但針對不同的使用群,所以在一些重要場合及生產實踐中應該選擇WindowsNT作為計算機的作業系統,此外,從發展趨勢來看,WindowsNT已經成為定型產品,具有相對穩定性。

在不同作業系統下編寫驅動程式是有很大區別的,在DOS平臺上,應用程式和裝置驅動程式之間沒有標準的介面,它們在外部表現為一個副檔名為EXE的檔案,驅動程式的作用被柔和在應用程式中,這樣,應用程式為了使用不同廠商的同一類裝置,必須瞭解這些裝置在介面上具體的硬體實現,同時,對於一個特定型號的硬體產品,所有支援它的應用軟體中對於控制整個裝置動作的這部分程式碼,可能被多次重寫。這種情況不適應硬體及應用軟體的飛速發展。Windows系統在這方面,進行了根本性改進,把控制裝置動作的這部分程式碼獨立出來,提出了裝置驅動程式的概念,驅動程式是應用程式和硬體裝置之間的一個橋樑,應用程式與驅動程式之間有明確的介面,應用程式通過與驅動程式交換資訊,達到控制外設的目的。介面定義的操作是面向裝置的,這就是說,在應用程式的設計中,並不用關心對外設操作的具體硬體實現,只是對驅動程式發出一系列指令既可;驅動程式接受來自上層應用程式的指示,具體操縱實際硬體,完成使用者功能。具體實現上,Win95/98系列與WindowsNT又有所區別,WindowsNT是嚴格按照上述思路設計的;而Win95/98系列不那麼嚴格,其支援上述思路,但同時應用程式也可以繞過驅動程式直接訪問實際物理I/O,這樣做,增加程式設計的靈活性,但同時,對系統可靠性造成一定隱患。這也正是Win95/98系列可靠性低於WinNT的原因之一。

表1-1 三種作業系統下訪問介面比較

作業系統應用程式訪問介面方式訪問許可權
DOS 直接訪問所有[注]
Windows95/98 通過裝置驅動程式* 所有[注]
直接訪問僅I/O埠
WindowsNT 通過裝置驅動程式* 所有[注]


[注]‘所有’指I/O埠,RAM匯流排,中斷,DMA。

WindowsNT裝置驅動程式的組成原理

WindowsNT作業系統結構分為使用者模式和核心模式,使用者模式下的程式設計為應用程式的設計,而開發裝置驅動程式,則屬於核心模式下的程式設計,核心模式元件包括NT Executive(ExXxx),核心(KeXxx),硬體抽象層(HalXxx)。其層次如圖2-1所示,其中NT Executive 包括幾個獨立的軟體元件,它們是系統服務介面(ZwXxx),物件管理器(ObXxx),配置管理器,程序管理器(PsXxx),安全監視器(SeXxx),虛擬空間管理器(MemXxx),本地程序呼叫,I/O管理器(IoXxx)。核心模式的系統服務並不是全部公開的,而是提供了一系列開發裝置驅動程式需要的函式(上文括號內為函式形式,函式手冊參見[2]Kernel-Mode Drivers-Reference章節),換言之,這些函式功能是所有核心模式的系統服務功能的子集。

驅動程式由一系列相對獨立的函式組成,由I/O管理器根據需要呼叫這些函式,對於一個需要處理中斷的最簡單的驅動程式也需要由以下幾個函式構成:

erEntry() 運行於PASSIVE_LEVEL
驅動程式入口點,當驅動程式被手動或自動裝入系統後,驅動程式從這點開始執行,主要用於定位硬體資源,建立指向其它驅動程式函式的指標等其它初始化工作。

load() 運行於PASSIVE_LEVEL
用於驅動程式從系統卸出之前,釋放由驅動程式佔用的所有系統資源。

r() 運行於DIRQL
中斷服務程式。

cForIsr() 運行於DISPATCH_LEVEL
中斷服務程式後處理程式,以排隊方執行不太關鍵程式碼的執行,由於排隊機制及優先順序,不會造成程式碼擁塞從而提高中斷服務程式的響應並且提高系統總體I/O吞吐率。

en() 運行於PASSIVE_LEVEL
處理應用程式Win32函式CreateFile()請求。

ose() 運行於PASSIVE_LEVEL