天天看點

Windows NT 核心基本結構

Windows NT 核心基本結構和特征

盡管大部分人每天在Windows系統上工作學習娛樂,但是對于其核心結構很多人仍然是不了解的。一方面是由于其核心源代碼不開源,另一方面則是由于相關資料的奇缺。我大二基本上花了一學期來學習和探究NT核心。雖然不敢說自己對其有很深入的了解,但至少其基本結構還算是清楚的。但是我畢竟才學有限,肯定會有不完善的地方,還請各位不吝賜教。

目前微軟所有的主流作業系統均是基于NT核心,比如:

Windows 2000/XP/Server 2003(基于NT5)

Windows Vista (基于NT6)

Windows 7(基于NT6.1, 我沒裝過Win7,不過據說是這樣的)

盡管很多人責備Windows在一些方面存在很多問題,但是這并不是核心的錯,總的來說,NT的是一個成熟穩定且先進的核心,我認為在今後相當長的一段時期内,NT核心仍将是主流,且不會有很大變化(當然,局部的更新是完全毫無疑問的)

微軟早期希望把NT做成一個純微核心結構,關于微核心和單一核心的差別,各位如有不清楚的,可以去網上搜尋一下。後來為了提高圖形子系統的性能,避免大量的核心态和使用者态切換,微軟便将其移入核心之中,使其成為核心一部分(類似的還有後來的DirectX技術)。由此可見,NT并不是一個完全的微核心,它也具有單一核心的某些特征。

NT核心具有以下幾個特征(摘自Undocumented Windows NT)

Portability (可移植性)

如你所知,Windows NT 可以運作在多種平台上,即 Intel、MIPS、Power PC 和 DEC Alpha。衆多廠商都為 Windows NT 的可移植性做出了貢獻。 其中最為重要的因素可能是其實作所使用的語言。Windows NT 大部分是用 C 語言編寫的,也有一部分用的是 C++。 平台相關的彙編語言隻在必需的地方才用到。Windows NT 團隊還将作業系統中硬體相關的部分與其它部分隔離開,單獨放進了 HAL.DLL。 如此一來,Windows NT 中與硬體無關的部分的代碼就可以用 C 之類的進階語言來編寫,也是以可以很容易地移植到各種平台。

Extensibility(可擴充性)

Windows NT 具有很高的可擴充性,但因為缺少文檔,其可擴充的特性卻極少得到發掘。未公開的特性的名單中,子系統首當其沖。子系統在作業系統中提供了多種作業系統接口。隻需添加新的子系統程式就可以為 Windows NT 擴充新的作業系統接口,但是對于公開添加新子系統過程的要求微軟卻一直打馬虎眼。

Windows NT 的核心是高可擴充的,因為可以将核心子產品作為驅動程式動态加載。對于 Windows NT,微軟提供了足夠的文檔來編寫硬體裝置驅動——即硬碟驅動、網卡驅動、錄音帶機驅動等等。在 Windows NT 下還可以編寫不控制裝置的驅動程式。甚至連檔案系統也是作為驅動程式加載的。

Windows NT 的可擴充性的另一個例子就是系統調用接口的實作。 開發者要修改作業系統行為,一般都需要鈎挂或添加系統調用。 Windows NT 的開發團隊實際了良好的系統調用接口以友善鈎挂和添加系統調用。但是微軟還是沒有公開這些機制。

Compatibility(相容性)

長久以來,向下相容性都是 Intel 處理器和微軟作業系統的一大特征,也是這兩位巨人成功的關鍵。Windows NT 必須能運作 DOS、Win16 和 OS/2 的程式。相容性是 Windows NT 開發團隊使用子系統概念的另一個原因。除二進制相容之外(執行不同格式的可執行檔案),Windows NT 還為符合 POSIX 的程式提供了源代碼級的相容。增強相容性的其他方面還表現在除自己本身的 NTFS 外,Windows NT 支援其它的檔案系統,如 DOS 的 FAT 和 OS/2 的 HPFS。

Maintainability(可維護性)

Windows NT 的代碼量很大,維護着些代碼的工作量也相當大。NT 的開發團隊通過使用面向對象的設計實作了高可維護性。再有,将作業系統的功能分成各個層也提高了可維護性。最上面的一層,也就是使用者見到的作業系統層面,是子系統層。子系統提供系統調用接口來為外界提供應用程式程式設計接口。在系統調用接口層之下的是 NT 的 executive,executive 又建立在核心之上,而核心又依賴于硬體抽象層(HAL),硬體抽象層與硬體直接通訊。

NT 的開發團隊所選的程式設計語言也與 Windows NT 的可維護性有關。正如我們前面提到的,整個作業系統都是用 C 和 C++ 來編寫的,隻有極少數不用不行的地方用了彙編語言。

Security(安全性)

Windows NT 是一個安全的作業系統,是因為它有以下幾點特征:使用者在使用系統之前必須先登陸。 系統中的資源都被視為對象,而每一個對象都相應由一個安全描述符。安全描述符有一個安全清單來訓示那些使用者可以通路該對象。

盡管有這些,要是沒有一個安全的檔案系統,作業系統也不能說是安全的。 DOS 時的 FAT 檔案系統沒有預見到任何的安全問題,其作為一個單使用者的系統,也不用防範安全問題。

為了克服此缺陷,Windows NT 團隊推出了一種新的檔案系統,這種檔案系統基于 OS/2 的檔案系統 HPFS。這種新的 Windows NT 的自有檔案系統叫 NTFS。它支援通路控制,使用者可以為 NTFS 下建立的檔案或目錄指定通路權限,NTFS 隻允許有通路權限的程序通路該檔案或目錄。

Multiprocessing(多程序)

Windows NT 支援對稱多處理,Windows NT 的工作站版本可以支援兩個處理器,伺服器版可以支援到4個。為支援多處理,作業系統需要特殊的同步機制。在單處理器系統中,通過禁用中斷,臨界區中的代碼執行時不會被打斷。這對于維護核心資料結構的完整性來說是必需的。在多處理器環境下,就不可能在所有的處理器上都禁用中斷。在多處理環境中,Windows NT 使用自旋鎖來保護核心資料結構。

注:多處理可分為對稱的和非對稱的。在非對稱多進行中,有一個處理器為主處理器,其它的處理器都為從處理器。隻有主處理器運作在核心模式,其它從處理器都隻運作在使用者線程。隻要運作在使用者線程的從處理器一調用系統服務,主處理器就接管此線程并執行所需的核心服務。排程程式,一個核心程式,之運作在主處理器上。是以,主處理扮演者排程員的角色,将使用者模式線程分派給從處理器。很自然,與所有處理器都可在核心或使用者模式運作的對稱多處理相比,主處理器負擔很重,系統不均衡。

International Language Support(國際化語言支援)

如今衆多的 PC 使用者都使用英語之外的其它語言。與這些使用者能很好互動的關鍵就是使作業系統能支援使用者們的語言。Windows NT 通過使用 Unicode 标準的字元集實作了這一目标。Unicode 标準規定了一個16位的字元集,而ASCII 使用的是8位字元集。 Unicode 的前256個字元的編碼與 ASCII 的相同。這就為非拉丁語的語言留出了充足的空間。Win32 API 能接受 Unicode 和 ASCII 兩種字元集,而 Windows NT 的核心則隻能使用 Unicode。盡管應用程式程式員可以不去了解 Unicode,但驅動程式的開發者必須熟悉 Unicode,因為核心接口函數隻接受 Unicode 字元串而且驅動的入口點都用的是 Unicode。

Windows NT 從 MACH 作業系統那裡借用了核心體系,MACH 作業系統是在卡耐基梅隆大學開發的。MACH 作業系統的基本理念就是通過将複雜的作業系統功能交給使用者級程序而将核心減至最小。這種客戶機-伺服器的作業系統體系還有另外一個目的:允許在同一作業系統上使用多種 APIs。通過在伺服器程序中實作 APIs 就可以做到。

MACH 作業系統的核心提供了非常簡單的一組接口函數。伺服器程序使用這組接口函數實作出某種 API 來提供一組更複雜的接口函數。Windows NT 從 MACH 那裡借用了這個理念。Windows NT 中的伺服器程序被稱作子系統。子產品化和結構化的程式設計都是優秀軟體管理的原則,NT 選擇使用客戶機-伺服器的體系結構顯示了它對這種原則的服從。Windows NT 本可以将所需的 APIs 在核心實作,也可以在核心上加上不同的層來實作不同的 APIs。出于維護性和擴充性的目的,NT 團隊選擇了子系統的辦法。

Windows NT 中有兩種子系統: integral subsystems 和 environment subsystems。Integral subsystems,如安全管理子系統,完成基本的作業系統任務。 Environment subsystems 則使得一台 Windows NT 機器能使用不同種類的 APIs。Windows NT 的子系統能支援以下的 APIs:

Win32 子系統。Win32 子系統提供 Win32 API。使用 Win32 API 的應用程式可以運作在微軟 提供的所有平台上—

WOW 子系統。Windows on Windows (WOW) 子系統提供了對 16-bit Windows 應用程式的相容,使得 Win16 的應用程式可以在 Windows NT 上運作。隻要沒有使用 Windows NT 不支援的未公開函數,這些應用程式都可以運作。

NTVDM 子系統。NT Virtual DOS Machine (NTVDM) 提供了一個基于文本的環境,DOS 程式可以在這個環境中運作。

OS/2 子系統。OS/2 子系統能運作 OS/2 應用程式。WOW、NTVDM 和 OS/2 都隻能用在 Intel 平台上,因為他們都對應用程式提供二進制相容性。而用于一種處理器的可執行檔案或二進制檔案就不能用在另一種處理器上,因為處理器間的機器指令格式不同。

POSIX 子系統。POSIX 子系統提供符合 POSIX 1003.1 标準的 API。

應用程式并不知道所調用的 API 是由相應的子系統處理的。這種隐藏是通過每種子系統各自的用戶端 DLL 來實作的。這種 DLL 将 API 調用轉換為本地過程調用(local procedure call,LPC)。本地過程調用類似于聯網的 UNIX 上的遠端過程調用(RPC)。使用 RPC,客戶應用程式可以調用運作在網絡上另一台機器上的伺服器程序。 LPC 對運作在同一台計算機上的客戶機與伺服器進行了優化。

NT核心主要包含以下幾個重要檔案:

Ntoskrnl.exe(或者Ntkrnlpa.exe)  

HAL.Dll

NTDll.Dll

Win32k.Sys

NT核心的核心是NT EXECUTIVE。對應的檔案是Ntoskrnl.exe。如果是機器是多處理器的,則是Ntkrnlpa.exe。非常可笑的是,這個檔案可以直接删除,其後果就是重新開機後Windows無法啟動,甚至連滾動條都看不到。該檔案隻有2MB左右的大小,但可謂是麻雀雖小五髒俱全,它作為整個Windows中最核心的部分,向外界提供了複雜的接口。

與之相輔相成的是HAL.Dll檔案,即Hardware Abstraction Layer 硬體抽象層 。它直接與機器的硬體打交道,将硬體的差異對其之上的層隐藏起來。Windows NT 是一個有高可移植性的作業系統,運作在多種平台上。HAL.DLL 包含的代碼向核心的其它部分隐藏了處理器和機器相關的細節。是以平台之間隻有 HAL.DLL 不同,剩下的使用 HAL 接口的核心代碼都有很高的可移植性。

NTDll.Dll子產品。導出了大部分的Native API函數,提供了由使用者态至核心态的切換的功能。做過Windows平台開發的人都知道,Windows API主要由Kernel32.Dll, User32.Dll, GDI32.Dll構成。其實對WindowsAPI的調用最終會被轉接到NTDll。即所謂Native API,命名上基本上就是在原API前面加上Nt或者Zw(比如CreateFile就變成了NtCreateFile)。而Kernel32.Dll, User32.Dll, GDI32.Dll三個檔案則組成了Win32子系統,它們本身不實作API,它導出的函數被稱為stub 函數(盡管名稱上看起來很迷惑人)

Win32K.sys子產品。實作了Windows的圖形處理部分。USER32 和 GDI32 使用系統調用接口來調用 WIN32K.SYS 中的服務。由于其工作與核心态,是以具有很高的性能,這也成就了Windows系統的強大的圖形處理能力。

本文轉自 kevx 51CTO部落格,原文連結:http://blog.51cto.com/spinlock/174696,如需轉載請自行聯系原作者