mkinitcpio

出自 Arch Linux 中文维基

mkinitcpio 是一個創建 initramfs 的 bash 腳本。來自 mkinitcpio(8)幫助頁面。

初始內存盤本質上是一個很小的運行環境(早期用戶空間),用於加載一些核心模塊,並在 init 接管啟動過程之前做必要的準備。有了這個環境,才能支持加密根文件系統、RAID上的根文件系統等高級功能。mkinitcpio 支持自定義的鈎子擴展、運行時自動檢測以及其他功能。

從前,內核在啟動過程早期(掛載根目錄和移交控制權給init之前)處理一切硬件的檢測和初始化。然而,隨着技術的演進,這種做法變得十分繁瑣。

如今,根文件系統可能位於各種硬件上,如SCSI設備、SATA設備、U盤,而這些硬件受控於形形色色的廠家所提供的五花八門的驅動之下。另外,根系統可以加密、壓縮,可存放在RAID陣列中,或者一個邏輯卷組上。為了簡化這複雜的過程,可以把管理權轉入一個用戶空間:初始化內存盤。

另見:/dev/brain0 » Blog Archive » Early Userspace in Arch Linuxmkinitcpio 從Arch Linux開發者和社區貢獻中得到了進一步發展。 另見 public Git repository.

安裝[編輯 | 編輯原始碼]

安裝 軟件包 mkinitcpio。這個軟件包是 linux 軟件包的依賴,應該已經自動安裝了。高級用戶可以從mkinitcpio-gitAUR 獲取 mkinitcpio 的最新開發版本.

注意: 若要使用git開發版本,強烈建議同時加入arch-projects 郵件列表!

創建和啟用鏡像[編輯 | 編輯原始碼]

自動匹配生成[編輯 | 編輯原始碼]

每次安裝或升級內核,pacman鈎子自動產生.preset文件,保存在/etc/mkinitcpio.d/。例如:linux.preset文件是官方穩定版linux包產生的。一個preset是簡明的創建初始化內存鏡像需要的列表信息,以取代手動明確各種參數和輸出文件位置。默認mkinitcpio都會創建兩個內存盤鏡像:

  1. 默認鏡像/boot/initramfs-linux.img按照mkinitcpio #配置明確的指令創造而來。
  2. fallback鏡像/boot/initramfs-linux-fallback.img。產生過程和上面一樣。唯一區別,就是創建時跳過了autodetect鈎子擴展,因而它包含全範圍內更多的內核模塊,可以支持大部分系統。(ps:原文刪除這個陳述,感覺有些用處autodetect擴展會探測硬件信息,針對硬件向鏡像添加需要的模塊,因此縮小了鏡像。)

生成preset之後,pacman鈎子會利用proset提供的信息調用 mkinitcpio 腳本創建上面的兩個鏡像。

注意: .preset 在內核更新後會被用來自動生成內存鏡像,編輯它們要小心仔細。

手動生成[編輯 | 編輯原始碼]

手動運行腳本,參照mkinitcpio(8) 幫助頁面獲得指引。尤其是利用內核包生成(重新生成)預設,使用-p/--preset選項按照預設生成鏡像。例如 為 linux 包生成鏡像,使用這個命令:

# mkinitcpio -p linux

利用-P/--allpresets選項,根據所有現存的預設文件生成鏡像。典型的用法是當全局設置#配置變化後用此法生成全部的內存鏡像:

# mkinitcpio -P

可以按照不同的配置文件創建任意數量的內存鏡像。想要引導加載的鏡像必須在相應的引導加載程序 配置中明確寫出。

自定義生成[編輯 | 編輯原始碼]

可以使用相應的配置文件產生一個鏡像。例如,接下來會根據/etc/mkinitcpio-custom.conf裡指令生成初始化內存鏡像,並且將其保存在 /boot/initramfs-custom.img

# mkinitcpio --config /etc/mkinitcpio-custom.conf --generate /boot/initramfs-custom.img

如果為一個不是當前運行的內核創建鏡像,增加內核版本號到命令行。已經被安裝的內核版本號可以在/usr/lib/modules/中找到,對於每個內核語法結構和uname -r命令輸出結果一致。

# mkinitcpio --generate /boot/initramfs-custom2.img --kernel 5.7.12-arch1-1

統一內核鏡像[編輯 | 編輯原始碼]

從31版本開始, mkinitcpio 也能生成 統一內核鏡像英語unified kernel image

配置[編輯 | 編輯原始碼]

mkinitcpio的主配置文件是/etc/mkinitcpio.conf。此外,內核軟件包的預配置文件位於/etc/mkinitcpio.d(例如:/etc/mkinitcpio.d/linux.preset)。

用戶可以編輯配置文件中的六個變量,參見mkinitcpio.conf(5)獲得更多細節:

MODULES
在鈎子擴展運行前需要加載的內核模塊。
BINARIES
內存盤鏡像中包含的額外的二進制文件(一般是可執行的命令)。
FILES
內存盤鏡像中包含的其他文件。
HOOKS
要執行的鈎子擴展,它是在生成鏡像時執行的腳本。
COMPRESSION
內存盤鏡像的壓縮方式。
COMPRESSION_OPTIONS
傳遞給壓縮工具的額外參數,強烈不建議使用,mkinitcpio 可以自動根據壓縮算法傳遞需要的參數(例如對 xz 傳遞 --check=crc32 to xz), 手動設置了錯誤的參數可能導致系統無法啟動。
注意:
  • 一些系統需要的鈎子像 lvm2, mdadm_udev, and encrypt 默認 不是開啟的 。參見 #鈎子(HOOKS) 仔細遵循指示。
  • 存在多個硬盤控制器使用相同的節點名字,但是擁有不同的內核模塊(例如,兩個SCSI/SATA控制器或2個IDE控制器)應該使用 持久化設備命名persistent block device naming 保證正確的設備被掛載。否則在兩次系統啟動時根系統的位置可能改變導致內核崩潰。

模塊(MODULES)[編輯 | 編輯原始碼]

MODULES數列指定了啟動過程最開始時早於一切事情就要加載的模塊。

如果模塊名稱前加上一個?問號,那麼即使系統無法找到該模塊也不會報錯。對於自己編譯的內核,其中內置了某些模塊在,這些模塊在鈎子或配置文件中顯式的列出來時,該功能可能有用。

注意:
  • 如果使用reiser4,該模塊必須放入MODULES數列中。
  • 當使用encrypt or sd-encrypt 鈎子時,目標系統和運行mkinitcpio系統不同時,鍵盤模塊和/或啟動系統期間需要解鎖LUKS設備的文件系統模塊加入 MODULES 數列。例如,如果需要使用位於一個ext2系統的鑰匙文件,但是運行mkinitcpio的系統中ext2文件系統沒有被掛載,增加ext2。參見 dm-crypt/System configuration#cryptkey 獲得更多細節。
  • 如果使用USB3接口的鍵盤,希望用它來解鎖LUKS設備。增加usbhid xhci_hcd
  • 如果使用顯示器連接擴展塢,可能需要加入你的顯卡模塊使初始化輸出信息可見(例如,為大多數英特爾顯卡加入 i915 )。

二進制文件和普通文件(BINARIES、FILES)[編輯 | 編輯原始碼]

這兩個選項允許用戶添加任何文件到鏡像中。BINARIESFILES數列在鈎子運行之前指定了要加入內存盤鏡像的文件,可以覆蓋鈎子擴展提供的文件。BINARIES中的二進制文件會自動放入一個標準的PATH路徑,而且會自動加入可執行文件依賴的函數庫。FILES中的文件則不進行上述處理,as-is直接原樣放入鏡像。例如:

FILES=(/etc/modprobe.d/modprobe.conf)
BINARIES=(kexec)

注意BINARIES and FILESBash數列,配置支持多個選項,用空格隔開。

鈎子(HOOKS)[編輯 | 編輯原始碼]

HOOKS設置是此文件中最重要的設置。Hooks 是一系列的小腳本,描述哪些東西需要加入到鏡像裏面。有些鈎子還包含了運行組件,可以提供額外的行特定動作,像啟動服務、構建存儲棧的塊設備等a stacked block device。Hooks 按照配置文件中HOOKS項中給出的順序執行。

默認的HOOKS可以滿足大部分簡單的單硬盤系統。對於堆棧的或多塊設備像 LVM, RAID, or dm-crypt 等複雜根分區系統,請查看相應的 Wiki 頁面,進行必要的進一步設置。 (英文文檔刪除下面關於鍵盤內容,可能是 keyboard 默認加入HOOKS,後面的問題不再是問題,出于謹慎我保留了下來) PS/2 鍵盤用戶 : 要在初始化早期階段使用鍵盤,請把 keyboard 鈎子加入 HOOKS. 個別的鍵盤無法自動檢測到 i8042 控制器,出現 i8042: PNP: No PS/2 controller found. Probing ports directly 報錯信息,導致無法使用鍵盤,請把 atkbd 加入 MODULES.

編譯鈎子[編輯 | 編輯原始碼]

編譯鈎子位於/usr/lib/initcpio/install,自定義的編譯鈎子可能位於/etc/initcpio/install/。這些文件會在運行 mkinitcpio 時被包含進腳本,應該提供如下兩個函數:buildhelpbuild 函數描述了需要加入鏡像的模塊、文件和二進制文件。mkinitcpio(8) 中的記錄的 API 幫助添加這些項目。help 函數在鈎子執行後輸出描述信息。

列出可用的鈎子列表:

$ mkinitcpio -L

使用 mkinitcpio 的 -H/--hookhelp 選項輸出對於某一鈎子的幫助。例如:

$ mkinitcpio -H udev

運行時鈎子[編輯 | 編輯原始碼]

運行時鈎子可以在/usr/lib/initcpio/hooks中找到自定義的運行時鈎子在/etc/initcpio/hooks/。 對於任何運行時掛鈎,都應該始終有一個同名的構建鈎子,它會調用add_runscript將運行時掛鈎添加到映像中。 這些文件是由早期用戶空間中的busybox ash shell調用。除清理鈎子以外(清理鈎子是倒序執行的),它們始終將按照HOOKS設置中列出的順序運行。 運行時鈎子可能包含以下功能:

run_earlyhook: 一旦掛載了API文件系統並且已經解析了內核命令行,便會運行這個功能。 通常,從此處啟動早期引導過程所需的額外守護程序(例如udev,它從早期引導過程的開始就被需要)。

run_hook: 這個功能在早期鈎子掛接後不久便運行。 這是最常見的鈎子特點,應在此處進行諸如堆疊塊設備的組裝之類的操作。

run_latehook: 此名稱的功能在掛載根設備後運行。 應當謹慎地將其用於根設備的進一步設置,或用於掛載其他文件系統,例如/usr

run_cleanuphook: 該名稱的功能將儘可能晚地運行,並且以與配置文件的HOOKS設置中列出功能的相反順序來運行。 這些鈎子應該用於所有的最終清理操作,例如關閉由早期鈎子啟動的所有守護程序。

注意: 運行時鈎子僅僅被busybox的init使用。systemd 鈎子觸發一個 systemd 基礎的初始化, 它不需要運行任何運行時鈎子,而是使用systemd單元。

常用鈎子[編輯 | 編輯原始碼]

下面是一個常見鈎子和它們如何影響鏡像的創建以及運行時的次序。注意這個表格是不完整的,因為一些包會提供一些自定義的鈎子。

這篇文章的某些內容需要擴充。

原因: 增加關於hostdata, memdisk, sleepstrip的信息, 找出dmraid等是否在 systemd 為基礎的鏡像中正常工作或被需要。 (在 Talk:Mkinitcpio#Improvements for the Common hooks table and section about systemd hook 中討論)
busybox 初始化 systemd 初始化 編譯鈎子 運行時鈎子 (僅busybox 初始化)
base 安裝初始化目錄結構,安裝基本工具及其依賴。除非知道你在做什麼,總是保持此鈎子為第一個鈎子,因為當沒有使用systemd鈎子時,它提供關鍵的busybox初始化過程。
當使用systemd鈎子時此鈎子可選,因為它僅提供busybox恢復shell。
注意: 因為root賬戶在初始化內存鏡像是鎖定的,恢復shell是不能用的。locked. 參見 FS#70408.
udev systemd 增加 udevd, udevadm,和一小套udev規則進鏡像。 從內核中啟動udev守護進程和uevents過程; 創建設備節點。因為不需要用戶清晰的明確出必須設備這是簡化的引導過程,推薦使用。
usr 增加支持/usr 在獨立分區。參見#/usr 放到單獨分區 獲得更多細節。 在掛載真正根分區後掛載 /usr 分區 。
resume 試圖從"suspend to disk" 狀態重新開始。 參見 休眠 做進一步設置。
btrfs 設置必備模塊能夠讓Btrfs 支持Btrfs的多設備分區。需要安裝 btrfs-progs 開啟功能。Btrfs在單設備分區時此鈎子不需要。 udev 鈎子或systemd不存在時,運行 btrfs device scan 組裝多設備Btrfs根文件系統。安裝btrfs-progs 包使用此鈎子。
autodetect 系統掃描後創建設備白名單從而減少內存鏡像的尺寸。確定校驗進入的模塊正確性和完整性。為了自動偵測發揮作用,必須放在其他子系統鈎子之前。放在'autodetect'鈎子之前的鈎子將會被完整安裝。
modconf /etc/modprobe.d//usr/lib/modprobe.d/中包含探測模塊配置文件。
block 加載所有的塊設備,以前fw, mmc, pata, sata, scsi, usb, and virtio 鈎子分別提供。
net not implemented 增加必要網絡設備模塊。必須安裝 mkinitcpio-nfs-utils 包, 參見 #使用 net 支持NFS為基礎的根文件系統。
dmraid ? 支持fakeRAID根設備。必須安裝 dmraid 包。注意如果你的控制器支持,更好選擇是mdadm 聯合 mdadm_udev鈎子支持fakeRAID根設備。參見 #使用 RAID 磁盤陣列 使用dmraid定位組裝fakeRAID塊設備。
mdadm_udev 通過udev支持組裝RAID陣列。必須安裝 mdadm 包。若在FakeRAID使用這個鈎子推薦將 mdmon 加入 BINARIES. 參見 #使用 RAID 磁盤陣列
keyboard 為鍵盤設備增加必要的模塊。如果USB或串口鍵盤在早期用戶空間起作用加入此鈎子(可以輸入密碼或和shell交互)。有一個副作用,一些非鍵盤的輸入設備也可能加進來,但這並不可靠。此鈎子代替老的 usbinput鈎子。
注意: 使用不同的硬件配置啟動的系統(例如筆記本電腦連接外置鍵盤和內置鍵盤或headless systems)時,此鈎子需要放在autodetect之前才能在引導中使用鍵盤,例如使用encrypt鈎子解密加密設備。
keymap sd-vconsole /etc/vconsole.conf加入特定的 鍵盤映射keymap(s) 到鏡像。在早期用戶空間如果使用系統加密, 尤其全盤加密, 此鈎子放在encrypt鈎子之前。
consolefont /etc/vconsole.conf中加入特定的 終端字體 到鏡像。 在早期用戶空間自/etc/vconsole.conf裡,使用特定的終端字體。
encrypt sd-encrypt 增加dm_crypt 內核模塊 和 cryptsetup 工具到鏡像。 必須安裝cryptsetup包。
注意: 啟動時反覆確認keyboard鈎子放在解密設備前面。和/或當使用鑰匙文件解鎖時,存放鑰匙文件的文件系統加入#模塊(MODULES) 裡。
偵測和解鎖加密根系統。參見 #運行時配置

sd-encrypt 參見 dm-crypt/系統配置#使用systemd-cryptsetup-generator英語dm-crypt/System configuration#Using systemd-cryptsetup-generator

lvm2 加入設備映射內核模塊和lvm 工具到鏡像。 必須安裝lvm2 包。 如果根系統在LVM這是必須的鈎子。
fsck 增加fsck二進制文件和特定系統幫助文件,允許fsck在掛載前處理根系統(和/usr分區如果有)。如果放在autodetect鈎子前僅僅加載的定的幫助文件到根系統。強烈推薦使用此鈎子,獨立/usr分區需要它。強烈建議如果使用的此鈎子同時要加入必要模塊保證鍵盤在早期用戶空間使用。
使用這個鈎子需要在內核參數加入 rw參數。(討論). 參見 fsck#啟動時檢查英語fsck#Boot_time_checking
filesystems 除非在MODULES中加入了文件系統,不然此鈎子是必須的。

編寫鈎子擴展[編輯 | 編輯原始碼]

(*最新的英文文檔刪除了這部分內容,感覺似乎用些用處暫時留了下來。) 一個 initcpio 鈎子僅僅是另一段 shell 腳本,它包含了必要的信息指引 mkinitcpio 哪一個可執行文件應該被加載,以及以什麼參數被加載。它在某些罕見情況下很有用,比如一些文件需要在用戶空間的早期或晚期被加載,而這又沒有被其他已經安裝的腳本提供。

首先創建實際的腳本:

/usr/lib/initcpio/install/hook
 #!/bin/bash
 
 build() {
     add_binary /bin/bash  #/bin/bash is given as an example, you can type your desired executable here
     add_runscript  # will determine the name of the script, and add appropriately from /usr/lib/initcpio/hooks
 }
 
 help() {
     cat <<HELPEOF
     Line used as help information #Typing mkinitcpio -H hook will display this information
 HELPEOF
 }

然後創建這個實際的鈎子:

/usr/lib/initcpio/hooks/hook
 run_hook ()
 {
     msg -n ":: This is an example hook"
     bash #your executable example
     msg "done."
 }
注意: 沒有必要為這兩個腳本設定可執行權限,也不建議這樣做。

現在編輯 /etc/mkinitcpio.conf 來包含你的自定義鈎子。你也可在 /etc/rc.sysinit 包含腳本來在用戶空間的後期加載。

壓縮方式(COMPRESSION)[編輯 | 編輯原始碼]

內核支持幾種initramfs的壓縮方式 - gzip, bzip2, lzma, xz, lzo, lz4 and zstd。mkinitcpio默認使用zstd壓縮鏡像,注意zstd運行的多線程模式(使用了-T0選項,以偵測到內核數量作為線程數量。)

系統中的 mkinitcpio.conf 已經註釋掉了各種 COMPRESSION 選項,要使用某個壓縮方式,請取消前面的註釋,並確認安裝了相應的壓縮工具包。不指定 COMPRESSION 選項會使用 zstd 壓縮的 initramfs 文件。想要創建一個未壓縮的鏡像,在配置中指定COMPRESSION=cat 或者在命令行使用 -z cat

提示:lz4 在高壓縮率模式(-9)下鏡像有2.5的壓縮比率,以付出最慢的單線程壓縮速度為代價,可以獲得最快的解壓縮速度。lzo使用輕度較好的壓縮模式後仍然有較快的解壓速度。 zstd 提供多樣解決方案, 通過參數使用多線程壓縮方式和大範圍壓縮水平,參見 zstd(1) § Operation modifiers。 xz在其高壓縮預設(-9)中以大約5的縮減因子實現了最小的體積,但代價是解壓速度要慢得多。

壓縮選項(COMPRESSION_OPTIONS)[編輯 | 編輯原始碼]

還有一些額外的標準可以傳遞到 COMPRESSION 指定的程序,例如:

COMPRESSION_OPTIONS='-9'
注意: 這個選項可以留空, mkinitcpio 會確保任何支持的壓縮方法有必要的標誌來產生一個可以工作的鏡像。 另一方面,使用錯誤的參數選項可能導致內核不能引導,因為錯誤參數導致內核不能解壓生成的壓縮檔。

運行時配置[編輯 | 編輯原始碼]

這篇文章的某些內容需要擴充。

原因: 哪個選項可以在 systemd 鈎子工作, 哪個只能在 base-only? (在 Talk:Mkinitcpio 中討論)

運行時配置選項可以通過內核命令行傳遞到 init 以及某些鈎子。內核命令行參數通常是由啟動引導器提供。下面討論的參數可以附加到內核命令行以改變默認行為。參見 Arch 啟動過程內核參數以獲取更多信息。

從基本鈎子啟動[編輯 | 編輯原始碼]

root
這是內核命令行中指定的最重要的參數,因為它決定了哪一個設備會被掛載為你的正確的 root 設備。mkinitcpio 可以靈活的允許不同的格式,例如:
root=/dev/sda1                                                # /dev 节点
root=LABEL=CorsairF80                                         # 卷标
root=UUID=ea1c4959-406c-45d0-a144-912f4e86b207                # UUID
root=PARTUUID=14420948-2cea-4de7-b042-40f67c618660            # GPT partition UUID
注意: 下面的選項改變了 init 在 initramfs 環境中的默認行為。參見 /lib/initcpio/init 獲取更多信息。當systemd鈎子作用是,這些參數不起作用,既然來自base鈎子的 init 被取代了。(正如上面的疑問參數該怎麼寫?)
break
如果break 或者 break=premount 被指定,init 暫停啟動過程(在加載鈎子之後,但是在掛載根文件系統之前) 然後啟動一個交互的 shell,可以用來解決問題。這個 shell 可以在root被指定的break=postmount掛載之後啟動。正常的啟動過程可以在退出這個 shell 之後繼續。
disablehooks
在運行時可以通過添加 disablehooks=hook1{,hook2,...} 禁用某些鈎子。例如
disablehooks=resume
earlymodules
改變模塊加載的順序。可以通過 earlymodules=mod1{,mod2,...} 指定一些模塊提前加載。 (例如,這可以用來確保多個網絡接口的正確順序。)

參見: 常規故障排除#系統啟動問題mkinitcpio(8)

使用 RAID 磁盤陣列[編輯 | 編輯原始碼]

參見 RAID#Configure mkinitcpio

使用 net[編輯 | 編輯原始碼]

警告: NFSv4 仍然不被支持 FS#28287

必須的包

net 需要 mkinitcpio-nfs-utils 包。

內核參數

内核文档包含最新的信息和清晰的说明。

ip=

這個參數告訴內核怎樣生成設備IP位址和怎樣安裝路由表。它佔據9列參數: ip=<client-ip>:<server-ip>:<gw-ip>:<netmask>:<hostname>:<device>:<autoconf>:<dns0-ip>:<dns1-ip>:<ntp0-ip>

如果這些參數在內核命名行為缺失,所有區域被認為是空白。默認參數在 kernel documentation 應用。通常這就意味這內核利用自動配置表來配置。

<autoconf> 參數單獨作為 ip 的值出現 (沒有上面提及的: 分割的字符串)。如果值是 ip=offip=none, 不執行自動配置,否則會執行自動配置。最常見的是ip=dhcp.
 

參數進一步擴展,參見 kernel documentation.

例子:

 ip=127.0.0.1:::::lo:none  --> 启用 loopback 界面。
 ip=192.168.1.1:::::eth2:none --> 启用静态 eth2 界面
 ip=:::::eth0:dhcp --> 为eth0启用dhcp。
注意: 確認使用內核設備命名 (例如 eth0) 作為 <device> 參數, 不要使用 網絡配置#Network interfaces 命名 (例如 enp2s0) 因為這個不起作用。

BOOTIF= 使用多個網卡的時候,此參數可以指定要使用網卡的 Mac 地址。在接口號可能變化或與 IPAPPEND 2 、IPAPPEND 3 選項共用時比較有用。默認使用 eth0.

示例:

BOOTIF=01-A1-B2-C3-D4-E5-F6  # 注意前缀加"01-" 并且字母要大写。

nfsroot=

如果命令行中沒有給出 nfsroot 參數,那麼默認的 /tftpboot/%s 會被使用。

 nfsroot=[<server-ip>:]<root-dir>[,<nfs-options>]

運行mkinitcpio -H net 查看參數詳細解釋。

使用 lvm[編輯 | 編輯原始碼]

如果你的根分區在 LVM文件系統中, 參見 Install Arch Linux on LVM#Adding mkinitcpio hooks.

使用加密根目錄[編輯 | 編輯原始碼]

如果使用 加密根目錄,請參考 Dm-crypt/System configuration#mkinitcpio

/usr 放到單獨分區[編輯 | 編輯原始碼]

如果將 /usr 放在單獨分區,必須滿足:

  • 添加 fsck 鈎子, /usr/etc/fstab分區表中的passno 參數列為設置為2 以便啟動時檢查該分區。作為常規推薦 如果想要/usr分區可以在啟動是被檢查,以上設置是中肯的。沒有這個鈎子 /usr 永遠不能被檢查。
  • 如果沒使用systemd鈎子那麼增加usr鈎子。這樣將會在掛載根系統後掛載/usr 分區。

疑難解答[編輯 | 編輯原始碼]

解壓縮鏡像[編輯 | 編輯原始碼]

如果你對 initrd 鏡像的內容感到好奇,你可以解壓縮它然後看看裏面的文件。

initrd 鏡像是一個 SVR4 CPIO 壓縮包,通過 findbsdcpio 命令生成,利用可被內核理解的壓縮方式被有選擇的壓縮,參考#壓縮方式(COMPRESSION)

mkinitcpio 包含了一個叫做 lsinitcpio(1) 的工具,可以列出和/或解壓縮出 initramfs 鏡像的內容。

你可以用下面的命令列出鏡像中的文件:

$ lsinitcpio /boot/initramfs-linux.img

然後全部解壓縮到當前文件夾:

$ lsinitcpio -x /boot/initramfs-linux.img

你也可以用更對人類友好的方式列出鏡像中的重要的部分:

$ lsinitcpio -a /boot/initramfs-linux.img

重新壓縮解壓之後修改過的鏡像[編輯 | 編輯原始碼]

警告: 我保留舊的翻譯為斜體加黑

在按照上面的方法解壓了一個鏡像並且進行了修改之後,你可以通過以下的方法得到重新壓縮它所需要的命令。按照下面的例子修改 /usr/bin/mkinitcpio 中的這一行 (line 531 in mkinitcpio v20-1.):

#MKINITCPIO_PROCESS_PRESET=1 "$0" "${preset_cmd[@]}"
MKINITCPIO_PROCESS_PRESET=1 /usr/bin/bash -x "$0" "${preset_cmd[@]}"

然後用常見的參數運行 mkinitcpio (一般來說是 mkinitcpio -p linux), 大約在最後的20行你會看見類似下面的一些輸出:

+ find -mindepth 1 -printf '%P\0'
+ LANG=C
+ bsdcpio -0 -o -H newc --quiet
+ gzip

它們代表你所需要運行的命令,比如像這樣:

# find -mindepth 1 -printf '%P\0' | LANG=C bsdcpio -0 -o -H newc --quiet | gzip > /boot/initramfs-linux.imgBold text
警告: (下面是新的翻譯,我沒理解如何激活這個功能?英文wiki就講了這麼多,請老鳥補充詳細。所以我保留上面的翻譯)

激活/usr/bin/mkinitcpio腳本的 build_image 功能使用此參數(我沒理解如何激活這個功能?請補充詳細。):

build_image outfile compression

將會產生一個擁有build_image功能的新腳本,用上面的參數運行它(outfile輸出文件名字,compression壓縮工具),將會把當前目錄下的內容壓縮到一個名字為outfile的新文件裡。

警告: 建議在運行上面的命令產生一個新的/boot/initramfs-linux.img之前把現有的鏡像重命名作為備份,以便情況不妙時有後悔藥吃。如果因為失誤導致系統無法啟動,你需要用fallback鏡像或者boot CD啟動,然後運行mkinitcpio來overwrite掉之前做的更改,或者你自己修好它然後重新壓縮鏡像。

"/dev must be mounted" when it already is[編輯 | 編輯原始碼]

mkinitcpio使用這個檢測通過判斷/dev/fd/ 是否存在來判斷/dev是否被掛載。如果其他一切看起來都很好,可以通過以下方式手動「創建」:

# ln -s /proc/self/fd /dev/

(顯然, /proc 必須被安裝. mkinitcpio 無論如何要求這樣,指示它要檢測的下一件事。)

Possibly missing firmware for module XXXX[編輯 | 編輯原始碼]

當內核更新後,鏡像initramfs被重新構建時,你可能得到以下警告:

==> WARNING: Possibly missing firmware for module: wd719x
==> WARNING: Possibly missing firmware for module: aic94xx
==> WARNING: Possibly missing firmware for module: xhci_pci

如果產生 default鏡像時出現這些或相近的信息,那麼按照警告要求安裝額外的被需要的固件firmware。絕大部分固件firmware通過 安裝安裝 linux-firmware包獲得。其他提供firmware的包可以查看下表或在 official repositoriesAUR 中搜索固件模塊名字。

除此以外,警告信息只出現在 fallback 鏡像生成時,可以按照下面的建議來:

  • 如果不需要使用缺失模塊的硬件,可以安全的忽略這些警告。
  • 如果想要消除這些警告,安裝缺失的固件firmware,聚合包mkinitcpio-firmwareAUR 包括絕大部分可選的固件(firmware)。 相應的可以手工安裝需要的包:
模塊
aic94xx aic94xx-firmwareAUR
bfa linux-firmware-qlogic
bnx2x linux-firmware-bnx2x
liquidio linux-firmware-liquidio
mlxsw_spectrum linux-firmware-mellanox
nfp linux-firmware-nfp
qat_4xxx 固件Firmware 已經不可用。
qed linux-firmware-qlogic
qla1280 linux-firmware-qlogic
qla2xxx linux-firmware-qlogic
wd719x wd719x-firmwareAUR
xhci_pci upd72020x-fwAUR
  • 如果想去掉警告,但不想浪費磁盤空間在不需要的固件包上,可以禁止fallback 鏡像的生成:
    1. 在所有位於/etc/mkinitcpio.d/中的 .preset 文件中修改 PRESETS=('default' 'fallback') 行,為 PRESETS=('default')
    2. 移除fallback鏡像: # rm /boot/*-fallback.img
    3. 重新生成引導記錄 (例如,對於 GRUB: # grub-mkconfig -o /boot/grub/grub.cfg)。
警告: 如果default鏡像啟動失敗,禁止 fallback 鏡像生成將會失去另外一個引導進入系統的選項。進行此操作前,確認擁有可引導的installation medium 作為急救模式。

沒有發現 PS/2 控制器[編輯 | 編輯原始碼]

在一些主板(主要是早期的但是也有一些新的主板), i8042 控制器不能被自動偵測到。這很罕見,但是一些人確定沒有鍵盤使用。 可以提前偵測到這種情況。PS/2 接口得到 i8042: PNP: No PS/2 controller found. Probing ports directly 信息,加 atkbdMODULES 數列。

標準急救過程[編輯 | 編輯原始碼]

使用不正確的初始化內存鏡像盤經常出現不可引導。因此遵守以下的系統急救過程:

在一台機器引導成功,但在另一台引導失敗[編輯 | 編輯原始碼]

在主要鏡像 initramfs 掃描 /sysmkinitcpioautodetect 鈎子 過濾掉了 kernel modules ,這些模塊在啟動被調用。 如果轉移/boot 目錄到其他機器,在早期用戶空間造成啟動失敗,原因是新的硬件由於缺失內核模塊不能被偵測到。注意USB 2.0 和 3.0 需要不同的模塊。

修正這個缺陷,首先試着從引導記錄bootloader 中選擇 fallback 鏡像 ,因為這個鏡像不使用autodetect過濾模塊。 一旦引導成功,在新機器上運行mkinitcpio用正確的模塊重建主要鏡像。如果fallback鏡像失敗,試着用 Arch Linux live CD/USB,使用 arch-chroot 進入系統中, 在新機器上運行 mkinitcpio 。最後的手段,手工增加模塊到[#MODULES|手動]]鏡像中。

參考資料[編輯 | 編輯原始碼]