完全啟動 linux 所需的最小根文件系統應用程序是什麼?
這是一個關於使用者空間應用程序的問題,但請聽我說!
可以說,啟動 Linux 的功能發行版需要三個“應用程序”:
- Bootloader - 對於嵌入式,通常是 U-Boot,雖然不是硬性要求。
- 核心 - 這很簡單。
- 根文件系統 - 沒有它就無法啟動到 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
,umount
和halt
,但是沒有也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
/dev
if 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 核心的唯一行為是在引導時啟動的第一個程序。(我不會在這裡討論initrd和initramfs的微妙之處。)這個程序,傳統上稱為init,具有程序 ID 1 並具有某些特權(對KILL 信號免疫)和責任(收穫孤兒)。你可以執行一個帶有 Linux 核心的系統並啟動你想要的任何東西作為第一個程序,但是你所擁有的是一個基於 Linux 核心的作業系統,而不是通常所說的“Linux”—— Linux,在常識中術語,是一個類 Unix作業系統,其核心是Linux 核心. 例如,Android 是一個作業系統,它不是類 Unix,而是基於 Linux 核心。