close
Windows 內核研究—1.Windows XP啟動過程Windows 內核研究—1.Windows XP啟動過程

Windows startup sequence

Windows architecture

Windows startup sequence

Windows啟動過程預覽
1. MBR & Boot Sector

物理硬盤是以扇區(sector)為單位來尋址的。 Windows的安裝程序會在安裝的時候,將一些內容寫入你

安裝系統的那個硬盤的第一個扇區。這塊內容就稱為Master Boot Record(MBR).

MBR包括兩塊內容:
(1). Boot code;
(2). Partition table;

Boot code,也就是啟動代碼。這段代碼是在系統啟動的時候, BIOS完成了自檢過程,選擇了啟動設備(

也就是你某個硬盤),然後就將該磁盤的MBR讀入內存, 並且跳轉到MBR所在地址,從而執行其Boot code.

Partition table,也就是分區表。該表只有4項(entry), 因為MS的OS允許一個磁盤最多被分為4個主分

區(primary partition)。 這裡的分區表裡面的內容就是這4個分區的相關信息, 包括其起始的sector,

相應的標誌等等。

對於啟動過程而言,MBR的boot code會搜尋這個分區表,在其中查找帶有可啟動標誌( 也稱為Active)的

分區,然後將該分區的第一個sector(也就是Boot sector)讀入,並且執行其中的代碼。

在安裝程序寫入Boot sector之前,需要獲知其所在分區的文件系統類型(FAT? FAT32? NTFS?),然後寫

入不同的Boot sector。為什麼對於不同的文件系統需要不同的Boot sector呢?原因在於Boot sector的

任務,就是要載入OS的系統啟動文件,而載入文件的過程, 是需要文件系統參與的,所以對應於不同的文

件系統,在Boot sector裡面就需要不同的文件系統支持代碼, 以次來完成系統文件的加載。對於Windows

啟動而言,需要加載的文件為Ntldr。

需要補充的是,boot sector裡面對於文件系統的支持代碼是「最小化」了的。 畢竟boot sector的大小最多

也就只有512 bytes,要帶有完整的文件系統是不大可能的。而且, 我們的需求也很簡單,只需要它能夠

理解該文件系統,並且能夠讀取其中的文件就可以了, 我們並沒有寫入文件的需求。

Boot sector將Ntldr加載完成之後, 就跳轉到Ntldr的入口處,接下去的任務, 就交給Ntldr了。這時候,

系統還是運行在16位的實模式下, Ntldr會開啟Paging,並轉入32為保護模式。

這個過程中,可能碰到的錯誤信息是下面這個:
對於NTFS文件系統,"BOOT: Couldn't find NTLDRP";
對於FAT文件系統,"NTLDR is missing";
這個錯誤的意思是Boot sector在分區的根目錄下沒有找到Ntldr。

2. NTLDR

NTLDR是一個「中間人」,在Boot Sector轉入NTLDR的時候,系統處於實模式下, 這時候程序訪問的任何地址都是實地址,也就是物理地址( 雖然這其中還有80x86最基本的分段功 能,學過這個實模式彙編的應該知道),並且, 這個地址範圍也受限在1M(20位地址)以內。所以, 進入NTLDR後最先要做的事情就是轉入保護模式,以便 於能夠完全訪問32位地址範圍。不過, 由於此時沒有設置好相應的頁表,所以,還不能進行虛實地址轉換( 也就是還沒有分頁的功能)。

NTLDR需要初始化一定的頁表,然後開啟分頁。這時候, 系統已經進入了Windows的標準狀態(保護模式+分頁)。 前面說到轉入保護模式的時候,漏說 了一個事情,就是初始化GDT和IDT。這裡面, 關鍵的是Windows使用的是Flat Memory Mode,也就是其保護模式下,所有段的基地址都一樣。 這點和其內存管理的機制息息相關,這邊就先提一下。

雖然系統已經進入了保護模式,不過, 此時的NTLDR還需要依賴一些BIOS調用, 來訪問磁盤以及顯示系統。如果磁盤是SCSI的, 而BIOS調用無法訪 問此類磁盤,那麼NTLDR就加載Ntbootdd. sys來替代boot code中的磁盤訪問代碼。NTLDR和Boot Sector類似, 也包含了NTFS和FAT文件系統的只讀代碼,區別麼, 其稍有進步,就是能訪問子目錄了。

由於從Windows2000開始,都有了「休眠」( Hibernation)這種關機方式。於是, NTLDR需要檢查系統上是否存在有效的 Hiberfil.sys文件,如果有, 那麼表明最近一次關機是以「休眠」的方式關機的。於是, NTLDR就開始走「捷徑」:讀入 Hiberfil.sys文件,然後直接跳轉到內核中「 喚醒休眠」的代碼,從而啟動計算機。

正常啟動的情況下,NTLDR讀入boot.ini文件。 如果該文件表明有多個可啟動選項,於是就顯示啟動菜單, 供用戶選擇。

這裡又有一個可能的例外,雖然現在這個可能性已經很小了。 這個例外就是有DOS的啟動選項(包括Win9x和ME系列)。 這個情況下,NTLDR 加載 Bootsect.dos文件,轉回實模式, 並且跳轉到該文件中的MBR代碼。這時候, 就和最開始啟動的狀態(讀入MBR)一樣了, 從而啟動相應的OS。

在用戶選擇了啟動菜單後, NTLDR還要根據該項的參數做一些相應的操作。 對於這些參數麼,這裡就不作說明和解釋了。

NTLDR加載並執行Ntdetect.com。 該程序是一個16位保護模式的程序,通過BIOS調用, 獲取系統硬件的信息(比如總線類型啊,系統時間 啊,磁盤驅動器啊,並口串口啊等等),然後將這些信息集中起來, 返回給NTLDR, 並且這些信息在啟動的後期會保存到註冊標的HKLM\ HARDWARE \DESCRIPTION下。

貌似上面的這些工作都是在後台做的, 除了那個可能出現的啟動菜單外,其他工作都是用戶看不到的。 接下來,就該給用戶一些反饋信息了。

NTLDR先清屏,然後顯示「Starting Windows」和進度條。這裡,2000和XP/ 2003有所不同。2000會顯示黑白屏的進度條, 這時候屏幕上還沒有Windows的logo。而 XP/2003會顯示帶有Windows logo的彩屏進度條,需要注意的是, NTLDR在開始加載任何「啟動驅動」(boot driver)之前,進度條一直是空的。

還有大家可能注意到過的,就是在顯示「Starting Windows」的時候,下面還會顯示「For troubleshooting and advanced startup options for Windows, press F8.」,然後進度條出現並開始滾動(前進)的時候, 就沒有機會按F8來進入安全模式之類的了。其實想像, 這裡面還是有原因的。因為在系統開始加載驅動之 前,主要做的事情只是加載內核文件和註冊表的System hive。這兩個事情和安全模式之類的其他啟動方式沒有關係, 無論是安全模式還是標準啟動,都需要加載這兩部分東西。 而安全模式和標準模式的區別,在於其 加載的驅動有所不同。所以, 一旦Windows開始加載那些boot driver之後,就無法在改變模式了。


在NTLDR從顯示「Starting Windows」開始,需要經過以下步驟:

1. 加載正確的內核以及HAL(默認為Ntoskrnl. exe和Hal.dll)。 如果NTLDR在加載這兩個文件的過程中出錯,無法完成加載, 那麼會顯示 下面這條出錯信息:Windows could not start because the following file was missing or corrupt,並且會告訴你無法加載的文件名。

2. 從\Windows\System32\Config\ System讀入System hive。
註:hive是指一個包含了註冊表中某個子樹的文件。

3. 在System hive中找出所有的boot driver(這類driver的start值為0, 即SERVICE_BOOT_START)。 系統的所有driver都在註冊表的HKLM\ SYSTEM\CurrentControlSet\ Services下面有對應的子鍵(subkey)。

4. 加載boot drivers所在分區的文件系統驅動,以便於之後的boot driver的加載。

5. 加載boot drivers。這時候,才會開始更新屏幕上的進度條。 對於Windows 2000來說,就是那個黑白進度條。

6. 設置CPU寄存器,並且跳轉到Ntoskrnl.exe的入口。

好,NTLDR的任務總算完成了, 接下去就全部交給Ntoskrnl了。當然, 在轉交控制權的時候,自然也將對方需要的信息(包括內存佈局, 硬件信息,System hive等)也都交給Ntoskrnl,這樣, NTLDR才完成了它的使命。





arrow
arrow
    全站熱搜

    Estar007 發表在 痞客邦 留言(0) 人氣()