跳至內容
出自 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 文件。 以下示例將在 default 處配置最小的 initramfs 映像 ,and create a new normal image that is built 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}'
注意:The awk command returns only the first field, using {print $1} , of every line with exactly 3 fields, enforced by NF==3. Module dependencies include the 4th field to show which module pulled in the dependency, thus being filtered out due to that fourth field. Arch's mkinitcpio takes care of dependencies for legitimate values included in the arrays MODULES=(), FILES=(), and 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 文件。