CentOS 6 開機流程——linux由kernel和rootfs組成。kernel負責進程管理、內存管理、網絡管理、驅動程序、文件系統、安全等;rootfs由程序和glibc組成,完善操作系統的功能。同時linux內核的特點是模塊化,通過對模塊裝載卸載可以對內核功能自定義。linux內核鏡像文件:/boot/vmlinuz-2.6.32-696.el6.x86_64
整體的流程
- BIOS/開機自檢
- MBR引導(Boot Loader)
- 啟動內核
- 啟動第一個進程init
一、BIOS/開機自檢
1.1 微控制器
系統想要啟動必須先加載BIOS,按下電源鍵時,給微控制器下達一條復位指令,各寄存器復位,最后下達一條跳轉指令,跳轉到BIOS的ROM,使得硬件去讀取主板上的BIOS程序,在這之前都是由硬件來完成,之后硬件就會把控制權交給BIOS;
1.2 BIOS->POST
隨后BIOS程序加載CMOS(可讀寫的RAM芯片,保存BIOS設置硬件參數的數據)的信息,借CMOS取得主機的各項硬件配置;
取得硬件配置的信息之后,BIOS進行加電自檢(Power-on self Test,POST)過程,檢測計算機各種硬件信息,如果發現硬件錯誤則會報錯(發出聲音警告);
之后BIOS對硬件進行初始化
BIOS將自己復制到物理內存中繼續執行,開始按順序搜尋可引導存儲設備,決定存儲設備的順序(即定義第一個可引導的磁盤,當然是在有兩個磁盤的前提),接下來就會讀取磁盤的內容,但是要讀取磁盤文件必須要有文件系統,這對BIOS掛載文件系統來說是不可能,因此需要一個不依賴文件系統的方法使得BIOS讀取磁盤內容,這種方法就是引入MBR。最后BIOS通過INT 13硬件中斷功能讀取第一個可引導的存儲設備的MBR(0磁道0扇區)中的boot loader。將MBR加載到物理內存中執行。小tip:判斷可引導磁盤就是判斷每個磁盤前512字節結尾是否存在55AA,有就是可引導,沒有就繼續檢查下一個磁盤。
MBR載入內存后,BIOS將控制權轉交給MBR(準確的說應該是MBR中的boot loader),然后MBR接管任務開始執行。
二、MBR引導(Boot Loader)
載入了第一個可引導的存儲設備的MBR后,MBR中的boot loader就要讀取所在磁盤的操作系統核心文件(即后面所說的內核)了。
2.1 boot loader
但是呢還存在一些問題,不同操作系統的文件系統格式不同?還有我們知道一個磁盤可以安裝多個操作系統,boot loader怎么能夠做到引導的就是我們想要的操作系統呢?這么多不同的功能單靠一個446字節的boot loader是遠遠不夠的。因此必須弄一個相對應的程序來處理各自對應的操作系統核心文件,這個程序就是操作系統的loader(注意不是MBR中的boot loader),這樣一來boot loader只需要將控制權交給對應操作系統的loader,讓它負責去啟動操作系統就行了。
這里有張圖能更好地解釋boot loader的作用:
解讀上圖內容,我們知道一個硬盤的每個分區的第一個扇區叫做boot sector,這個扇區存放的就是操作系統的loader,所以我們常說一個分區只能安裝一個操作系統,如上圖,第一個分區的boot sector存放著windows的loader,第二個分區放著Linux的loader,第三個第四個由于沒有安裝操作系統所以空著。至于MBR的boot loader是干嘛呢, boot loader有三個功能:提供選單,讀取內核文件,轉交給其他loader ,
提供選單就是給用戶提供一張選項單,讓用戶選擇進入哪個操作系統;
讀取內核文件,我們知道系統會有一個默認啟動的操作系統,這個操作系統的loader在所在分區的boot sector有一份,除此之外,也會將這個默認啟動的操作系統的loader復制一份到MBR的boot loader中,這樣一來MBR就會直接讀取boot loader中的loader了,然后就是啟動默認的操作系統;
轉交個其他的loader,當用戶選擇其他操作系統啟動的時候,boot loader會將控制權轉交給對應的loader,讓它負責操作系統的啟動。
另外我看書上寫,安裝windows操作系統的時候,windows會主動復制一份自己的loader到MBR中的boot loader中,這種操作在linux下不會。所以我們安裝多重操作系統的時候要求先安裝windows,然后再安裝Linux;我們假設先安裝Linux,再安裝windows的時候就會自動把windows的loader復制到MBR中的boot loader,這樣一來就會默認優先啟動windows。然而先安裝windows,自動復制windows的loader到boot loader,再安裝Linux的時候,我們可以設置把Linux的loader復制到boot loader中,把原先windows的覆蓋掉,這樣才能設置Linux默認啟動。
2.2 Linux的GRUB
Linux的loader使用的是GRUB,我們常說的Linux中的loader就是grub,我認為這種說法是不準確的,我們知道MBR的boot loader是446字節,而grub呢,不僅僅446字節。
那MBR的boot loader和grub到底是什么關系呢,在這里說明,GRUB是一個啟動管理器,和Linux沒有強制的關系,當然也可以用GRUB啟動Windows。首先我們可以通過rpm -qi grub命令查看grub的版本。
進入/boot/grub目錄下,我們可以看到很多文件,其實Linux的loader為stage1那個文件(如下圖,剛好512字節),我們在安裝Linux的時候,系統會把stage1文件安裝到所在分區的boot sector中,同時默認Linux啟動的話,也需要把stage1中的引導代碼安裝到MBR中的boot loader中。該文件太小,能完成的功能有限,因此Linux的loader只是簡單的引導作用。
MBR完成了主程序的引導后,會把控制權交給GRUB,主引導程序開始加載配置文件了,但是加載這些配置文件之前需要有文件系統的支持,可是現在還沒有文件系統呢,在網上查閱資料說的“GRUB內置文件系統訪問支持,雖然是極度精簡的,但已經具備根據路徑讀取相應文件的二進制流。換句話說,GRUB在不依賴Linux內核的情況下具有讀取配置文件與內核映像的能力”。GRUB的內置文件系統其實是依靠stage1_5那些文件定義的,而且有不同文件系統的stage1_5。我們在安裝Linux的時候會把stage1_5相關文件放到0磁道1-62扇區中(一個磁道63個扇區,劃分分區是從1磁道開始的,除了MBR外,所以會有62個扇區作為保留扇區),用于定義grub的文件系統。
而后開始讀取stage2開始真正地讀取配置文件grub.conf。解析/boot/grub/grub.conf文件
default=0#?默認啟動第一個系統內核,即后面的title部分,1代表第二個,依次類推, timeout=5#?設置系統留給用戶選擇系統內核的時間為5s。 splashimage=(hd0,0)/grub/splash.xpm.gz #?用戶選擇內核時候的背景圖片文件,這里的hd0,0是第一個硬盤的第一個分區,沒有/dev/sdaX的概念 hiddenmenu?????#?是否顯示選單畫面 title?CentOS?6?(2.6.32-696.el6.x86_64)????#?第一個選單的名字,可以自定義 ????root?(hd0,0)????#?內核文件放置的分區 ????kernel?...?ro?root=?...?rhgb?quiet ????#?內核文件;讀取內核文件之后要掛載/目錄,只讀,root后跟真正的/目錄掛載的分區 ????#?rhgb?表示默認圖形顯示,把啟動過程覆蓋掉 ????#?quit表示系統啟動時將模塊啟動的詳細信息屏蔽,只顯示模塊啟動時候成功(ok?or?failed) ????initrd?...#?內核鏡像文件
總之,MBR就是加載內核文件的。
三、啟動內核
3.1 加載內核文件
MBR將內核文件(代碼)載入物理內存中執行,內核就是/boot/vmlinuz-2.6.32-696.el6.x86_64,觀察該文件,發現這是一個壓縮鏡像文件。
控制權轉交給內核后,內核重新檢測各種硬件信息,(第一次為POST自檢)我們前邊說了,一個完整的Linux包括內核和內核之上的程序,因此內核還要加載提供這些程序功能的模塊,然而這些模塊都在根目錄的/lib/modules/2.6.32-696.el6.x86_64下(/和/lib/modules/不能掛載不同的分區),這時候內核還沒有文件系統的概念,沒有文件系統就沒辦法掛載根目錄,想要掛載根目錄就需要相應的模塊支持,而我們原本的問題就是如何加載模塊(先有雞后有蛋的問題)。
3.2 加載initrd
/boot/initramfs-2.6.32-696.el6.x86_64.img文件就是解決上面問題的,我們來看一下這個文件:
file?initramfs-2.6.32-696.el6.x86_64.img?#?查看該文件類型 cp?initramfs-2.6.32-696.el6.x86_64.img?/app cd?/app mv?initramfs-2.6.32-696.el6.x86_64.img?initramfs-2.6.32-696.el6.x86_64.img.gz #?gzip解壓文件必須以.gz后綴 gzip?-d?initramfs-2.6.32-696.el6.x86_64.img.gz? file?initramfs-2.6.32-696.el6.x86_64.img? #?查看需要借助cpio命令 mkdir?init cd?init cpio?-id?<?/app/initramfs-2.6.32-696.el6.x86_64.img? #?解壓至/app/init目錄下
我們發現解壓之后的內容類似于真正/目錄下內容,這是因為這是一個最小化的Linux根文件系統。內核就是先把這個文件展開,形成一個虛擬文件系統,內核借虛擬文件系統裝載必要的模塊,完成后釋放該虛擬文件系統并掛載真正的根目錄。
initrd的制作:
mkinitrd /boot/initramfs-$(uname -r).img $(uname -r)
dracut /boot/initramfs-$(uname -r).img $(uname -r)
四、啟動第一個進程init
4.1 init進程:主要功能是準備軟件執行的環境
內核完成硬件檢測和加載模塊后,內核會呼叫第一個進程,就是/sbin/init,至此內核把控制權交給init進程
讀取初始化配置文件/etc/inittab,決定操作系統的runlevel,/etc/inittab內有這樣一句:
id:runlevel:action:process
id | 代表設定的項目,沒有具體的實際意義 |
runlevel | 執行級別,0-關機、1-單用戶、2-沒有NFS的多用戶、
3-真正的多用戶、4-預留、5-Xwindows、6-reboot |
action | init的動作行為,initdefault表示要默認啟動的runlevel |
process | 執行動作的指令,一般為腳本文件 |
4.2?/etc/rc.d/rc.sysinit
讀取/etc/rc.d/rc.sysinit系統初始化腳本,設置主機名,掛載/etc/fstab中的文件系統,修改/etc/sysctl.conf 的內核參數等各項系統環境。
查看該腳本內容,大致功能如下
定義主機名,如果不存在則將主機名定義為localhost;
讀取/etc/sysconfig/network文件,設置網絡環境;
掛載內存裝置/proc和USB裝置/sys,如果USB裝置存在,則會加載usb模塊并掛載usb文件系統;
接下來是SELINUX的一些相關設置;
設定text banner,顯示歡迎界面;
…
將開機啟動信息存放到/var/log/dmesg中。
4.3?/etc/rc.d/rc
執行/etc/rc.d/rc腳本,下面是/etc/rc.d/rc腳本中我們關心的代碼部分:
#?First,?run?the?KILL?scripts. for?i?in?/etc/rc$runlevel.d/K*?;?do #?Check?if?the?subsystem?is?already?up. subsys=${i#/etc/rc$runlevel.d/K??} [?-f?/var/lock/subsys/$subsys?-o?-f?/var/lock/subsys/$subsys.init?]?||?continue check_runlevel?"$i"?||?continue #?Bring?the?subsystem?down. [?-n?"$UPSTART"?]?&&?initctl?emit?--quiet?stopping?JOB=$subsys $i?stop [?-n?"$UPSTART"?]?&&?initctl?emit?--quiet?stopped?JOB=$subsys done #?Now?run?the?START?scripts. for?i?in?/etc/rc$runlevel.d/S*?;?do #?Check?if?the?subsystem?is?already?up. subsys=${i#/etc/rc$runlevel.d/S??} [?-f?/var/lock/subsys/$subsys?]?&&?continue [?-f?/var/lock/subsys/$subsys.init?]?&&?continue check_runlevel?"$i"?||?continue
根據運行級別(0123456)進入相應的/etc/rc.d/rcN.d目錄,啟動和關閉相關的系統服務。里邊存放著一堆以K和S開頭的軟鏈接文件,分別代表對應的服務。K開頭表示該運行級別下需要把該服務殺死,S開頭表示該運行級別下需要把該服務開啟。,上訴操作都是由/etc/rc.d/rc腳本來完成的。另外我們還注意都S和K后邊的數字,他們的數字代表了讀取的順序,因為有些服務是具有一定的關聯性。
而且每個rcN.d目錄內最后都會有一個S99local文件?,該文件指向 ../rc.local腳本。
4.4?/etc/rc.d/rc.local
系統根據runlevel執行完/etc/rc.d/rcN.d中的腳本后,調用/etc/rc.d/rc.local腳本
這時候系統已經完成了各種必要系統服務的啟動,假如我們想自定義一些指令要在開機的時候啟動,我們就可以把他們放到/etc/rc.d/rc.local內,該文件默認為空。
4.5 啟動終端
接下來會由/sbin/mingetty指令啟動終端,由于系統設置啟動tty1-tty6?,所以會啟動6個命令行終端。最終呈現給我們的就是這樣一個畫面:
本文來自投稿,不代表Linux運維部落立場,如若轉載,請注明出處:http://www.www58058.com/98426