Windows系統啟動過程詳細分析

來源:互聯網
上載者:User


開電源啟動機器幾乎是電腦愛好者每天必做的事情,面對螢幕上出現的一幅幅啟動畫面,我們一點兒也不會感到陌生,但是,電腦在顯示這些啟動畫面時都做了些
什麼工作呢?相信有的朋友還不是很清楚,本文就來介紹一下從開啟電源到出現Windows的藍天白雲時,電腦到底都幹了些什麼事情。


先讓我們來瞭解一些基本概念。第一個是大家非常熟悉的BIOS(基本輸出入系統 (BIOS)),BIOS是直接與硬體打交道的底層代碼,它為作業系統提供了控制硬體
裝置的準系統。BIOS包括有系統BIOS(即常說的主板BIOS)、顯卡BIOS和其它裝置(例如IDE控制器、SCSI卡或網卡等)的BIOS,其
中系統BIOS是本文要討論的主角,因為電腦的啟動過程正是在它的控制下進行的。BIOS一般被存放在ROM(唯讀儲存晶片)之中,即使在關機或掉電以
後,這些代碼也不會消失。

第二個基本概念是記憶體的地址,我們的機器中一般安裝有32MB、64MB或128MB記憶體,這些記憶體的每一個位元組都被賦予了一個地址,以便CPU訪問內
存。32MB的位址範圍用十六進位數表示就是0~1FFFFFFH,其中0~FFFFFH的低端1MB記憶體非常特殊,因為最初的8086處理器能夠訪問的
記憶體最大隻有1MB,這1MB的低端640KB被稱為基本記憶體,而A0000H~BFFFFH要保留給顯示卡的顯存使用,C0000H~FFFFFH則被
保留給BIOS使用,其中系統BIOS一般佔用了最後的64KB或更多一點的空間,顯卡BIOS一般在C0000H~C7FFFH處,IDE控制器的
BIOS在C8000H~CBFFFH處。


好了,下面我們就來仔細看看電腦的啟動過程吧。


第一步:
當我們按下電源開關時,電源就開始向主板和其它裝置供電,此時電壓還不太穩定,主板上的控制晶片集會向CPU發出並保持一個RESET(重設)訊號,讓
CPU內部自動回復到初始狀態,但CPU在此刻不會馬上執行指令。當晶片集檢測到電源已經開始穩定供電了(當然從不穩定到穩定的過程只是一瞬間的事情),
它便撤去RESET訊號(如果是手工按下電腦面板上的Reset按鈕來重啟機器,那麼鬆開該按鈕時晶片集就會撤去RESET訊號),CPU馬上就從地址
FFFF0H處開始執行指令,從前面的介紹可知,這個地址實際上在系統BIOS的位址範圍內,無論是Award BIOS還是AMI
BIOS,放在這裡的只是一條跳轉指令,跳到系統BIOS中真正的啟動代碼處。


第二步: 系統BIOS的啟動代碼首先要做的事情就是進行POST(Power-On Self
Test,加電後自檢),POST的主要任務是檢測系統中一些關鍵裝置是否存在和能否正常工作,例如記憶體和顯卡等裝置。由於POST是最早進行的檢測過
程,此時顯卡還沒有初始化,如果系統BIOS在進行POST的過程中發現了一些致命錯誤,例如沒有找到記憶體或者記憶體有問題(此時只會檢查640K常規內
存),那麼系統BIOS就會直接控制喇叭發聲來報告錯誤,聲音的長短和次數代表了錯誤的類型。在正常情況下,POST過程進行得非常快,我們幾乎無法感覺
到它的存在,POST結束之後就會調用其它代碼來進行更完整的硬體檢測。


第三步:
接下來系統BIOS將尋找顯卡的BIOS,前面說過,存放顯卡BIOS的ROM晶片的起始地址通常設在C0000H處,系統BIOS在這個地方找到顯卡
BIOS之後就調用它的初始化代碼,由顯卡BIOS來初始化顯卡,此時多數顯卡都會在螢幕上顯示出一些初始化資訊,介紹生產廠商、圖形晶片類型等內容,不
過這個畫面幾乎是一閃而過。系統BIOS接著會尋找其它裝置的BIOS程式,找到之後同樣要調用這些BIOS內部的初始化代碼來初始化相關的裝置。


第四步: 尋找完所有其它裝置的BIOS之後,系統BIOS將顯示出它自己的啟動畫面,其中包括有系統BIOS的類型、序號和版本號碼等內容。

第五步: 接著系統BIOS將檢測和顯示CPU的類型和工作頻率,然後開始測試所有的RAM,並同時在螢幕上顯示記憶體測試的進度,我們可以在CMOS設定中自行決定使用簡單耗時少或者詳細耗時多的測試方式。

第六步: 記憶體測試通過之後,系統BIOS將開始檢測系統中安裝的一些標準硬體裝置,包括硬碟、CD-ROM、串口、並口、軟碟機等裝置,另外絕大多數較新版本的系統BIOS在這一過程中還要自動檢測和設定記憶體的定時參數、硬碟參數和訪問模式等。

第七步: 標準裝置檢測完畢後,系統BIOS內部的支援隨插即用的代碼將開始檢測和配置系統中安裝的隨插即用裝置,每找到一個裝置之後,系統BIOS都會在螢幕上顯示出裝置的名稱和型號等資訊,同時為該裝置分配中斷、DMA通道和I/O連接埠等資源。


第八步: 到這一步為止,所有硬體都已經檢測配置完畢了,多數系統BIOS會重新清屏並在螢幕上方顯示出一個表格,其中概略地列出了系統中安裝的各種標準硬體裝置,以及它們使用的資源和一些相關工作參數。


第九步: 接下來系統BIOS將更新ESCD(Extended System Configuration
Data,擴充系統配置資料)。ESCD是系統BIOS用來與作業系統交換硬體設定資訊的一種手段,這些資料被存放在CMOS(一小塊特殊的RAM,由主
板上的電池來供電)之中。通常ESCD資料只在系統硬體設定發生改變後才會更新,所以不是每次啟動機器時我們都能夠看到“Update ESCD…
Success”這樣的資訊,不過,某些主板的系統BIOS在儲存ESCD資料時使用了與Windows 9x不相同的資料格式,於是Windows
9x在它自己的啟動過程中會把ESCD資料修改成自己的格式,但在下一次啟動機器時,即使硬體設定沒有發生改變,系統BIOS也會把ESCD的資料格式改
回來,如此迴圈,將會導致在每次啟動機器時,系統BIOS都要更新一遍ESCD,這就是為什麼有些機器在每次啟動時都會顯示出相關資訊的原因。


第十步:
ESCD更新完畢後,系統BIOS的啟動代碼將進行它的最後一項工作,即根據使用者指定的啟動順序從磁碟片、硬碟或光碟機啟動。以從C盤啟動為例,系統BIOS
將讀取並執行硬碟上的主引導記錄,主引導記錄接著從分區表中找到第一個使用中的磁碟分割,然後讀取並執行這個使用中的磁碟分割的分區引導記錄,而分區引導記錄將負責讀取並
執行IO.SYS,這是DOS和Windows 9x最基本的系統檔案。Windows
9x的IO.SYS首先要初始化一些重要的系統資料,然後就顯示出我們熟悉的藍天白雲,在這幅畫面之下,Windows將繼續進行DOS部分和GUI(圖
形使用者介面)部分的引導和初始化工作。


如果系統之中安裝有引導多種作業系統的工具軟體,通常主引導記錄將被替換成該軟體的引導代碼,這些代碼將允許使用者選擇一種作業系統,然後讀取並執行該作業系統的基本引導代碼(DOS和Windows的基本引導代碼就是分區引導記錄)。

上面介紹的便是電腦在開啟電源開關(或按Reset鍵)進行冷啟動時所要完成的各種初始化工作,如果我們在DOS下按Ctrl+Alt+Del按鍵組合
(或從Windows中選擇重新啟動電腦)來進行暖開機,那麼POST過程將被跳過去,直接從第三步開始,另外第五步的檢測CPU和記憶體測試也不會再進
行。我們可以看到,無論是冷啟動還是暖開機,系統BIOS都一次又一次地重複進行著這些我們平時並不太注意的事情,然而正是這些單調的硬體檢測步驟為我們
能夠正常使用電腦提供了基礎。



Windows啟動過程介紹


信不少人碰到過裝了個什麼東西之後,重啟Windows就發現起不來了。所以,想把Windows啟動過程中作了些什麼事情,分哪些stages做個介
紹。
這裡要介紹的是Windows 2k/xp/2k3系列的啟動過程,nt系列麼,很類似。
雖然Windows是非開源的(廢話!:o
),不過還是有不少資料可以參考的,還包括MS的那些public的symbol。如果有機會可以試試Kernel的live
debug,那麼相信還是能看到不少東西的。不過話說回來,這事情我也沒做過……
等回頭自己機器上裝好VMWare之類的,再Try吧,到時候會把過程記錄下來貼到這裡的。



Windows的啟動過程麼,主要包括以下幾個部分:

1. Master Boot Record (MBR)

2. Boot sector


3. Ntldr (這個可能有人會覺得眼熟,是不是碰到過啟動的時候說找不到Ntldr呢?;) )


4. Ntoskrnl.exe

5. Smss


6. Winlogon

7. Service control manager (SCM)
OK。


將在這個文章裡依據上述的啟動過程,對這些組件逐個介紹。當然,這裡面大部分內容來自於《Inside Windows 2000》和《Windows
Internals》這兩本書的相應章節(Startup and
shutdown)。我能做的事情基本上就是翻譯和複述了,最多可能加上一些相關的注釋。
當然,如果看過關於linux啟動過程源碼(分析)的朋友,估計會不滿足於下面介紹這麼點內容,而且這裡也基本不談到硬體相關的部分(最多可能僅補充一些
我知道的硬體相關內容),誰叫咱看不到源碼呢。


 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才完成了它的使命。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.