早期使用者空間支援¶
最後更新:2004-12-20 tlh
“早期使用者空間”是一組庫和程式,它們提供各種功能,這些功能非常重要,可以在 Linux 核心啟動時使用,但不需要在核心本身內部執行。
它由幾個主要的基礎設施元件組成
gen_init_cpio,一個構建包含根檔案系統映象的 cpio 格式存檔的程式。 該存檔被壓縮,壓縮後的映象連結到核心映象中。
initramfs,一段程式碼,在核心引導過程中間解壓縮壓縮的 cpio 映象。
klibc,一個使用者空間 C 庫,目前單獨打包,它針對正確性和小尺寸進行了最佳化。
initramfs 使用的 cpio 檔案格式是 “newc”(又名 “cpio -H newc”)格式,並在 “initramfs 緩衝區格式” 檔案中進行了說明。 有兩種方法可以新增早期使用者空間映象:指定要用作映象的現有 cpio 存檔,或者讓核心構建過程從規範構建映象。
CPIO 歸檔方法¶
您可以建立一個包含早期使用者空間映象的 cpio 存檔。 您的 cpio 存檔應在 CONFIG_INITRAMFS_SOURCE 中指定,它將被直接使用。 CONFIG_INITRAMFS_SOURCE 中只能指定一個 cpio 檔案,並且不允許目錄和檔名與 cpio 存檔組合使用。
映象構建方法¶
核心構建過程也可以從源部分構建早期使用者空間映象,而不是提供 cpio 存檔。 這種方法提供了一種建立具有 root 擁有的檔案的映象的方法,即使該映象是由非特權使用者構建的。
該映象在 CONFIG_INITRAMFS_SOURCE 中指定為一個或多個源。 源可以是目錄或檔案 - 從源構建時不允許 cpio 存檔。
源目錄將打包其自身及其所有內容。 指定的目錄名稱將對映到“/”。 打包目錄時,可以執行有限的使用者和組 ID 轉換。 可以將 INITRAMFS_ROOT_UID 設定為需要對映到使用者 root (0) 的使用者 ID。 可以將 INITRAMFS_ROOT_GID 設定為需要對映到組 root (0) 的組 ID。
原始檔必須是 usr/gen_init_cpio 實用程式所需的格式的指令(執行“usr/gen_init_cpio -h”以獲取檔案格式)。 檔案中的指令將直接傳遞給 usr/gen_init_cpio。
當指定目錄和檔案組合時,initramfs 映象將是它們的聚合。 透過這種方式,使用者可以建立一個“root-image”目錄並將所有檔案安裝到其中。 由於裝置專用檔案不能由非特權使用者建立,因此可以在“root-files”檔案中列出特殊檔案。 “root-image”和“root-files”都可以列在 CONFIG_INITRAMFS_SOURCE 中,並且完整的早期使用者空間映象可以由非特權使用者構建。
作為一個技術說明,當指定目錄和檔案時,整個 CONFIG_INITRAMFS_SOURCE 將傳遞給 usr/gen_initramfs.sh。 這意味著 CONFIG_INITRAMFS_SOURCE 實際上可以解釋為 gen_initramfs.sh 的任何合法引數。 如果指定一個目錄作為引數,則掃描內容,執行 uid/gid 轉換,並輸出 usr/gen_init_cpio 檔案指令。 如果將目錄指定為 usr/gen_initramfs.sh 的引數,則檔案的內容將簡單地複製到輸出。 目錄掃描和檔案內容複製的所有輸出指令都由 usr/gen_init_cpio 處理。
另請參閱“usr/gen_initramfs.sh -h”。
這一切都指向哪裡?¶
klibc 發行版包含一些必要的軟體,使早期使用者空間有用。 klibc 發行版目前與核心分開維護。
您可以從 https://kernel.linux.club.tw/pub/linux/libs/klibc/ 獲取不太頻繁的 klibc 快照
對於活躍使用者,最好使用 klibc git 儲存庫,地址為 https://git.kernel.org/?p=libs/klibc/klibc.git
除了 klibc 庫之外,獨立的 klibc 發行版目前還提供三個元件
ipconfig,一個配置網路介面的程式。 它可以靜態配置它們,也可以使用 DHCP 動態獲取資訊(又名“IP 自動配置”)。
nfsmount,一個可以掛載 NFS 檔案系統的程式。
kinit,“膠水”,它使用 ipconfig 和 nfsmount 來替換對 IP 自動配置的舊支援,透過 NFS 掛載檔案系統,並繼續使用該檔案系統作為 root 來引導系統。
kinit 構建為單個靜態連結的二進位制檔案,以節省空間。
最終,希望有更多的核心功能轉移到早期使用者空間
幾乎所有的 init/do_mounts*(這部分的開頭已經到位)
ACPI 表解析
在此處插入不需要真正位於核心空間中的笨拙子系統
如果 kinit 不能滿足您當前的需求,並且您有足夠的位元組要燒燬,則 klibc 發行版包含一個小的 Bourne 相容 shell (ash) 和許多其他實用程式,因此您可以替換 kinit 並構建完全滿足您需求的自定義 initramfs 映象。
如有問題和幫助,您可以在 https://www.zytor.com/mailman/listinfo/klibc 註冊早期使用者空間郵件列表
它是如何工作的?¶
核心目前有 3 種掛載根檔案系統的方法
所有必需的裝置和檔案系統驅動程式都編譯到核心中,沒有 initrd。 init/main.c:init() 將呼叫 prepare_namespace() 以掛載最終的根檔案系統,基於 root= 選項和可選的 init= 以執行一些其他 init 二進位制檔案,而不是列在 init/main.c:init() 的末尾。
一些裝置和檔案系統驅動程式構建為模組並存儲在 initrd 中。 initrd 必須包含一個二進位制檔案“/linuxrc”,該檔案應該載入這些驅動程式模組。 也可以透過 linuxrc 掛載最終的根檔案系統並使用 pivot_root 系統呼叫。 initrd 透過 prepare_namespace() 掛載和執行。
使用 initramfs。 必須跳過對 prepare_namespace() 的呼叫。 這意味著一個二進位制檔案必須完成所有工作。 該二進位制檔案可以透過修改 usr/gen_init_cpio.c 或透過新的 initrd 格式(一個 cpio 存檔)儲存到 initramfs 中。 它必須被稱為“/init”。 此二進位制檔案負責完成 prepare_namespace() 將完成的所有事情。
為了保持向後相容性,/init 二進位制檔案僅在它透過 initramfs cpio 存檔時才會執行。 如果不是這種情況,init/main.c:init() 將執行 prepare_namespace() 以掛載最終的根並執行預定義的 init 二進位制檔案之一。
Bryan O’Sullivan <bos@serpentine.com>