Wie erstelle ich eine benutzerdefinierte Linux-Distribution, auf der nur ein Programm und sonst nichts ausgeführt wird?

12

Wie ich meine eigene "benutzerdefinierte" Linux-Distribution erstellen könnte, die nur ein Programm ausführt , ziemlich genau so wie XBMCbuntu .

user3462992
quelle
Willkommen bei U & L, nehmen Sie an einer Führung teil und nehmen Sie sich Zeit, um zu lernen, wie Sie eine Frage stellen können, was Sie tun möchten. weil die Definition der Anwendung ziemlich vage ist und überhaupt nichts bedeutet, weil ich raten würde, sie zu verwenden, busyboxaber 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.
Kiwy
1
Scheint mir ziemlich klar zu sein ...
Goldlöckchen
@ TAFKA'goldilocks 'naja, nein, ich wette, Sie können immer noch auf ein Terminal oder ähnliches auf XBMCubuntu zugreifen, während anscheinend nur eine App grafisch ausgeführt wird, aber nicht nur eine App. Ich habe einmal eine kleine Distribution von Grund auf mit nur einem Kernel und einer Busybox erstellt. In diesem Fall kann man sagen, dass Busybox Ihre einzige App ist, selbst wenn es Dienste gibt, die vom Kernel gestartet werden.
Kiwy
@ Kiwi Das ist dann eine gute Antwort (besser als LFS). Denken Sie daran: 1) Diese Frage kann für andere Personen nützlich sein, deren allgemeiner Zweck derselbe ist, sodass eine Reihe von Antworten gut ist. 2) Hier gibt es zwar eine Reihe möglicher Lösungen - dh TIMTOWTDI - und einige können es auch sein Ich bin mir ziemlich sicher, dass sie alle funktionieren werden und ein wesentlicher Aspekt bei der Entscheidung für eine Lösung subjektiv sein wird (z. B. aufgrund des Vorwissens und der Erfahrung des OP, nicht aufgrund der objektiven Natur der Aufgabe). .
Goldlöckchen

Antworten:

6

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 jessieVerö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.

Goldlöckchen
quelle
1
Sie können nicht verzichten , initaber sicherlich können Sie tun , ohne upstart, systemd,oder sysv. initnur einige ausführbare Datei mit dem Namen , initdass Ihr Kernel aufruft , wenn es steigt initramfs.in den meisten Fällen diese anderen drei sind nicht einmal , initaber sie sind tatsächlich execin Ed , init,die häufig istbusybox.
mikeserv
@mikeserv Absolut (und ich habe ausdrücklich erwähnt, dass dies nicht die einzigen drei Möglichkeiten sind). Beachten Sie auch, dass ich absichtlich ausgeschlossen habe, busyboxweil dies eine gesonderte Behandlung in einer gesonderten Antwort verdient, aber nicht von mir.
Goldlöckchen
Wie liebenswürdig von Ihnen zu bieten! Aber auf keinen Fall.
Mikeserv
Es wäre interessant zu wissen, ob dieser Ansatz tatsächlich in der Praxis funktioniert. Hat es tatsächlich jemand versucht?
Faheem Mitha
@FaheemMitha Wenn Sie meinen, was ich hier empfehle (passen Sie die Init-Konfiguration an), funktioniert dies natürlich - so funktioniert das System bereits, Sie würden nur eine abgespeckte und vereinfachte Version erstellen (ich bin sicher, das ist es was XBMCbutu ist). Wenn Sie damit meinen, init durch eine spezialisiertere ausführbare Datei ala Busybox zu ersetzen, ist dies wahrscheinlich schwieriger als es sich lohnt, es sei denn, Sie müssen dies auf diese Weise tun - der Hauptzweck von Busybox ist die Verwendung in winzigen eingebetteten Umgebungen (z. B. mit nur wenigen) MB RAM).
Goldlöckchen
18

Minimales Init-Hallo-Weltprogramm Schritt für Schritt

Geben Sie hier die Bildbeschreibung ein

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 /initProgramm zugegriffen werden kann, wenn der Kernel ausgeführt wird.

Dann cdin 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/sdXund:

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.sheines 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

Ciro Santilli 冠状 病毒 审查 六四 事件 法轮功
quelle
4
Dies ist wahrscheinlich die am meisten unterschätzte Antwort hier: D. Genial!
msouth
1
@msouth jetzt etwas weniger :-)
Ciro Santilli 法轮功 病毒 审查 审查 六四
1

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

Sicherheitstier
quelle
1

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:

Ouki
quelle
1

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.

Plugwash
quelle