Wie ich meine eigene "benutzerdefinierte" Linux-Distribution erstellen könnte, die nur ein Programm ausführt , ziemlich genau so wie XBMCbuntu .
Wie ich meine eigene "benutzerdefinierte" Linux-Distribution erstellen könnte, die nur ein Programm ausführt , ziemlich genau so wie XBMCbuntu .
Antworten:
Ich würde mich nicht mit LFS anlegen, das ist ein Gartenweg, der zu dunklen Wäldern führt.
Beginnen Sie mit einer Distribution, in der Sie viel Kontrolle über die Erstinstallation haben, wie z. B. Arch, oder einer Headless-Edition, wie z. B. Ubuntu Server. Dabei geht es weniger darum, Platz zu sparen, als vielmehr darum, die Komplexität der Init-Konfiguration zu begrenzen. Ausgehend von einer Headless-Distribution können Sie, wenn für die Anwendung, die Sie ausführen möchten, eine GUI benötigen, hinzufügen, was dafür erforderlich ist, ohne dass Sie eine von init gestartete GUI-Anmeldung (auch bekannt als Display Manager oder DM) und einen vollständigen Desktop benötigen Umwelt dazu zu gehen.
Anschließend möchten Sie lernen, wie Sie das Init-System für Ihre Zwecke konfigurieren. Beachten Sie, dass Sie nicht auf Init verzichten können. Dies ist möglicherweise das beste Mittel, um Ihr Ziel zu erreichen. Es gibt drei Variationen von init, die üblicherweise unter Linux verwendet werden (aber es gibt einige andere ):
Debian verwendet eine Variation des klassischen Unix SysV-Init . Ab der jessie
Veröffentlichung hat Debian auch zu systemd
( https://wiki.debian.org/systemd ) gewechselt.
Ubuntu und Derivate verwenden Upstart .
Fedora, Arch und Derivate verwenden systemd .
Wenn Sie noch nichts davon wissen, ist keines von ihnen besonders schwer zu bedienen als eines der anderen. Wenn Sie sich für eine der beiden späteren entscheiden, bieten sie einige Mechanismen für die Abwärtskompatibilität mit SysV, aber kümmern Sie sich nicht darum , es ist NICHT einfacher. 1
Hier geht es darum, die Funktionsweise von init beim Booten zu minimieren. Auf diese Weise können Sie ein System erstellen, auf dem nur eine minimale Menge an Software ausgeführt wird, um die Anwendung zu unterstützen, auf die Sie sich konzentrieren möchten. Auf diese Weise wird im Wesentlichen ein Server eingerichtet. Übrigens, es ist also eine häufige Aufgabe (beachten Sie, dass nicht buchstäblich "nur" ein Userland-Prozess ausgeführt werden kann, zumindest nicht sinnvoll).
Wenn es sich bei der Anwendung, die Sie ausführen möchten, um ein GUI-Programm handelt (ein gutes Beispiel dafür, warum Sie nicht buchstäblich nur eine Anwendung ausführen können, da für GUI-Apps ein X-Server erforderlich ist), können Sie ein solches Programm verwenden ~/.xinitrc
.
#!/bin/sh
myprogram
Wenn Sie dann sind startx
, wird nur Ihr Programm ausgeführt, und es ist unmöglich, Desktops zu ändern oder etwas anderes zu starten, teilweise weil es keinen Fenstermanager oder keine Desktop-Umgebung gibt (daher gibt es auch keinen Fensterrahmen oder keine Titelleiste).
1. Um den Punkt ein wenig zu beleuchten: Wenn Sie dies untersuchen, werden Sie möglicherweise einige Probleme mit systemd und Emporkömmlingen von Leuten finden, die zuvor mit SysV vertraut waren und behaupten, dass sie zu kompliziert sind. Objektiv gesehen sind sie jedoch nicht komplexer als SysV (IMO systemd ist tatsächlich einfacher zu verwenden), aber die meisten Hunde bevorzugen sozusagen ihre alten Tricks. Dieses Greifen lässt allmählich nach, da beide Systeme bereits seit einiger Zeit im Einsatz sind.
init
aber sicherlich können Sie tun , ohne upstart, systemd,
oder sysv. init
nur einige ausführbare Datei mit dem Namen , init
dass Ihr Kernel aufruft , wenn es steigt initramfs.
in den meisten Fällen diese anderen drei sind nicht einmal , init
aber sie sind tatsächlich exec
in Ed , init,
die häufig istbusybox.
busybox
weil dies eine gesonderte Behandlung in einer gesonderten Antwort verdient, aber nicht von mir.
Minimales Init-Hallo-Weltprogramm Schritt für Schritt
Kompilieren Sie eine Hallo-Welt ohne Abhängigkeiten, die in einer Endlosschleife endet. 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
Wir können den Exit-Systemaufruf oder die Kernel-Panik nicht verwenden.
Dann:
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"
Dadurch wird ein Dateisystem mit unserer Hallo-Welt erstellt /init
, das das erste Userland-Programm ist, das der Kernel ausführen wird. Wir hätten auch weitere Dateien hinzufügen können, auf d/
die über das /init
Programm zugegriffen werden kann, wenn der Kernel ausgeführt wird.
Dann cd
in den Linux - Kernel - Baum, Build ist wie üblich, und führen Sie es in 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"
Und Sie sollten eine Linie sehen:
FOOBAR FOOBAR FOOBAR FOOBAR FOOBAR FOOBAR FOOBAR
auf dem Emulatorbildschirm! Beachten Sie, dass dies nicht die letzte Zeile ist. Sie müssen also etwas weiter nach oben schauen.
Sie können C-Programme auch verwenden, wenn Sie sie statisch verknüpfen:
#include <stdio.h>
#include <unistd.h>
int main() {
printf("FOOBAR FOOBAR FOOBAR FOOBAR FOOBAR FOOBAR FOOBAR\n");
sleep(0xFFFFFFFF);
return 0;
}
mit:
gcc -static init.c -o init
Für die dynamische Verknüpfung muss eine ausführbare Datei für den dynamischen Linker eingerichtet werden, von denen die häufigsten Teil von C-Standardbibliotheken wie glibc sind.
Sie können auf echter Hardware mit einem USB-Anschluss ausgeführt werden /dev/sdX
und:
make isoimage FDINITRD="$ROOTFS_PATH"
sudo dd if=arch/x86/boot/image.iso of=/dev/sdX
Gute Quelle zu diesem Thema: Technischer Tipp: Verwendung von initramfs | landley.net Außerdem wird die Verwendung gen_initramfs_list.sh
eines Skripts aus dem Linux-Kernel- Quellbaum zur Automatisierung des Prozesses erläutert .
Getestet unter Ubuntu 16.10, QEMU 2.6.1.
Nächste Schritte
Als nächstes möchten Sie BusyBox einrichten .
BusyBox implementiert grundlegende POSIX-y-CLI-Dienstprogramme, einschließlich einer POSIX-y-Shell, mit der Sie einfacher interaktiv mit dem System experimentieren können.
Persönlich ziehe ich es an dieser Stelle vor, mich nur auf Buildroot zu verlassen , eine erstaunliche Reihe von Skripten, die das Erstellen von allem aus dem Quellcode und das Erstellen des Root-Dateisystems automatisieren.
Ich habe dafür einen sehr detaillierten und automatisierten Helfer hochgeladen: https://github.com/cirosantilli/linux-kernel-module-cheat
Wenn Sie ein wenig in der Programmierung sind und es von Grund auf neu erstellen möchten, können Sie LFS verwenden, dh Linux von Grund auf neu http://www.linuxfromscratch.org/
Wenn Sie Ubutnu anpassen möchten, können Sie Ubunt-Builder verwenden. Wenn Sie es auf RPM-Basis verwenden möchten, können Sie SUsE-Studio verwenden. Mit Suse Studio können Sie benutzerdefiniertes Suse Linux erstellen
Prost
Es geht mehr darum, was Ihr "ein Programm" erfordert.
Sie können immer noch gut verstehen, wie man Dinge zusammensetzt, indem Sie ein LFS (auch bekannt als " Linux From Scratch ") erstellen . Dann werden Sie die Dinge hinzufügen, die für Ihr Programm erforderlich sind, oder eine vollständige Verteilung anstreben, da das Erstellen eines schweren Subsystems wie Gnome oder KDE auf LFS ein echtes Problem sein kann.
Natürlich kann das Zurückgehen zunächst einfacher sein, aber das Entfernen von Dingen aus einer vollständigen Distribution kann problematisch sein: Führen Sie dies in einer VM aus und kopieren Sie diese VM bei jedem Schritt.
(meine 2 Cent)
Bearbeiten :
Wie von SecurityBeast hervorgehoben , können Sie sich nicht nur mit einer vollständigen Distribution wie CentOS oder Ubuntu befassen , sondern auch mit dem Erstellen von Distributionstools wie:
Was Sie fragen müssen, ist, was Ihr "ein Programm" benötigt und welche Ressourcen Sie haben.
Wenn es eine große Auswahl an Bibliotheken und Support-Binärdateien benötigt, ist es möglicherweise am besten, eine "normale" Linux-Distribution (Debian oder ähnliches) zu verwenden und nur ein wenig mit dem Boot-Prozess herumzuspielen.
Wenn es eine engere Auswahl an Support-Dingen benötigt, aber dennoch Dinge wie Netzwerk oder Support für eine Vielzahl von Hardware mit verschiedenen Kernel-Modulen oder Userland-Support-Bits erfordert und Sie nicht möchten, dass der Speicherplatz einer regulären Distribution überlastet wird, dann würde ich einen Blick darauf werfen eingebettete Distributionen (Buildroot oder ähnliches) oder vielleicht ein Linux-from-Scratch-Ansatz (obwohl dies Kopfschmerzen bei der Wartung sein kann)
Wenn Sie genau das benötigen, was ein nicht modularer Kernel bieten kann, und sonst nichts, dann kann es funktionieren und die leichteste Lösung sein, wenn Sie Ihre eigene Binärdatei direkt auf dem Kernel ausführen.
busybox
aber das ist wahrscheinlich nicht das, was Sie wollen. Nehmen Sie sich also bitte die notwendige Zeit, um Ihre Bedürfnisse auszudrücken, und wir können Ihnen möglicherweise helfen. Zögern Sie nicht , Ihre Frage zu bearbeiten , um relevante Elemente hinzuzufügen.