本章主要介紹系統的整體結構,關鍵部件之間的交互,以及運行在什麼環境。node
2.系統結構c++
2.1 需求和設計目標程序員
2.3 整體結構shell
2.3.2 對稱多處理windows
2.3.3 可伸縮性()api
2.3.5 版本檢查sass
2.4.9.5 Winlogon,lsass和Userinit
略
在大多數用戶操做系統中,應用程序與操做系統自己是隔離的:操做系統代碼在內核模式下執行,能夠訪問系統數據和硬件,應用程序代碼運行在用戶模式下,只有有限的接口可使用,對系統數據訪問受限,沒法直接訪問硬件。
和unix同樣,windows系統大部分代碼和驅動程序都是共享相同的受保護的內核模式空間。意味着操做系統任何組件,均可以破壞其餘組件的數據。
固然用戶程序和操做系統全部組件是隔離的。應用程序沒法直接訪問系統中特權部分的數據和代碼。
windows內核模式組件也體現了基本的面向對象設計原則。如他們不會直接進入另外一個組件的數據結構來訪問該組件維護的數據。相反是利用正式的接口來傳遞參數,訪問和修改相應的數據接口。
可是嚴格上來講windows並非一個面向對象系統。windows內部使用c語言,並非面向對象系統,c語言對象實現,只是借用了面嚮對象語言的特性。
本節介紹windows的設計目標和包裝方式,以下圖windows整體結構中的關鍵系統組件。
有4中用戶模式進程:
1.固定的系統支持進程,如登錄進程,會話管理器進程。
2.服務進程,宿納了windows服務,如進程管理器和假脫機服務。
3.用戶應用程序,有6個類型:windows32位,windows64位,windows3.1 16位,ms-dos 16位,posix32位或者OS/2 32位。
4.環境子系統服務進程,實現了操做系統環境的部分支持。這裏的環境是指操做系統展現給用戶或者程序員的個性化部分。
在windows下,用戶程序不能直接訪問原始的windows服務,要經過一個或者多個子系統動態連接庫。
windows內核組件包含:
1.windows執行體,包含基本的操做系統服務,如內存管理,進程和線程管理,安全性,I/O,網絡,跨進程通訊。
2.windows內核,是由一組底層的操做系統功能構成,如線程調度,終端和異常處理分發。以及處理器同步。提供了一組例程和基礎對象。執行體的其餘部分利用這些例程和對象實現更高層次的功能。
3.設備驅動程序,硬件設備驅動程序,也包含文件系統和網絡驅動程序。其中硬件設備驅動程序將用戶的I/O函數調用轉化爲特定的硬件設備請求。
4.硬件抽象層,指一層特殊代碼,它把內核,設備驅動程序和windows執行體其餘部分跟與平臺相關的硬件差別隔離開來。
5.窗口和圖形系統:實現了圖形用戶界面函數。
文件名 |
組件 |
Ntoskrnl.exe |
執行體和內核 |
Ntkrnlpa.exe |
執行體和內核,支持物理地址擴展,是的系統可尋址64GB物理內存 |
Hal.dll |
硬件抽象層 |
Win32k.sys |
Windows子系統的內核模式部分 |
Ntdll.dll |
內部支持函數,以及執行體函數和系統服務分發存根(stub) |
Kernerl32.dll,Advapi32.dll,User32.dll,Gdi32.dll |
Windows的核心子系統DLL |
windows的一個設計目標是要可以運行在各類不一樣的硬件體系結構上。
windows有2中方式支持可移植性以支持多種硬件體系結構和平臺:
1.windows有一個分層設計,系統底層部分與處理器體系結構相關,或與平臺相關的,這些部分被隔離到獨立的模塊中,因此搞成不須要考慮體系結構的區別。有2個組件爲系統提供了可移植性:內核和硬件抽象層。
2.windows的絕大多數代碼是由c語言編寫的,少部分是使用c++編寫的,只有那些須要直接與系統硬件通訊的部分或者對性能極端敏感的操做系統部分,纔是用匯編語言編寫的。
多任務是值多個執行線程之間共享同一個處理器的操做技術。
可以很好的在多處理器運行是windows 的設計目標。windows是一個對稱多處理(SMP)操做系統。沒有主處理器,操做系統和用戶線程能夠被調度到任何一個處理器上運行,並且全部的處理器共享惟一的內存空間。
對稱處理和非對稱處理不一樣,操做系統選一個處理器運行系統內核代碼。而其餘處理器運行用戶代碼。
xp和2003支持2中新的多處理器系統:超線程(hyperthreading),NUMA(非一致性的內存結構)。
超線程是intel一個技術,能夠一個物理處理器上有多個邏輯處理器,是的一個邏輯cpu能夠在其餘邏輯cpu正在忙着的時候繼續運行。
在非一致性內存結構NUMA系統中,處理器被組織成更小的單元,成爲node,每一個結點都有本身的處理器和內存,並同一個一個緩存一致(cache-cohernet)的互聯總線鏈接到更大的系統上。NUMA系統上的windows仍然做爲一個smp系統運行。全部的處理器能夠訪問全部內存。不過本地結點比其餘節點速度要快,系統想要提升性能作法是,根據現場用到的內存所在的節點,講現場調度到同一個處理器上。
在windows的最初設計上32位最多隻支持32個cpu,64位支持64個cpu。並無本質的因素來限制處理器個數。註冊表LocensedProcessors能夠限制處理器個數。
考慮到性能問題內核和HAL分爲2個版本,單處理器和多處理器版本。
在系統磁盤上的文件名 |
在發佈介質上單處理器版本的名稱 |
在發佈介質上多處理器版本的名稱 |
Ntoskrnl.exe |
Ntoskrnl.exe |
Ntkrnlmp.exe |
Ntkrnlpa.exe |
Ntkrnlpa.exe in \windows\<arch>\Driver.cab |
Ntkrpamp.exe in \windows\<arch>\Driver.cab |
Hal.dll |
取決於系統類型 |
取決於系統類型 |
如下只針對2000系統 |
|
|
Win32.sys |
\I386\UNIPROC\Win32k.sys |
\I386\Driver.cab中Win32.sys |
Ntdll.dll |
\I386\UNIPROC\Ntdll.dll |
\I386\Ntdll.dll |
Kernel32.dll |
\I386\UNIPROC\Kernel32.dll |
\I386\Kernel32.dll |
多處理器系統下,管家你的問題是可伸縮性。windows有如下功能這些功能對windows做爲一個多處理器起到關鍵性的做用:
1.能一個處理器上運行系統代碼,也能夠在多個處理器上運行。
2.在單個進程內執行多個線程,這些線程能夠在不一樣的處理器上運行。
3.內核內部(如自旋鎖,排隊自旋鎖以及壓棧鎖)以及設備驅動程序和服務器進程內部的細粒度同步,是的多個組件能夠並行在多個處理器上運行。
4.如I/O完成端口之類的編程機制,是的能夠實現高效的多線程進程,而且這樣的程序再多處理系統上有很好的伸縮性。
客戶版和服務器版主要區別是有:
支持的處理器個數不一樣。
支持的物理內存不一樣。
所支持的併發網絡鏈接數不一樣。
略
已經看過上面的簡易的結構圖,瞭解了高層的結構體系。
以後都會圍繞這個圖展開,第三章解釋windows使用的主要控制機制(如中斷,對象管理器)。第五章啓動和關閉windows的過程。第四章介紹各個管理機制(註冊表,服務進程,WMI)。剩餘的章節更加詳細的討論各個關鍵區域內存結構和操做(進程,線程,內存管理,安全性,I/O,存儲管理,高速緩存管理器,windos文件系統和網絡)。
如上圖,最初windows有3個子系統,os/2,posix,wondows。os/2最後一次發佈和Windows2000。到了xp posix也不發佈了。3個子系統中windows子系統比較特別,是必須啓動的。
查看註冊表HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\SubSystems下面有子系統的信息。
其中Required值表示了啓動要加載的子系統,如上圖,值爲Debug和Windows。Window值包含了windows子系統的文件規範,csrss.exe它表明了客戶/服務器運行時的子系統。Debug爲空。Optional值爲Os2,Posix表示這2個子系統,被按需啓動。Kmode表示windows子系統的內核環境下運行的部分爲win32k.sys。
環境子系統角色是將windows基礎系統服務暴露給應用程序。每一個子系統都提供了對於windows原生服務不一樣部分的訪問能力。也就是說創建在某個子系統上的應用程序能夠作到的,是另外一個創建在不一樣子系統的應用程序沒法作到的。如posix的fork。
每一個exe能夠執行映像被綁定到一個子系統上,如VC++ link命令/SUBSYSTEM能夠指定類型代碼,可使用Exetype工具查看此類型代碼。
用戶程序不能直接調用windows服務而是經過dll來調用如windows子系統dll(kernel32.dll,advapi32.dll,user32.dll,Gdi32.dll),POSIX子系統DLL(psxdll.dll)。當一個應用程序調用子系統可能會發生3中狀況:
1.函數徹底在該子系統dll中實現的,在用戶模式下運行。
2.該函數要求調用windows執行一次或屢次。
3.改函數要求在環境子系統中完成某個工做。
Windows子系統有一下幾個主要組件構成:
1.環境子系統進程(Csrss.exe),包含下列支持:
a.控制檯(文本)窗口
b.建立或刪除進程和線程
c.對16爲虛擬DOS機(VDM)進程的一部分支持。
d.其餘一些函數,好比GetTempFile,DefineDosDevice,ExitWindowsEx,以及幾個天然語言函數支持。
2.內核模式驅動程序(win32k.sys)包含:
a.窗口管理器,它控制窗口顯示管理屏幕輸出,採集來自鍵盤,鼠標,和其餘設別的輸入,同時也負責將用戶的消息傳遞給應用程序。
b.圖形設備接口,他是專門正對圖形輸出設備的函數庫。
3.子系統dll
子系統dll,如Kernel32.dll,Advapi32.dll,User32.dll,Gdi32.dll,將windows api文檔化,對應到Ntoskrnl.exe和Win32k.sys大多數未文檔化的系統服務調用。
4.圖形設備驅動
指硬件香瓜你的圖形顯示器驅動程序,答應及驅動程序和視頻微端口驅動程序。
posix能夠當作是一個基於unix的可移植的操做系統接口。值的是正對unix風格的操做系統接口的一組國際標準。posix鼓勵廠商實現unix風格,編譯在系統之間遷移。
須要使用posix子系統,要求使用platform sdk中使用posix的頭文件和庫文件。posix是按需啓動的當第一次啓動posix,psxss.exe要運行起來。posix的映像文件不是直接運行的。一個特殊的稱爲posix.exe的支持映像文件被啓動起來,而後再建立一個子程序來運行posix應用程序。
和posix同樣,有用性頗有限,並且OS/2已經不在適用於windows了。
NTDLL.DLL是一個特殊的系統支持庫,主要用於子系統DLL。包含兩個類型函數:
1.系統服務分發存根(stubs),他們會調用Windows執行體系服務。
2.內部支持函數,供子系統,子系統DLL以及其餘的原生映像文件使用。
第一組函數是爲windows執行體系服務提供接口,在用戶模式下能夠經過接口函數調用windows執行體的系統服務,如(NtCreatefile,NtSetEvent)
對於每一個這樣的函數,ntdll包含了一個同名入口,函數內部的代碼包含了與處理器體系接口相關的模式切換指令,經過該指令可轉換到內核模式下,從而調用系統服務分發器。分發器檢查某些參數後,再調用真正的內核模式系統服務,其中包含ntoskrnl.exe內部實現代碼。
NTDLL.DLL也包含了許多支持函數,好比映像文件加載器(以ldr開頭的函數)、對管理器、Windows子系統進程通訊函數(Csr開頭的函數)、以及通常運行庫(Rtl開頭的函數)、也包含了異步調用(APC)分發器和異常分發器。
Windows執行體是Ntoskrnl.exe中的上層,內核是其下層。執行體包含如下幾類函數:
1.可在用戶模式下調用的導出函數。這些函數成爲(系統服務)並經過ntdll導出。還有一些未文檔化的如LPC、NtQueryInformationProcess
2.可經過DeviceIoControl函數調用設備驅動器函數。
3.只能在內核模式下導出的函數,而且這兒寫函數在Windows DDK或者Windows IFS Kit已經文檔化。
4.在內核模式下調用,未在Windows DDK或者IFS Kit中文檔化的導出函數。
5.定義爲全局符號,可是未被導出的函數。如以Iop或者Mi開頭的函數(分別是內部IO管理器支持函數和內部內存管理器支持函數)。
6.未定義爲全局符號,而是在一個模塊內容的函數。
Windows執行體還包含如下組件:
1.配置管理器,複製系統註冊表的實現和管理
2.進程和線程管理器,建立或者終止進程和線程。
3.安全應用監視器,強制在本地計算機上實行安全策略,它守護着系統資源執行對運行時對象的保護和審計。
4.I/O管理器:實現了設備無關的I/O,負責將這些操做分發到恰當的設備驅動程序作進一步處理。
5.即插即用(pnp)管理器:爲了支持一個特定的設備,肯定驅動,並加載這些驅動。
6.電源管理器:負責協調事件,而且向設備驅動程序產生電源管理I/O通知。如電源管理器設備爲系統空間,經過將cpu置於睡眠來下降電源電耗。
7.WDM Windows管理規範例程:容許設備驅動發佈有關性能和配置信息以及接受來自用戶模式的WMI服務命令。
8.高速緩存管理器:提升了以文件爲基礎的I/O操做的性能,其作法是讓最近引用過磁盤數據留在主內存中以便快速訪問。(而且延遲了寫操做,在將更新數據發送到磁盤前先在內存中停留一小段時間。)
9.內存管理器:實現了虛擬內存
10.邏輯預取器:加速系統和進程啓動過程
另外Windows執行提還包含了4組主要支持函數:
1.對象管理器,建立,管理,刪除Windows執行體對象和抽象數據類型,這些對象和數據類型表明了操做系統資源。
2.LPC設施,在同一臺機器上用戶進程和服務器進程之間傳遞消息。
3.公共運行庫,字符串處理,算術操做等函數。
4.執行體支持例程:如系統內存分配,互鎖的內存訪問,以及2中特殊的同步對象:資源和快速互斥體。
內核是由Ntoskrnl.exe中的一組函數以及對硬件體系結構的低層支持構成的。Ntoskrnl.exe中的這組函數提供了一些最基本的機制。內核代碼使用C編寫,並不容易在C中訪問的任務,則保留使用匯編。大部分函數都已經文檔化,以Ke開頭。
內核給高層作支持。內核實現了操做系統最基本的機制(調度,分發)。把各類策略決定留給了執行體。
內核外看來,執行體將線程和其餘可共享資源都表示爲對象。這些對象要求一些策略開銷。這些開銷在內核中不存在,內核實現了一組更簡單的對象,稱爲內核對象,幫助內核控制好中心處理過程,而且支持執行體對象的建立工做。執行體層的絕大多數對象包裝了一個或者多個內核對象,把他們的內核屬性合併起來。
一組內核對象創建了有關控制各類操做系統功能叫作控制對象,另外一組內核對象融合了同步的能力,改變或者影響線程調度叫分發器對象。分發器對象包含了內核線程,互斥體,事件,內核事件對,信號量,定時器,等待定時器。
執行體經過內核函數建立內核對象實例,維護對象實例。構建更加複雜的對象提供給用戶。
內核的另外一個主要功能是將執行體和設備驅動程序從windows所支持的各類硬件體系結構中抽象出來,或者隔離出來變化的差別。
在內核設計是竟可能的使用公共代碼最大化。內核支持的可移植性接口,在不一樣的體系結構上是等同的。並且實現這組接口的大部分代碼,在不一樣的結構體系上也是相同的。可是有些代碼和體系結構有關,如上下文切換。
從高層看線程選擇和上下文切換可使用相同的算法(上一個線程的執行上下文被保存起來,新線程的環境被加載進來),但在不一樣的處理器上,實現仍是有差別的。執行上下文是由處理器的寄存器來描述的,因此要保存和加載哪些數據仍是有差異的。
硬件抽象層是系統可移植的關鍵。HAL是一個可加載的,內模式模塊提供了windows當前運行平臺的低層接口。它隱藏了與硬件相關的細節,如I/O接口,中斷控制器,以及多處理器通訊機制等,體系結構或者機器相關的功能。
windows內部組件以及用戶編寫的設備驅動並不直接訪問硬件,當它們須要得到與平臺相關的信息時,它們能夠經過調用HAL例程來保存可移植性。DDK中能找到不少有關HAL在驅動中的用法。
雖然windows帶了幾個HAL,可是安裝時只能有一個被選中,而且copy到系統磁盤,其文件名爲hal.dll。
設備驅動程序是可加載的內核模式(以.sys結尾),他們在I/O管理器和相應的硬件之間創建連接。驅動在內核模式下,位於如下3個環境之一:
1.在發起I/O功能的用戶線程環境中
2.在內核模式系統線程的環境中
3.做爲一箇中斷的結果(所以不存在任何特定的進程或者線程執行環境中)
驅動也是調用HAL,所以驅動程序能夠在windows支持的cpu體系結構上代碼級移植,在同一個體系結構族內是二進制可移植的。
設備驅動有如下幾類:
1.硬件設備驅動程序,經過HAL操做硬件,從而輸出到設備或者網絡,或者從設備或者網絡中輸入。硬件設備驅動也有不少類型如,總線驅動,人機界面驅動等。
2.文件系統驅動程序是指能夠接受面向文件的I/O請求,並將這些請求轉化成針對某一特定設備的I/O請求。
3.文件系統過濾器驅動程序:如截取了I/O請求而且執行某些增值處理以後再傳遞給下一層驅動(執行磁盤鏡像,加密的驅動程序)。
4.網絡重定向器和服務器指文件系統I/O請求傳遞給網絡上的某一臺機器。或者從網絡上接收此類請求的文件系統驅動程序。
5.協議驅動程序,如TCP/IP,NetBEUI,IPX/SPX之類的網絡協議
6.內核流式過濾器驅動程序:這樣的驅動被串接起來,以便對流數據進行信號處理。
驅動程序是內核模式中添加代碼的惟一方式。
如下系統進程會出如今每一個windows系統中(其中空閒進程,system進程並非完整的過程,由於它們不是運行在用戶模式的可執行文件):
1.空閒進程
2.system進程
3.會話管理器(smss.exe)
4.windows子系統(csrss.exe)
5.登錄進程(winlogon.exe)
6.服務控制管理器(services.exe)和它建立的子服務進程(如系統提供通用服務宿主進程svrhost.exe)
7.本地安全認證服務器(lsass.exe)
空閒進程是第一個進程,並無在用戶模式下的實際映像文件。
標記爲中斷和DPC(分發過程調用)用於中斷和延遲過程調用的時間,他們並非進程,列在這裏是由於他們都會消耗cpu,並無計算在任何一個進程中,而是被算在系統空閒中。
system進程是一種特殊線程的母體。這些特殊線程只能運行在內核模式哦。系統線程有普通線程全部屬性和環境,可是隻運行系統空間中加載的代碼。系統線程沒有地址空間,所以動態存儲空間,都必須從系統中內存堆分配,好比換頁或者非換頁池。
系統線程是由PsCreateSystemThread來建立的,這個函數只能在內核環境下才能被調用。
內核會建立一個稱爲平衡集管理器的系統線程,每秒沒喚醒一次,可能發出調度和內存管理相關事件。告訴緩存管理器也使用系統線程來實現「預讀」和」延遲寫」功能。
在排查問題是,知道系統線程映射到某個驅動程序中,甚至映射到包含改代碼的子例程中,必定很是有用。
因此若是system進程中的線程正在運行,首先要肯定哪些線程在運行。經過線程看哪一個驅動開始的或者檢查調用棧,得知在運行到哪裏了。
會話管理器(smss.exe)是系統中第一個建立的用戶模式進程,由負責完成執行體和內核初始化工做的內核模式系統線程最後建立實際的smss.exe進程。
在windows啓動過程當中,會話管理器負責許多比較重要的步驟,如打開頁面文件,執行延遲文件更名,刪除操做,建立環境變量。將子系統程序(csrss.exe)和winlogon.exe啓動起來。winlogon進程依次啓動其餘系統進程。
smss.exe的主線程執行以上步驟後,一直在csrss.exe和winlogon的進程上等待。若是這2個進程中任何一個非正常終止了,則ssms.exe讓系統崩潰,(崩潰代碼:status_system_process_terminated或0xc000021a)由於windows依賴這2個進程才能運行。
smss等待加載子系統的請求,調式事件,以建立新的終端服務器會話的請求。
終端服務會話是由smss來完成的。當smss接到一個建立會話的請求時,先調用NtSetSystemInformation,請求創建內核模式數據結構。又調用內部的內存管理函數MmSessionCreate該函數創建起會話虛擬地址空間,改地址空間包含會話中的換頁池以及由win32子系統的內核模式部分和其餘的會話空間設備驅動程序所分配,屬於某個會話的數據結構,而後會爲該會話建立winlogon和csrss實例。
winlogon登錄進程處理交互式用戶的登錄和註銷,當sas被按下(ctrl+atl+del),winlogon接到一個用戶登錄請求。
登錄過程的身份識別和認證是在一個名爲GINA(圖形識別和認證)的可替換DLL中,windows的標準爲GINA爲Msgina.dll實現了默認的windows登錄界面。然而開發人員能夠提供他們本身的GINA DLL來實現其餘的身份識別和認證機制如:基於聲波的方法。
一旦用戶名和口令捕捉到了就能夠送到本地安全認證服務器進程(lsass.exe)進行認證。lsass調用適當的認證包,以執行實際的驗證操做,好比口令是否符合存儲在活動目錄或者sam中的口令信息。
在成功完成驗證後,lsass調用安全引用監視器中的一個函數(如:NtCreateToken)建立一個訪問令牌對象。對象包含當前用戶的安全範圍。winlogon利用此訪問令牌來建立該用戶會話中的初始進程默認爲userinit.exe。
userinit執行該用戶環境的一些初始化工做,而後再查找註冊表winlogon下的shell而且建立一個進程來運行系統定義的外殼程序(默認explorer.exe)
而後userinit退出,這就是explorer.exe沒有父進程的緣由。winlogon在註銷,登錄,sas winlogon是活動的。關於登錄過程各個步驟的完整秒死能夠看第5章。有關安全認證能夠查看第八章。
windows中的服務能夠自一個服務器進程,也能夠是一個驅動程序。這一指的是用戶模式進程(如:unix的守護進程),這些進程能夠在系統引導是自動啓動起來,而無需交互式的登錄過程。也能夠被配置爲手動啓動。
服務控制器是一個特殊的系統進程,用於啓動,中止服務進程也複製服務進程之間的交互。服務有3個民粹:運行中進程名,註冊表內名稱以及管理器的顯示名。
在服務進程和所運行的服務之間並非一一對應的,由於有些服務和其餘共享一個進程。註冊表服務類型代碼指明瞭共享仍是獨佔進程。
許多windows組件使用系統服務實現如Spooler,event log,Task Scheduler和多個網絡組件。
本章主要歸納的介紹了一遍windows體系結構,檢查了一遍關鍵的組件,他們之間是如何聯繫起來的。