Linxu系統的啟動過程
啟動流程
1、引導Linux啟動是從BIOS中的地址0xFFFF0處開始的,BIOS由兩部分組成:POST代碼和運行時服務,運行時服務是為操作系統提供一些接口,如溫度檢測等。
-
BIOS的第一個步驟是加電自檢(POST),完成對硬件的的檢測,如某些硬件出現錯誤無法通過檢測就導致系統無法啟動,POST完成之后將被清出內存;
-
BIOS的第二個步驟是進行設備的枚舉和初始化,按CMOS的設置搜索處于活動狀態并且可引導的設備(floppy、CD-ROM、USB、Disk、NFS),加載主引導記錄(MBR),到內存。此時BIOS將控制權交給Boot Loader
2、MBR的前 446 個字節是主引導加載程序(Boot Loader),其中包含可執行代碼和錯誤消息文本。接下來的 64 個字節是分區表,其中包含 4 個分區的記錄(每個記錄16 bytes)。MBR 以兩個特殊數字(0xAA55)結束。這個數字會用來進行 MBR 的有效性檢查。
-
Boot Loader就是stage1,通過內置的地址引導了stage1_5 的引導加載程序加載/boot分區,進而加載stage2。MBR中的Boot Loader備份在了 /boot/grub/stage1 中
-
-
stage1_5在/boot/grub目錄,用于識別內核所在分區的文件系統類型,是Boot Loader所處的 stage1 加載 stage2 的過渡,在這之后才能進入Grub引導程序。
3、Grub引導程序處于stage2,通過讀取 /etc/grub.conf 文件,顯示出內核列表,指定了內核鏡像和 initrd 所在的分區為root,設定內核參數,并加載vmlinuz和initramfs這兩個文件到內存中。在這一階段可以編輯啟動項目如指定根分區root,內核kernel,initrd鏡像等;也可以進入grub command line手動寫啟動信息。
事實上,GRUB(GRand Unified Bootloader)管理開機啟動的過程分成了三個階段stage1/stage1.5/stage2。其中stage1主要負責BIOS和GRUB之間的交接。這部分才是真正放在MBR中的bootloader。而后stage1.5是連接stage1和stage2之間的通道,起著過渡的作用。最后才是GRUB中真正核心的部分stage2,它可以讓用戶以選項的方式將操作系統加載、修改選項和內核參數。
4、當內核映像被加載到內存中,并且stage2 的引導加載程序釋放控制權之后,內核階段就開始了,內核在完成自身的初始化之后進行探測可識別的所有硬件設備,由于內核中只包含了少量的硬件驅動,此時會借助內存中的initrd根文件系統加載相關驅動程序。當內核具備訪問根文件系統功能時,initrd根文件系統將被卸載,并掛載真正的根文件系統。這就是內核的初始化過程,系統已經脫離了 /boot 分區,獨立存活在內存中。
-
vmlinuz-xxx內核鏡像是一個 zImage(壓縮映像,小于 512KB)或一個 bzImage(較大的壓縮映像,大于 512KB),它是使用 zlib 進行壓縮過的內核文件
-
initramfs-xxx.img是由stage2 引導加載程序加載到內存中的,它會被復制到 RAM 中并掛載到系統上。這個 initrd 會作為 RAM 中的臨時根文件系統使用,并允許內核在沒有掛載任何物理磁盤的情況下完整地實現引導。initrd文件包括可加載模塊的驅動程序,為內核提供可訪問磁盤和磁盤上的文件系統的接口,并為其他硬件提供了驅動程序。由于根文件系統是磁盤上的一個文件系統,因此內核通過initrd取得根分區的訪問,并掛載真正的根文件系統。這是一個解包的initramfs鏡像文件:
-
內核非常小,rpm -ql kernel看到大部分驅動模塊都在安裝內核時放在了/lib/modules/version/目錄下,只有編譯內核過程中被選擇的模塊才會成為內核鏡像的一部分,還有一部分驅動模塊存放在initfd鏡像中,這些驅動模塊確保了Linux內核可以在眾多的架構上運行,并且兼容絕大多數硬件平臺。
5、內核初始化的最后一步就是啟動 init
進程。在init 以守護進程方式存在,是所有其他進程的祖先(PID=1
),init 進程非常獨特,能夠完成其他進程無法完成的任務。
-
在
CentOS 5
中使用sysvinit
初始化系統:sysvinit 就是 system V 風格的 init 系統,顧名思義,就是源于 System V 系列 UNIX -
init 通過讀取 ‘
/etc/inittab
’ 文件完成系統初始化的過程: -
inittab文件
-
選擇runlevel :Sysvinit 讀取 ‘
/etc/inittab
’ 文件中是否含有 ‘initdefault’ 項,有則init 將啟動默認運行的模式。如果沒有默認的運行模式,將進入系統控制臺,手動決定進入何種運行模式。 -
who -r 與 runlevel #查看當前的runlevel
-
runlevel通常會 7 種模式,即runlevel 0 ~ 6 。
通常:
# 0 – halt (Do NOT set initdefault to this)
# 1 – Single user mode
# 2 – Multiuser, without NFS (The same as 3, if you do not have networking)
# 3 – Full multiuser mode
# 4 – unused
# 5 – X11
# 6 – reboot (Do NOT set initdefault to this)
. 系統選擇進入 runlevel
. 運行系統初始化腳本,即/etc/rc.d/rc.sysinit
. 運行指定運行級別對應的目錄下的腳本,即/etc/rc.d/rc#.d/目錄下的服務腳本
. 捕獲組合鍵的定義
. 定義電源 fail/restore 腳本
. 啟動 getty 和虛擬控制臺
字段定義格式及含義 id:runlevels:action:process
. id:標識符
. runlevels:在哪個級別運行此行
. action:在什么情況下執行此行
. process:要運行程序
[action]
. initdefault:設定默認運行級別
. sysinit:系統初始化
. wait:等待級別切換至此級別時執行
. respawn:一旦程序終止,會重新啟動
-
/etc/rc.d/rc.sysinit
-
運行 rc.sysinit 以便執行一些重要的系統初始化任務。在RHEL 5中rc.sysinit 主要完成以下這些工作:
-
激活 udev 和 selinux
-
設置定義在/etc/sysctl.conf 中的內核參數
-
設置系統時鐘
-
加載 keymaps
-
使能交換分區
-
設置主機名(hostname)
-
根分區檢查和 remount
-
激活 RAID 和 LVM 設備
-
開啟磁盤配額
-
檢查并掛載所有文件系統
-
清除過期的 locks 和 PID 文件
-
/etc/rc.d/rc 和/etc/rc.d/rc#.d/
-
rc是個腳本,后面接參數,如:l5:5:wait:/etc/rc.d/rc 5 ,這里的wait意味著init系統將等待rc啟動服務腳本。
-
rc 根據 runlevel 執行rc#.d 目錄下啟動腳本。每個 runlevel 都有一個對應的 rc#.d 目錄
-
在這些目錄下存放著很多不同的腳本,文件名以
S 開頭
的腳本表示在當前runlevel中啟動,K開頭
的腳本表示不在當前runlevel中啟動 -
在/etc/rc.d/rc#.d 目錄下的腳本其實都是一些軟鏈接文件,真實的腳本文件存放在
/etc/init.d
目錄下,也就是說在/etc/init.d目錄下的文件會自動
以S##script或K##script的軟鏈接
存在于各 runlevel 的目錄下 -
chkconfig –levle comm off實質上就是把S##script 改成了 K##script文件。注意這里的數字是在腳本內部定義的。自定義服務腳本時,定義的S數字盡量大,以免依賴的服務還沒有啟動。當使用 init #命令切換runlevel時,有些服務被關閉,此時定義的K數字盡量小,在依賴服務關閉前停止。
-
/etc/rc.d/rc.local
-
rc#.d/
S99local
文件沒有鏈接至/rc.d/init.d/而是rc#.d/S99local -> ../rc.local,因此,命令放置于/etc/rc.d/rc.local
目錄可實現開機時自動運行,簡化了些服務腳本的過程。 -
/sbin/mingetty,X Display Manager(如果需要的話)
-
init在等待/etc/rc.d/rc執行完畢之后,將在指定的各個虛擬終端上運行/sbin/mingetty,等待用戶的登錄。 至此,Linux的啟動完成
自定義服務腳本
#自定義服務腳本,使用 chkconfig 管理 [root@cent6]/etc/rc.d/init.d>cat testsrv #!/bin/bash #chkconfig:35 92 22 #默認啟動runlevel 3 5 ,S92testsrv ,K22testsrv #description:test service in /etc/rc.d/init.d/ #放在/etc/rc.d/init.d/自動鏈接至 0 - 6 runlevel …… [ -x \$0 ]||chomd +x $0 #添加至服務列表 [root@cent6]~>chkconfig --add testsrt #從服務列表刪除 [root@cent6]~>chkconfig --del testsrt #確認當前testsrv啟動的runlevel [root@cent6]/etc/rc5.d>chkconfig --list testsrv testsrv 0:off 1:off 2:off 3:on 4:off 5:on 6:off #選擇on的rc5.d/,此時有S92testsrv文件,并且是一個軟鏈接 [root@cent6]/etc/rc5.d>ll S92testsrv lrwxrwxrwx. 1 root root 17 Aug 17 11:37 S92testsrv -> ../init.d/testsrv #修改S92 為預定義的 K22 文件,目的是看看runlevel5是否仍然 on [root@cent6]/etc/rc5.d>mv S92testsrv K22testsrv #runlevel5已經是off,說明chkconfig off 等于創建 K 開頭的文件 [root@cent6]/etc/rc5.d>chkconfig --list testsrv testsrv 0:off 1:off 2:off 3:on 4:off 5:off 6:off #再次開啟 runlevel5的testsrv服務 [root@cent6]/etc/rc5.d>chkconfig --level 5 testsrv on testsrv 0:off 1:off 2:off 3:on 4:off 5:on 6:off #rc5.d/目錄下再次生成了S92testsrv文件 [root@cent6]/etc/rc5.d>ll S92testsrv lrwxrwxrwx. 1 root root 17 Aug 17 11:37 S92testsrv -> ../init.d/testsrv
-
Sysvinit 不僅需要負責初始化系統,還需要負責關閉系統。在系統關閉時,為了保證數據的一致性,需要小心地按順序進行結束和清理工作。比如應該先停止對文件系統有讀寫操作的服務,然后再 umount 文件系統,否則數據就會丟失。這種順序的控制這也是依靠/etc/rc.d/rc#.d/目錄下所有腳本的命名規則來控制的,在該目錄下所有以 K 開頭的腳本都將在關閉系統時調用,字母 K 之后的數字定義了它們的執行順序。這些腳本負責安全地停止服務或者其他的關閉工作。
Sysvinit 管理命令和控制功能
-
halt、init、killall、last、lastb、mesg、pidof、poweroff、reboot、shutdown、runlevel、sulogin、telinit、utmpdump、wall
Sysvinit 小結
-
sysvinit 的一個重要優點是確定的執行順序:腳本嚴格按照啟動數字的大小順序執行,一個執行完畢再執行下一個,有利于錯誤排查
-
串行地執行腳本導致 sysvinit 運行效率較慢,此外動態設備加載等 Linux 新特性體現出 sysvinit 的一些問題
補充:守護進程
-
獨立守護進程:就像上面的myservice一般能實現自我管理的守護進程
-
超級守護進程:xinetd服務,就像一個代理人,如管理telnet服務,雖然端口開著,但是服務沒有被激活
-
瞬時守護進程:不需要關聯至運行級別,以服務的方式被激活,由超級守護進程xinetd管理,可以認為這是Systemd的啟動方式
Upstart
-
UpStart 主要的概念是 job 和 event。Job 就是一個工作單元,用來完成一件工作,比如啟動一個后臺服務,或者運行一個配置命令。每個 Job 都等待一個或多個事件,一旦事件發生,upstart 就觸發該 job 完成相應的工作。UpStart 解決了之前提到的 sysvinit 的缺點。采用事件驅動模型
-
UpStart 可以:
更快地啟動系統
當新硬件被發現時動態啟動服務
硬件被拔除時動態停止服務 -
這些特點使得 UpStart 可以很好地應用在桌面或者便攜式系統,處理這些系統中的動態硬件插拔特性。
-
原inittab下的記錄
/etc/init/control-alt-delete.conf:快捷鍵重啟的腳本,建議注釋掉,防止誤操作
/etc/init/tty.conf:重啟終端腳本
/etc/init/start-ttys.conf:登錄終端腳本
/etc/init/rc.conf:啟動腳本
/etc/init/prefdm.conf:圖像界面腳本
Systemd
-
CentOS 7 使用systemd替換了SysV。Systemd目的是要取代Unix時代以來一直在使用的init系統,兼容SysV和LSB的啟動腳本,而且夠在進程啟動過程中更有效地引導加載服務
-
systemd的特性有:
支持并行化任務
同時采用socket式與D-Bus總線式激活服務;
按需啟動守護進程(daemon);
利用 Linux 的 cgroups 監視進程;
支持快照和系統恢復;
維護掛載點和自動掛載點;
各服務間基于依賴關系進行精密控制。
原創文章,作者:helloc,如若轉載,請注明出處:http://www.www58058.com/46234