如何創建只執行一個程序而不執行其他程序的自定義 Linux 發行版?
我如何才能創建自己的“自定義”Linux 發行版,它只執行一個程序,幾乎與XBMCbuntu 完全相同。
我不會開始弄亂 LFS,那是一條通往一些黑暗樹林的花園小路。
從您可以對初始安裝有很多控制權的發行版開始,例如 Arch,或無頭版本,例如 Ubuntu 伺服器。這樣做的目的不是為了節省空間,而是為了限制 init 配置的複雜性;從無頭髮行版開始,如果您要執行的應用程序需要 GUI,您可以添加所需的內容,而不必以由 init 啟動的 GUI 登錄(又名顯示管理器或 DM)和成熟的桌面結束環境去配合它。
然後,您想了解如何根據您的目的配置init 系統——請注意,您不能沒有 init,它可能是實現您的目標的最佳方式。現在大多數 linux 發行版上使用的 init 系統是systemd。
這裡的重點是盡量減少 init 在啟動時所做的事情,這就是您如何創建一個系統,該系統將執行最少的軟體來支持您想要關注的應用程序——這本質上是伺服器的設置方式,順便說一句,因此這是一項常見任務(請注意,您不能真正執行“僅一個”使用者態程序,至少沒有用處)。
如果您要執行的應用程序是一個 GUI 程序(這是一個很好的例子,說明為什麼您不能只執行一個應用程序,因為 GUI 應用程序需要 X 伺服器),您可以擁有一個
~/.xinitrc
看起來像這樣的程序;#!/bin/sh myprogram
然後
startx
,您的程序將是唯一執行的程序,並且無法更改桌面或啟動其他任何東西,部分原因是沒有視窗管理器或桌面環境(因此,也沒有視窗框架或標題欄)。
最小的init hello world程序一步一步
編譯一個沒有任何以無限循環結束的依賴項的 hello world。
init.S
:.global _start _start: mov $1, %rax mov $1, %rdi mov $message, %rsi mov $message_len, %rdx syscall jmp . message: .ascii "FOOBAR FOOBAR FOOBAR FOOBAR FOOBAR FOOBAR FOOBAR\n" .equ message_len, . - message
我們不能使用 exit 系統呼叫,否則核心會崩潰,從 init 優雅退出的唯一方法是使用syscall關閉機器
reboot
。然後:
mkdir d as --64 -o init.o init.S # assemble ld -o d/init init.o # link cd d find . | cpio -o -H newc | gzip > ../rootfs.cpio.gz ROOTFS_PATH="$(pwd)/../rootfs.cpio.gz"
這將使用我們的 hello world at 創建一個文件系統
/init
,這是核心將執行的第一個使用者態程序。我們還可以向其中添加更多文件,並且在核心執行時d/
可以從程序中訪問它們。/init
然後
cd
進入Linux核心樹,照常建構,在QEMU中執行:git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git cd linux git checkout v4.9 make mrproper make defconfig make -j"$(nproc)" qemu-system-x86_64 -kernel arch/x86/boot/bzImage -initrd "$ROOTFS_PATH"
你應該看到一行:
FOOBAR FOOBAR FOOBAR FOOBAR FOOBAR FOOBAR FOOBAR
在模擬器螢幕上!請注意,它不是最後一行,因此您必須往上看一點。
如果靜態連結它們,也可以使用 C 程序:
#include <stdio.h> #include <unistd.h> int main() { printf("FOOBAR FOOBAR FOOBAR FOOBAR FOOBAR FOOBAR FOOBAR\n"); sleep(0xFFFFFFFF); return 0; }
和:
gcc -static init.c -o init
動態連結需要設置一個動態連結器執行檔,其中最常見的是 glibc 等 C 標準庫的一部分。
您可以在帶有 USB 的真實硬體上執行,
/dev/sdX
並且:make isoimage FDINITRD="$ROOTFS_PATH" sudo dd if=arch/x86/boot/image.iso of=/dev/sdX
關於這個主題的重要資料:技術提示:如何使用 initramfs | landley.net它還解釋瞭如何使用
gen_initramfs_list.sh
,這是一個來自 Linux 核心原始碼樹的腳本,用於幫助自動化該過程。在 Ubuntu 16.10、QEMU 2.6.1 上測試。
下一步
接下來您要做的是設置BusyBox,另請參閱:什麼是最小的 Linux 實現?
BusyBox 實現了基本的 POSIX-y CLI 實用程序,包括一個 POSIX-y shell,您可以通過它更輕鬆地以互動方式試驗系統。
就個人而言,在這一點上,我更喜歡只依賴Buildroot,這是一組令人驚嘆的腳本,可以自動從原始碼建構所有內容並製作根文件系統。
我已經為此上傳了一個非常詳細和自動化的幫助程序:https ://github.com/cirosantilli/linux-kernel-module-cheat