Es wurden viele Fragen gestellt, wie ich meinen Pi in meinem Netzwerk finden kann . Andere - einschließlich ich - haben zeitaufwändige Probleme beim Versuch, eine Menge neuer PIs bereitzustellen.
Während die Erstellung von benutzerdefinierten Bildern eine Lösung für diese Probleme sein könnte, frage ich mich, ob es andere Lösungen gibt.
Wäre es möglich, mit (nur) dem /boot
Verzeichnis, das auf normalen Computern (Win / OSX) für den Zugriff geöffnet ist /boot/cmdline.txt
, Text an ein Bash-Skript weiterzuleiten, auszuführen und anschließend zu löschen?
Antworten:
Ich habe eine leicht modifizierte Version von Raspberian-light erstellt, die diese Anforderung erfüllt. Sie führt Ihr benutzerdefiniertes Skript /boot/firstboot.sh beim ersten Start aus:
https://github.com/nmcclain/raspberian-firstboot
quelle
Sie können bewirken, dass Code ausgeführt wird, indem Sie mit der Kernel-Befehlszeile herumspielen. Die naheliegendste Methode besteht darin, init durch etwas anderes zu ersetzen. Die häufigste Anwendung hierfür ist das Starten einer Shell sehr früh im Startvorgang, normalerweise, weil Sie etwas reparieren müssen oder weil alles andere sehr stark beschädigt ist, z.
Beachten Sie, dass zu diesem Zeitpunkt des Startvorgangs alle Dateisysteme noch schreibgeschützt bereitgestellt werden. Darüber hinaus gibt es eine ganze Reihe von Dingen, die einfach nicht richtig funktionieren. Da kein richtiger Init ausgeführt wird, funktioniert das Herunterfahren und Neustarten nicht. Sie müssen das Root-Dateisystem manuell erneut schreibgeschützt bereitstellen und beispielsweise
reboot -f
zum Neustart aufrufen .Ich habe keine Ahnung, ob Sie auf diese Weise Argumente an bash übergeben können. Ich habe es nie versucht. Wenn Sie theoretisch
-c
zu Bash übergehen können , können Sie diesem Bash-Prozess anweisen, alles zu tun. Aber es könnte sich zu einem ziemlich langen Streit entwickeln, und ich weiß nicht, ob der Kernel solche Dinge zulassen würde.Zweitens können Sie tun. Sie können ein erstes Ramfs (Initramfs) in das Dateisystem kopieren und den Bootloader für die Verwendung konfigurieren
config.txt
. Es gibt verschiedene Möglichkeiten, Skripte in ein initramfs zu bekommen, um spezielle Dinge zu tun. Sie müssen jedoch ein spezielles initramfs für diesen Zweck vorbereiten (siehe initramfs-tools (8)), daher bin ich mir nicht sicher, ob dies eine bessere Lösung als ein benutzerdefiniertes Image ist.Sie könnten das Skript in / boot einfügen (ich habe über Ihren Vorschlag zu "normalen" Computern gelacht, aber dies wäre das Bit, auf das Sie von diesen Computern aus zugreifen können) und versuchen, dies über die Kernel-Init-Zeile zu starten, aber Dateien auf dos-Dateisystemen sind nicht vorhanden Es ist nicht ausführbar, es sei denn, Sie machen es für das gesamte Dateisystem.
Wenn ich es wäre, würde ich ein benutzerdefiniertes Image erstellen, das DHCP zum Konfigurieren des Netzwerks verwendet und ein benutzerdefiniertes Skript enthält, das beim Booten ausgeführt wird. Dieses Skript sucht nach einer bestimmten Datei, die als Flag fungiert. Wenn die Datei vorhanden ist, tun Sie nichts. Wenn nicht, konfigurieren Sie die Dinge und erstellen Sie die Flag-Datei.
Ihr Konfigurationsskript könnte sogar das Original von einem http-Server abrufen. Dies bedeutet, dass Sie kein neues Bild erstellen müssen, wenn Sie etwas optimieren müssen.
Das sollte die am wenigsten stressige Lösung sein.
Eine letzte Möglichkeit, aber Sie müssen dies auf einem "nicht regulären" Computer tun :-) Sie können das ext4-Dateisystem auf ein Loop-Gerät mounten und Dateien darauf kopieren, ohne es zuerst auf die SD-Karte zu schreiben. Für ein Standardbild von Raspbian Jessie wäre es ungefähr so:
Ich mache gerne einen erzwungenen Fsck auf meinen Dateisystemen, bevor ich Bilder mache. Setzt die Anzahl der Mount beim ersten Start auf Null :-)
EDIT : Nach vielen Monaten und mehr Erfahrung. Sie möchten sich U-Boot ansehen. Ersetzen Sie den Bootloader durch U-Boot. Dies kann von einer "normalen Maschine" aus erfolgen. Sobald Sie U-Boot installiert haben, können Sie entweder eine Distribution über das Netzwerk booten, von der aus Sie die SD-Karte problemlos flashen können, oder Sie können die Karte theoretisch direkt flashen, obwohl ich keine Ahnung habe, wie schwer das sein würde.
Im Wesentlichen bringt U-Boot Netzwerk-Boot auf den Raspberry Pi, was es alleine nicht unterstützt.
quelle
init=script & init
? Das Skript wird im Hintergrund ausgeführt, während init normal gestartet wird. Das Skript würde zu Beginn eine Bedingungsprüfung benötigen und z. B. fortfahren, wenn init seine Arbeit beendet hat.Für diejenigen, die eine Lösung bevorzugen, die nur Skripte enthält, die in der FAT32- Bootpartition abgelegt wurden , finden Sie hier eine Vorgehensweise. [ Bearbeiten: Die Dateien sind jetzt in einem Projekt- Pi-Boot-Skript verfügbar .]
Wie in anderen Antworten erwähnt, handelt es sich um die Befehlszeilenargumente, mit denen der Linux-Kernel gestartet wird. Diese Argumente befinden sich in /boot/cmdline.txt .
Ich habe dies auf Raspbian Buster (v10.1) 2019-09-26 getestet. Es funktioniert auf einer neu geflashten SD-Karte oder auf dem heruntergeladenen IMG -Image, das Sie dann auf eine beliebige Anzahl von SD-Karten flashen können.
1. Bearbeiten Sie die Kernel-Argumente
Öffnen Sie die Textdatei /boot/cmdline.txt , entfernen Sie alle
init=
Teile daraus und fügen Sie diese am Ende der Zeile hinzu:Das letzte Wort in dieser Zeile ist der Name eines Skripts, das vom Kernel als erster Prozess (PID = 1) anstelle von / sbin / init ausgeführt wird . Die Hilfeseite zu Kernel-Argumenten enthält nur Argumente
.
, die nicht an die ausführbare Datei init übergeben werden. Sie können das Skript also nicht unbeaufsichtigt aufrufen .2. Legen Sie das Skript auf die Startpartition
Speichern Sie Folgendes auf der Boot-Partition als / unbeaufsichtigt (den Namen, den Sie in die Befehlszeile eingegeben haben):
Dieses Skript führt einige notwendige Vorbereitungen durch (Kapitel 1), dann alles, was Sie tun möchten (2) und dann bereinigen und neu starten (3). Ersetzen Sie das Zeug unter 2 durch die Befehle, die Sie ausführen möchten.
Für einige Konfigurationsaufgaben benötigen Sie wahrscheinlich einen normalen Start, um Netzwerk- und andere Dienste aufzurufen. Daher bereitet das Beispiel in dieser Version (siehe unten) nur die Ausführung eines geeigneten Skripts vor, wenn der Pi neu gestartet wird.
3. Legen Sie alle anderen Dateien, die Ihr Skript benötigt, auf der Startpartition ab
...offensichtlich.
Beispiel
Zusammen mit meinem Skript habe ich einen Ordner payload / auf die Boot-Partition gelegt, der die Dateien enthält, die ich auf die Linux-Partition verschieben möchte. In dem oben unbeaufsichtigten Skript
Dieses Skript nimmt verschiedene Anpassungen vor, die mir gefallen: Es erstellt und formatiert eine andere FAT32-Partition und fügt sie zu / etc / fstab hinzu, damit der pi-Benutzer darauf schreiben kann (für Anwendungsprotokolle usw.); Ändert die Größe der ext4-Partition und des Dateisystems auf den Rest der SD-Karte. ändert das Gebietsschema, die Zeitzone, den Hostnamen (basierend auf der Seriennummer der CPU) und das WLAN-Land; Legt das WiFi-Netzwerk und die Passphrase fest. schaltet SSH ein; behebt ein Problem mit den Spracheinstellungen für SSH-Sitzungen; Konfiguriert das Booten in einer Konsole ohne automatische Anmeldung. schreibt einige Daten über das System in eine Datei auf der Boot-Partition; und natürlich wird dieser Symlink entfernt, damit er beim Booten nicht erneut ausgeführt wird.
Die meisten Benutzer werden dies für unnötig halten und bevorzugen die Verwendung von PiBakery , pi-init2 oder einem benutzerdefinierten ext4-Image, die großartige Lösungen darstellen. Ich bevorzuge dies, weil ich es vollständig verstehen kann und keine andere Software ausführen muss. Und es funktioniert auch: Mit der IMG- Datei, in die ich meine Skripte eingefügt habe, dauert es 6 Minuten, eine SD-Karte zu flashen + in einen Pi zu legen + sie laufen zu lassen, um sich selbst zu konfigurieren.
Quelle Ich fand die Idee eines Skripts als
init=
Kernel-Argument und diemount
Befehle, die erforderlich sind, damit es funktioniert, im Skript init_resize.sh , das standardmäßig ausgeführt wird, um die Größe der Linux-Partition zu ändern.quelle
Ich würde nicht empfehlen, irgendetwas im Boot-Bereich (außer
config.txt
) zu berühren, es sei denn, Sie haben ein detailliertes Verständnis dafür, was das Zeug tut.cmdline.txt
ist nicht dafür ausgelegt, Dinge auszuführen, wenn das RPi startet. Es wird verwendet, um Parameter beim Booten an den Linux-Kernel zu übergeben.Ich würde vorschlagen, dies alles über SSH zu tun. Ein Skript auf Ihrem Desktop kann ein bash / python / java / c / any-Programm auf das RPi übertragen, ausführen und dann löschen, wenn es fertig ist. Wenn Sie dem Skript auf Ihrem Desktop Threading hinzufügen, können Sie es gleichzeitig an beliebig viele Geräte senden.
quelle
Wenn Sie das Image so ändern können, dass beim ersten Start ein Skript automatisch ausgeführt wird, können Sie das Image einfach so ändern, wie es Ihr Skript tun würde, und diese SD-Karte dann in einer Image-Datei speichern und zum Flashen verwenden SD-Karten, die Sie mit neuen RPis verwenden werden. Wenn Sie beispielsweise möchten, dass alle Ihre RPis einen bestimmten Eintrag in haben
/etc/fstab
, können Sie sich einfach/etc/fstab
selbst ändern , anstatt ein Skript zu schreiben, das die Änderung vornimmt .Wenn Sie unbedingt Skript - Aktionen benötigen (zB wenn jedes Bild sollte in einer anderen Art und Weise modifiziert werden), könnten Sie Ihre bewegen
/etc/rc.local
zu/etc/rc.bak
und ein Skript setzen in/etc/rc.local
dem sich mit ersetzt/etc/rc.bak
in den letzten Befehl. Dieses Skript kann die ersten Startaktionen selbst ausführen oder ein bestimmtes Skript von der/boot
Partition aus aufrufen, wenn Sie dies bevorzugen.Es ist möglich, eine automatische Ausführung
/boot
durchzuführen, indem nur die Partition berührt wird , indem dem Kernel ein spezielles Boot-Ramdisk-Image bereitgestellt wird, wie hier beschrieben . Dieses Image würde die Skripte enthalten, um die Root-Partition zu ändern und dann selbst zu löschenconfig.txt
. Ich bin mir nicht sicher, ob es die Mühe wert ist.quelle
Vielleicht möchten Sie sich mein Projekt Nard ansehen, das eine Lösung für Ihr Problem bietet:
1) Jeder SD-Karte kann mit einem normalen Windows-PC eine eindeutige ID zugewiesen werden, wie hier beschrieben:
http://www.arbetsmyra.dyndns.org/nard/#devsettingsid
2) Schalten Sie alle Ihre Pis ein
3) Deaktivieren Sie nach Möglichkeit die PC-Firewall
4) Öffnen Sie ein DOS-Eingabeaufforderungsfenster und pingen Sie die Subnetz-Broadcast-Adresse an
5) Listen Sie die ARP-Tabelle mit dem Windows-Befehl "arp -a" auf. In der Liste finden Sie die MAC- und IP-Adressen aller in der Nähe befindlichen Raspberry Pi.
6) Stellen Sie mit Telnet eine Verbindung zu jedem Gerät her (normalerweise auch unter Windows verfügbar). Die Begrüßungsphrase zeigt die in Schritt 1 zugewiesene ID an.
quelle