前言
本文是本系列文章的最后一篇,主要介紹MS-DOS,各類(lèi)Windows和Linux操作系統(tǒng)的啟動(dòng)過(guò)
程,用了這么久的操作系統(tǒng)是該系統(tǒng)地了解一下啟動(dòng)的完整過(guò)程。
一、MS-DOS 啟動(dòng)過(guò)程
當(dāng)PC啟動(dòng)時(shí),讀取啟動(dòng)盤(pán)第一個(gè)扇區(qū)并執(zhí)行其中的引導(dǎo)代碼。如果發(fā)現(xiàn)了DOS 引導(dǎo)扇區(qū),
會(huì)將IO.SYS的前三個(gè)扇區(qū)加載到內(nèi)存中,并將PC控制權(quán)交由IO.SYS(輸入輸出模塊)。
IO.SYS接管計(jì)算機(jī)控制權(quán)執(zhí)行如下操作:
首先將IO.SYS其他部分內(nèi)容加載到內(nèi)存,依此初始化每個(gè)缺省設(shè)備
接著加載處理MS-DOS內(nèi)核文件MSDOS.SYS,不過(guò)在MS-DOS 7.0中,MSDOS.SYS改
為啟動(dòng)配置文件
再者處理 CONFIG.SYS文件,CONFIG.SYS是重要的配置文件,是可以進(jìn)行編輯的文本
文件
內(nèi)容示例:
DEVICE=C:\DOS71\ECHO.SYS w/e/l/c/o/m/e ..
DEVICE=C:\DOS71\ECHO.SYS c/o/p/y/r/i/g/h/t ..
DEVICE=C:\DOS71\HIMEM.SYS
...
SHELL=COMMAND.COM /P /E:640
...
SET PATH=C:\DOS71; ..;
注:SHELL行表示SHELL環(huán)境使用command.com,啟動(dòng)的工作路徑為C:\DOS71,環(huán)境
大小是640字節(jié),/p表示這個(gè)是父進(jìn)程,不能夠關(guān)閉或使用exit退出。更多詳細(xì)內(nèi)容請(qǐng)參
考wiki。
根據(jù)CONFIG.SYS配置加載相應(yīng)的SHELL,MS-DOS一般為COMMAND.COM
處理COMMAND.COM時(shí),會(huì)調(diào)用AUTOEXEC.BAT批處理腳本
AUTOEXEC.BAT里面的命令都是可以SHELL環(huán)境下執(zhí)行的,主要作用是設(shè)置一些環(huán)境變
量。如鍵盤(pán),聲卡等等。同時(shí)也會(huì)初始一些低級(jí)的系統(tǒng)工具,如磁盤(pán)緩存,鼠標(biāo)驅(qū)動(dòng),
鍵盤(pán)驅(qū)動(dòng)等。最后顯示命令提示符。
二、基于MS-DOS的Windows啟動(dòng)過(guò)程
Windows 3.x/95/98/Me 前期引導(dǎo)的由MS-DOS負(fù)責(zé)。在啟動(dòng)階段,處理config.sys和執(zhí)行autoexec.bat
同時(shí)會(huì)讀取配置文件WIN.INI和SYSTEM.INI,并加載相應(yīng)的虛擬設(shè)備驅(qū)動(dòng)(從SYSTEM.INI或者
HKLM\System\CurrentControlSet\Services\VxD)。所有系統(tǒng)配置文件和設(shè)備驅(qū)動(dòng)都被加載后,32
位vxd消息服務(wù)(Msgsrv32)會(huì)啟動(dòng)mprexe.exe,準(zhǔn)備用戶登錄和網(wǎng)絡(luò)登陸,當(dāng)用戶登陸到Windows
后,系統(tǒng)加載Explorer.exe,進(jìn)入Windows。
基于MS-DOS的Windows,可以在啟動(dòng)到DOS的命令提示符下,鍵入win,手工啟動(dòng)Windows。
此時(shí)實(shí)際上是調(diào)用win.com文件。
詳細(xì)的啟動(dòng)過(guò)程見(jiàn)轉(zhuǎn)載的《Win 98系統(tǒng)啟動(dòng)過(guò)程全揭密》一文。
http://blog.csdn.net/liwei_cmg/archive/2008/09/15/2931385.aspx
三、基于Win NT 操作系統(tǒng)的啟動(dòng)過(guò)程
WIN NT與基于DOS的Windows有顯著的不同,其操作系統(tǒng)引導(dǎo)程序?yàn)?NTLDR。引導(dǎo)啟動(dòng)過(guò)程
如下:
x86或x64平臺(tái)下,計(jì)算機(jī)以實(shí)模式啟動(dòng)并加載NTLDR。NTLDR是一個(gè)二進(jìn)制文件,有兩部分
組成,StartUp module 和 OS loader 。StartUp module 的主要任務(wù)就是將計(jì)算機(jī)切換到保護(hù)模式。
OS loader 主要包括識(shí)別訪問(wèn)IDE硬盤(pán)的分區(qū)文件系統(tǒng)(如FAT, NTFS等等)的基本功能,如果是
SCSI硬盤(pán),還需要加載Ntbootdd.sys文件,獲取相應(yīng)的SCSI驅(qū)動(dòng)。
引導(dǎo)程序接著讀取boot.ini配置文件,并顯示用戶選擇操作系統(tǒng)菜單。如果boot.ini丟失,系統(tǒng)會(huì)
缺省選擇C:\Windows目錄。
這個(gè)時(shí)候,Windows 2000以及后續(xù)版本的ntldr,會(huì)去查找hiberfil.sys(休眠文件,與內(nèi)存等同大
小,是上次操作系統(tǒng)休眠時(shí)的內(nèi)存鏡象),將此文件讀取并加載內(nèi)存。
boot.ini文件內(nèi)容示例:
[boot loader]
timeout=30
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
multi(a)disk(b)rdisk(c)partition(d)這部分內(nèi)容是關(guān)鍵,是采用ARC命名規(guī)則。ARC第一部分用
于標(biāo)識(shí)硬件適配卡(磁盤(pán)控制器),即為multi或者scsi選項(xiàng),這里使用的是multi。multi表示一個(gè)非
scsi硬盤(pán)或一個(gè)由scsi bios訪問(wèn)的scsi硬盤(pán),而scsi則表示一個(gè)scsi bios禁止的scsi硬盤(pán)。
(a)表示磁盤(pán)控制器的序號(hào),從0開(kāi)始。
disk(b),僅對(duì)multi項(xiàng)有意義,表示磁盤(pán)控制器的硬盤(pán)序號(hào),從0開(kāi)如。
rdisk(c),僅對(duì)scsi項(xiàng)有意義,表示磁盤(pán)控制器的硬盤(pán)序號(hào),從0開(kāi)始。
partition(d),表示對(duì)應(yīng)硬盤(pán)分區(qū)號(hào),從1開(kāi)始。
注意,當(dāng)只有一個(gè)操作系統(tǒng)選擇項(xiàng)時(shí),啟動(dòng)菜單不會(huì)顯示。用戶選擇操作系統(tǒng),如果不是基
于NT的操作系統(tǒng),NTLDR會(huì)讀取bootsect.dos,并交付計(jì)算機(jī)的控制權(quán)。如果選擇的是基于NT
的操作系統(tǒng),接下來(lái)NTLDR會(huì)執(zhí)行ntdetect.com,收集硬件信息。此時(shí),NTLDR清屏并顯示
Windows啟動(dòng)進(jìn)度條,這時(shí)如果按下F8,會(huì)顯示高級(jí)啟動(dòng)菜單,包括安全模式選項(xiàng)。
收集完所有相關(guān)硬件信息后,接著啟動(dòng)NToskrnl.exe(NT 操作系統(tǒng)內(nèi)核文件), 并讀取加載硬
件抽象層文件(hal.dll)。如果有文件丟失,系統(tǒng)會(huì)提示 "Windows could not start because the following file
was missing or corrupt",并終止啟動(dòng)。這時(shí)系統(tǒng)控制權(quán)交由內(nèi)核,顯示W(wǎng)indows Logo。
加載內(nèi)核時(shí),啟動(dòng)的硬件設(shè)備信息保存在 HKLM\SYSTEM,可以看到一系列鍵值組成Control Set,
如ControlSet001,ControlSet003,ControlSet004,CurrentControlSet等。Windows使用CurrentControlSet
讀取存取當(dāng)前信息。Windows在啟動(dòng)過(guò)程中使用HKLM\SYSTEM\Select確定對(duì)應(yīng)的鍵值。
Default NTLDR的默認(rèn)選擇,F(xiàn)ailed 值如果等于 Default值,NTLDR會(huì)顯示錯(cuò)誤信息,并提示
菜單是否以最后一次正確配置信息啟動(dòng)(LastKnownGood),如果用戶選擇LastKnownGood,Default
值也被修改為L(zhǎng)astKnownGood的值。
內(nèi)核啟動(dòng)過(guò)程:
ntoskrnl.exe 內(nèi)核
hal.dll 硬件抽象層
kdcom.dll 內(nèi)核調(diào)試擴(kuò)展dll
bootvid.dll windows logo 以及進(jìn)度條顯示
配置信息注冊(cè)表位置
HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\BootExecute
以相應(yīng)順序 HKLM\SYSTEM\CurrentControlSet\Control\ServiceGroupOrder 啟動(dòng)服務(wù),這
時(shí)會(huì)顯示進(jìn)度條,Windows 2000以前版本進(jìn)度條能反映服務(wù)加載,Server 2003和XP則是意
思一下,服務(wù)加載是異步的。
所有的設(shè)備驅(qū)動(dòng)加載好了以后,NToskrnl.exe啟動(dòng)Session Manager Subsystem (smss.exe)。
在所有文件打開(kāi)之前,smss.exe啟動(dòng)Autochk。Autochk 掛載(mount)所有的驅(qū)動(dòng),檢查是否正常,
上一次關(guān)閉是否徹底,否則會(huì)啟動(dòng)chkdsk進(jìn)行掃描修復(fù),即我們常見(jiàn)的Check Disk。Session Manager Subsystem
配置信息位置:HKLM\SYSTEM\CurrentControlSet\Control\Session Manager。
啟動(dòng)時(shí),smss.exe處理過(guò)程:
創(chuàng)建環(huán)境變量 HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment
啟動(dòng)內(nèi)核態(tài)Win32子系統(tǒng)(win32k.sys),允許windows切換到圖形化
啟動(dòng)用戶態(tài)Win32子系統(tǒng)Client/Server Runtime Server Subsystem (csrss.exe)
創(chuàng)建虛擬內(nèi)存頁(yè) HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management
啟動(dòng)winlogon.exe, 加裁 Graphical Identification And Authentication (GINA) ,提供用戶登錄支持
Winlogon啟動(dòng)過(guò)程:
Winlogon 調(diào)用 GINA ,出現(xiàn)登錄提示框,用戶輸入用戶名密碼
Winlogon 啟動(dòng) Local Security Authority Subsystem Service (lsass.exe) 驗(yàn)證登錄
Winlogon 啟動(dòng) Service Control Manager (SCM) ,SCM依此啟動(dòng)設(shè)置為自動(dòng)啟動(dòng)的服務(wù)
Winlogon之后的階段就是用戶登錄階段了。
用戶登錄階段:
更新Control Sets的LastKnownGood
用戶計(jì)算機(jī)的組策略被應(yīng)用
啟動(dòng)如下位置的應(yīng)用
HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce
HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\policies\Explorer\Run
HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Run
HKCU\Software\Microsoft\Windows NT\CurrentVersion\Windows\Run
HKCU\Software\Microsoft\Windows\CurrentVersion\Run
HKCU\Software\Microsoft\Windows\CurrentVersion\RunOnce
All Users ProfilePath\Start Menu\Programs\Startup\
Current User ProfilePath\Start Menu\Programs\Startup\
Windows NT format 命令會(huì)將 Volume Boot Record 寫(xiě)入磁盤(pán),主要是為了運(yùn)行 NTLDR 程序。
在 Windows Vista 和 Windows Server 2008,NTLDR 不在使用,其被 winload.exe 和 Windows
Boot Manager 所替代。
四、Windows Vista 啟動(dòng)過(guò)程
Wiki 關(guān)于 Vista 的啟動(dòng)預(yù)覽:
Bios > Master Boot Record > Boot Sector > Windows Boot Manager > Read from BCD >
Search for hibernation file > Start winload.exe > Start ntoskrnl.exe > Start smss.exe >
Start winlogon.exe > start services and login interface
Vista 啟動(dòng)過(guò)程與 NT 內(nèi)核的操作系統(tǒng)稍有區(qū)別。Boot Sector 加載的是 Windows Boot Manager
(Bootmgr.) ,然后讀取 Boot Configuration Da
的是NTLDR。
Boot Configuration Da
可以使用bcdedit.exe進(jìn)行編輯。
winload.exe是操作系統(tǒng)的引導(dǎo)程序,由Windows Boot Manager調(diào)用,與NT下NTLDR功能是等
同的。
五、Linux 啟動(dòng)過(guò)程
很容易發(fā)現(xiàn),計(jì)算機(jī)啟動(dòng)的控制權(quán)都是如下變化,BIOS->Boot Loader->Kernel。Linux也不例外。
之前的文章《Linux手機(jī)DIY.內(nèi)核初探.系統(tǒng)后臺(tái)啟動(dòng)簡(jiǎn)單介紹》http://blog.csdn.net/liwei_cmg/archive/2006/11/28/1418109.aspx
也曾對(duì)Linux啟動(dòng)作過(guò)介紹,不過(guò)偏重于手機(jī)嵌入式的實(shí)際代碼,這里我想只就理論體系去簡(jiǎn)單說(shuō)明。
要理解內(nèi)核啟動(dòng)的具體詳細(xì)過(guò)程,就需要對(duì)內(nèi)核源碼有全面的認(rèn)識(shí),目前自感缺乏這方面的知識(shí)。
啟動(dòng)概覽:
機(jī)器加電啟動(dòng) BIOS
引導(dǎo)階段 Boot loader stage 1 (MBR) Boot loader stage 2 (LILO, GRUB ...)
啟動(dòng)內(nèi)核 (linux)
初始化 INIT (用戶)
Boot loader 階段:
系統(tǒng)實(shí)模式下執(zhí)行引導(dǎo)扇區(qū)代碼,部分加載引導(dǎo)程序(Boot loader)后,將控制權(quán)交給引導(dǎo)程序。
Linux引導(dǎo)程序通常為lilo和grub。接著引導(dǎo)程序?qū)⑹S嗟膬?nèi)容加載到內(nèi)存,并準(zhǔn)備選擇待引導(dǎo)的操
作系統(tǒng)。
<GRUB>
Boot loader stage 1,BIOS 讀取執(zhí)行 MBR,然后繼續(xù)引導(dǎo) Boot loader stage 2。
Boot loader stage 2,控制權(quán)已經(jīng)在GRUB手中,如果這部分的代碼在一個(gè)大磁盤(pán)驅(qū)動(dòng)器上,還
需要加載Boot loader stage 1.5,其中包括對(duì)超過(guò)1024柱面和LBA驅(qū)動(dòng)器的支持。Boot loader stage 1.5
可以存放在MBR,也可以存放在分區(qū)上。Boot loader stage 2 執(zhí)行并顯示 GRUB 操作系統(tǒng)選擇
菜單,也允許修改操作系統(tǒng)環(huán)境和參數(shù)。GRUB支持訪問(wèn)文件系統(tǒng),本身的配置文件就是存放在
分區(qū)文件系統(tǒng)下,便于調(diào)整修改。/boot/grub 目錄中包含了 stage1、stage1.5 和 stage2 GRUB
引導(dǎo)加載程序等。
注:《服務(wù)器配置實(shí)例(一).HP Prolient ML570 服務(wù)器》http://blog.csdn.net/liwei_cmg/archive/2007/05/20/1618174.aspx
一文中就介紹了GRUB不能引導(dǎo)的處理方法。
GRUB配置文件/etc/grub.conf,內(nèi)容示例:
# grub.conf generated by anaconda
#
# Note that you do not have to rerun grub after making changes to this file
# NOTICE: You do not have a /boot partition. This means that
# all kernel and initrd paths are relative to /, eg.
# root (hd0,0)
# kernel /boot/vmlinuz-version ro root=/dev/sda1
# initrd /boot/initrd-version.img
#boot=/dev/sda
default=0
timeout=10
splashimage=(hd0,0)/boot/grub/splash.xpm.gz
title Red Hat Linux (2.4.20-8)
root (hd0,0)
kernel /boot/vmlinuz-2.4.20-8 ro root=LABEL=/
initrd /boot/initrd-2.4.20-8.img
<LILO>
LILO方式是比較古老的方式,不支持文件系統(tǒng),其引導(dǎo)代碼直接存放在MBR區(qū)。系統(tǒng)一旦引導(dǎo)
失敗后,只能通過(guò)軟盤(pán)啟動(dòng)盤(pán)之類(lèi)的方式加以修復(fù)。LILO直接使用裸設(shè)備方式讀取數(shù)據(jù),顯示菜單
以便用戶選擇操作系統(tǒng),并加以引導(dǎo)。
LILO啟動(dòng)配置文件為/etc/lilo.conf,內(nèi)容示例:
prompt
timeout=50
default=linux
boot=/dev/sda
map=/boot/map
install=/boot/boot.b
message=/boot/message
linear
image=/boot/vmlinuz-2.4.20-8
label=linux
initrd=/boot/initrd-2.4.20-8.img
read-on
append="root=LABEL=/"
Kernel 內(nèi)核階段:
引導(dǎo)程序?qū)inux內(nèi)核映象加載到內(nèi)存中,這個(gè)內(nèi)核映象并不是可執(zhí)行的內(nèi)核,是經(jīng)過(guò)壓縮
后的內(nèi)核,通常是一個(gè)zImage(小于512K)或者bzImage(大于512K) ,需要調(diào)用zlib進(jìn)行解壓縮。
內(nèi)核加載時(shí)會(huì)處理一些硬件上的設(shè)置,并將內(nèi)核映象完全解壓縮到高位內(nèi)存區(qū),加載RAM disk,
然后啟動(dòng)內(nèi)核。
<x86 系列的執(zhí)行過(guò)程>
《Linux手機(jī)DIY.內(nèi)核初探.系統(tǒng)后臺(tái)啟動(dòng)簡(jiǎn)單介紹》http://blog.csdn.net/liwei_cmg/archive/2006/11/28/1418109.aspx
一文中雖然介紹的是arm系列的CPU,但從過(guò)程來(lái)講是相似的,簡(jiǎn)單列下調(diào)用過(guò)程。
arch/i386/boot/head.S start()
arch/i386/boot/compress/head.S startup_32()
arch/i386/boot/compress/misc.c decompress_kernel()
arch/i386/kernel/head.S startup_32()
init/main.c start_kernel()
init/main.c cpu_idle()
pivot_root ()
完成解壓縮后的 startup_32 () 函數(shù)(也稱為清除程序或進(jìn)程 0),會(huì)進(jìn)行內(nèi)存管理(頁(yè)表初
始化,內(nèi)存分頁(yè))。然后檢測(cè) CPU 的類(lèi)型以及可選的浮點(diǎn)單元(FPU),最后調(diào)用 start_kernel
函數(shù),進(jìn)入體系結(jié)構(gòu)無(wú)關(guān)的 Linux 內(nèi)核部分。其實(shí)可以理解為 Linux 內(nèi)核的 main 函數(shù)。
start_kernel () 完成大部分的初始化任務(wù),設(shè)置IRQs,內(nèi)存配置,啟動(dòng)init進(jìn)程(第一個(gè)用戶進(jìn)程),
最后啟動(dòng)空任務(wù)cpu_idle()。這時(shí)進(jìn)程調(diào)度接管了計(jì)算機(jī)的控制權(quán),通過(guò)啟用中斷,可以提供多
任務(wù)處理能力。
內(nèi)核啟動(dòng)過(guò)程中同時(shí)也掛載了 initial RAM disk ("initrd") ,先前已加載,用戶系統(tǒng)啟動(dòng)的臨時(shí)root
文件目錄。這使得加載驅(qū)動(dòng)模塊時(shí)不必要使用物理磁盤(pán)或者其他磁盤(pán)驅(qū)動(dòng),減小了內(nèi)核體積。
內(nèi)核啟動(dòng)會(huì)調(diào)用 pivot_root () ,卸載RAM disk,代替它的是真正的磁盤(pán)文件系統(tǒng)。RAM disk
使用的內(nèi)存同時(shí)也被回收。
上述工作完成后,啟動(dòng)init進(jìn)程(通常為/sbin/init)。init是所有進(jìn)程的父進(jìn)程,主要任務(wù)就是根據(jù)
/etc/inittab配置文件創(chuàng)建相應(yīng)進(jìn)程。init,inittab相關(guān)知識(shí)相參考man手冊(cè)。
六、寫(xiě)在最后
文章的整理頗費(fèi)時(shí)間,回顧整個(gè)系列,自感對(duì)存儲(chǔ)相關(guān)的知識(shí)作了一次較為全面的梳理,從技術(shù)
到物理設(shè)備,再到邏輯結(jié)構(gòu),操作系統(tǒng),每個(gè)知識(shí)點(diǎn)都有極為深層的內(nèi)容。相信大多數(shù)人只停留在
皮毛,而這個(gè)系列已不在是皮毛,已接觸到了皮層。
聯(lián)系客服