1. 程式人生 > >Windows系統程式設計師的“內功”修煉

Windows系統程式設計師的“內功”修煉

注:這篇blog是從一本書(《竹林蹊徑——深入淺出Windows驅動開發》)的推薦序中摘錄出來的。

我一直認為,編寫程式是一件很奇妙的事情,它可以帶來創造和控制的慾望。每當我閱讀或者編寫一段程式碼時,腦子裡自然地就會想象這段程式碼怎樣完成預定的邏輯。當面對一個不熟悉的開發環境,或者一個新的基礎平臺時,首先要清楚這個環境或者平臺是如何工作的,以及提供了哪些功能。程式碼本身可能非常複雜,甚至奧妙無窮,但通常情況下,真正優美的高質量程式碼往往是簡單的、易於理解的。對於程式碼編寫者或者維護者來說,真正見功夫的地方不在於程式碼本身,而在於對下層開發平臺的理解和駕馭能力,可能這就是俗稱的“內功”。

這個觀點既適用於應用軟體程式設計師,也適用於系統軟體程式設計師。對於應用軟體程式設計師,低層的應用開發平臺是支撐應用開發的基礎,譬如,基於

Windows SDK來開發Windows應用程式,那麼,程式設計師有必要理解Windows SDK中的基本要素,諸如訊息分發機制、各種圖形功能等。在這種情況下,閱讀一些典型的例子程式程式碼往往能起到快速引領入門的效果。同樣地,C/C++程式設計師如果侷限於C/C++語言本身,很難編寫出高質量的實用程式。他們不僅要掌握C/C++執行庫中函式和型別的用法,甚至還要理解這些函式和型別的實現機理。即使原始碼層面上的庫,例如STL(C++的標準模板庫),也需要理解其程式碼實現才能靈活自如地用好這些庫(比如STL中的各種容器資料結構、迭代器或演算法)。

那麼,對於系統軟體程式設計師,“內功”是什麼呢?系統軟體是指作業系統本身或者依附於作業系統上為應用軟體提供服務的軟體。系統軟體可能有機會跟硬體直接打交道,這賦予了程式設計師更強的控制能力,他們有機會介入作業系統的行為邏輯,甚至改變作業系統的行為特性。但隨之而來的是對系統軟體程式碼的更高要求。現代作業系統為應用軟體提供了很強的容錯能力,應用程式的失敗通常不會波及到作業系統自身的穩定性,但作業系統對系統軟體的容錯能力卻比較有限,畢竟系統軟體執行起來之後可能被融入到作業系統的執行邏輯中成為作業系統的一部分。因此,理解和掌握作業系統的執行機制成為系統程式設計師編寫出正確、高效的系統軟體的基本前提。所謂“內功”,便著落在此。

Windows平臺上開發軟體,編寫Windows核心驅動程式是最為考驗程式設計師“內功”的。核心驅動程式的程式碼量通常不大,但驅動程式框架中的任何一個函式,甚至這些函式中任何一行程式碼都可能背後蘊含著複雜的邏輯,或者隱式的要求和假設。即使驅動程式編寫者在純粹自行定義的函式中,也必須謹慎地關注一些與環境有關的因素,譬如程式碼是否可被中斷、是否可重入,或者所引用的記憶體是否被交換到外存。另一方面,應用軟體開發中的很多概念,比如地址空間、記憶體管理、異常處理和多執行緒併發等等,在驅動程式開發中可能需要有不同的理解方法。此外,常用的C執行庫函式基本上不再適合於驅動程式了,驅動程式編寫者必須面對一個全新的底層環境和支援平臺。因此,要編寫可正確執行的驅動程式,程式設計師不僅要清楚地理解驅動程式所針對的目標裝置或功能(可能包括硬體裝置的各種特性),還要掌握

Windows核心是如何與驅動程式打交道的,以及核心中諸多管理和執行機制,尤其是記憶體管理、執行緒排程和併發控制。

Windows核心驅動程式被載入到核心中並且啟動以後,它們變成了Windows核心的一部分,驅動程式中的介面函式在恰當的時刻被核心呼叫,這是Windows驅動程式的基本工作方式。Microsoft定義了WDM(Windows驅動程式模型)來規定驅動程式的結構以及Windows核心如何與WDM驅動程式打交道。WDM不僅包括I/O管理器定義的驅動程式框架,還定義了在驅動程式中如何支援PnP(Plug and Play,即插即用)、電源管理和WMI(Windows Management InstrumentationWindows管理規範)。因此,若要編寫一個完全支援WDM的驅動程式,也需要理解WDM中所涉及的各個核心元件。

為了便於Windows驅動程式的開發,Microsoft定義了一個驅動程式框架,稱為WDF(Windows Driver Foundation),其中針對核心驅動程式的部分稱為KMDF(Kernel-Mode Driver Framework)KMDF實際上是一個庫,它封裝了WDM中一些基本的程式碼邏輯,從而使程式設計師可以更加方便地編寫出WDM驅動程式。KMDF可以部分地簡化Windows核心驅動程式的開發任務,但是本質上它並沒有降低核心驅動程式的複雜性,甚至需要程式設計師付出額外的學習努力。

總而言之,作為一名系統程式設計師,你需要洞悉目標作業系統中與你的軟體打交道的各個部件,也要非常清楚地知道你所依賴的開發工具是如何幫助你做到這一點的。系統程式設計師往往面臨著比應用程式設計師更長的學習曲線,但是,系統程式設計師從編寫程式中獲得的樂趣也是在應用層上難以體會得到的。