Linux 系統(tǒng)開機(jī)加電后發(fā)生了什么?
掃描二維碼
隨時(shí)隨地手機(jī)看文章
-
POST自檢
-
BIOS(Boot Sequence)
-
加載對應(yīng)引導(dǎo)上的MBR(bootloader)
-
主引導(dǎo)設(shè)置加載其BootLoader
啟動BIOS,準(zhǔn)備實(shí)模式下的中斷向量表和中斷服務(wù)程序
電腦啟動后,CPU邏輯電路被設(shè)計(jì)為只能運(yùn)行內(nèi)存中的程序,沒有能力直接運(yùn)行存在于軟盤或硬盤中的操作系統(tǒng),如果想要運(yùn)行,必須要加載到內(nèi)存(RAM)中。
POST自檢
BIOS的第一步動作就是進(jìn)行 上電自檢(POST)
初始化設(shè)備
BIOS的第二步動作就是 枚舉本地設(shè)備并初始化
BIOS-runtime服務(wù)按照boot啟動順序搜索設(shè)備,尋找BBR
由于BIOS功能使用上的不同,它由兩個部分組成:POST和runtime服務(wù)。POST完成后,它將從存儲器中被清除,但是BIOS runtime服務(wù)會被保留,用于目標(biāo)操作系統(tǒng)。
引導(dǎo)操作系統(tǒng)內(nèi)核并為保護(hù)模式做準(zhǔn)備
位于MBR中的主 boot loader 是一個512字節(jié)的鏡像,其中不僅包含了 bootload 程序代碼,還包含了一個小的分區(qū)表。
把第一階段和第二階段的 boot loaders 聯(lián)合起來,就是在x86個人電腦中,我們所說的 linux loader(LILO)或者 GRand Unified Bootloader(GRUB)。由于 GRUB 修正了一些 LILO 中存在的缺陷,因此下面就讓我們來看看 GRUB(如果你希望得到更多的關(guān)于 GRUB,LILO 和與之相關(guān)話題的討論資源,請見文后的參考資料)在次 boot loader 存在與內(nèi)存中后,就可以對文件系統(tǒng)進(jìn)行查詢了,同時(shí)將默認(rèn)的內(nèi)核鏡像以及初始化內(nèi)存盤鏡像也被加載到內(nèi)存中。
對于 GRUB 來說,一個比較好的方面就是它包含了 linux 文件系統(tǒng)的知識。與LILO使用裸扇區(qū)不同的是,GRUB 能夠從 ext2 或者 ext3 文件系統(tǒng)中加載 linux 內(nèi)核。它是通過將本來兩階段的 boot loader 轉(zhuǎn)換成三個階段的 boot loader。在第一階段(MBR)中會啟動 stage1.5 的 boot loader 來理解 linux 內(nèi)核鏡像中的特殊的文件系統(tǒng)格式,例如,reiserfs_stage1-5(用于從reiserf日志文件系統(tǒng)中進(jìn)行加載)或 e2fs stage1_5 (用于從wxt2或ext3文件系統(tǒng)進(jìn)行加載)。當(dāng) stage1.5 的 boot loader 被加載并運(yùn)行時(shí),stage2 的 boot loader 才能被加載。當(dāng) stage2 被加載時(shí),GRUB能根據(jù)請求的情況顯示一個可選內(nèi)核的清單(在 /etc/grub.conf 中進(jìn)行定義,同時(shí)還有幾個軟符號鏈接 /etc/grub/menu.lst 和 /etc/grub.conf)。你可以選擇一個內(nèi)核,修改其附加的內(nèi)核參數(shù)。同時(shí),你可以選擇使用命令行的shell來對啟動過程進(jìn)行更深層次的手工控制。
加載內(nèi)核并從實(shí)模式轉(zhuǎn)換為保護(hù)模式
當(dāng)內(nèi)核映像被加載到內(nèi)存中(加載過程仍然用int 0x13中斷向量),并且次引導(dǎo)加載程序釋放控制權(quán)之后,內(nèi)核階段就開始了。
加載內(nèi)核鏡像
內(nèi)核映像并不是一個可執(zhí)行的內(nèi)核,而是一個壓縮過的內(nèi)核映像。通常它是一個 zImage(壓縮映像,小于 512KB)或一個 bzImage(較大的壓縮映像,大于 512KB),它是提前使用 zlib 進(jìn)行壓縮過的。在這個內(nèi)核映像前面是一個例程,它實(shí)現(xiàn)少量硬件設(shè)置,并對內(nèi)核映像中包含的內(nèi)核進(jìn)行解壓,然后將其放入高端內(nèi)存中,如果有初始 RAM 磁盤映像,就會將它移動到內(nèi)存中,并標(biāo)明以后使用。然后該例程會調(diào)用內(nèi)核,并開始啟動內(nèi)核引導(dǎo)的過程。
進(jìn)入保護(hù)模式并初始化
-
進(jìn)入保護(hù)模式
-
設(shè)置中斷描述附表和全局描述符表
-
創(chuàng)建了內(nèi)存分頁機(jī)制
啟動內(nèi)核
-
start_kernel啟動內(nèi)核
-
創(chuàng)建init進(jìn)程
BIOS階段–準(zhǔn)備實(shí)模式下的中斷向量表和中斷服務(wù)程序
BIOS是什么
上個世紀(jì)70年代初,”只讀內(nèi)存”(read-only memory,縮寫為ROM)發(fā)明,開機(jī)程序被刷入ROM芯片,計(jì)算機(jī)通電后,第一件事就是讀取它。計(jì)算機(jī),啟動這塊芯片里的程序叫做”基本輸出輸入系統(tǒng)”(Basic Input/Output System),簡稱為BIOS。
BIOS存儲的信息
BIOS芯片中主要存放:
-
自診斷程序:通過讀取CMOSRAM中的內(nèi)容識別硬件配置,并對其進(jìn)行自檢和初始化;
-
CMOS設(shè)置程序:引導(dǎo)過程中,用特殊熱鍵啟動,進(jìn)行設(shè)置后,存入CMOS RAM中;
-
系統(tǒng)自舉裝載程序:在自檢成功后將磁盤相對0道0扇區(qū)上的引導(dǎo)程序裝入內(nèi)存,讓其運(yùn)行以裝入DOS系統(tǒng);
-
主要I/O設(shè)備的驅(qū)動程序和中斷服務(wù):由于BIOS直接和系統(tǒng)硬件資源打交道,因此總是針對某一類型的硬件系統(tǒng),而各種硬件系統(tǒng)又各有不同,所以存在各種不同種類的BIOS,隨著硬件技術(shù)的發(fā)展,同一種BIOS也先后出現(xiàn)了不同的版本,新版本的BIOS比起老版本來說,功能更強(qiáng)。
BIOS是如何啟動的
CPU硬件邏輯設(shè)計(jì)為在加電瞬間強(qiáng)行將CS值置為0XF000,IP為0XFFF0,這樣CS:IP就指向0XFFFF0這個位置,這個位置正是BIOS程序的入口地址。
BIOS需要在內(nèi)存中加載中斷向量表和中斷服務(wù)程序
BIOS程序被固化在計(jì)算機(jī)主機(jī)板上的一塊很小的ROM芯片里?,F(xiàn)在CS:IP已經(jīng)指向了0XFFFF0這個位置,意味著BIOS開始啟動。隨著BIOS程序的執(zhí)行,屏幕上會顯示顯卡的信息,內(nèi)存的信息,說明BIOS程序在檢測顯卡,內(nèi)存,這個就是POST開機(jī)自檢期間,有一項(xiàng)對啟動操作系統(tǒng)至關(guān)重要的工作,那就是BIOS在內(nèi)存中建立中斷向量表和中斷服務(wù)程序
BIOS階段的工作
POST開機(jī)自檢
BIOS程序首先檢查,計(jì)算機(jī)硬件能否滿足運(yùn)行的基本條件,這叫做”硬件自檢”(Power-On Self-Test),縮寫為POST。如果硬件出現(xiàn)問題,主板會發(fā)出不同含義的蜂鳴,啟動中止。如果沒有問題,屏幕就會顯示出CPU、內(nèi)存、硬盤等信息。
-
對于嚴(yán)重故障(致命性故障)則停機(jī),此時(shí)由于各種初始化操作還沒完成,不能給出任何提示或信號;
-
對于非嚴(yán)重故障則給出提示或聲音報(bào)警信號,等待用戶處理),如果沒有故障,POST完整自己的接力任務(wù),將尾部工作交接給BIOS處理
加載BIOS
BIOS把控制權(quán)轉(zhuǎn)交給下一階段的啟動程序。
引導(dǎo)操作系統(tǒng)
硬件自檢完成后,我們期望能否啟動操作系統(tǒng),但是問題出來了
-
操作系統(tǒng)存放在哪?
-
BIOS如何找到操作系統(tǒng)?
-
BIOS如何加載操作系統(tǒng)?
背景知識
多操作系統(tǒng)時(shí)的啟動順序
主引導(dǎo)記錄 MBR
位于MBR中的主boot loader是一個512字節(jié)的鏡像,其中不僅包含了程序代碼,還包含了一個小的分區(qū)表。
-
第1-446字節(jié):調(diào)用操作系統(tǒng)的機(jī)器碼。
-
第447-510字節(jié):分區(qū)表(Partition table)。
-
第511-512字節(jié):主引導(dǎo)記錄簽名(0x55和0xAA)。
分區(qū)表
硬盤分區(qū)有很多好處。考慮到每個區(qū)可以安裝不同的操作系統(tǒng),”主引導(dǎo)記錄”因此必須知道將控制權(quán)轉(zhuǎn)交給哪個區(qū)。分區(qū)表的長度只有64個字節(jié),里面又分成四項(xiàng),每項(xiàng)16個字節(jié)。所以,一個硬盤最多只能分四個一級分區(qū),又叫做“主分區(qū)”。
-
第1個字節(jié):如果為0x80,就表示該主分區(qū)是激活分區(qū),控制權(quán)要轉(zhuǎn)交給這個分區(qū)。四個主分區(qū)里面只能有一個是激活的。
-
第2-4個字節(jié):主分區(qū)第一個扇區(qū)的物理位置(柱面、磁頭、扇區(qū)號等等)。
-
第5個字節(jié):主分區(qū)類型。
-
第6-8個字節(jié):主分區(qū)最后一個扇區(qū)的物理位置。
-
第9-12字節(jié):該主分區(qū)第一個扇區(qū)的邏輯地址。
-
第13-16字節(jié):主分區(qū)的扇區(qū)總數(shù)。
-
一是提高每個扇區(qū)的字節(jié)數(shù),
-
二是增加扇區(qū)總數(shù)。
引導(dǎo)操作系統(tǒng)的過程
由硬盤啟動時(shí),BIOS通常是轉(zhuǎn)向第一塊硬盤的第一個扇區(qū),即主引導(dǎo)記錄(MBR)。裝載GRUB和操作系統(tǒng)的過程,包括以下幾個操作步驟:
加載主引導(dǎo)加載程序-基本裝載程序
眾所周知,硬盤上第0磁道第一個扇區(qū)被稱為MBR,也就是Master Boot Record,即主引導(dǎo)記錄,它的大小是512字節(jié),別看地方不大,可里面卻存放了預(yù)啟動信息、分區(qū)表信息。
MBR程序只是找到只是硬盤分區(qū)內(nèi)最前面的446個字節(jié)的Boot Loader,然后查找相關(guān)配置和定義。然后將控制權(quán)交給主引導(dǎo)代碼。主引導(dǎo)代碼的任務(wù)包括
-
掃描分區(qū)表,找到一個激活(可引導(dǎo))分區(qū);
-
找到激活分區(qū)的起始扇區(qū);
-
將激活分區(qū)的引導(dǎo)扇區(qū)裝載到內(nèi)存7C00處;
-
將控制權(quán)交給引導(dǎo)扇區(qū)代碼;
加載次引導(dǎo)記載程序–高級裝載程序bootload如GRUB
系統(tǒng)讀取內(nèi)存中的grub配置信息(一般為menu.lst或grub.lst),并依照此配置信息來啟動不同的操作系統(tǒng)。
為什么這么復(fù)雜
早期的操作系統(tǒng)并沒有那么復(fù)雜,當(dāng)然bootload也沒有那么多功能,但是如今我們的操作系統(tǒng)越來越復(fù)雜,bootload也越來越龐大,而且如今在一臺電腦上安裝多系統(tǒng)變得那么平常,因此之前簡單的bootload已經(jīng)無法滿足這些功能。
-
提供菜單:用戶可以選擇不同的開機(jī)選項(xiàng),這也是多重引導(dǎo)的重要功能
-
載入內(nèi)核文件:直接指向可開機(jī)的程序段來開始操作系統(tǒng)。
-
轉(zhuǎn)交其他Loader:將引導(dǎo)加載功能轉(zhuǎn)交給其他loader負(fù)責(zé)
-
每個分區(qū)都有自己的啟動扇區(qū)
-
系統(tǒng)分區(qū)為第一及第二分區(qū)
-
實(shí)際可開機(jī)的內(nèi)核文件是放置到各分區(qū)內(nèi)的
-
loader只會認(rèn)識自己的系統(tǒng)分區(qū)內(nèi)的可開機(jī)內(nèi)核文件,以及其他的Loader而已
-
loader可直接指向或者是間接將管理權(quán)交給另一個管理程序
現(xiàn)在想一下,為什么人家常說:”如果要安裝多重引導(dǎo),最好先安裝Windows再安裝Linux呢“?
這是因?yàn)長inux在安裝時(shí),你可以選擇將引導(dǎo)加載程序安裝在MBR或個別分區(qū)的啟動扇區(qū),而且Linux的Loader可以手動設(shè)置菜單,所以你可以在Linux的Boot Loader里面加入Windows開機(jī)選項(xiàng)
Windows在安裝的時(shí)候,他的安裝程序會主動覆蓋掉MBR以及自己所在分區(qū)的啟動扇區(qū),你沒有選擇的機(jī)會,而且他沒有讓我們自己選擇菜單功能
加載操作系統(tǒng)內(nèi)核
用戶選擇要加載的內(nèi)核之后,次引導(dǎo)加載程序(GRUB)就會根據(jù)/boot/grub.conf配置文件中所設(shè)置的信息,從/boot/所在的分區(qū)上讀取Linux內(nèi)核映像,然后把內(nèi)核映像加載到內(nèi)存中并把控制權(quán)交給Linux內(nèi)核。
-
檢測硬件
-
解壓縮自己并安裝必要驅(qū)動
-
初始化與文件系統(tǒng)相關(guān)的虛擬設(shè)備,LVM或RAID
-
裝載根文件系統(tǒng),掛在根目錄下面
-
完成之后,linux在進(jìn)程空間里面加載init程序,下面輪到init干活
-
0:關(guān)機(jī)
-
1:單用戶模式
-
2:無網(wǎng)絡(luò)支持的多用戶模式
-
3:有網(wǎng)絡(luò)支持的多用戶模式
-
4:保留,未使用
-
5:有網(wǎng)絡(luò)支持有X-Window支持的多用戶模式
-
6:重新引導(dǎo)系統(tǒng),即重啟
init進(jìn)程執(zhí)行rc.sysinit
在設(shè)定了運(yùn)行等級后,Linux系統(tǒng)執(zhí)行的第一個用戶層文件就是/etc/rc.d/rc.sysinit腳本程序,它做的工作非常多,包括設(shè)定PATH、設(shè)定網(wǎng)絡(luò)配置(/etc/sysconfig/network)、啟動swap分區(qū)、設(shè)定/proc等等。如果你有興趣,可以到/etc/rc.d中查看一下rc.sysinit文件,里面的腳本夠你看幾天的
啟動內(nèi)核模塊
具體是依據(jù)/etc/modules.conf文件或/etc/modules.d目錄下的文件來裝載內(nèi)核模塊。
執(zhí)行不同運(yùn)行級別的腳本程序
根據(jù)運(yùn)行級別的不同,系統(tǒng)會運(yùn)行rc0.d到rc6.d中的相應(yīng)的腳本程序,來完成相應(yīng)的初始化工作和啟動相應(yīng)的服務(wù)。
執(zhí)行/etc/rc.d/rc.local
你如果打開了此文件,里面有一句話,讀過之后,你就會對此命令的作用一目了然:
# You can put your own initialization stuff in here if you don’t
# want to do the full Sys V style init stuff.
rc.local就是在一切初始化工作后,Linux留給用戶進(jìn)行個性化的地方。你可以把你想設(shè)置和啟動的東西放到這里。
執(zhí)行/bin/login程序,進(jìn)入登錄狀態(tài)
此時(shí),系統(tǒng)已經(jīng)進(jìn)入到了等待用戶輸入username和password的時(shí)候了,你已經(jīng)可以用自己的帳號登入系統(tǒng)了。