Linux

完全啟動 linux 所需的最小根文件系統應用程序是什麼?

  • October 16, 2021

這是一個關於使用者空間應用程序的問題,但請聽我說!

可以說,啟動 Linux 的功能發行版需要三個“應用程序”:

  1. Bootloader - 對於嵌入式,通常是 U-Boot,雖然不是硬性要求。
  2. 核心 - 這很簡單。
  3. 根文件系統 - 沒有它就無法啟動到 shell。包含核心引導到的文件系統,以及init稱為表單的位置。

我的問題是關於#3。如果有人想建構一個極小的 rootfs(對於這個問題,假設沒有 GUI,只有 shell),啟動到 shell 需要哪些文件/程序?

這完全取決於您希望在設備上擁有哪些服務。

程式

您可以讓 Linux 直接啟動到**shell**中。它在生產中不是很有用——誰只想有一個 shell 坐在那裡——但是當你有一個互動式引導載入程序時,它作為一種干預機制很有用:傳遞init=/bin/sh到核心命令行。所有 Linux 系統(和所有 unix 系統)在/bin/sh.

您將需要一組shell 實用程序BusyBox是一個很常見的選擇;它包含一個 shell 和用於文件和文本操作(cp、、grep…)、網路設置(ping、、ifconfig…)、程序操作(ps、、nice…)和各種其他系統工具(fdisk、、、mount… )的常用實用程序syslogd。BusyBox 具有極高的可配置性:您可以在編譯時選擇您想要的工具甚至個別功能,以便為您的應用程序獲得合適的大小/功能折衷方案。除此之外sh,你不能真正做任何事情的最低限度是mount,umounthalt,但是沒有也cat, cp, mv, rm,是不典型的mkdir, rmdir, ps,sync等等。BusyBox 安裝為一個名為 的二進製文件busybox,每個實用程序都有一個符號連結。

普通 unix 系統上的第一個程序稱為**init**. 它的工作是啟動其他服務。BusyBox 包含一個初始化系統。除了二進製文件(init通常位於 .什麼時候。對於 BusyBox,是可選的;如果它失去,您會在控制台上獲得一個 root shell,並且腳本(預設位置)在啟動時執行。/sbin``/etc/inittab``/etc/inittab``/etc/init.d/rcS

這就是你所需要的,當然,除了讓你的設備做一些有用的程序之外。例如,在我執行OpenWrt變體的家用路由器上,唯一的程序是 BusyBox nvram(用於讀取和更改 NVRAM 中的設置)和網路實用程序。

除非您的所有執行檔都是靜態連結的,否則您將需要動態載入程序 ( ld.so,根據 libc 的選擇和處理器體系結構,可能會以不同的名稱呼叫它) 和所有動態庫( /lib/lib*.so,也許其中一些在/usr/lib)這些執行檔。

目錄結構

Filesystem Hierarchy Standard描述了 Linux 系統的通用目錄結構。它適用於桌面和伺服器安裝:在嵌入式系統上可以省略很多。這是一個典型的最小值。

  • /bin: 可執行程序(有些可能在/usr/bin裡面)。
  • /dev:設備節點(見下文)
  • /etc: 配置文件
  • /lib: 共享庫,包括動態載入器(除非所有執行檔都是靜態連結的)
  • /proc: proc 文件系統的掛載點
  • /sbin: 可執行程序。區別/bin在於/sbin僅對系統管理員有用的程序,但這種區別在嵌入式設備上沒有意義。您可以創建/sbin一個符號連結到/bin.
  • /mnt:在維護期間方便地將只讀根文件系統作為臨時掛載點
  • /sys: sysfs 文件系統的掛載點
  • /tmp: 臨時文件的位置(通常是tmpfs掛載)
  • /usr:包含子目錄bin和. 存在於不在根文件系統上的額外文件。如果你沒有,你可以創建一個到根目錄的符號連結。lib``sbin``/usr``/usr

設備文件

以下是最小的一些典型條目/dev

  • console
  • full(寫入它總是報告“設備上沒有剩餘空間”)
  • log(程序用來發送日誌條目的套接字),如果您有一個syslogd守護程序(例如 BusyBox)從它讀取
  • null(就像一個總是空的文件)
  • ptmx和一個pts目錄,如果你想使用偽終端(即除控制台以外的任何終端)——例如,如果設備已聯網並且你想通過 telnet 或 ssh 登錄
  • random(返回隨機字節,有阻塞風險)
  • tty(總是指定程序的終端)
  • urandom(返回隨機字節,從不阻塞,但在新啟動的設備上可能是非隨機的)
  • zero(包含無限的空字節序列)

除此之外,您還需要硬體條目(網路介面除外,這些條目不包含在 中/dev):串列埠、儲存等。

對於嵌入式設備,您通常會直接在根文件系統上創建設備條目。高端系統有一個MAKEDEV用於創建/dev條目的腳本,但在嵌入式系統上,該腳本通常不會捆綁到映像中。如果某些硬體可以熱插拔(例如,如果設備具有 USB 主機埠),/dev則應由**udev**管理(您可能仍然在根文件系統上有一個最小設置)。

啟動時操作

除了根文件系統,你還需要掛載幾個才能正常執行:

  • procfs on /proc(幾乎不可或缺)
  • sysfs on /sys(幾乎不可或缺)
  • tmpfs文件系統打開/tmp(允許程序創建將在 RAM 中的臨時文件,而不是在可能位於快閃記憶體或只讀的根文件系統上)
  • tmpfs、devfs 或 devtmpfs on /devif dynamic(參見上面“設備文件”中的 udev)
  • devpts on/dev/pts如果你想使用 [pseudo-terminals (參見pts上面的註釋)

您可以製作/etc/fstab文件並呼叫mount -a,或mount手動執行。

如果您有任何地方可以寫入日誌,請啟動系統日誌守護程序(以及klogd核心日誌,如果syslogd程序不處理它)。

在此之後,設備已準備好啟動特定於應用程序的服務。

如何製作根文件系統

這是一個漫長而多樣的故事,所以我在這裡要做的就是提供一些指示。

根文件系統可以保存在 RAM 中(從 ROM 或快閃記憶體中的(通常壓縮的)映像載入),或基於磁碟的文件系統(儲存在 ROM 或快閃記憶體中),或從網路(通常通過TFTP)載入(如果適用) . 如果根文件系統在 RAM 中,則將其設為 initramfs — 一個 RAM 文件系統,其內容是在引導時創建的。

存在許多用於為嵌入式系統組裝根映像的框架。BusyBox FAQ中有一些提示。Buildroot是一種流行的方法,它允許您使用類似於 Linux 核心和 BusyBox 的設置來建構整個根映像。OpenEmbedded是另一個這樣的框架。

維基百科有一個(不完整的)流行的嵌入式 Linux 發行版列表。您可能擁有的嵌入式 Linux 的一個範例是用於網路設備的OpenWrt系列作業系統(在修補匠的家用路由器上很流行)。如果您想通過經驗學習,您可以從 Scratch 嘗試 Linux,但它面向業餘愛好者的桌面系統,而不是嵌入式設備。

關於 Linux 與 Linux 核心的說明

融入 Linux 核心的唯一行為是在引導時啟動的第一個程序。(我不會在這裡討論initrdinitramfs的微妙之處。)這個程序,傳統上稱為init,具有程序 ID 1 並具有某些特權(對KILL 信號免疫)和責任(收穫孤兒)。你可以執行一個帶有 Linux 核心的系統並啟動你想要的任何東西作為第一個程序,但是你所擁有的是一個基於 Linux 核心的作業系統,而不是通常所說的“Linux”——  Linux,在常識中術語,是一個類 Unix作業系統,其核心是Linux 核心. 例如,Android 是一個作業系統,它不是類 Unix,而是基於 Linux 核心。

引用自:https://unix.stackexchange.com/questions/136278