跳至內容
本頁使用了標題或全文手工轉換
出自 Arch Linux 中文维基

本文介紹如何為具有特定、已知和靜態硬體配置的系統創建精簡、最小的 initramfs。 Falconindy (Dave Reisner) 的 Optimizing Bootup With mkinitcpio 詳細闡述了該過程。

Udev 要求

創建自己的 initramfs 映像的一大優點是可以移除 udev 鉤子。這個鉤子在 initramfs 中占了相當大一塊空間(使用 LZ4 和 LZOP 壓縮時約為 700-800 KiB,其他算法較小)。因此它不僅導致啟動時加載耗時更長(需要解壓更多的數據),而且初始化其自身時也要額外的時間。但是,仍有部分操作需要 udev,包括解析 UUID、LABEL、PARTUUID 和 PARTLABEL 標識符(workaround hook without-udev)以及包含 root 分區的 LVM 和 mdadm 設備。 若您不確定是否需要 udev,請繼續按照本頁上的說明操作,直到 #初步測試章節。如果在沒有 udev 的時候出了問題,請重新啟用此鉤子,再試一次。

另請注意,雖然大部分鍵盤(AT,PS/2,USB)不需要 udev 鉤子也能正常工作,但使用羅技統一接收器(Logitech Unified Receiver)的 USB 設備需要。此時,您可以在所有映像中包含 udev 或依賴 fallback 映像正常工作。

如果您確實需要 udev,最小化映像的努力可能就白費了。映像大小也許能減小約 600 KiB,但是啟動時間不會有顯著改變。在此情況繼續下去,不失為一次學習機會。

編輯 .preset 文件

在 Falconidy 的教程中,他編輯 /etc/mkinitcpio.conf 並運行 mkinitcpio -g 來創建測試 initramfs 映像,使系統上已知正常啟動的 initramfs 映像保持不變。 但是,如果您事後盲目運行 mkinitcpio -P,甚至 fallback 映像也會被刪除。

準備自行創建 initramfs 的更安全方法是修改 /etc/mkinitcpio.d 中的 .preset 文件。以下的範例設定將以最小的 initramfs 映像取代default,並依照 The Arch Way 的方式建立一個新的正常映像檔。 如果出現問題,您仍可以使用 normalfallback 映像。 完成後,您可以從配置中刪除 normal_* 行並刪除 initramfs-linux*-normal.img 文件。

...

PRESETS=('default' 'normal' 'fallback')
...

default_options="-S udev,block,mdadm_udev,filesystems,keyboard,fsck,consolefont"
...

#normal_config="/etc/mkinitcpio.conf"
normal_image="/boot/initramfs-linux-normal.img"
#normal_options=""
...

mdadm_udevconsolefont鉤子不在 Arch Linux 默認的配置中,在 *_options 行的 -S 參數中包含無關的鉤子不會導致錯誤。

找出需要的模組

本文或本節需要翻譯。要貢獻翻譯,請訪問簡體中文翻譯團隊

附註: 需要翻譯(在 Talk:Mkinitcpio/極簡 initramfs# 中討論)

找出機器需要的模組的最快方法是重啟電腦,使用 fallback 映像並通過引導加載程序(boot loader)添加 break=postmount 內核參數。於是在根文件系統掛載好後便可進入命令行界面。

重啟電腦後,通過以下命令來獲取需要的模組:

lsmod | awk 'NF==3{print $1}'
注意:awk 指令會傳回每一行的第一個欄位(使用 {print $1),但只限於那些剛好有三個欄位的行,這是透過 NF==3 來強制篩選的。 模組依賴關係會包含第四個欄位,用來顯示是由哪個模組引入這個依賴,因此這些行會因為有第四個欄位而被過濾掉。Arch 的 mkinitcpio 會處理那些正當包含在 MODULES=()FILES=()BINARIES=() 陣列中的依賴項目。

保存已加載模組的清單,輸入 exit 繼續啟動機器。

另一種方式是安裝 hwdetect 來幫助確定所需的模組。雖然此軟體包已停止維護,它仍可提供有價值的信息。另外,請參閱內核模組以開始使用本機工具。

初步編輯 mkinitcpio.conf

編輯 /etc/mkinitcpio.conf 修改 MODULES= 陣列。值得注意 /etc/mkinitcpio.conf 作為腳本調用,可以使用 bash 腳本構建 MODULES 陣列。

MODULES=()   # filesystems
MODULES+=()  # storage
MODULES+=()  # keyboard
MODULES+=()  # miscellaneous

把模組添加到配置中最後的 miscellaneous 行中,整理時再將模組移至合適的行去。

若需要對 root 分區設備和在 /etc/fstab任何其他掛載點進行文件系統檢查操作,請按下文配置:

  • 對於 ext[2|3|4] 設備:
BINARIES=(fsck fsck.ext[2|3|4] e2fsck)
  • 對於 vfat (UEFI boot) 設備:
BINARIES=(fsck fsck.vfat dosfsck)
  • 對於 btrfs 單盤設備:
BINARIES=(fsck fsck.btrfs btrfsck)
  • 對於 btrfs 多盤設備:
BINARIES=(fsck fsck.btrfs btrfs btrfsck)
  • 對於 xfs 設備:
BINARIES=(fsck fsck.xfs xfs_repair)
注意:
  • 上述示例中的第三個選項都是可選的,但除去它們將導致無法修復損壞的文件系統,此時需要從另一個 initramfs 啟動。
  • 鼓勵添加其他文件系統的條目。

初步測試

編輯 /etc/mkinitcpio.conf 並運行 mkinitcpio -P 重建所有 initramfs 鏡像。 然後重啟。

如果不需要 udev,第一次啟動應該會成功。 如果出現故障(例如,Arch 找不到根分區或鍵盤失靈),則需要返回並從default_options行的-S參數中刪除udev,然後再試一次。 如果需要使用 udev,請注意啟動時間不會有明顯改善,繼續嘗試只能作為學習經驗。

整理模組

現在您已經有了一個已知正常的可啟動 initramfs,是時候進一步精簡 initramfs 了。通常是一次刪除幾個模組,重建 initramfs 映像,然後重新啟動以查看一切是否仍然正常。若有功能異常,請使用 fallback initramfs 映像重啟並重新添加已刪除的模組,直到再次恢復正常。多次重複,直到只剩下所需的模組。 這可能是相對乏味的過程,因此提供了以下列表,以便減少前期工作。

注意:以下僅作示例參考,並不意味著適合每台設備。

文件系統模組

注意:只需要對應的模組:啟動時需要檢查文件系統的 root 設備和在 /etc/fstab 中的其他設備
  • ext[2,3,4]
  • xfs
  • jfs
  • reiserfs

存儲設備模組

  • sd_mod 用於所有 SCSI、SATA 和 PATA(IDE)設備
  • ahci 用於現代 AHCI 控制器上的 SATA 設備
  • nvmenvme_core 用於 NVMe(M.2、PCI-E)設備
  • sata_* 用於 IDE 模式控制器上的 SATA 設備
  • pata_* 用於 PATA(IDE)設備
  • ehci_pciusb_storage 用於 USB 存儲設備
  • virtio_blkvirtio_pci 用於使用 VirtIO 進行存儲的 QEMU/KVM 虛擬機

鍵盤模組

  • atkbd 用於 AT 和 PS/2 鍵盤,以及 QEMU/KVM 中的模擬鍵盤。
  • hid_genericohci_pciusbhid 用於普通 USB 鍵盤。
  • hid_logitech_djuhci_hcdusbhid 適用於使用羅技統一接收器的羅技 USB 鍵盤(需要 {ic|udev}} 鉤子)。

收尾工作

將 initramfs 壓縮到最小後,移除(或注釋掉).preset 文件中的 normal_* 行,並移除 /boot 中的 initramfs-linux*-normal.img 文件。