引導Linux系統涉及不同的組件和任務。在固件和硬件初始化過程(取決于機器的架構)之后,內核通過引導加載程序GRUB2啟動。此后,引導過程完全由操作系統控制并由systemd處理。systemd提供了一組“target”,用于為日常使用、維護或緊急情況啟動配置。
1 術語
init
有兩種不同的進程會被命名為init:
- 掛載到根文件系統的initramfs進程
- 從真正的根文件系統開始執行的所有其他進程的操作系統進程
在這兩種情況下,systemd程序都會處理這個任務。它首先從initramfs執行以掛載根文件系統。一旦成功,它將作為初始進程從根文件系統重新執行。為了避免混淆這兩個systemd進程,我們在initramfs上將第一個進程稱為init,將第二個進程稱為systemd。
initrd/initramfs
initrd(初始RAM磁盤)是一個映像文件,其中包含由內核加載并從/dev/ram作為臨時根文件系統掛載的根文件系統映像。掛載此文件系統需要文件系統驅動程序。
從內核2.6.13開始,initrd已被initramfs(初始RAM文件系統)取代,它不需要掛載文件系統驅動程序。openSUSELeap專門使用initramfs。但是,由于initramfs被保存為/boot/initrd,因此通常稱為“initrd”。
2 系統啟動過程
2.1 初始化和引導加載程序階段
在初始化階段,設置機器的硬件并準備好設備。 此過程在硬件架構之間存在顯著差異。
openSUSE Leap在所有架構上都使用引導加載程序GRUB2。根據架構和固件,啟動GRUB2引導加載程序可能是一個多步驟過程。引導加載程序的目的是加載內核和基于RAM的初始文件系統(initramfs)。
AArch64和AMD64/Intel64上的初始化和引導加載程序階段
電腦啟動后,BIOS和UEFI會初始化屏幕和鍵盤,并測試內存,但是不會訪問大容量存儲(硬盤)。隨后加載CMOS中的日期,時間和外設。識別到啟動介質后,系統控制權將會從BIOS/UEFI過度到boot loader。
在具有傳統BIOS的機器上,只能加載來自引導盤的第一個物理512字節扇區(主引導記錄,MBR)的代碼,只有最小的GEUB2適合MBR,它的主要目的是從MBR和第一個分區(MBR分區表)之間的間隙或從BIOS根分區(GPT分區表)加載一個包含文件系統驅動的GRUB2核心鏡像。這個景象包含了文件系統的驅動程序,因此能夠訪問位于根文件系統上的/boot目錄。/boot目錄包含了用于GRUB2核心一級內核和initramfs景象的附加模塊。一旦它可以訪問該分區,GRUB2就會將內核和initramfs鏡像加載到內存中,并將控制權交給內核。
當從包含一個加密的/boot分區的加密文件系統啟動BIOS時,需要輸入兩次密碼,第一次用于GRUB2加密/boot,第二次用于systemd掛載加密卷。
使用UEFI加載就會簡單些,固件能夠從具有GPT分區表的FAT磁盤分區中讀取。這個EFI系統分區(掛載到了/boot/efi)擁有足夠的空間來承載由固件直接加載和執行的成熟的GRUB2。
如果BIOS/UEFI支持網絡引導,還可以配置一個引導服務器,然后就可以通過PXE引導系統。BIOS/UEFI扮演了boot loader的角色。它從boot server獲取boot獎項并啟動系統。這是完全獨立于本地硬盤的。
2.2 內核階段
當boot loader通過了系統的控制,所有架構的加載過程就完全相同了。boot loader會加載內核和一個初始化基于RAM的文件系統(initramfs)到內存中,然后內核接管工作。
當內核設置好內存管理并且檢測到CPU的類型及特性后,將會初始化硬件并從使用initramfs加載的內存中掛載臨時根文件系統。
2.2.1 initramfs文件
initramfs(初始RAM文件系統)是一個小的cpio存檔,內核可以將其加載到RAM磁盤中。它位于/boot/initrd。它可以使用名為dracut的工具創建。
initramfs提供了一個最小的Linux環境,可以在安裝實際的根文件系統之前執行程序。這個最小的Linux環境由BIOS或UEFI例程加載到內存中,除了足夠的內存外,沒有特定的硬件要求。initramfs存檔必須始終提供一個名為init的可執行文件,該可執行文件在根文件系統上執行systemd守護程序,以便引導過程繼續進行。
在掛載根文件系統和啟動操作系統之前,內核需要相應的驅動程序來訪問根文件系統所在的設備。這些驅動程序可能包括特定類型硬盤的特殊驅動程序,甚至是訪問網絡文件系統的網絡驅動程序。根文件系統所需的模塊由initramfs上的init加載。加載模塊后,udev為initramfs提供所需的設備。稍后在啟動過程中,更改根文件系統后,需要重新生成設備。這是由systemd單元systemd-udev-trigger.service完成的。
重新生成initramfs
由于initramfs包含了驅動,因此在必要時需要進行升級,如果有相關的包,這過程會自動完成,YaST或zypper會提醒你生成新的initramfs,但有些時候需要手工完成這項工作。
- 硬件變化時添加驅動
如果變化的硬件需要不同的驅動加載到內核時,必須升級initramfs文件。
打開或創建文件/etc/dracut.conf.d/10-DRIVER.conf
,添加如下信息:
force_drivers+="RTL8822BE" #RTL8822BE為硬件型號,如果有多個硬件,兩個硬件型號使用空格隔開
- 將系統目錄移動到RAID或LVM中
當從一個正在運行的系統中移動交換機文件到RAID或邏輯卷時,需要創建一個包含支持軟件RAID或LVM驅動的initramfs。因此需要在/etc/fstab中創建新的掛載條目。
- 添加磁盤到包含了根文件系統的LVM組或btrfs RAID
這種情況下需要創建一個包含對擴大卷的支持的initramfs。
- 修改內核變量
如果通過sysctl接口修改相關聯的文件(/etc/sysctl.conf
或/etc/sysctl.d/*.conf
)來修改內核變量的值,下次重啟修改將會丟失,即使在運行時使用sysctl --system加載值,更改也不會保存到initramfs文件中。下面的例子是更新方法:
- 運行時生成新的initramfs文件
dracut MY_INITRAMFS
Replace MY_INITRAMFS with a file name of your choice. The new initramfs will be created as /boot/MY_INITRAMFS.
或者使用dracut -f
命令強制覆蓋現有文件
- 創建一個執行initramfs文件的軟鏈接。(執行了
dracut -f
命令不需要這一步)
(cd /boot && ln -sf MY_INITRAMFS initrd)
2.3 initramfs階段的init
臨時根文件系統是從內核掛載,該內核來自包含了可執行的systemd的initramfs。(在下面的initramfs上稱為init)。改程序會執行所有的必要操作來掛載正確的根文件系統。它為使用udev的大容量存儲控制器所需的文件系統和設備驅動程序提供內核功能。
initramfs上init的主要目的是準備安裝和訪問真正的根文件系統。根據系統配置,initramfs上的init負責以下任務。
-
Loading kernel modules
取決于你的硬件配置,可能需要特殊的驅動程序來訪問計算機的硬件組件(最重要的組件是硬盤)。要訪問最終的根文件系統,內核需要加載正確的文件系統驅動程序。 -
Providing block special files
內核根據加載的模塊生成設備事件。udev處理這些事件并在/dev中的RAM文件系統上生成所需的特殊塊文件。如果沒有這些特殊文件,文件系統和其他設備將無法訪問。 -
Managing RAID and LVM setups
如果您將系統配置為在RAID或LVM下保存根文件系統,則initramfs上的init會設置LVM或RAID,以便稍后訪問根文件系統。 -
Managing the network configuration
如果您將系統配置為使用網絡安裝的根文件系統(通過NFS安裝),則init必須確保加載了正確的網絡驅動程序,并且將它們設置為允許訪問根文件系統。
如果文件系統位于iSCSI或SAN等網絡塊設備上,則initramfs上的init也會建立與存儲服務器的連接。如果主要目標不可用,openSUSELeap支持從次要iSCSI目標啟動。
如果無法從引導環境中掛載根文件系統,則必須先檢查并修復根文件系統,然后才能繼續引導。對于Ext3和Ext4文件系統,將會自動啟動檢查器。XFS和Btrfs文件系統的修復過程不是自動化的,用戶會看到描述可用于修復文件系統的選項的信息。文件系統修復成功后,退出引導環境會導致系統重新嘗試掛載根文件系統。如果成功,引導將繼續正常進行。
2.3.1 安裝過程中initramfs階段的init
作為安裝過程的一部分,在初始引導期間調用initramfs上的init時,其任務與上述任務不同。請注意,安裝系統也不會從initramfs啟動systemd——這些任務由linuxrc執行。
-
Finding the installation medium
當開始安裝,機器會加載安裝內核和包含YaST安裝器的init。YaST安裝器運行在RAM文件系統中,他需要安裝介質的地址以用于操作系統的安裝。 -
Initiating hardware recognition and loading appropriate kernel modules
引導過程從用于大多數硬件配置的最小驅動程序集開始。在AArch64、POWER和AMD64/Intel64架構的機器上,linuxrc會進行初始硬件掃描,用于尋找適合的硬件驅動。在IBM Z架構機器上,需要提供驅動程序列表和參數。這些驅動用于生成客戶自定義的initramfs,它用于啟動系統。如果模塊不需要用于啟動而是用于冷插拔,則可以使用systemd加載模塊。 -
Loading the installation system
硬件被識別后,就會加載適合的驅動。udev程序會創建指定的設備文件,linuxrc會使用YaST安裝器開始安裝系統的過程。 -
Starting YaST
最后,linuxrc會啟動YaST,然后開始軟件包安裝和系統配置。
2.4 系統階段
找到“真正的”根文件系統后,會檢查錯誤并掛載。如果成功,initramfs將被清除并執行根文件系統上的systemd守護進程。systemd是Linux的系統和服務管理器。它是作為PID 1啟動的父進程,并充當啟動和維護用戶空間服務的init系統。