Es ist eine Frage zu User Space-Anwendungen, aber hör mir zu!
Um eine funktionierende Linux-Distribution zu booten, sind sozusagen drei "Anwendungen" erforderlich:
Bootloader - Für eingebettete Systeme ist dies in der Regel U-Boot, obwohl dies keine zwingende Voraussetzung ist.
Kernel - Das ist ziemlich einfach.
Root-Dateisystem - Ohne dieses System kann nicht in eine Shell gebootet werden. Enthält das Dateisystem, in das der Kernel bootet, und wo
init
es Form heißt.
Meine Frage bezieht sich auf # 3. Wenn jemand ein extrem minimales rootfs erstellen wollte (für diese Frage sagen wir mal keine GUI, nur Shell), welche Dateien / Programme sind erforderlich, um von einer Shell zu booten?
linux
embedded
startup
architecture
root-filesystem
MDMoore313
quelle
quelle
Antworten:
Das hängt ganz davon ab, welche Dienste Sie auf Ihrem Gerät haben möchten.
Programme
Sie können Linux direkt in eine Shell booten lassen . In der Produktion ist es nicht sehr nützlich - wer möchte nur eine Shell haben -, aber es ist nützlich als Interventionsmechanismus, wenn Sie einen interaktiven Bootloader haben: Übergeben Sie ihn
init=/bin/sh
an die Kernel-Befehlszeile. Alle Linux-Systeme (und alle Unix-Systeme) haben eine Bourne / POSIX-ähnliche Shell/bin/sh
.Sie benötigen eine Reihe von Shell-Dienstprogrammen . BusyBox ist eine sehr häufige Wahl; es enthält eine Shell und gemeinsamen Dienstprogramme für die Datei- und Textmanipulation (
cp
,grep
, ...), Netzwerk - Setup (ping
,ifconfig
, ...), Prozessmanipulation (ps
,nice
, ...) und verschiedene andere Systemtools (fdisk
,mount
,syslogd
, ...). BusyBox ist äußerst konfigurierbar: Sie können auswählen, welche Tools Sie möchten, und sogar einzelne Funktionen zum Zeitpunkt der Kompilierung auswählen, um den richtigen Kompromiss zwischen Größe und Funktionalität für Ihre Anwendung zu erzielen. Nebensh
dem bloße Minimum , dass Sie nicht wirklich etwas tun können , ohne istmount
,umount
undhalt
, aber es wäre untypisch nicht auch habencat
,cp
,mv
,rm
,mkdir
,rmdir
,ps
,sync
Und ein paar mehr. BusyBox wird als einzelne Binärdateibusybox
mit einem symbolischen Link für jedes Dienstprogramm installiert .Der erste Prozess auf einem normalen Unix-System wird aufgerufen
init
. Seine Aufgabe ist es, andere Dienste zu starten. BusyBox enthält ein Init-System. Zusätzlich zu derinit
Binärdatei (in der Regel in/sbin
) benötigen Sie die Konfigurationsdateien (in der Regel als/etc/inittab
- einige moderne Init-Ersetzungen beseitigen diese Datei, aber Sie werden sie nicht auf einem kleinen eingebetteten System finden), die angeben, welche Dienste gestartet werden sollen und wann. Bei BusyBox/etc/inittab
ist dies optional. Wenn es fehlt, erhalten Sie eine Root-Shell auf der Konsole und das Skript/etc/init.d/rcS
(Standardverzeichnis) wird beim Booten ausgeführt.Das ist alles, was Sie brauchen, abgesehen von den Programmen, die Ihr Gerät zu etwas Nützlichem machen. Auf meinem Heimrouter, auf dem eine OpenWrt- Variante ausgeführt wird, sind die einzigen Programme BusyBox
nvram
(zum Lesen und Ändern von Einstellungen im NVRAM) und Netzwerkdienstprogramme.Sofern nicht alle Ihre ausführbaren Dateien statisch verknüpft sind, benötigen Sie den Dynamic Loader (
ld.so
der abhängig von der Wahl von libc und den Prozessorarchitekturen unter verschiedenen Namen aufgerufen werden kann) und alle dynamischen Bibliotheken (/lib/lib*.so
möglicherweise einige davon in/usr/lib
), die von benötigt werden diese ausführbaren Dateien.Verzeichnisaufbau
Der Filesystem Hierarchy Standard beschreibt die allgemeine Verzeichnisstruktur von Linux-Systemen. Es richtet sich an Desktop- und Serverinstallationen: Viele davon können auf einem eingebetteten System weggelassen werden. Hier ist ein typisches Minimum.
/bin
: ausführbare Programme (einige können/usr/bin
stattdessen in sein)./dev
: Geräteknoten (siehe unten)/etc
: Konfigurationsdateien/lib
: gemeinsam genutzte Bibliotheken, einschließlich des Dynamic Loader (sofern nicht alle ausführbaren Dateien statisch verknüpft sind)/proc
: Einhängepunkt für das proc-Dateisystem/sbin
: ausführbare Programme. Die Unterscheidung mit/bin
ist/sbin
für Programme, die nur für den Systemadministrator nützlich sind, aber diese Unterscheidung ist auf eingebetteten Geräten nicht sinnvoll. Sie können/sbin
einen symbolischen Link zu erstellen/bin
./mnt
: Praktisch, um schreibgeschützte Root-Dateisysteme als Scratch-Mount-Punkt während der Wartung zu verwenden/sys
: Einhängepunkt für das sysfs-Dateisystem/tmp
: Speicherort für temporäre Dateien (oft eintmpfs
Mount)/usr
: Enthält Unterordnerbin
,lib
undsbin
./usr
existiert für zusätzliche Dateien, die sich nicht im Root-Dateisystem befinden. Wenn Sie das nicht haben, können Sie/usr
einen symbolischen Link zum Stammverzeichnis erstellen.Gerätedateien
Hier sind einige typische Einträge in einem Minimum
/dev
:console
full
(Beim Schreiben wird immer "kein Platz mehr auf dem Gerät" gemeldet.)log
(Ein Socket, über den Programme Protokolleinträge senden), wenn einsyslogd
Daemon (z. B. BusyBox) davon liestnull
(verhält sich wie eine Datei, die immer leer ist)ptmx
und einpts
Verzeichnis , wenn Sie Pseudo-Terminals verwenden möchten (dh ein anderes Terminal als die Konsole) - z. B. wenn das Gerät vernetzt ist und Sie telnet- oder ssh-in möchtenrandom
(liefert zufällige Bytes, riskiert das Blockieren)tty
(bezeichnet immer das Terminal des Programms)urandom
(Gibt zufällige Bytes zurück, blockiert niemals, kann aber auf einem frisch gebooteten Gerät nicht zufällig sein.)zero
(enthält eine unendliche Folge von Null-Bytes)Darüber hinaus benötigen Sie Einträge für Ihre Hardware (mit Ausnahme der Netzwerkschnittstellen, in die keine Einträge eingehen
/dev
): serielle Anschlüsse, Speicher usw.Bei eingebetteten Geräten erstellen Sie die Geräteeinträge normalerweise direkt im Root-Dateisystem. High-End-Systeme verfügen über ein Skript
MAKEDEV
zum Erstellen von/dev
Einträgen. Auf einem eingebetteten System ist das Skript jedoch häufig nicht im Image enthalten. Wenn eine Hardware per Hotplug angeschlossen werden kann (z. B. wenn das Gerät über einen USB-Host-Port verfügt),/dev
sollte dies von udev verwaltet werden (möglicherweise ist im Root-Dateisystem noch ein Mindestsatz festgelegt).Boot-Time-Aktionen
Über das Root-Dateisystem hinaus müssen Sie für den normalen Betrieb einige weitere bereitstellen:
/proc
(so ziemlich unverzichtbar)/sys
(so ziemlich unverzichtbar)tmpfs
Dateisystem ein/tmp
(damit Programme temporäre Dateien erstellen können, die sich im RAM befinden, und nicht im Root-Dateisystem, das sich möglicherweise in Flash oder schreibgeschützt befindet)/dev
if dynamic (siehe udev in " Gerätedateien " oben)/dev/pts
wenn Sie [Pseudo-Terminals verwenden möchten (siehe Bemerkungpts
oben)Sie können eine
/etc/fstab
Datei erstellen und aufrufenmount -a
odermount
manuell ausführen .Starten Sie einen Syslog- Daemon (sowie
klogd
für Kernel-Protokolle, wenn dassyslogd
Programm sich nicht darum kümmert), wenn Sie einen Platz zum Schreiben von Protokollen haben.Danach ist das Gerät bereit, anwendungsspezifische Dienste zu starten.
So erstellen Sie ein Root-Dateisystem
Dies ist eine lange und abwechslungsreiche Geschichte. Alles, was ich hier tun werde, ist ein paar Hinweise zu geben.
Das Root-Dateisystem kann im RAM (geladen von einem (normalerweise komprimierten) Image in ROM oder Flash) oder auf einem festplattenbasierten Dateisystem (gespeichert in ROM oder Flash) oder gegebenenfalls vom Netzwerk (häufig über TFTP ) geladen werden . Wenn sich das Root-Dateisystem im RAM befindet, machen Sie es zum initramfs - einem RAM-Dateisystem, dessen Inhalt beim Booten erstellt wird.
Es gibt viele Frameworks zum Zusammenstellen von Root-Images für eingebettete Systeme. In den BusyBox-FAQ gibt es einige Hinweise . Buildroot ist ein beliebtes Tool , mit dem Sie ein vollständiges Root-Image mit einem ähnlichen Setup wie der Linux-Kernel und die BusyBox erstellen können. OpenEmbedded ist ein weiteres solches Framework.
Wikipedia hat eine (unvollständige) Liste der gängigen Embedded Linux-Distributionen . Ein Beispiel für Embedded Linux in Ihrer Nähe ist die OpenWrt- Betriebssystemfamilie für Netzwerkgeräte (beliebt bei Heimroutern von Bastlern). Wenn Sie aus Erfahrung lernen möchten, können Sie Linux von Grund auf ausprobieren. Es richtet sich jedoch eher an Desktopsysteme für Bastler als an eingebettete Geräte.
Ein Hinweis zu Linux vs. Linux-Kernel
Das einzige Verhalten, das in den Linux-Kernel eingearbeitet ist, ist das erste Programm, das beim Booten gestartet wird. (Ich werde hier nicht auf die Feinheiten von initrd und initramfs eingehen.) Dieses Programm, das traditionell als init bezeichnet wird , hat die Prozess-ID 1 und verfügt über bestimmte Berechtigungen (Immunität gegen KILL-Signale ) und Verantwortlichkeiten (ernten von Waisen ). Sie können ein System mit einem Linux-Kernel ausführen und als ersten Prozess das starten, was Sie möchten. Dann haben Sie jedoch ein Betriebssystem, das auf dem Linux-Kernel basiert, und nicht das, was normalerweise als „Linux“ - Linux im allgemeinen Sinne - bezeichnet wird Der Begriff ist ein Unix- ähnliches Betriebssystem, dessen Kernel der Linux-Kernel ist. Beispielsweise ist Android ein Betriebssystem, das nicht wie Unix ist, sondern auf dem Linux-Kernel basiert.
quelle
Sie benötigen lediglich eine statisch verknüpfte ausführbare Datei, die isoliert auf dem Dateisystem abgelegt wird. Sie benötigen keine weiteren Dateien. Diese ausführbare Datei ist der Init-Prozess. Es kann Busybox sein. Das gibt Ihnen eine Shell und eine Vielzahl anderer Dienstprogramme, alles an sich. Sie können zu einem voll funktionsfähigen System wechseln, indem Sie die Befehle in busybox manuell ausführen, um das Root-Dateisystem mit Lese- / Schreibzugriff einzubinden, Knoten zu erstellen / zu entwickeln, echte Init-Befehle auszuführen usw.
quelle
Wenn Sie keine Shell-Dienstprogramme benötigen, ist eine statisch verknüpfte
mksh
Binärdatei (z. B. gegen klibc-130K unter Linux / i386) ausreichend. Sie benötigen ein/linuxrc
oder/init
oder/sbin/init
Skript, das nurmksh -l -T!/dev/tty1
in einer Schleife aufruft :Die
-T!$tty
Option ist einemksh
Neuerung, die es anweist, eine neue Shell auf dem angegebenen Terminal zu erzeugen und darauf zu warten. (Vorher war es nur-T-
ein Programm zu dæmonise und-T$tty
zu laichen auf einem Terminal aber nicht warten. Das war nicht so schön.) Die-l
Option einfach erzählt ein Login - Shell ausgeführt werden ( in dem es heißt/etc/profile
,~/.profile
und~/.mkshrc
).Dies setzt voraus, dass Ihr Terminal ein
/dev/tty1
Ersatz ist. (Mit mehr Magie kann das Terminal automatisch herausgefunden werden. Sie erhalten/dev/console
keine vollständige Auftragssteuerung.)Sie benötigen ein paar Dateien,
/dev
damit dies funktioniert:Wenn Sie mit der Kernel-Option booten, ist
devtmpfs.mount=1
kein gefülltes/dev
Verzeichnis mehr erforderlich. Es muss lediglich ein leeres Verzeichnis sein (das als Mountpoint verwendet werden kann).Normalerweise benötigen Sie einige Dienstprogramme (von klibc, busybox, beastiebox, toybox oder toolbox), die jedoch nicht wirklich benötigt werden.
Möglicherweise möchten Sie eine
~/.mkshrc
Datei hinzufügen , in der $ PS1 und einige grundlegende Shell-Aliase und -Funktionen eingerichtet werden.Ich habe einmal eine 171K komprimierte (371K unkomprimierte) initrd für Linux / m68k erstellt, wobei ich nur mksh (und dessen Beispiel-mkshrc-Datei) und klibc-utils verwendet habe. (Dies war jedoch, bevor -T! Zur Shell hinzugefügt wurde, sodass
/dev/tty2
stattdessen die Anmeldeshell gestartet und eine Nachricht an die Konsole gesendet wurde, die den Benutzer auffordert, die Terminals zu wechseln.) Es funktioniert einwandfrei.Dies ist ein wirklich minimales Setup. Die anderen Antworten bieten hervorragende Tipps für Systeme mit etwas mehr Funktionen. Dies ist ein echter Sonderfall.
Haftungsausschluss: Ich bin der MKSH-Entwickler.
quelle
mksh
.Minimales init hallo Weltprogramm Schritt für Schritt
Kompilieren Sie eine Hallo-Welt ohne Abhängigkeiten, die in einer Endlosschleife enden.
init.S
:Wir können nicht
sys_exit
oder sonst die Kernel Panics verwenden.Dann:
Dies schafft ein Dateisystem mit unserer Hello World unter
/init
, dem ersten Userland-Programm, das der Kernel ausführen wird. Wir hätten auch weitere Dateien hinzufügen können, aufd/
die über das/init
Programm zugegriffen werden kann, wenn der Kernel ausgeführt wird.Dann
cd
in den Linux-Kernel-Baum einbauen wie gewohnt und in QEMU ausführen:Und Sie sollten eine Linie sehen:
auf dem Emulatorbildschirm! Beachten Sie, dass es nicht die letzte Zeile ist, Sie müssen also etwas weiter nachschlagen.
Sie können C-Programme auch verwenden, wenn Sie sie statisch verknüpfen:
mit:
Sie können auf echter Hardware mit einem USB-Anschluss ausgeführt werden
/dev/sdX
und:Hervorragende Quelle zu diesem Thema: http://landley.net/writing/rootfs-howto.html Hier wird auch erklärt, wie Sie dieses
gen_initramfs_list.sh
Skript aus dem Linux-Kernel-Quellbaum verwenden, um den Prozess zu automatisieren.Nächster Schritt: Richten Sie BusyBox so ein, dass Sie mit dem System interagieren können: https://github.com/cirosantilli/runlinux
Getestet unter Ubuntu 16.10, QEMU 2.6.1.
quelle