1. 程式人生 > 實用技巧 >Linux之系統啟動流程之(1)流程概述

Linux之系統啟動流程之(1)流程概述

Linux之系統啟動流程之(1)流程概述

Linux一般來說是通過引導MBR來啟動程式的,所以本片之介紹MBR啟動方式流程。

Linux組成:Kernel+rootfs

kernel(系統核心模組)功能:

程序管理、記憶體管理、網路管理、驅動程式、檔案系統、按全功能。

rootfs(根檔案系統):相應程式和glibc,根是自引用的,能夠自我識別

庫:函式集合,function, 呼叫介面(標頭檔案負責描述)

過程呼叫:procedure,無返回值

函式呼叫:function

程式:二進位制執行檔案

核心設計流派:

單核心(monolithice kernel):Linux (LMP)

把所有功能集成於同一個程式

微核心(micro kernel):

Windows, Solaris(執行緒)

每種功能使用一個單獨子系統實現

Linux核心的特點:

支援模組化: .ko (核心模組物件)

如:檔案系統,驅動程式,網路協議等

(注):支援核心模組的動態裝載和解除安裝

啟動所需組成部分:

核心檔案:/boot/vmlinuz-VERSION-release.img

ramdisk:輔助的偽根系統

CentOS 5ramdisk --> initrd

/boot/initrd-VERSION-release.img

CentOS6, 7ramfs -->initrdamfs

/boot/initramfs-VERSION-release.img

模組檔案存放路徑:/lib/modules/VERSION-release

CentOS6啟動順序:

總體順序:

POST-->BIOS(Boot Sequence)-->MBR(bootloader,446)-->Kernel-initrd-->(ROOTFS)-->/sbin/init

大致順序:

加電自檢-->MBR引導-->GRUB-->載入核心

CentOS6啟動流程:

1、載入BIOS的硬體資訊,獲取第一個啟動裝置

2、讀取第一個啟動裝置MBR的引導載入程式(grub)的啟動資訊

3、載入核心操作裝置

4、核心執行init程式,並獲取預設的執行資訊

5、init程式執行/etc/rc.d/rc.sysinit檔案

6、啟動核心的外掛模組(/etc/modprobe.conf)

7、init執行執行的各個批處理檔案(scripts)

8、init執行/etc/rc.d/rc.local

9、執行/bin/login程式,等待使用者登入

10、登入之後開始以Shell 控制主機

詳解啟動過程

主機板及相關硬體作用

POSTPrower-On-Self-Test,加電自檢,是BIOS功能的一個主要部分。負責完成對CPU

主機板、記憶體、硬碟子系統、序列行介面、鍵盤、CD-ROM光碟機等硬體情況的檢查測。

ROMBIOSBasic Inpupt and Ouput System,儲存著有關計算機最重要的基本輸入輸出程式,系統資訊設定、開機加電自檢和系統啟動自舉程式等。

RAMCMOS互補金氧半導體,儲存BIOS主備的程式各項引數的設定。

按次序查詢引導裝置,第一個有載入程式的裝置為本次啟動裝置。

引導載入部分作用

bootloader(MBR):引導載入器

bootloader型別補充:

windowsntloader,僅是啟動OS

Linux:功能豐富,提供選單,執行使用者選擇要啟動系統或不同的核心版本;把使用者選定的核心裝載到記憶體到特定空間中,解壓、展開,並把系統控制權移交給記憶體。

Linux中使用的bootloder

LIIOLInux LOader

GRUBGRand Unified Bootloader

GRUB 0.XGRUB LegacyGRUB2

MBR:系統盤的前446位元組:bootloader,64:分割槽表,2 :55AA

GRUB:GRand Unified Bootloader

primary boot loader

Stage1MBR,第1階段

secondary boot loader

Stage1_5:識別常見的不同檔案系統型別,第1,.5階段

Stage2/root/grub/,第2階段

kernel部分:

自身初始化:

探測可識別到的所有硬體裝置

載入硬體驅動(可能借助於ramdisk載入驅動)

以自讀方式掛載根檔案系統

執行使用者空間的第一個應用程式:/sbin/init

init程式的型別:

SysVinit, CentOS 5及之前

配置檔案:/etc/inittab

Upstartinit, CentOS6

配置檔案:/etc/inittab, /etc/init/*.conf

Systemdsystemd, CentOS7

配置檔案:/usr/lib/systemd/system

/etc/systemd/system

ramdisk型別:

核心中的特性之一:使用緩衝和快取來加速對磁碟上的檔案訪問

ramdisk --> ramfs 提供速度

CentOS 5initrd,工作程式:mkinitrd

CentOS 6initramfs,工具程式:mkinitrd,dracut

注意:ramkdisk為表示模擬一個虛擬磁碟來進行根切換,而ramfs直接是模擬了一種檔案系統所有快取和解壓的速度更快。

系統初始化:

POST-->BootSequence(BIOS)-->Bootloader(MBR)-->kernel(ramdisk)-->

(ROOBTFS虛擬根檔案系統切換)-->init(或者systemd)

系統的執行級別(CentOS6之前):/sbin/init(切換級別的命令)

0halt 關機

1single user mode, 單使用者模式, 直接以管理員切入(init s | single)

2mulit user mode, no NFS 沒有NFS服務的字元介面多使用者模式

3mulit user mode, text mode 字元介面多使用者模式

4reseved 保留級別,可同3級別

5multi user mode, graphic mode 帶圖形介面的多使用者模式

6reboot 重啟

預設級別:3,5

切換級別:init #

檢視級別:runlevel ; who -r

init初始化:

init程序其初始化檔案:/etc/inittab

初始化執行級別(RUN LEVEL

系統初始化指令碼

對應執行級別的指令碼目錄

捕獲某個關鍵字順序

定義UPS電源終端/恢復腳步

在虛擬控制檯生成getty

在執行級別5初始化X(圖形介面程式)

各個啟動過程使用的配置檔案的作用

/sbin/init:(/etc/inittab)

upstartubuntu組織開發,(RHEL 6版本以後)d-dusevent-driven,基於事件驅動

systemd(完整的並行程序)

/etc/inittab配置檔案介紹:

每一行定義一種action以及與之對應的 process,格式:

id:runlevels:action:process

id:表示符

runlevels:在哪個執行級別執行此行;

action:在什麼情況執行此行,一般常見有下面幾種情況:

wait:切換至此級別執行一次;

respawn:此process終止,就重新啟動

initdefault:設定預設執行級別;process欄位可省略

sysinit:設定系統初始化方式,此處一般為指定/etc/rc.d/rc.sysinit

process:要執行程式;

舉例說明/etc/inittab:

按預設3級別基本的預設/etc/inittab檔案配置說明:

id:3:initdefault:#預設執行級別為3級別,init程式讀取此行按3級別進入系統

si::sysinit:/etc/rc.d/rc.sysinit#載入檔案rc.sysinit,並執行此指令碼中的設定

l3:3:wait:/etc/rc.d/rc 3

#根據上面3級別進入系統後,執行對應的rc.d/rc腳步,後面引數為3,然後進入搜尋對應級別下的服務腳步,及/etc/rc.d/rc3.d/下的服務腳步,然後按順序關閉檔案中對應 K開頭的服務,開啟S開頭的服務。

/etc/rc.d/rc.init:系統初始化指令碼

1、設定主機名

2、設定歡迎資訊

3、啟用udevselinux

4、掛載/etc/fstab檔案中定義的檔案系統

5、檢查根檔案系統,並以讀寫方式重新掛載根檔案系統系統

6、設定系統時鐘

7、啟用swap裝置

8、根據/etc/sysctl.conf檔案設定核心引數

9、啟用lvmsoftware raid裝置

10、載入額外的裝置的驅動程式

11、清理操作

/etc/rc.d/rc腳步說明:

/etc/rc.d/rc中核心服務控制語句類似以下指令碼型別:

[[email protected]kernel]#catrc.sh
#!/bin/bash
#
[$#-lt1]&&exit1;
runlevel=$1
path="/etc/rc.d"
forkin${path}/rc${runlevel}.d/K*;do
echo"$kstopped...";#原本rc應該是$kstop,接收stop引數來關閉對應服務
done

forsin${path}/rc${runlevel}.d/S*;do
echo"$sstart....";#原本rc應該是$sstart,解析start引數來開啟對應服務
done


解析:因為這是一個測試語句,就不傳指定的{start|stop|status|restart}引數了,這裡使用echo輸出來模擬代替。當然真正的rc腳步必須要介紹一個引數來決定來決定對那個執行級別下的服務類腳步來操作,這裡輸入3測試:

#測試腳步執行

[[email protected] kernel]# ./rc.sh 3

說明:然後會發現先輸出K後跟數字的先關閉,然後S後跟數字的再啟動。數字越小,越先操作,數字越小的越後操作,因此可以猜測到3級別在啟動的時候會先關閉那麼不需要的服務,而又需要開啟哪些服務。

rc腳步啟動總結說明:

rc # --> 意味著讀取/etc/rc.d/rc#.d/ 下的檔案

K*K####執行次序;數字越小先執行及關閉;數字越小的服務,通常為依賴到別的服務;

S*S####執行次序;數字越小先執行及開啟;數字越小的服務,通常為被依賴到的服務;

系統服務管理命令(CentOS5、6):

chkconfig 命令

chkconfig - updates and queries runlevel information for system services

更新和查詢系統服務的執行級別資訊

選項及用法:

檢視服務所在執行級別狀態:

chkconfig --list:查詢所有獨立守護服務的啟動設定,注意:獨立守護程序!

chkconfig --list SERVICE_NAME #查詢指定服務所有級別的啟動或關閉情況

新增服務

chkconfig --add SERVICE_NAME(腳步名稱)

新增的SysV的服務腳步放置於/etc/rc.d/init.d (/etc/init.d)目錄下

新增的腳步的前幾行需要特定標示格式加入:

#!/bin/bash

#runlevels

解析:runlevles表示初始在哪些基本下啟動,-表示都不啟動,可以單個可以多個,如23表示23級別下,而3表示只在3級別啟動

#chkconfig: runlevels SS KK

解析:當chkconfig命令來為此指令碼在rc#.d目錄建立連結時,runlevel表示預設建立S*開頭的連結,除此之外的級別都建立為K*開頭的連結。

注:連結的開頭說明:

S後面的啟動優先順序為SS所表示的數字;

K後面關閉優先次序為KK所表示的數字;

#description:

解析:用於說明此指令碼的簡單功能:\ 表示續行符號,如 start what \ aa

刪除服務:

chkconfig --del SERVICE_NAME #刪除指定服務腳步在對於級別下建立的連結檔案

修改指定的連結型別:

chkconfig [--level runlevels] name <on|off|reset|resetpriorities>

--level runlevles:要設定的級別;省略時表示2345級別

新增刪除、設定自定義服務案例:

1、編寫一個模擬SysV風格的服務腳步,及能夠接收{start|stop|status|restart}4鍾引數:

[[email protected]kernel]#vimmyservice.sh

#表現內容如下,用判斷一個檔案是否存在來判斷服務是否啟動

[[email protected]kernel]#catmyservice.sh
#!/bin/bash
#
prog="/var/lock/subsys/`basename$0`";

start(){
[!-f${prog}]&&touch${prog}
[$?-eq0]&&echo"`basename$0`startOk"||echo"`basename$0`running....";
}

stop(){
[-f${prog}]&&rm-f${prog}
[$?-eq0]&&echo"`basename$0`stopOK"||echo"`basename$0`stopped...";
}

status(){
[-f${prog}]&&echo"`basename$0`running..."||echo"`basename$0`stopped...";
}

usages(){
echo"UnkownUsages:`basename$0`{start|stop|restart|status}";
}

declare-aarr=(startstoprestartstatus);

case$1in
${arr[0]})
start
;;
${arr[1]})
stop
;;
${arr[2]})
stop
start
;;
${arr[3]})
status
;;
*)
usages
;;
esac

#給腳步加執行許可權,然後測試腳步

[[email protected]kernel]#chmod+xmyservice.sh

#給腳步的程式碼行前面加入chkconfig的SysV服務啟動指令碼風格片段

wKiom1ffTYWAXg3cAAANcs2dQ0I760.png

解析:這裡的35以及下面的description描述資訊可以省略不寫,只是對此指令碼做一個介紹,而chkconfig:設定的引數必須寫,新增此服務時讀取此行,會在35下級別對應的目錄(/etc/rc.d/rc3.d/)下生成以S66開頭的符號連結檔案和K22開頭符號連結檔案。

2、將剛才編寫的myservic模擬服務腳步新增到啟動服務列表

#測試成功後,將此指令碼拷貝至/etc/rc.d/init.d/目錄下,注意不要加.sh字尾

[[email protected]kernel]#cp-p./myservice.sh/etc/rc.d/init.d/myservice

#檢視myservice腳步是否已經拷貝成功

[[email protected]kernel]#ls-l/etc/rc.d/init.d/myservice
-rwxr-xr-x1rootroot697Sep1121:55/etc/rc.d/init.d/myservice

#然後cd切換到此目錄(/etc/rc.d/init.d)程序操作

[[email protected]kernel]#cd/etc/rc.d/init.d/
[[email protected]init.d]#pwd
/etc/rc.d/init.d

#使用chkconfig命令新增定義的服務腳步

[[email protected]init.d]#chkconfig--addmyservice

3、檢視是否根據在chkconfig檔案頭的級別、檔案序列號引數在對應目錄生成了連結檔案

#檢視myservervie的SysV級別表示

[[email protected]init.d]#grep'^#chkconfig'myservice
#chkconfig:356622

#檢視對應的35級別是否生成了對應的檔案連結

[[email protected]init.d]#ls-l/etc/rc.d/rc3.d/*myservice*
lrwxrwxrwx1rootroot19Sep1122:13/etc/rc.d/rc3.d/S66myservice->../init.d/myservice
[[email protected]init.d]#ls-l/etc/rc.d/rc5.d/*myservice*
lrwxrwxrwx1rootroot19Sep1122:13/etc/rc.d/rc5.d/S66myservice->../init.d/myservice

解析:可以看到在3和5級別服務腳步連結目錄下都是隻生成了S開頭的檔案,所有,此時表示在每次執行3和5級別時,會自動開啟此服務。

#檢視當前此服務所有級別的自動開啟和關閉狀態

[[email protected]init.d]#chkconfig--listmyservice
myservice0:off1:off2:off3:on4:off5:on6:off

解析:這裡顯示myservice服務3級別和5級別都是啟動狀態,和對應級別服務目錄生成的符號連結檔案所對應,都是S開頭,下面關閉此服務35執行級別自動啟動:

#使用chkconfig命令關閉 3級別的自啟動狀態

[[email protected]init.d]#chkconfig--level3myserviceoff

#再次檢視myservice服務所有執行級別的狀態

[[email protected]init.d]#chkconfig--listmyservice
myservice0:off1:off2:off3:off4:off5:on6:off

解析:這裡發現3級別已經變成了off,那麼對應的3級別服務目錄下的連結檔案會變嗎?

#檢視3級別服務目錄(/etc/rc.d/rc3.d/)下mysevice連結檔案

[[email protected]init.d]#ls-l/etc/rc.d/rc3.d/*myservice*
lrwxrwxrwx1rootroot19Sep1122:23/etc/rc.d/rc3.d/K22myservice->../init.d/myservice

解析:這裡發現已經根據/etc/rc.d/init.d/myservice腳步裡設定的K開頭22引數,改變了檔案的連結命令,從S66變成了K22。

4、測試/etc/rc.d/rcN.d/*的連結檔案和chkconfig服務列表的關係

#下面反過來,直接使用重命令來修改連結檔名,檢視是否會修改chkconfig列表裡的狀態:

#修改K22myservice連結檔名為S66myservce(安照chkconfig行定義好的)

[[email protected]init.d]#mv/etc/rc.d/rc3.d/K22myservice/etc/rc.d/rc3.d/S66myservice

#檢查檔名是否已經改變

[[email protected]init.d]#ls-l/etc/rc.d/rc3.d/*myservice*
lrwxrwxrwx1rootroot19Sep1122:23/etc/rc.d/rc3.d/S66myservice->../init.d/myservice

#此時使用chkconfig命令來檢視3級別下是否已經變成on及自啟動服務

[[email protected]init.d]#chkconfig--listmyservice
myservice0:off1:off2:off3:on4:off5:on6:off

解析:OK,原來內部只是不斷已經連線名來對指定執行級別的服務腳步進行開啟或關閉處理,當然,此指令碼必須要在/etc/rc.d/init.d存在,否則chkconfig不會識別,而且此服務腳步檔案還必須需要有chkfonig標示行,及指定級別、生成序列號等。

5、額外的圖形字元介面工具ntsyv

不僅可以使用chkconfig命令,還有專用的圖形工具(ntsysv),不過只針對當前執行級別設定

#檢視當前終端所在的執行級別

[[email protected]init.d]#runlevel
N3
[[email protected]init.d]#who-r
run-level32016-09-0106:32last=S

解析:以上連個命令都會顯示所在的執行級別,從上面輸出得知,當前在3級別執行。

#輸入ntsvsy列出當前執行級別的服務列表

[[email protected]init.d]#ntsysv

#ntsvsy開啟的Services列表中找到自定義的myservice服務

wKioL1ffTfzwtF1eAAAjNxaezr8015.png

說明:這裡前面的[ ]裡面有個*符號,說明在當前執行級別已經設定自啟動,也就是3級別。

#對Cancel按鈕按回車退出,使用chkconfig檢視3級別myservice是否自啟動

[[email protected]init.d]#chkconfig--listmyservice
myservice0:off1:off2:off3:on4:off5:on6:off

解析:這裡顯示時on狀態,和 ntsysv工具裡的對應。

#再次開啟ntsysv工具,對myservice此行按空格,讓*符號消失

wKiom1ffThPzO_x_AAAV95TcmT4392.png

注意:這裡設定好後,使用tab鍵切換到ok按回車才能儲存設定並退出。

#使用chkconfig命令myservice在3級別是否已經變成off

[[email protected]init.d]#chkconfig--listmyservice
myservice0:off1:off2:off3:off4:off5:on6:off

#再次檢視3級別的服務連結檔案是否為K22*開頭

[[email protected]init.d]#ls-l/etc/rc.d/rc3.d/*myservice*
lrwxrwxrwx1rootroot19Sep1122:47/etc/rc.d/rc3.d/K22myservice->../init.d/myservice

#清除myservice對應的所有符號連結檔案

[[email protected]init.d]#chkconfig--delmyservice

#再次使用chkconfig命令以及出現找不到此服務,說明所有級別下連結已經清除完

[[email protected]init.d]#chkconfig--listmyservice
servicemyservicesupportschkconfig,butisnotreferencedinanyrunlevel(run'chkconfig--addmyservice')

#但是此指令碼並沒有刪除

[[email protected]init.d]#ls-l/etc/rc.d/init.d/myservice
-rwxr-xr-x1rootroot772Sep1122:11/etc/rc.d/init.d/myservice

#刪除此指令碼檔案即可恢復開始原狀

[[email protected]init.d]#rm-f/etc/rc.d/init.d/myservice


總結:

linuxCentos6發行版來說,開機啟動流程為:

1、POST加電自檢,然後找到BLOS中設定的第一個啟動裝置;

2、然後從此裝置及硬碟中找到磁碟的前446位元組,及bootloader,完成第一階段;

3、然後根據bootloader中的grub資訊找到boot分割槽;

4、讀取/boot/grub/grub.conf配置檔案中讀取vmlinuz核心檔案,然後解壓並載入核心;

5、在載入完成後然後解壓initrd initramfs.img)模擬載入器來切換到真正的根檔案系統,這時實際上運行了initramfs 中有一段核心腳步為init,及grub.conf中定義的根分割槽(如root=/dev/sda2),然後進入系統;

6、隨之根據核心檔案中定義會預設執行/sbin/init第一個系統啟動程式;

7、/sbin/init預設讀取/etc/initab檔案,讀取設定的預設執行級別;

8、然後執行/etc/rc.d/rc.sysinit檔案來設定一些系統的級別級別配置(如載入核心模組、設定主機名,重新掛載檔案系統等);

9、然後根據預設執行級別來找對應級別下的目錄服務腳步連結檔案來執行,也就是執行/etc/rc.d/rc,當然這裡的腳步讀有一個上述說到的SysV風格的chkconfig標識(#chkconfig level SS KK),然後安裝關閉K開頭連結腳步和開啟S開頭的連結腳步,最終啟動所有服務;

10、執行完所有服務後這裡最後會執行/etc/rc.d/rc.local (這裡包含了一些可以自定義的程式);

11、最終開啟根據下面的定義的終端個數來確定開啟幾個終端,會藉助agettymingetty來找到/bin/login程式來開啟使用者互動式登入介面,此時登入後就打開了/bin/bash程式了。


轉載於:https://blog.51cto.com/mengzhaofu/1853920