個人認識的windows啟動過程。。。




我把windows啟動看成三部分,windows引導過程、核心加載過程、使用者登入會話建立過程。
一:windows引導過程
當機箱接通電源,首先得到控制的是BIOS代碼。其中的功能主要有兩個:一是執行必要的硬體檢測工作,二是允許使用者通過一些功能鍵來配置目前系統的硬體設定(BIOS設定)。。。
完成這兩個功能之後,BIOS将控制權交給硬碟主引導記錄(MBR),MBR是由windows安裝程式在安裝windows的時候填充的,裡面的代碼被成為引導代碼。引導代碼主要完成的功能是檢索分區以得到引導分區,然後将引導分區的第一個扇區讀入記憶體。。。。、
之後,MBR将控制權交與引導扇區。
引導扇區的主要職責是給windows提供有關該硬碟上卷的結構與檔案系統格式方面的資訊,并且在目前卷的根目錄中,讀入windows的加載程式,即ntldr檔案。這兩個功能就要求了引導扇區必須具備能夠識别檔案系統和讀取檔案的全部代碼。為了擺脫引導扇區盤塊的限制,微軟的做法是,使引導扇區的内容去加載其它扇區的程式來完成該操作,在這裡,引導扇區就相當于一個loader.
在将ntldr加載入記憶體後,引導扇區将控制權交給ntldr的入口點
在ntldr之前,系統是工作在dos實模式之下,而windows必須工作在保護模式。為了引導windows的啟動,ntldr首要的工作就是做好實模式和保護模式的切換。
ntldr分兩個部分組成。第一部分為實模式代碼,另一部分為windows可執行檔案代碼,其中第二部分也叫做os loader。
在引導扇區交控制權給ntldr之後,首先得到控制權的是實模式代碼它完成實模式下裝置的初始化,為切換到保護模式做好環境的準備之後,便通知處理器将環境切換為保護模式,然後交控制權與os loader。
由于剛剛進入保護模式,虛拟位址轉移機制尚未開啟,是以os loader首先要把實體記憶體管理起來,用一個記憶體描述符數組把每一段記憶體的大小和用途全都記錄下來,然後建構頁目錄,頁表,再設定好也目錄寄存器,最後打開頁面映射機制。在這個過程中,有些初始化必須在實模式下進行,是以os loader有時候會進行實模式和保護模式的切換。
os loader随後就在引導分區的根目錄下面讀入boot.ini檔案,然後,清楚螢幕,并檢查根目錄下有沒有hiberfil.sys檔案。這個檔案是休眠标志。如果這個檔案存在,則說明這次計算機啟動是一次休眠喚醒的過程,這個時候,os loader會交控制權給系統喚醒代碼。
如果hiberfil.sys不存在,則os loader則解析boot.ini的引導選項來顯示引導選擇菜單(如果隻有一項菜單便跳過顯示)。
注:解釋一下boot.ini檔案。
[boot loader]
timeout=3
default=multi(0)disk(0)rdisk(0)partition(1)/WINDOWS
[operating systems]
multi(0)disk(0)rdisk(0)partition(1)/WINDOWS="Microsoft Windows XP Professional" /noexecute=optin /fastdetect
格式分兩部分,boot loader(引導加載),Operating Systems(作業系統)。
timeout:系統選擇菜單的等待時間,default為預設作業系統
Multi 表示一個非SCSI硬碟裝置或一個由SCSI BIOS通路的SCSI硬碟,此處也可以為SCSI,表示一個SCSI BIOS禁止的SCSI硬碟,後面跟的數字表示作業系統的系統根目錄所在分區所在的硬碟所在的磁盤控制器在同一磁盤控制器上的序号。
disk:對于SCSI硬碟,y表示作業系統的系統根目錄所在分區所在的硬碟在同一磁盤控制器上的硬碟序号。對于multi,disk的值恒為0;
rdisk:表示磁盤的序列号。
Partition:表示分區序号。
(boot.ini的資料出自百度百科)。
當使用者選擇所要登入的作業系統之後,os loader加載執行NTDETECT.COM,這是16位程式,主要功能是利用作業系統的BIOS來查詢系統的基本裝置和配置資訊。這些資訊在系統資料庫初始化之後會放在HKLM/HARD WARE/DESCRIPTION中。
等待NTDETECT.COM執行完畢,os loader開始加載核心子產品映像檔案,預設為ntoskrnl.exe。以及HAL映像檔案(HAL.DLL)。然後在加載服務啟動中标記為SERVICE_BOOT_START啟動的裝置驅動,以及檔案系統驅動程式。到這裡位置,引導作業系統所需要的前提才算全部被加載,同是OS LOADER構造參數塊LOADER_PARAMETER_BLOCK。該參數塊定義如下:
typedef struct _LOADER_PARAMETER_BLOCK {
LIST_ENTRY LoadOrderListHead;
LIST_ENTRY MemoryDescriptorListHead;
LIST_ENTRY BootDriverListHead;
ULONG_PTR KernelStack;
ULONG_PTR Prcb;
ULONG_PTR Process;
ULONG_PTR Thread;
ULONG RegistryLength;
PVOID RegistryBase;
PCONFIGURATION_COMPONENT_DATA ConfigurationRoot;
PCHAR ArcBootDeviceName;
PCHAR ArcHalDeviceName;
PCHAR NtBootPathName;
PCHAR NtHalPathName;
PCHAR LoadOptions;
PNLS_DATA_BLOCK NlsData;
PARC_DISK_INFORMATION ArcDiskInformation;
PVOID OemFontFile;
struct _SETUP_LOADER_BLOCK *SetupLoaderBlock;
PLOADER_PARAMETER_EXTENSION Extension;
union {
I386_LOADER_BLOCK I386;
// ALPHA_LOADER_BLOCK Alpha;
// IA64_LOADER_BLOCK Ia64;
} u;
} LOADER_PARAMETER_BLOCK, *PLOADER_PARAMETER_BLOCK;
該參數塊一般是由OS LOADER填充,剩下的由核心初始化的時候填充。(哪些是由OS LOADER填充,那些是由核心初始化填充???)
到此為止,ntldr 任務完成,交出控制權給核心子產品的出口函數:kiSystemStartup。
windows引導過程結束,核心初始化開始。
二:核心初始化
ntldr交控制權于ntoskrnl.exe。核心初始化開始。
ntoskrnl的入口函數為kiSystemStartup。由于子產品間耦合的關系,核心初始化沒有辦法線性執行。而是将過程分為兩個階段。階段0和階段1,啟動子產品靠着一個辨別位來确定目前啟動是處于階段0還是階段1。
階段0:初始化階段1要用到的資料,在該階段,中斷被禁止。kiSystemStartup首先初始化處理器狀态。包括IDT、TSS、PCR、然後調用HalInitializeProcess為目前處理器初始化其HAL中的PCR和處理器間中斷向量,接着調用kiinitialineKernel初始化核心,完成之後即變為空閑。在階段0初始化的時候,程序管理器PCR建立一個程序對象idle,建立system.exe程序。
kiInitializeKernel傳回後,kiSystemStartup啟動中斷。開始允許新線程的建立。
到此時,階段0啟動完畢。階段1開始啟動。初始化函數phase1Initialization,間接調用KeStartAllProcess啟動其它的處理器。其它的處理器啟動的過程和主處理器相似,但少了很多初始化的過程。
在階段1的初始化過程中,在螢幕上開始顯示windows圖示和進度。
過程如下:
1、設定辨別為1,表示階段1開始。
2、HalInitSystem,執行HAL的階段1初始化。
3、初始化圖形引導驅動。
4、調用PoInitSystem完成電源初始化。
5、調用HalQueryRealTimeCloce,完成時間的初始化;
調用keSetSystemTime設定時間。
6、SeStartAllProcessers,啟動所有的處理器。
7、完成階段1初始化。
8、進度10%
9、建立/SystemRoot符号連結,完成記憶體管理器初始化。
10、加載國家語言支援,初始化緩存管理器,初始化配置管理器,初始化系統資料庫編輯器,初始化核心預讀器。
11、進度15%
12、初始化檔案系統支援庫。初始化調試器(kdcom.dll),初始化即插即用裝置。
13、進度20%
14、初始化LPC子系統,初始化執行本地元件。
15、進度25%
16、調用IoInitSystem函數來初始化I/O子系統。初始化I/O子系統中的狀态變量,建立驅動程式對象和裝置對象。加載“引導-啟動”類型驅動。加載“系統-啟動”類型驅動。
17、進度75%。
18、核心子產品标記為可分頁。
19、進度80%
20、電源管理器,裝置管理器完全初始化。
21、進度85%
22、完全引用螢幕初始化(SRM),建立安全引用螢幕的指令服務線程,該線程建立一個“引用螢幕指令端口”的LPC端口,接受lsass.exe程序傳來的安全服務指令。
23、進度90%
24、建立會話管理器(smss.exe)程序。
25、進度100%。
26、啟動ZwWaitForSigltObject等待smss.exe程序五秒鐘,五秒鐘内smss退出則系統崩潰。(注意:會話管理器雖然為系統程序,但是在系統中并沒有做核心守護,平時結束了smss.exe,是不會引起系統崩潰的,原因就在這裡。)
核心初始化完畢。使用者登入會話開始。
三:使用者登入會話建立
smss.exe獲得控制權,使用者登入會話開始。
首先,初始化系統資料庫内容。(核心啟動階段1僅僅啟動了系統資料庫管理器和system儲巢)。。
smss.exe要啟動的東西在系統資料庫中的位置:
HKLM/SYSTEM/CurrentControlSet/Control/Session Manager
主要鍵值按啟動順序排列介紹如下:
BootExecute 運作在啟動時執行的程式。自動校驗程式。
FileRenameOperation 啟動時檔案删除重命名。
/KnownDlls 打開已知dll(系統,全局共享)
/Memory Management/PagingFiles 建立頁面檔案,也就是虛拟記憶體。
Environment 全局環境變量。
/SabSystems/kmode windows子系統的核心子產品。
/subSystems/Windows 啟動windows子系統程序(csrss.exe)
建立LPC端口對象為啟動lsass做好準備。
啟動winlogon.exe,初始化登入窗體和預設桌面。
核心ZwWaitForSigleObject來等待winlogon.exe和csrss.exe程序,有一個結束則系統崩潰。
啟動Services.exe,啟動自啟動的服務和裝置。
啟動本地權威子系統lsass.exe程序,建立LPC連接配接。
Winlogon獲得使用者名和密碼後,首先調用lsass.exe的lsaLookupAuthenticationPackage函數以獲得認證包,然後由lsass來驗證。
Winlogon檢查UseInit的值,啟動程序(預設為UseInit.exe)。
UserInit.exe檢查Shell的值(預設為explore.exe),啟動explore。
UserInit退出。
啟動Run鍵值下,自啟動檔案夾下的啟動項。windows啟動完成。。。