Linux 啟動流程及相關知識

2022-07-24 18:02:20

基礎知識

linux系統的組成

  • 核心(kerner)

  • 根檔案系統(rootfs)

核心提供作業系統的功能,根檔案系統包含常用的一些工具,這些工具。這些工具的執行離不開glibc庫檔案。

程式:二進位制程式檔案

庫:庫是函數的集合,用來實現介面呼叫等功能。程式的執行依賴這些庫檔案

Linux核心的功能:檔案系統管理、程序管理、網路管理、驅動程式、記憶體管理等

CentOS 6

CentOS 6 啟動流程: 4步

POST--->MBR--->GRUB--->載入核心

POST:Power-On-Self-Test,加電自檢。由主機板的bios程式完成。
bios:basic input output system。基本出入輸出系統
MBR

MBR: 主開機記錄(Master Boot Record)。是硬碟的第一個磁區(0磁軌0磁區),總共有512個位元組,前446個位元組儲存的是bootloader的階段一程式(以二進位制的形式存放)

bootloader:是用來啟動(引導)作業系統的一個程式。(安裝作業系統的時候會自動安裝)
bootloader這個程式裡面定義了作業系統(核心)存放的位置等

windows用的bootloader:ntloader,僅用來啟動作業系統的

linux用的bootloader:現在使用的是GRUB,不僅用來啟動作業系統,還有多種功能
#早期版本用的是0.97版本,現在用的是2.02版本

grub的啟動流程:啟動作業系統前載入grub。

階段1:加電自檢完成後,通過bios檢測裝置驅動。如果是硬碟啟動就讀取硬碟的第一個磁區(MBR)。並將MBR中的前446位元組(bootloader)載入到記憶體中進行執行 #二進位制檔案,可以直接存取的

階段1.5:因為grub的另外一部分是存放在檔案系統的/boot目錄下的,但是要想解析這個對應的檔案,需要識別這個檔案系統。所以需要藉助檔案系統的驅動程式。因為MBR的前446位元組存放不下檔案系統的驅動,所以檔案系統驅動放在了MBR的後續磁區中

階段2:解析載入檔案系統對應目錄下grub的組態檔,找到作業系統(linux)。 #非二進位制,所以不可以直接存取,而是一個檔案系統。需要檔案系統的驅動才能存取解析到對應的資料

#階段1和1.5都是為了階段2做準備的。

CentOS6 Grub第二階段的存放位置:/boot/grub

grub.conf:grub的關鍵組態檔,裡面定義了核心存放的相關路徑等內容

#組態檔格式
default:表示預設啟動那個核心 #例如default=0表示預設第一個核心作為引導
timeout:在啟動介面停留的時間
hidenmenu:隱藏的啟動選單,預設看不到的
	tiele:啟動介面顯示的選單項
	root(hd#.#):表示boot分割區所在的位置,#hd0.0--hd表示硬碟 0.0表示第一塊硬碟的第一個分割區
	kerner: /PATH/TO/KERNEL_FILE--核心檔案所在的位置(/vmlinux表示boot目錄下的vmlinux這個檔案) root=UUID=xxxx--表示利用核心,要載入的檔案系統的根系統,系統硬碟真正的根(比如/dev/sda1這塊硬碟掛載到根上面 那麼載入的就是這個硬碟)
	initrd:系統的一個輔助檔案,是一個小型的linux檔案系統,核心進入硬碟根的時候會藉助它

bootloader是硬體和作業系統之間的一個媒介。硬體通過bootloader才能找到作業系統。

採用硬碟引導進入救援模式的方法

系統無法啟動使用光碟的方式進入救援模式:

採用光碟啟動(引導),進入rescue模式
#重啟系統出現進度條的時候快速按ESC鍵,然後選擇CD-ROM Dirver,然後選擇Troubleshooting,選擇Rescue a CentOS liux System,然後選擇1繼續,然後切換到/mnt/sysimage這個目錄下操作。因為救援模式預設進入的根不是硬碟系統的根。而是ramdisk裡的檔案系統,並沒有切換到本機硬碟上的「真正」檔案系統
#正常啟動的系統他不會掛載到/mnt/sysimage這個目錄下的
連結:http://t.zoukankan.com/duzhaoqi-p-7327525.html

#chroot /mnt/sysimage #切換到真正的根目錄下面

#grub-install /dev/sda #執行秀姑grub的命令

#sync #將快取中的資訊同步到硬碟

#exit  #退出重啟

#exit

Centos6的Grub修復方法

首先需要使用光碟引導進入救援模式

#grub資訊被破壞的修復方法
使用grub-install來修復:grub-install --root-directory=DIR /dev/DISK

grub-install 磁碟名稱  #安裝grub到硬碟上,會自動找到整個硬碟的第一個磁區MBR的前446個位元組。

#無法修復grub的階段二所對應的組態檔,需要手動編寫 /boot/grub/grub.conf這個組態檔
Centos6 修復grub的方法:
方法一: #無法修復/etc/grub/grub.conf這個檔案

grub-install命令: grub-install 磁碟名稱  #安裝grub到硬碟上,會自動找到整個硬碟的第一個磁區MBR的前446個位元組。

載入核心

grub載入linux核心後,通過核心載入硬碟的根,啟動系統中的第一個程序init。

核心想要進入硬碟的根,需要檔案系統驅動。因為根分割區有自己的檔案系統。

驅動的功能由核心提供,核心的驅動存放位置在/lib目錄下,例如ext4的檔案系統驅動:ext4.ko.所以要載入檔案系統的驅動就需要進入根的檔案系統,顯然不行。

所以核心此時不是從這裡面載入檔案系統驅動,而是從GRUB組態檔中的initrd後面指定的檔案裡面載入的檔案系統。(是一個小型的linux檔案系統)
init程序啟動以後就會通過以下順序執行相關的組態檔來設定系統

(1)/etc/inittab組態檔:確定系統使用那個執行模式(runlevel)
CentOS的執行模式有7個,對應數位0--6

0:關機
6:重啟
1:安全模式
3:字元模式
5:圖形介面模式

(2)執行/etc/rc.d/rc.sysinit這個指令碼。初始話系統的一些資訊。

設定主機名

設定歡迎資訊

載入對應的服務設定

裝置的掛載

交換空間的準備

系統時鐘等資訊

(3)根據對應的執行模式執行對應的資料夾下面指令碼:/etc/rcX.d/xxx

比如執行模式是3:就執行/etc/rc3.d/ 下的指令碼。

/etc/rc3.d/下面的檔案都是軟連結,指向/sbin/init下面的指令碼。

以K開頭的檔案:開機啟動 K##:##執行次序;數位越小,越先執行;

以S開頭的檔案:開機不啟動。S: S##:##執行次序;數位越小,越先執行;

CentOS6的服務管理工具

  • service:服務的開啟和關閉

  • chkconfig:服務的開機啟動等

service

service 服務 start|stop|restart

service --status-all

例如:service network start (networkCentOS8棄用了)
chkconfig
chkconfig 服務 on|off

rc.local檔案

  • 是一個開機啟動檔案,不屬於任何執行模式。開機的時候所有的服務指令碼都執行完成後才會執行他。

  • CentOS7以及後面的版本想用這個檔案的話,需要手動新增可執行許可權才會執行。

  • ubuntu預設沒有這個檔案,需要手動建立並更改許可權才可以使用。

/etc/rc.local

/etc/rc.d/rc.local
#/etc/rc.local -> rc.d/rc.local rc.local是 rc.d/rc.local的一個軟連線

正常級別下,最後啟動一個服務S99local沒有連結至/etc/rc.d/init.d一個服務指令碼,而是指向
了/etc/rc.d/rc.local指令碼

想開機時自動執行的命令,可直接放置於/etc/rc.d/rc.local檔案中

/etc/rc.d/rc.local在指定執行級別指令碼後執行

CentOS6 啟動流程總結:

1.POST,裝置加電自檢(cpu、記憶體、硬碟、io裝置等檢查)

2.MBR引導找到GRUB

3.GRUB執行完成後載入核心,核心載入硬碟的根

4.載入系統第一個程序init,並按順序執行以下組態檔和指令碼。
	/etc/inittab

	/etc/rc.d/rc.sysinit

	/etc/rcX.d/xxx

5.所有服務啟動完成後執行rc.local這個指令碼裡面的內容。

6.終端啟動,登入相關的設定和驗證。

Linux的/proc和/sys目錄

虛擬資料夾概念:

虛擬的資料夾,因為其資料內容是存放在記憶體中的,不是存放在硬碟中

/proc和/sys都是虛擬的資料夾

/proc

proc是程序(process)的縮寫。這個目錄檔案裡面存放的是程序的相關資訊,把系統中的程序資訊、核心狀態放在proc中,是一個虛擬的資料夾,對應的資料資訊是記憶體中的狀態。

/proc/sys

這個目錄檔案裡面的資訊可以修改,可以通過這些設定來控制核心

sysctl 工具

sysctl:修改系統的核心引數

sysctl修改的引數是臨時生效的,通過編寫組態檔的方式實現持久化生效

#組態檔
/run/sysctl.d/*.conf

/etc/sysctl.d/*.conf

/usr/local/lib/sysctl.d/*.conf

/usr/lib/sysctl.d/*.conf

/lib/sysctl.d/*.conf

/etc/sysctl.conf  #主要存放在這裡面,一般都在這個組態檔裡面編寫設定。

#格式:
和檔案中的格式不一樣,使用點(.)來隔開路徑。/proc/sys不用寫, 因為這個組態檔對應就是管理/proc/sys這個資料夾的
#常用引數:
-w   臨時改變某個指定引數的值

-a   顯示所有生效的系統引數

-p   從指定的檔案載入系統引數
範例
禁止ping通本機:
[root@centos8 ~]#cat /etc/sysctl.d/test.conf
net.ipv4.icmp_echo_ignore_all=1
[root@centos8 ~]#sysctl -p /etc/sysctl.d/test.conf

清除快取方法
echo 1|2|3 >/proc/sys/vm/drop_caches

/sys

/sys目錄檔案存放的是和硬體有關的一些資訊,也是虛擬資料夾,不是真正的硬碟上的資料夾,對應的也是記憶體中的資料。

範例

新新增硬碟的識別
echo "- - -" > /sys/class/scsi_host/hostX/scan #X表示數位,從0開始的

核心模組管理

核心的組成部分:
  • kernel:核心核心,一般為bzImage,通常在/boot目錄

  • kernel object:核心物件,一般放置於/lib/modules/VERSION-RELEASE/

  • 輔助檔案:ramdisk

核心版本檢視:
uname -r
-r 顯示VERSION-RELEASE
核心模組命令
  • lsmod

  • modprobe

lsmod:
  顯示核心已經裝載的模組
  顯示的內容來自於: /proc/modules檔案
範例:
[root@centos8 ~]#lsmod 
Module                 Size Used by
uas                    28672  0
usb_storage            73728  1 uas
nls_utf8               16384  0
isofs                  45056  0 #顯示:名稱、大小,使用次數,被哪些模組依賴
modprobe:用於裝載或者解除安裝核心模組
  裝載:modprobe 模組名
  解除安裝: modprobe -r 模組名  # rmmod命令:解除安裝模組

systemd服務

從CentOS7開始,就使用systemd服務代替init作為系統啟動的第一個程序。

systemd的特性:
  • 服務並行啟動

  • 可以按照需要啟動對應守護進行

  • 自動管理服務的依賴關係

  • Unit(單元)的概念

  • 使用systemctl管理工具

systemd的核心概念Unit(單元)
systemd把服務都籠統稱為Unit(單元),通過組態檔進行標識和設定。

Unit存放的位置:/lib/systemd/system

systemd的Unit型別:
(1)service:類似於Centos6裡面的服務指令碼。檔案擴招名為.service

(2)target:類似於Centos6裡面的執行級別。副檔名為.target

(3)socket:義程序間通訊用的socket檔案。副檔名為.socket

#socket的理解
socket翻譯過來是通訊端,原意為插座、插孔。

socket可以理解為:ip地址+埠+協定型別

例如:一臺筆記型電腦(server),一個耳機(client),一個u盤(clinet),一個滑鼠(client),
	socket就可以想象成筆記型電腦上的usb介面、音訊介面。
	耳機需要連線到電腦聽歌,需要用到音訊介面,u盤需要連結電腦拷貝資料,需要用到usb介面。
	socket就負責幫助這些外接裝置找到筆記型電腦中相對應的驅動以便他們完成自己的工作,反之也是這樣。

socket就是位於兩個層面(傳輸層和應用層)中間的一個參與者,服務於兩方。

http是應用層協定,解決如何包裝資料,TCP/IP協定是傳輸層協定,主要解決資料怎麼在網路中傳輸。

一個網路協定 + 一個ip + 一個埠號,就組成了一個socket
原文連結:https://blog.csdn.net/EJEEMT/article/details/90212312

Unit的組態檔

/usr/lib/systemd/system #每個服務最主要的啟動指令碼設定,類似於之前的/etc/init.d/

/lib/systemd/system #ubutun的對應目錄

/run/systemd/system #系統執行過程中所產生的服務指令碼,比上面目錄優先執行

/etc/systemd/system #管理員建立的執行指令碼,類似於/etc/rcN.d/Sxx的功能,比上面目錄優先執行

#/etc/systemd/system:系統管理員和使用者使用
#/usr/lib/systemd/system:發行版打包者使用

systemd的service

service這種unit型別的Unit檔案格式

由三部分組成:

  • Unit:定義的是這個單元的相關資訊

  • Service:定義的是這個服務的相關資訊

  • Install:定義的是服務啟動和關閉的一些選項

Unit段的常用選項
Description:unit的描述資訊

After:當前unit在那些unit後面啟動,其功能與Before相反

Requires:依賴到的其它units,強依賴,被依賴的units無法啟用時,當前unit也無法啟用

Wants:依賴到的其它units,弱依賴

Conflicts:定義units間的衝突關係

Service段常用選項

Type:定義啟動型別

EnvironmentFile:環境組態檔

simple:預設值,後臺啟動常駐於記憶體

ExecStart:啟動unit要執行命令或指令碼的絕對路徑

ExecStartPre: ExecStart前執行

ExecStartPost: ExecStart後執行

ExecStop:停止unit要執行的命令或指令碼

Restart:當設定Restart=1 時,服務意外終止會再次自動啟動

RestartSec: 重啟等待時間,預設100ms

PrivateTmp:設定為yes時,會在生成/tmp/systemd-private-UUID-NAME.service-XXXXX/tmp/目錄

Install段常用選項

Alias:別名,可使用systemctl command Alias.service

RequiredBy:被哪些units所依賴,強依賴

WantedBy:被哪些units所依賴,弱依賴

Also:安裝本服務的時候還要安裝別的相關服務

daemon-reload

當建立或者更改了硬碟上的unit的相關檔案以後,需要使用daemon-reload載入到系統的記憶體中才會生效。

或者重啟系統也能生效

範例: 自定義service的unit檔案

[root@centos8 ~]#vim /lib/systemd/system/hello.service 
[Unit] 
Description=Hello World 

[Service] 
TimeoutStartSec=0
ExecStart=/bin/sh -c "while true; do echo Hello World; sleep 1; done"
ExecStop=/bin/kill sh

[Install] 
WantedBy=multi-user.target

#會在後臺持續輸出 hello word,寫入到了系統紀錄檔中/var/log/meseage
#ubuntu的紀錄檔檔案是: /var/log/sys.log

systemd的target

執行級別:不同的執行級別是不同的服務組合而來的結果。
systemd的target就類似於CentOS6的runlevel

0  ==> runlevel0.target-> poweroff.target
1  ==> runlevel1.target-> rescue.target
2  ==> runlevel2.target-> multi-user.target
3  ==> runlevel3.target-> multi-user.target
4  ==> runlevel4.target-> multi-user.target
5  ==> runlevel5.target-> graphical.target#graphical.target是基於multi-user.target來的
6  ==> runlevel6.target-> reboot.target #

systemd的管理工具

systemctl是systemd單元(unit)的管理工具

格式:systemctl COMMAND unit_name

start|stop|restart|status

mask:禁用服務

umask:取消禁用的服務

enable:設定開機啟動

disable:取消開機啟動

is-active:檢視unit是否啟用

is-enable:檢視unit是否開機啟動

list-units:檢視所有的unit

範例

啟動一個服務:
systemctl start unit_name.service #字尾可以省略不屑

設定服務開機重啟並立馬啟動:
systemctl enable unit_name.service --now

檢視系統中型別為service的unit
systemctl list-unit --type service --all

service服務的狀態

loaded Unit組態檔已處理

active(running) 一次或多次持續處理的執行

active(exited) 成功完成一次性的設定

active(waiting) 執行中,等待一個事件

inactive 不執行

enabled 開機啟動

disabled 開機不啟動

static 開機不啟動,但可被另一個啟用的服務啟用

indirect 重定向到別處

修改執行級別

  • 通過命令的方式修改

  • 通過開機啟動的時候修改

#通過systemctl命令切換執行模式:
systemctl isolate name.target #效果等同於:init X

#開機的時候指定核心模式:隻影響當次的啟動
啟動時,到啟動選單,按e鍵,找到在linux 開頭的行後新增systemd.unit=desired.target 
#centos7是linux16開頭

例如:systemd.unit=emergency.target 
systemd.unit=rescue.target

CentOS7及後續版本的啟動流程

  • 1.POST:系統加電自檢並找到MBR

  • 2.MBR引導並載入GRUB

  • 3.GRUB引導核心並載入硬碟檔案系統上的根系統

  • 4.啟動系統的第一個程序systemd程序

  • 5.執行systemd對應的unit(target這種型別的)

破解 CentOS 7和8的 root 密碼

方法一:
啟動時任意鍵暫停啟動 #進入核心啟動的介面 畫面停止在啟動選單上面

按e鍵進入編輯模式

將遊標移動linux 開始的行,新增核心引數 rd.break #rd.break暫停正常的啟動,進入臨時的救援模式
#centos7是linux16開頭,這一行就是grub裡面的一行核心引數設定

按ctrl-x啟動

#使用mount命令檢視,發現指定的硬碟是掛載到/sysroot這個目錄下的,所以當前的根目錄不是真正硬碟的根。
#但是我們的硬碟又是以為唯讀的方式掛載到/sysroot下的,無法修改檔案等操作,所以需要重新掛載。
mount –o remount,rw /sysroot

chroot /sysroot  #改變根目錄為我們硬碟檔案的根目錄

passwd root #輸入密碼

#如果SELinux是啟用的,才需要執行下面操作,如查沒有啟動,不需要執行

touch /.autorelabel  #重新打selinux的標籤

exit

reboot
方法二:
啟動時任意鍵暫停啟動,出現核心啟動的介面

按e鍵進入編輯模式

將遊標移動linux 開始的行,改為 rw init=/sysroot/bin/sh

按ctrl-x啟動

chroot /sysroot

passwd root

#如果SELinux是啟用的,才需要執行下面操作,如查沒有啟動,不需要執行
touch /.autorelabel

exit

reboot

修復 GRUB2的方法

GRUB2:CentOS 7,8及ubuntu1804都使用
GRUB2的主要組態檔:
/boot/grub2/grub.cfg
修復GRUB組態檔的方法:
法一:grub2-mkconfig > /boot/grub2/grub.cfg

法二:grub2-mkconfig  -o  /boot/grub2/grub.cfg  -o:表示他的標準輸出
修復grub:
grub2-install /dev/sda #BIOS環境

grub2-install #UEFI環境