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.
init=/bin/bash
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:
sudo losetup /dev/loop0 /tmp/gw.img -o 62914560
sudo mount /dev/loop0 /mnt
sudo cp /my/superduper/script.sh /mnt
sudo umount /dev/loop0
sudo fsck -f /dev/loop0 # This is optional
sudo losetup -d /dev/loop0
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.