一個Linux系統(tǒng)的組成部分
Linux系統(tǒng)組成部分:內(nèi)核+根文件系統(tǒng)粉寞;理解這個概念非常重要化焕,簡單來說,系統(tǒng)啟動就是為了啟動內(nèi)核坝咐,讓內(nèi)核加載根文件系統(tǒng)循榆,最后執(zhí)行初始化程序。
Linux開機(jī)啟動流程
首先簡要概括下Linux系統(tǒng)的啟動流程
從按下電源鍵開始墨坚,Linux的啟動流程大概如下
1.POST自檢
2.按順序?qū)ふ乙龑?dǎo)程序
3.啟動內(nèi)核
4.內(nèi)核加載根文件系統(tǒng)
5.啟動init程序
下面來詳細(xì)說明下各啟動階段都做了什么
一秧饮、POST自檢
POST自檢主要對硬件設(shè)備的檢查設(shè)備的運(yùn)行狀態(tài),POST自檢也是一個程序泽篮,安裝在主板的的ROM上盗尸,讀取CMOS中的信息,以了解部分硬件的信息帽撑,比如硬件自檢(post)泼各、硬件上的時(shí)間、硬盤大小和型號等亏拉。包括扣蜻,手動進(jìn)入bios界面看到的信息,都是在這一階段獲取到的及塘,如下圖莽使。
當(dāng)硬件掃描完成后,開始讀取第一個設(shè)備的MBR笙僚,如果第一個設(shè)備沒有MBR芳肌,則會讀取第二個。
二肋层、尋找引導(dǎo)程序
硬盤的第一個扇區(qū):MBR(Master Boot Record) 主引導(dǎo)記錄
引導(dǎo)程序?yàn)榱思虞d內(nèi)核而存在亿笤,當(dāng)POST自檢沒問題后,計(jì)算機(jī)會按照用戶所給定的存儲設(shè)備順序來讀取MBR栋猖,為什么讀取MBR净薛,因?yàn)镸BR保存了引導(dǎo)程序,但引導(dǎo)程序不一定安裝在MBR上掂铐,本文這個步驟只針對MBR罕拂,但無論哪種啟動方式都好,目的都是一樣的全陨,為了加載引導(dǎo)程序爆班!
MBR也稱:主引導(dǎo)記錄,位于磁盤的第一個扇區(qū)辱姨,和分區(qū)無關(guān)柿菩,和操作系統(tǒng)無關(guān),注意雨涛,MBR位于磁盤的第一個扇區(qū)枢舶,因此一個硬盤只有一個MBR;
MBR由512 Byte組成
446 Byte:存放引導(dǎo)程序(bootloader);
64 Byte:存放磁盤的分區(qū)表;
最后2 Byte:用于標(biāo)識MBR是否有效,如果BIOS讀取時(shí)替久,發(fā)現(xiàn)MBR最后2個字節(jié)的數(shù)值不是0x55AA,則認(rèn)為這個MBR是沒用的凉泄,會去讀取下一個設(shè)備。
這里需要注意的是蚯根,不要把MBR和bootloader的概念混在一起后众,2個是不同的東西,一定要區(qū)分開颅拦,bootloader存放在MBR中蒂誉;MBR不單單存放bootloader還有存放分區(qū)信息呢。
引導(dǎo)程序
引導(dǎo)程序是為了加載內(nèi)核而存在距帅,引導(dǎo)程序是有很多的右锨,其中,就有g(shù)rub一個碌秸,很多的Linux發(fā)行版使用grub這個程序作為它的引導(dǎo)程序绍移,它有兩個版本。
grub 0.X:Linux5讥电、6使用
grub 1.X:Centos7使用
本文只針對grub 0.X引導(dǎo)程序來說明登夫,grub 0.X也稱為grub lagecy,有三部分組成允趟,也稱為三個階段恼策。stage1,stage1.5,stage2。分別安裝在不同的位置上
stage1: 安裝在MBR的前446個字節(jié)中
stage1.5: 安裝在MBR后面潮剪,第一個分區(qū)前的間隙中
stage2: 放在磁盤某個分區(qū)中
為什么要劃分為三個階段涣楷?
因?yàn)橐龑?dǎo)程序grub實(shí)在太大了(相比起MBR只有446字節(jié)來說)上面三個階段中,stage2才是gurb的核心程序抗碰,它是向我們提供菜單的提供者狮斗,它的代碼量大小,遠(yuǎn)超446字節(jié)弧蝇,是不能直接存放在MBR中碳褒。stage1只是為了加載stage2折砸,但前面說了stage2是存放在磁盤分區(qū)中的,磁盤分區(qū)要想保存文件沙峻,必須擁有文件系統(tǒng)睦授。而要讀取這個文件系統(tǒng)上的文件,是需要驅(qū)動的摔寨,而現(xiàn)在文件系統(tǒng)格式這么多(如ext2,3,4去枷、ntfs、xfs...)而stage1只有446Byte存放引導(dǎo)程序是复,明顯是不夠的删顶,所以引入了stage1.5,stage1.5保存了文件系統(tǒng)驅(qū)動淑廊,用于提供文件系統(tǒng)驅(qū)動協(xié)助stage1加載stage2逗余,當(dāng)stage1有文件驅(qū)動的支持后,才能讀取磁盤分區(qū)上的數(shù)據(jù)季惩,從而能加載stage2
stage1_5的目的之一是識別文件系統(tǒng)猎荠,但文件系統(tǒng)的類型有很多,所以對應(yīng)的stage1_5也有很多種蜀备,如下圖:
這些文件通常存放在/boot/grub目錄下关摇,satge2程序也存放在該目錄下,在安裝系統(tǒng)的時(shí)候碾阁,通常情況下输虱,很多人的做法是把boot分區(qū)單獨(dú)分區(qū),而且分區(qū)格式一般都是比較常見的脂凶,這是為什么呢宪睹?
原因也很簡單,如上圖蚕钦,stage1.5所支持的文件系統(tǒng)不多亭病,某些特殊或比較少見的文件系統(tǒng)是不支持的,而現(xiàn)在也有很多人喜歡把根文件系統(tǒng)掛載到LVM之類的邏輯文件系統(tǒng)嘶居,而grub沒有這類文件系統(tǒng)的驅(qū)動罪帖。如果把boot目錄掛載在grub不能識別的文件系統(tǒng)上,引導(dǎo)就沒辦法進(jìn)行邮屁。所以一般boot單獨(dú)分區(qū)就是因?yàn)檫@個整袁。
順利啟動stage2之后,屏幕應(yīng)當(dāng)顯示一個菜單佑吝,讓用戶選擇要啟動的系統(tǒng)或內(nèi)核坐昙。這個菜單是通過配置文件定義的,配置文件在根目錄下的grub目錄,引導(dǎo)程序的根目錄和內(nèi)核的根目錄是兩回事芋忿,迄今炸客,內(nèi)核還沒啟動疾棵,還沒去找文件系統(tǒng)呢,所以別混肴痹仙。
用戶在菜單中選定了某一功能后是尔,在背后就會按照配置文件的定義來啟動內(nèi)核,grub legacy的配置文件很有意思蝶溶,我會對grub legacy的配置文件作詳細(xì)說明,請查看我的其他文章宣渗。
grub會按照配置文件所給定的參數(shù)來啟動內(nèi)核。
三、啟動內(nèi)核
內(nèi)核存放在哪里究反?grub如何啟動內(nèi)核舟奠?
第一個問題:內(nèi)核存放在哪里?
內(nèi)核文件通常存放在/boot目錄下鞍恢,通常該目錄也是grub程序的根目錄傻粘,內(nèi)核是以bzimage壓縮存放在該目錄中,并且名稱一般都是以vmlinuz-后跟版本號帮掉。這樣的方式來命名
第二個問題:如何啟動內(nèi)核
很簡單弦悉,通過配置文件,該配置文件通常存放在/boot/grub目錄中蟆炊,名字通常為:grub.conf
配置文件定義了各種菜單稽莉,每個一般都對應(yīng)一個內(nèi)核,以及傳遞一些運(yùn)行參數(shù)給內(nèi)核涩搓,
如上圖污秆,開頭的幾個選項(xiàng)是一些通用配置,只要定義默認(rèn)菜單昧甘、超時(shí)時(shí)間和背景圖的一些選項(xiàng)良拼。重點(diǎn)是用紅色框和綠色框的內(nèi)容。
每個title對應(yīng)一個菜單充边,如下圖庸推,title后面的字符串就是菜單所顯示的內(nèi)容。
每個菜單浇冰,基本上都定義了三個類內(nèi)容:root予弧、kernel、initrd
第一個選項(xiàng):root
指定grub以哪個硬盤分區(qū)作為根目錄(hd0,0)是指第一個磁盤第一個分區(qū)的意思湖饱,它的索引從0開始算起掖蛤。
這里說明一下,hd0,0一般掛載在/boot目錄下井厌,如也就是說蚓庭,hd0,0致讥,其實(shí)對應(yīng)sda1(sda1也是第一個磁盤第一個分區(qū)的意思嘛)然后sda1又掛在/boot目錄下,所以指定root=hd0,0器赞;其實(shí)也就是root=/boot的意思垢袱。雖然有點(diǎn)繞,但是最好還是理解一下港柜。
第二個選項(xiàng):kernel
kernel:后面指定壓縮好的內(nèi)核文件存放路徑请契,前面已經(jīng)說了內(nèi)核文件一般存放在/boot目錄下,然后上一個root選項(xiàng)指定了hd0,0作為根目錄夏醉,相當(dāng)于grub的根就是/boot爽锥,所以kernel 后面指定的/vmlinuz-4.14.341其實(shí)說的就是/boot/vmlinuz-4.14.341這個文件。
指定好linux內(nèi)核位置之后畔柔,還需要傳遞參數(shù)給內(nèi)核氯夷,如linux的根文件系統(tǒng)在哪里,這是必須給出的靶擦。
綠框的是位置腮考,因?yàn)槲业母募到y(tǒng)存放在LVM邏輯卷上,所以看上去可能不太好理解玄捕。
第三個選項(xiàng):initrd
理解這個之前踩蔚,先來說明下,內(nèi)核啟動后枚粘,主要的工作就是加載根文件系統(tǒng)寂纪,然后啟動init初始化程序(通常就是/sbin/init),隨后的所有用戶空間的工作全部由init完成赌结,內(nèi)核不關(guān)心用戶空間的程序捞蛋。
內(nèi)核為了加載init程序,需要加載根文件系統(tǒng)柬姚,因?yàn)閕nit程序就是存放在根文件系統(tǒng)的/sbin目錄下拟杉,而加載根文件系統(tǒng)是必須要有文件系統(tǒng)的驅(qū)動。而文件系統(tǒng)的驅(qū)動又在哪里呢量承?答案是在磁盤某個分區(qū)上搬设,內(nèi)核加載磁盤需要磁盤驅(qū)動,而驅(qū)動又存放在磁盤上撕捍,這就有了先有雞還是先有蛋的問題拿穴,那么如何解決呢?
解決方法一:把根文件系統(tǒng)的驅(qū)動以模塊方式嵌入到內(nèi)核中忧风,但文件系統(tǒng)又太多默色,都嵌入到內(nèi)核明顯是不合適的
解決方法二:跟grub那樣,在加載真正的根文件系統(tǒng)之前狮腿,先加載這個臨時(shí)的根文件系統(tǒng)腿宰,然后再去加載真正的根文件系統(tǒng)呕诉。這個臨時(shí)的根文件系統(tǒng),這個臨時(shí)的文件系統(tǒng)是安裝操作系統(tǒng)之后產(chǎn)生的吃度,不是默認(rèn)提供的甩挫,在安裝系統(tǒng)時(shí)候,我們創(chuàng)建好了根文件系統(tǒng)椿每,這個initramdisk就能根據(jù)我們的根文件系統(tǒng)來嵌入對應(yīng)的文件系統(tǒng)驅(qū)動伊者,而不用嵌入其他的驅(qū)動。如圖
initramdisk存放著根文件系統(tǒng)的驅(qū)動生成的initramdisk文件存放在和內(nèi)核一起的目錄亦渗。
在Centos5之前,這個文件名叫:initrd-VERSION-RELEASE.img
在Centos6兑牡、7央碟,這個文件名叫:initramfs-VERSION-RELEASE.img
兩者區(qū)別在于
Linux特性之一:通過使用緩沖/緩存來達(dá)到加速對磁盤上文件的訪問的目的税灌,而ramdisk是加載到內(nèi)存并模擬成磁盤來使用的均函,所以Linux就會為內(nèi)存中的“磁盤”再使用一層緩沖/緩存
CentOS 5系列以及之前版本是存在此問題。
而為了解決一問題菱涤,CentOS 6/7系列版本就將其改為initramfs-VERSION-RELEASE.img苞也,使用文件系統(tǒng)的方式就可以避免雙緩沖/緩存了,我們可以說這是一種提速機(jī)制粘秆。
而且這兩類的臨時(shí)根系統(tǒng)有各自的特點(diǎn)如迟,在其他文章中再說明
以上三個選項(xiàng)內(nèi)容指定好后,grub程序把內(nèi)核和臨時(shí)根文件系統(tǒng)從磁盤中加載到內(nèi)存中并解壓運(yùn)行攻走。內(nèi)核通過臨時(shí)根加載到真正的根文件系統(tǒng)后殷勘,切換到真正的根文件系統(tǒng)中運(yùn)行初始化程序init。
Centos5根6和7的臨時(shí)根文件系統(tǒng)有區(qū)別昔搂,在Centos5中玲销,使用initrd.xxx來作為臨時(shí)根,內(nèi)核通過內(nèi)核線程來先掛載真正的根文件系統(tǒng)摘符,然后再運(yùn)行Init程序贤斜。而Centos6和7使用initramfs.xxx作為臨時(shí)根,在initramfs中逛裤,內(nèi)核直接就執(zhí)行init程序了瘩绒,掛載真正的根文件系統(tǒng)是由init程序來完成。
五带族、啟動init程序
接下來就是用戶空間init程序的介紹锁荔,Centos 5 6 7 中init程序都不一樣。
Centos5使用sysV作為init程序
Centos6使用upstart作為init程序
Centos7使用systemd作為init程序
各init程序的區(qū)別我用其他文章做說明蝙砌。
其實(shí)init程序啟動之后堕战,Linux的啟動已經(jīng)完成了
init的工作無非就是把初始化環(huán)境坤溃,啟動開機(jī)啟動程序,打印登陸提示符給用戶嘱丢。