Linux 系統啟動流程
內核簡介:
kernel功能:進程管理、內存管理、網絡管理、驅動程序、文件系統、安全功能
庫:函數的集合,同時提供調用接口;不能作為程序的執行入口單獨執行,只能被程序調用
過程調用:procedure,無返回結果
函數調用:function,有返回結果
內核設計流派:
單內核設計:把所有功能模塊集成於同一個程序(Linux)
微內核設計:每種功能模塊使用一個單獨子系統實現(Windows、Solaris)
Linux內核特點:
支持模塊化:*.ko(內核模塊文件)如:文件系統,硬件驅動,網絡協議等
支持模塊的動態裝載和卸載
Linux內核組成部分:
核心文件:/boot/vmlinuz-Version-Release
ramdisk:輔助的偽根文件系統
CentOS 5: /boot/initrd-Version-Release.img
CentOS 6、7: /boot/initramfs-Version-Release.img
模塊文件:/lib/modules/Version-Release/
Linux啟動流程:
Centos5、6啟動流程:POST—>Boot Sequence(BIOS)—>Boot Loader (MBR)—>Kernel(ramdisk)—> rootfs (readonly)—>switchroot—>/sbin/init—>(/etc/inittab, /etc/init/*.conf)—>設定默認運行級別—>系統初始化腳本—>關閉或啟動對應級別下的服務—>啟動終端—>登陸系統(登陸界面環境)—>啟動shell(shell環境)。
POST(Power OnSelf Test)加電自檢
POST它首先對每一個硬件設備進行檢查。完成後會尋找存有引導記錄的設備,找到之後讀入操作系統引導記錄,然後將系統控制權交給引導記錄,並由引導記錄來完成系統的順利啟動。
Boot Sequence(BIOS)
在系統啟動之前不知道計算機的系統在哪裏,所以在計算機的bios上定義了設備啟動順序,它會安照設備的啟動順序去查找引導加載器。
Boot Loader(MBR)
MBR:Master Boot Record 主引導記錄在可引導設備的前512bytes中(硬盤的第一個扇區),前446bytes為bootloader,接下來的64bytes為分區表信息,最後2bytes標記為55AA(表示為可引導設備)
Boot loader引導加載器,用來引導系統的啟動,它把用戶選定的內核加載到內存空間中,把控制權交給內核。
Windows下引導加載器:ntloader
Linux下引導加載器:
LILO:LInux LOader
GRUB:GRand Unified Bootloader
GRUB Legacy?0.X?傳統版本為0.X
GRUB2????1.X?與傳統版本完全不一樣的1.X版本
????功能:提供一個菜單,允許用戶選擇要啟動的系統或內核版本;把用戶選定內核裝載到RAM的特定空間中並解壓展開,而後把系統控制權移交給內核;
????MBR所給予的空間畢竟太小,容不下較大的引導程序,因此grub程序被分為三段:"stage 1" 被裝入磁盤的MBR中;特殊的"stage 1.5"被裝入MBR隨後的扇區,它能夠識別內核和"stage 2"所在分區的文件系統格式並幫助引導"stage 2",它是"stage 1"和"stage 2"之間的紐帶;"stage 2"位於文件系統上。stage 2程序和grub.conf可以與內核文件處於不同的分區上(但必須位於同一磁盤),只要"stage 1.5"能夠驅動它們各自所在的分區。
????GRUB引導過程分為三段:
??????stage1:MBR(0柱面0磁道1扇區)
??????stage1_5:MBR隨後的扇區
??????stage2:讀取grub.conf配置文件,並實現引導功能的擴展
Kernel:加載系統內核,執行系統初始化信息
在GRUB中選定內核進入,內核會對自身初始化;探測可識別到的所有硬件設備,加載硬件驅動程序(有可能需要借助ramdisk加載驅動);以只讀方式掛載根文件系統;運行用戶空間的第一個應用程序:/sbin/init
?Centos5:initrd
initrd文件生成工具程序:mkinitrd
Centos6,7:initramfs(cpio格式)
initramfs文件生成工具程序:dracut、mkinitrd
ramdisk:Linux內核的特性之一,使用緩沖和緩存來加速對磁盤上的文件訪問:
為什麽將initrd改為initramfs,前者把內存模擬成磁盤,後者直接把內存模擬成文件系統;如果模擬成磁盤,將磁盤加載到內存中,內核需將initrd再次緩存到內核的內存空間當中,相當於在內存中緩存兩次;但是如果模擬成文件系統,內核可以直接訪問文件系統所在的內存空間,這樣效率更高性能更好
initrd 、initramfs都屬虛擬文件系統,在早期的linux系統中,一般只有硬盤或者軟盤被用來作為Linux根文件系統的存儲設備,因此也就很容易把這些設備的驅動程序集成到內核中。但是現在的Linux系統中可能將根文件系統保存到各種存儲設備上,包括scsi、sata,usb-disk等等。如果把這些設備的驅動代碼全部編譯到內核中內核會很龐大。
為了解決這一矛盾,於是出現了基於ramdisk的initrd( bootloader initialized RAM disk )。initrd是一個被壓縮過的小型根目錄,這個目錄中包含了啟動階段中必須的驅動模塊、可執行文件和啟動腳本。當系統啟動的時候bootloader會把initrd文件讀到內存中,然後把initrd文件在內存中的起始地址和大小傳遞給內核。內核在啟動初始化過程中會解壓縮initrd文件,然後將解壓後的initrd掛載為根目錄,並執行根目錄中的/linuxrc腳本(cpio格式的initramfs為/init,而image格式的initrd為/linuxrc),腳本會加載真實文件系統中存放的設備驅動程序,以及在/dev目錄下創建必要的設備節點。這樣就可以mount真正的根目錄,並切換到這個根目錄中。
Linux 發行版在內核中只編譯了基本的硬件驅動,在Linux系統安裝過程中通過檢測系統硬件,生成包含安裝系統硬件驅動的initrd,在內核引導過程中先加載initrd虛擬文件系統,然後由initrd掛載真正的文件系統,完成後initrd從RAM中退出,並不消耗內存,initrd只是一個暫時的文件系統。
在Linux2.5內核中出現了initramfs,它的作用和initrd類似,只是和內核編譯成一個文件(initramfs是經過gzip壓縮後的cpio格式文件),該cpio格式的文件被鏈接進了內核中特殊的數據段.init.ramfs上,其中全局變量__initramfs_start和__initramfs_end分別指向這個數據段的起始地址和結束地址。內核啟動時會對.init.ramfs段中的數據進行解壓,然後使用它作為臨時的根文件系統。
initrd與initramfs的區別:
initrd是init ram disk,initramfs是init ram file system,前者把內存模擬成磁盤,後者直接把內存模擬成文件系統
cpio-initrd(initramfs)的處理流程
1、boot loader 把內核以及 initrd 文件加載到內存的特定位置
2、內核判斷initrd的文件格式,如果是cpio格式
3、將initrd的內容解壓到rootfs中
4、執行initrd中的/init文件,切換到真實的根文件系統,執行/sbin/init
image-initrd(initrd)的處理流程
1、boot loader把內核以及initrd文件加載到內存的特定位置。
2、內核判斷initrd的文件格式,如果不是cpio格式,將其作為image-initrd處理。
3、內核將initrd的內容保存在rootfs下的/initrd.image文件中。
4、內核將/initrd.image的內容讀入/dev/ram0設備中,也就是讀入到一個內存盤中。
5、接著內核以可讀寫的方式把/dev/ram0設備掛載為原始的根文件系統。
6、如果/dev/ram0被指定為真正的根文件系統,那麽內核跳至最後一步正常啟動。
7、執行initrd上的/linuxrc文件,linuxrc通常是一個腳本文件,負責加載內核訪問根文件系統必須的驅動, 以及加載根文件系統。
8、/linuxrc執行完畢,真實的根文件系統被掛載
9、如果真實根文件系統存在/initrd目錄,那麽將/dev/ram0從/移動到/initrd;如果不存在/initrd目錄,/dev/ram0將被卸載。
10、在真實根文件系統上進行正常啟動過程 ,執行/sbin/init。
init程序:啟動用戶空間的第一個程序/sbin/init,完成系統初始化
在內核、硬件及驅動信息加載完畢後,內核會呼叫用戶空間中的第一個執行程序/sbin/init,init程序主要功能是準備軟件運行環境,包括系統的主機名稱、網絡配置、文件系統格式等其他服務的啟動管理。而這些所有的操作都是通過init的配置文件來定義
一旦啟動了init,內核就不管了,所有的後續操作都是由init去加載運行用戶空間的應用程序來完成各種各樣的工作,只有當這些應用程序完成系統調用或者系統發生中斷時需要特權操作時,內核才會參與;剩余的其它過程都不在參與,而是由用戶空間的程序來完成
init程序的類型:
Centos 5:SysV init
由於Centos5采用的是SysV init方式,其特點是啟動用戶空間的服務程序,通常通過腳本進行,有依賴關系的服務將被串行啟動;這也就導致了Centos5的系統啟動過程非常緩慢
配置文件:/etc/inittab
Centos 6:Upstart,但程序名依然為/sbin/init
采用Upstart的方式,其特點是守護進程間的通信依賴於D-Bus進行,因此,可基本實現類似並行啟動
??配置文件:centos6中/etc/inittab中只是部分配置文件,大多數配置文件在/etc/init/*.conf(*.conf為upstart風格的配置文件)
Centso 7:Systemd
采用Systemd方式,其特點是服務只有在第一次被訪問時才會真正啟動起來;因此Centos 7系統的啟動過程非常快
??配置文件:一部分在/usr/lib/systemd/system/目錄下,另外一部分在/etc/systemd/system/目錄下;Systemd完全兼容SysV腳本機制;因此service命令依然可用;不過建議使用systemctl命令來控制服務;
運行/sbin/init程序—>讀取/etc/inittab文件獲得運行級別—>運行系統初始化腳本/etc/rc.d/sysinit—>運行/etc/rc#.d/
系統運行級別:
Centos 6:Upstart兼容了centos 5的init
運行級別:為了系統的運行或維護等目的而設定的機制;一共7(0-6)個級別
0:關機,shutdown
1:單用戶模式(single user),以root用戶登陸,無需認證;維護模式
2:多用戶模式(multi user),會啟動網絡功能,但不會啟動NFS;維護模式
3:多用戶模式,完全功能模式;文本界面
4:預留級別;目前無特別使用目的,但習慣以同3級別功能使用
5:多用戶模式,完全功能模式,圖形界面
6:重啟,reboot
默認運行級別:3或5
運行級別切換:init #
查看當前級別:
??who –r
??runlevel
配置文件:/etc/inittab
每行定義一種action以及與之對應的process
id:runlevels:action:process
id:一個任務的標識符,可以自己定義只要不重復
runlevels:在哪些級別啟動此任務;#,###,也可以為空,表示所有級別
action:在什麽條件下啟動此服務;常用action有以下4種
wait:等待切換至此任務所在的級別時執行一次
respawn:一旦此任務終止,就自動重新啟動之
initdefault:設定默認運行級別;此時process省略
sysinit:設定系統初始化方式,process一般會指定/etc/rc.d/rc.sysinit腳本
????process:任務,要執行的程序
例如:
id:3:initdefault:?設定系統默認運行級別為3級別(如果個內核傳遞了運行級別參數,以傳遞的參數為準)
si::sysinit:/etc/rc.d/rc.sysinit?設置系統初始化方式為運行/etc/rc.d/rc.sysinit腳本
運行指定運行級別下的服務腳本:
l0:0:wait:/etc/rc.d/rc 0??在0運行級別運行/etc/rc.d/rc腳本,並給腳本傳遞了參數0
l1:1:wait:/etc/rc.d/rc 1
l2:1:wait:/etc/rc.d/rc 2
l3:1:wait:/etc/rc.d/rc 3
l4:1:wait:/etc/rc.d/rc 4
l5:1:wait:/etc/rc.d/rc 5
l6:6:wait:/etc/rc.d/rc 6
rc腳本接受一個運行級別數字為參數,"/etc/rc.d/rc #"意味著去運行去/etc/rc.d/rc#.d/目錄下的服務腳本,這些腳本用來控制對應級別下服務的啟動或停止(按優先級順序執行);
K##*:以K開頭的是要停止的服務;##是優先級,數字越小越優先關閉;依賴別的服務才能啟動的服先關閉,被依賴的服務後關閉;
S##*:以S開頭要啟動的服務;##是優先級,數字越小越優先啟動;被依賴的服務先啟動,依賴別的服務才能啟動的服務後啟動;
/etc/rc.d/rc#.d/目錄下的文件軟連接到/etc/rc.d/init.d/目錄中的腳本
系統初始化腳本功能:/etc/rc.d/rc.sysinit
1、設置主機名
2、設置歡迎信息
3、激活udev和selinux
4、掛載/etc/fstab文件中定義的所有文件系統
5、檢測根文件系統,並以讀寫方式重新掛載根文件系統
6、設置系統時鐘
7、根據/etc/sysctl.conf文件來設置內核參數
8、激活lvm以及軟raid設備
9、激活swap設備
10、加載額外設備的驅動程序
11、清理操作
服務啟動腳本:
/etc/init.d/*(/etc/rc.d/init.d/*)不同發行版可能路徑不一樣
腳本執行方式:
/etc/init.d/Server_Script {start|stop|restart|status}
service Server_Script {start|stop|restart|status}
設置服務在不同系統運行級別下的啟動和關閉:
chkconfig命令:管控/etc/init.d/每個服務腳本在各級別下的啟動或關閉狀態
查看:chkconfig --list [name]
chkconfig --list?查看全部服務在各級別下的狀態
chkconfig --list Name?查看指定服務在各級別下的狀態
??添加:chkconfig --add name
??能被添加的服務的腳本定義格式之一:
#!/bin/bash
#chkconfig: LLL NN MM
#description:
LLL?指定的級別需要啟動該服務,沒指定的級別關閉該服務;如果是"-"表示7個級別該服務都是關閉的
NN? 啟動服務時的優先級
MM? 停止服務時的優先級
刪除:chkconfig --del name
修改指定服務在指定運行級別下的狀態:
chkconfig [--level LEVELS] name<on|off|reset>
--level LEVELS?指定要控制的級別,不指定默認為2345
註意:正常級別下,最後一個啟動項(/etc/rc.d/rc#.d/)是一個S99local的服務,沒有鏈接至/etc/init.d下的某腳本,而是鏈接至/etc/rc.d/rc.local(/etc/rc.local)腳本;因此不便或不需寫為服務腳本的程序但是又希望能開機自動運行時,直接放置於此腳本文件中即可。
設置登錄終端:/etc/inittab
tty1:2345:respawn:/usr/sbin/mingetty tty1?2345運行級別啟動tty1,下面依次啟動其他5個虛擬終端
tty2:2345:respawn:/usr/sbin/mingetty tty2
tty3:2345:respawn:/usr/sbin/mingetty tty3
tty4:2345:respawn:/usr/sbin/mingetty tty4
tty5:2345:respawn:/usr/sbin/mingetty tty5
tty6:2345:respawn:/usr/sbin/mingetty tty6
1、mingetty會調用login程序
2、打開虛擬終端的程序除了mingetty之外,還有諸如getty等
總結:用戶空間的啟動流程
/sbin/init(/etc/inittab)設置默認運行級別
運行系統初始化腳本/etc/rc.d/rc.sysinit,完成系統的初始化
運行/etc/rc.d/rc#.d/目錄下面的腳本(實際是連接到/etc/rc.d/init.d/目錄下的腳本)關閉對應級別下的需要停止的服務,啟動對應級別下需要開啟的服務;
設置登錄終端
CentOS系統的啟動流程包括:內核空間的啟動流程和用戶空間的啟動流程
參考啟動流程圖一
參考啟動流程圖二
Linux 系統啟動流程