Inside NT Boot
NT的真正接管系統乃是從NT分區的引導扇區被引導開始.引導扇的引導代碼是在NT安裝時被寫入的.當NT被裝在FAT分區時,NT SETUP寫入的是能識別FAT FS的引導代碼,而當NT被裝在NTFS分區時,NT SETUP寫入的是能識別NTFS的引導代碼.所以,引導扇區含有一段相關的文件系統代碼.注意!這段代碼對文件系統僅能進行讀操縱,而不能進行寫操作.
當引導扇區被引導后,他所干的一件事就是查找NTLDR.該文件必須存在于根目錄下,否則系統提示:
BOOT:Couldn't find NTLDR.或A kernel file is missing from the disk.NT就死翹翹了.當加載NTLDR的時候系統仍然是處于實模式下.所以,NTLDR的第一件大事就是將CPU從實模式轉換到保護模式下.當NTLDR將所有的1M以下的內存頁描述符創建好后,NTLDR再開啟頁映射功能,現在NT可以訪問4G內存了.然后,NTLDR通過內建的文件系統代碼來查找根目錄下的BOOT.INI.(NTLDR含有FAT和NTFS2種文件系統的只讀代碼)根據BOOT.INI的內容提示用戶可選的操作系統.當用戶在缺省的時間內沒有選擇.NTLDR就引導缺省的操作系統.如果用戶選擇DOS,那么NTLDR就將根目錄下的BOOTSECT.DOS裝入內存,(BOOTSECT.DOS是DOS引導扇的COPY件.)然后執行一次熱啟動.如果此時C:是NTFS,DOS就不會被啟動出來.否則,DOS就被引導出來了.
啊哈,然后NTLDR就加載NTDECT.COM.這個程序將顯示NTDETECT V4.0 .....這個NTDECT.COM調用的乃是INTxx來執行一大堆的BIOS系統調用.用來進行系統配置的檢測.所有檢測到的東西將被存到系統注冊表的HKLM/HARDWARE/DESCRIPTION項下.
然后,執行再次恢復到NTLDR.屏幕顯示OSLOADER V4.0 ....接下來被加載的2個文件組成了WINDOWS NT的核心.那就是:HAL.DLL,NTOSKRNL.EXE.這2個文件在裝載時將被檢測PE校驗和,如果有問題或找不到.NT又要死翹翹了.有一點要說明.單處理器和多處理器的NTOSKRNL.EXE是不同的.支持多處理器的NTOSKRNL.EXE在安裝盤里的文件名稱是NTKRNLMP.EXE.但是一旦被COPY到NT的系統目錄里,名字就變成了NTOSKRNL.EXE.因為NTLDR只加載NTOSKRNL.EXE.加載完這2個文件后,NTLDR再加載所有引導必須的驅動程序,然后加載HKEY_LOCAL_MACHINE/SYSTEM/Services里的值SERVICE_BOOT_START的DRIVER.(此時不初始化.)(我也不知道SERVICE_BOOT_START的DRIVER怎么寫,因為一般的KMD如果用SERVICE_BOOT_START值啟動就會失敗.)然后NTLDR就會鎖定NTOSKRNL.EXE的main()函數,然后將控制轉移給NTOSKRNL.EXE.
BTW:NTOSKRNL.EXE的main()函數是
int main()
{ // Fire up NT!
? //
? KiSystemStartup();
? return 0;
}
這里描述的乃是NT FOR I386的最初的啟動.從引導到加載NTOSKRNL.EXE.而且里面仍然有很多分支沒寫.例如LAST KNOWN GOOD CONFIGERATION的處理等.直到現在,NT還沒有任何NT的模樣,連操作系統的雛形也沒顯示出來.
接下來NT開始了自己復雜的OS核心初始化.首先調用ExpInitializeExecutive,而該函數則調用HAL.DLL里引出的函數HallnitSystem().這時.NT就完成了對中斷控制器的初始化和時間片的設定.當HallnitSystem()返回,接下來進行的就是對內存管理器,安全引用監視器,對象管理器,進程管理器的初始化.在內存管理器完成初始化后,NT才顯示Microsoft (R) Windows NT (TM) Version 4.0 (Build 1381).而后面的SERVICE PACK號碼則是從注冊表里HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Control/Windows/CSDVersion取出.當進程管理器初始化完成后(進程管理器是NTOSKRNL.EXE里最后被初始化的一個管理器),進程管理器產生2個進程.一個,乃是IDLE進程.一個,乃是SYSTEM進程.而當返回到ExpInitializeExecutive后,ExpInitializeExecutive就變成了IDLE線程.而IDLE線程的優先級是最低的.
BTW:最要命的是NT SERVER的調度算法.每個線程在INTEL處理器上通常一下就占用120ms.當線程等待一個IO處理時,必定會吃到一個IDLE線程.因為NT的WIN32子系統通常在IO執行完成前不會返回到調用者,而且不切換到其他線程,所以通常情況下如果用SOFTICE呼出來總是看到系統停在HLT指令上.當一個硬件設備完成IO后,產生中斷來結束HLT.然后在大堆的后續代碼后才回到調用者.如果關閉HLT.系統能夠在有限的范圍內提高反應速度.我的HALPATCH就是干了關閉HTL指令的活.
好了好了.回到NT的啟動話題.
現在調用HAL激活多CPU的功能.(如果系統有2個以上CPU的話.WORKSTATION支持2CPU.SERVER支持4CPU.企業版支持8CPU.企業版SP3后還支持3GB應用程序空間.)然后將依次調用Object Manager, Executive, Kernel, Security Reference Monitor,Memory Manager,Cache Manager,Configuration Manager,I/O Manager, Process Manager.
其中IO管理器負責完成啟動值為SERVICE_BOOT_START的驅動程序的初始化,緊接著,啟動注冊表內啟動值為SERVICE_SYSTEM_START的裝載.
所有的DRIVER完成初始化后,還沒有任何USER MODE的程序,也沒有任何環境子系統.系統進程將調用核心函數ExInitializeSystem創建SMSS進程.就是SESSION MANAGER進程.SMSS是第一個USER MODE的應用程序.他又是一個真正的NATIVE APPLICATION.他不依賴于任何子系統.SMSS唯一需要的就是NTDLL.DLL.而且就是他創建了WIN32子系統.
然后SMSS干了:
創建LPC端口對象/SmApiPort.2個線程,等待客戶請求如加載子系統等.
創建環境變量.
定義DOS符號聯接.
創建附加的頁面調度文件.
從HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Session Manager/BootExecute找出引導時加載的NATIVE APPLICATION. 通常有CHKDSK.EXE等.
調用CONFIG MANAGER完成對 HKEY_LOCAL_MACHINE/SAM,HKEY_LOCAL_MACHINE/SAM/SECURITY, HKEY_LOCAL_MACHINE/SOFTWARE配置.
然后加載WIN32K.SYS.這時系統就被切換到圖形狀態.
啟動WIN32子系統.即CSRSS.EXE.
啟動WINLOGON.EXE.
創建用于調試的LPC端口,并創建線程來監視.
完成了這些工作后,SMSS就永遠等待WINLOGON和CSRSS的進程對象.把自己掛起.
WINLOGON在被啟動后.啟動SCM(服務管理器).將所有的"自動啟動"的SERVICE啟動起來.當然,WINLOGON并不等待任何SERVICE的完成啟動.很有可能用戶已經登陸而SERVICE沒有啟動出來.當用戶的START組里有某些應用程序需要依賴于某些SERVICE的存在的話,就有可能出錯.這也是新聞組上老是有程序員討論的老話題了.就象我們的程序員朋友老是愛寫些很初級的問題到自己的主頁上:)開玩笑:).
當所有的SERVICE啟動無誤后,現在HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet就成為了LAST KNOWN GOOD CONTROL SET.
當啟動SCM后,WINLOGON就創建個工作站,代表KBD,MOUSE,MONITOR.并確保連SERVICE也不能訪問該工作站,以保證安全性.當工作站創建好后,就打開3個桌面.APP,SCR SAVER,WINLOGON.MS號稱確保WINLOGON桌面的任何激活代碼和數據都不能被訪問.簡直就是屁.只要知道WINLOGON代碼的物理內存地址,什么不能修改辦到?:)當然,不知道WINLOGON的物理地址倒是真的:)然后就是建立LSA和LPC聯接.用于登陸.注銷.口令操作.
通過調用LsaLookupAuthenticationPackage獲取MSV1_0的相關ID,用于驗證身份.(從INSIDE WINDOWS NT抄的:))創建WINLOGON窗口類.確保SAS序列鍵按下后窗口過程被調用.只有WINLOGON桌面解鎖后才能切換到其他應用程序桌面.
在LOGON時,WINLOGON調用GINA來確認用戶登陸.這樣也提供了一個替換NT本身登陸驗證操作的方法.MS的核心討論組上老是有朋友研究如何獲取PASSWD.而答案往往是提供個GINA STUB.:DDD 當然,我自己沒有寫過GINA STUB.但是MS的相關文檔我看了一遍...估計對于寫個有用的GINA STUB還不夠.當然,我有偷懶的辦法,也是多數寫GINA STUB程序員的辦法,就是把自己串到老的GINA STUB上:DD MS是極力不推薦這樣干的.
當用戶驗證身份完畢,登陸成功,桌面就被解鎖.并且調用USERINIT.EXE.該程序會查找出用戶的SHELL.并啟動之.然后自己就結束生命.這就是從任何一個進程VIEWER看,SHELL都沒有父進程的原因.因為父進程已經結束了.
好了,這樣,NT就徹底啟動出來了.其中關鍵部分我想已經描述得很清楚了.將來有可能的話,我再對文章的語句潤潤色,看起來不要太枯燥?
總結
以上是生活随笔為你收集整理的Inside NT Boot的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Unity官网地址变更为https://
- 下一篇: ios UIScrollView 基础属