Arch 的啟動流程
為了啟動 Arch Linux,必須配置一個與 Linux 兼容的引導加載程序。引導加載程序負責在初始化啟動進程之前,加載好內核和 initial ramdisk。具體過程因 BIOS 和 UEFI 系統而異,詳細描述在本文和關聯頁面中給出。
固件類型[編輯 | 編輯原始碼]
固件是開機時最先執行的程序。
BIOS[編輯 | 編輯原始碼]
BIOS,又稱基本輸入輸出系統(Basic Input-Output System),是系統開啟時最先運行的程序(固件)。大多數情況下它儲存在主板自身的一塊閃存內,獨立於其他系統存儲。最早是為 IBM PC 開發,用於處理硬件初始化和啟動過程。從 2010 年起已逐漸被技術上不受限的 #UEFI 替換。
UEFI[編輯 | 編輯原始碼]
統一可擴展固件接口(Unified Extensible Firmware Interface,UEFI)支持讀取分區表和文件系統。UEFI 不從主引導記錄(MBR)中啟動任何引導代碼(無論其是否存在),相反,UEFI 的啟動過程依賴非易失性隨機訪問存儲器(NVRAM)中的引導條目。
UEFI 規範要求支持 FAT12、FAT16 和 FAT32 文件系統(參見 UEFI 規範 2.9 版 13.3.1.1 小節),但每個符合規範的廠商可以選擇添加對其他文件系統的支持;比如,蘋果公司(Apple)的 Mac 支持(並默認使用)他們自己的 HFS+ 或 APFS 文件系統。UEFI 的一些實現方案還支持光盤的 ISO-9660 文件系統。
UEFI 會啟動 EFI 應用程式。例如引導加載程序、引導管理器和 UEFI Shell 等等。這些應用程式通常以文件形式存儲在 EFI 系統分區中。廠商可以將其特定文件存儲在 EFI 系統分區中的 /EFI/vendor_name
文件夾下。應用程式可以通過在 NVRAM 中添加引導項或從 UEFI shell 中啟動。
UEFI 規範通過兼容性支持模塊(Compatibility Support Module,CSM)來支持傳統 #BIOS 引導。如果在 UEFI 中啟用了 CSM, UEFI 會為所有驅動器生成 CSM 引導項。如果選擇從某一個 CSM 引導項啟動,UEFI 的 CSM 會嘗試從這個磁盤的 MBR 引導代碼啟動。
系統初始化[編輯 | 編輯原始碼]
系統開啟,執行加電自檢(Power-on self-test,POST)之後:
在 BIOS 下的情況[編輯 | 編輯原始碼]
- 上電自檢後,BIOS 初始化引導所需的硬件(硬盤、鍵盤控制器等等)。
- BIOS 啟動在「BIOS 硬盤順序」中第一塊硬盤上的前 440 字節代碼(即主引導記錄引導代碼區域)。
- 引導加載程序在 MBR 引導代碼的第一階段,之後會從下列任意一處啟動第二階段代碼(如果有的話):
- 真正的#引導加載程序啟動。
- 隨後,引導加載程序通過鏈式加載或直接加載作業系統內核的方式加載作業系統。
在 UEFI 下的情況[編輯 | 編輯原始碼]
- 加電自檢後,UEFI 初始化引導所需的硬件(硬盤、鍵盤控制器等等)。
- 固件讀取 NVRAM 中的引導項,以決定要啟動哪一個 EFI 應用程式,以及從哪啟動(比如從哪一個硬盤和分區)。
- 一個引導項可能對應的只是一塊硬盤。在這種情況下,固件會尋找硬盤上的 EFI 系統分區,並嘗試在後備引導路徑
\EFI\BOOT\BOOTx64.EFI
處(在 IA32(32 位)UEFI 的系統上為BOOTIA32.EFI
)查找 EFI 應用程式。這就是可引導 UEFI 可移動媒體的工作原理。
- 一個引導項可能對應的只是一塊硬盤。在這種情況下,固件會尋找硬盤上的 EFI 系統分區,並嘗試在後備引導路徑
- 固件啟動 EFI 應用程式。
- 這可以是一個#引導加載程序,或者是使用 EFISTUB 的 Arch 內核本體。
- 其還可以是一些其他的 EFI 應用程式,比如是一個 UEFI shell 或一個#引導加載程序(例如 systemd-boot 或 rEFInd)。
如果啟用了安全啟動,啟動過程將會通過簽名驗證 EFI 二進制文件的真實性。
UEFI 中的多重引導[編輯 | 編輯原始碼]
因為每個作業系統或廠商都可以維護自己在 EFI 系統分區中的文件,同時不影響其他系統,所以 UEFI 的多重引導的原理就是啟動不同的、與特定作業系統引導加載程序所對應的 EFI 應用程式。這避免了依賴一個#引導加載程序去加載另一個作業系統的鏈式加載機制。
另請參閱與 Windows 系統雙引導。
引導加載程序[編輯 | 編輯原始碼]
引導加載程序(Boot Loader,又稱引導加載器、啟動加載器或啟動引導器)是由計算機固件(BIOS 或 UEFI)啟動的軟件。它負責用想要的內核參數加載內核,並根據配置文件初始化 RAM 磁盤。在 UEFI 的情況下,內核本身可以由 UEFI 使用 EFISTUB 直接啟動。要在引導前編輯內核參數,仍可以使用單獨的引導加載程序或引導管理器。
/boot
路徑。這意味着它必須要支持從塊設備、堆疊塊設備(LVM、RAID、dm-crypt、LUKS 等)開始,到內核和 initramfs 映像所在文件系統為止的一切功能。功能比較[編輯 | 編輯原始碼]
- 由於 GPT 是 UEFI 規範的一部分,因此所有的 UEFI 引導加載程序都支持 GPT 磁盤。在 BIOS 上使用 GPT 磁盤是可行的,可以使用 Hybrid MBR 的「混合引導(hybrid booting)」,或者使用新的純 GPT 協議。但是這個協議可能在某些 BIOS 實現上會出問題,詳情請參考 Rodsbooks。
- 在文件系統支持中提到的「加密」指的是文件系統級加密,和塊級別加密沒有任何關係。
名稱 | 固件 | 分區表 | 多重啟動 | 文件系統 | 注意 | ||||||
---|---|---|---|---|---|---|---|---|---|---|---|
BIOS | UEFI | MBR | GPT | Btrfs | ext4 | ReiserFS | VFAT | XFS | |||
EFISTUB | – | 是 | 是 | 是 | – | – | – | – | 繼承自固件1 | – | 內核是合法的 EFI 可執行文件,可從 UEFI 固件中的 efibootmgr 或者其他引導加載程序加載。 |
統一內核鏡像 | – | 是 | 是 | 是 | – | – | – | – | 繼承自固件1 | – | systemd-stub(7)、內核、initramfs、內核命令行打包而成的 EFI 可執行文件,可直接從 UEFI 固件或另一個引導加載程序加載。 |
Clover | 模擬 UEFI | 是 | 是 | 是 | 是2 | 否 | 不支持加密 | 否 | 繼承自固件1 | 否 | 修改版的 rEFIt 分支,用來運行黑蘋果(運行在非蘋果硬件上的 macOS)。 |
GRUB | 是 | 是 | 是 | 是 | 是 | 是 | 是 | 是 | 是 | 是 | 在 BIOS/GPT 配置下需要一個 BIOS 引導分區。 支持 RAID、LUKS1 和 LVM(但是不支持精簡配置卷)。 |
Limine | 是 | 是 | 是 | 是 | 是 | 否 | 不支持加密 | 否 | 是 | 否 | |
rEFInd | 否 | 是 | 是 | 是 | 是2 | 不支持加密 | 不支持加密 | 不支持尾部壓縮(tail-packing)功能 | 繼承自固件1 | 否 | 支持自動檢測內核和參數,無需明確配置,並支持快速啟動(fastboot)[2]。 |
Syslinux | 是 | 部分支持 | 是 | 是 | 部分支持 | 不支持:多設備卷、壓縮和加密 | 不支持加密 | 否 | 是 | 僅限 MBR;不支持稀疏索引節點(sparse inodes) | 不支持某些文件系統功能。[3] 沒有文件系統驅動[4],只能夠訪問自身所處的文件系統。 |
systemd-boot | 否 | 是 | 僅限手動安裝 | 是 | 是2 | 通過側載/旁加載3 | 通過側載/旁加載3 | 通過側載/旁加載3 | 繼承自固件1 | 通過側載/旁加載3 | 無法從 EFI 系統分區 或擴展引導加載程序分區 (XBOOTLDR) 以外的分區啟動二進制文件。支持在將 統一內核鏡像 放入esp/EFI/Linux 時自動檢測。
|
GRUB Legacy | 是 | 否 | 是 | 否 | 是 | 否 | 否 | 是 | 是 | 僅 XFS v4 | 停止開發,轉為 GRUB。 |
LILO | 是 | 否 | 是 | 否 | 是 | 否 | 不支持加密 | 是 | 是 | 是 | 因為局限性(如與 Btrfs、GPT 和 RAID 搭配使用時)已停止開發。 |
- 文件系統支持是從固件繼承的。UEFI 規範要求支持 FAT12,FAT16 和 FAT32 文件系統,但廠商可選擇添加對其他文件系統的支持。比如説,蘋果公司的 Mac 中的固件支持 HFS+ 文件系統。如果固件提供在啟動時加載 UEFI 驅動程序的接口,則可以通過加載文件系統驅動程序(需單獨獲取)的方式添加對其他文件系統的支持。
- 一種啟動管理器。它只能啟動其他的 EFI 應用程式,例如,使用
CONFIG_EFI_STUB=y
參數編譯的 Linux 內核映像和 Windows 中的bootmgfw.efi
。 - systemd-boot 支持加載 UEFI 文件系統驅動。這些驅動由 efifs包 提供,需要放在
esp/EFI/systemd/drivers/
中。
另請參見維基百科:引導加載程序比較。
內核[編輯 | 編輯原始碼]
內核是作業系統的核心。它運行於一個叫「內核空間」的底層上,負責機器硬件和應用程式之間的交流。為了儘可能充分地壓榨 CPU 性能,內核使用調度器,通過一定的優先級算法將 CPU 按照時間動態地分配給各個程序。讓我們感覺就像所有程序都在同時使用 CPU 一樣。
initramfs[編輯 | 編輯原始碼]
在#引導加載程序加載內核和可能存在的 initramfs(初始 RAM 文件系統)文件、並啟動內核之後,內核將 initramfs 檔案展開到(當時為空的)rootfs(初始根文件系統,比如 ramfs 或 tmpfs)。在內核構建過程中嵌入內核二進制文件的 initramfs 被首先提取,然後提取可能存在的外部 initramfs 文件。因此,外部 initramfs 中的文件會覆蓋嵌入式 initramfs 中具有相同名稱的文件。然後,內核執行 /init
(在 rootfs 中)作為第一個進程。早期用户空間(early userspace)啟動。
Arch Linux 官方支持的內核對內置的 initramfs 使用一個空的存檔(這是構建 Linux 時的默認)。外部 initramfs 映像可用 mkinitcpio、dracut 或 booster 生成。
initramfs 之所以存在,是為了幫系統訪問真正的根文件系統(參見 FHS)。也就是説,諸如 IDE、SCSI、SATA、USB/FW 一類硬件所要求的內核模塊,如果並沒有內置在內核裡,就會被 initramfs 負責加載。一旦通過 udev 隱式加載,或由程序或腳本顯式加載好模塊,啟動流程就會繼續下去。所以,initramfs 只需包含能夠讓系統訪問根文件系統的模塊即可,不用儘可能地包含一切模塊。其它需要用到的模塊之後會在 init 流程中被 udev 加載好。
Init 流程[編輯 | 編輯原始碼]
早期用户空間階段發生在掛載臨時 rootfs 時,對 #initramfs 提供的文件進行操作。
早期用户空間的功能是可配置的,但通常執行以下操作:
systemd-modules-load(8) 加載內核模塊, 比如掛載真正根文件系統所需的任何塊設備模塊。 處理真實根文件系統的解密(如果適用)。 加載 DRM 模塊,因為默認情況下會為樹內模塊啟用早期 KMS。 後期用户空間的啟動由 init 進程執行。Arch 正式使用 systemd,它建立在單元和服務的概念之上,但這裏描述的功能在很大程度上與其他 init 系統重疊。
Getty[編輯 | 編輯原始碼]
init 為每個虛擬終端(通常有六個)調用 getty,其為每個虛擬終端初始化 tty,並請求輸入用户名和密碼。當在某虛擬終端輸入用户名和密碼後,其 getty 會對照 /etc/passwd
和 /etc/shadow
檢查是否正確。如果正確,就接着調用 #login。或者,getty 可能會啟動顯示管理器,如果有的話。
顯示管理器[編輯 | 編輯原始碼]
顯示管理器可以配置用於代替原來的 tty 登錄提示 getty。
為了在引導後自動初始化顯示管理器,必須通過 systemd 手動啟用服務單元。有關啟用和啟動服務單元的更多信息,請參見使用單元。
Login[編輯 | 編輯原始碼]
通過設置環境變量、根據 /etc/passwd
的配置啟動用户的 shell,login 程序會為用户啟動會話。
在成功登錄後,剛剛啟動登錄 shell 之前,login 程序顯示 /etc/motd(message of the day)。在這裏,您可以顯示服務條款,以提醒用户您的本地政策,或您想吿訴他們的任何內容。
Shell[編輯 | 編輯原始碼]
用户的 shell 啟動後,在顯示命令行提示符前,它會執行一個運行時配置文件,比如 .bashrc。如果用户被設定為在登錄時自動啟用 X,該運行時配置文件會調用 xinit。
GUI、 xinit 或者 wayland[編輯 | 編輯原始碼]
xinit 也會調用用户的運行時配置文件 .xinitrc,後者一般用來啟動一個窗口管理器。如果用户退出了窗口管理器,xinit、startx、shell、login 就會依此順序中斷,返回到 #getty。