Linux

如何創建只執行一個程序而不執行其他程序的自定義 Linux 發行版?

  • October 16, 2021

我如何才能創建自己的“自定義”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

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