Benutzerdefinierte Wiederherstellungspartition

9

Ich arbeite an einem Projekt, bei dem Upgrades auf den Raspberry PI über HTTP durchgeführt werden und auf den Raspberry PI nicht direkt zugegriffen werden kann (nicht nur Karten austauschen können).

Ich hätte gerne eine Partition wie folgt eingerichtet:

  • Partition 1- / boot (enthält Kernel für beide Partitionen)
  • Partition 2- / (Wiederherstellungspartition)
  • Partition 3- / (primäre Partition)

Wenn ein Upgrade fehlschlägt und der Raspberry PI in eine Neustartschleife gerät oder beim Booten hängen bleibt, möchte ich, dass der Benutzer eine Taste drücken kann, die eine GPIO-Leitung auslöst, wodurch der Bootloader in die startet Wiederherstellungspartition anstelle der primären Partition.

Die Wiederherstellungspartition würde niemals aktualisiert werden, daher wäre dies sicher.

Ich sehe einige Optionen:

  1. Starten Sie immer die Wiederherstellungspartition, überprüfen Sie GPIO und starten Sie dann die primäre Partition, ohne dass eine Taste gedrückt wurde
  2. GPIO wird direkt vom Bootloader überprüft

Ich versuche im Grunde, etwas Ähnliches wie Router zu tun. Wenn Sie beim Booten das Zurücksetzen gedrückt halten, können Sie über ein neues Image oder etwas anderes TFTP-fähig machen.

Ist das mit dem Raspberry PI möglich? Wenn ja, gibt es eine Dokumentation dafür?

Bearbeiten:

Ich habe diese Antwort auf diese verwandte Frage gefunden: Ist es möglich, von der SD-Karte aus doppelt zu booten?

Ein Kommentar zu der obigen Frage führte mich hierher: http://www.berryterminal.com/doku.php/berryboot . Das sieht vielversprechend aus, aber ich muss es genauer untersuchen, um zu sehen, ob ich einen GPIO daraus lesen kann. Wenn jemand Erfahrung damit hat, wäre ich sehr interessiert.

Beatgammit
quelle
Lassen Sie uns wissen, wie Sie damit
umgehen
1
Ich glaube, ich habe einen Weg gefunden, dies zu erreichen, indem ich einen einfachen Bootloader der zweiten Stufe geschrieben habe. Deshalb werde ich ihn hier dokumentieren, wenn ich dazu komme.
Ich
1
Leider nein, aber ich habe die Wahrscheinlichkeit einer Beschädigung mithilfe eines RO-Dateisystems erheblich verringert: /boot(RO), /(RO), /var(RW), /home(RW). Das anfängliche Problem war eine Beschädigung des Dateisystems, wenn die Stromversorgung während des Startvorgangs unterbrochen wird. Ich würde trotzdem gerne einen Bootloader der 2. Stufe schreiben / finden.
Beatgammit
1
Sie können sich ansehen, was der NOOBS- Bootloader ( raspberrypi.org/archives/4100 ) für den Pi tut. Es könnte tatsächlich zu Ihren Zwecken passen, nur um es zu verwenden, da es Wiederherstellungspartitionen und Installation vorsieht.
Fred
1
Ich schlage vor, mit einem benutzerdefinierten Bootloader dagegen zu sein, verwende jedoch Hacks, die nach dem Start des Systems ausgeführt werden. Die Implementierung ist einfacher und das Debuggen sicherer. Ein fehlerhafter Bootloader kann Ihren Pi braten.
Maxthon Chan

Antworten:

5

Wenn der Fehler jederzeit nach dem Systemstart auftreten kann, können Sie einen Watchdog-Timer und ein Boot-Skript verwenden.

Das Prinzip dieser Methode besteht darin, dass das System bei jedem Neustart ohne ordnungsgemäßes Herunterfahren zur Wiederherstellungspartition wechselt.

Sie müssen ein Skript schreiben, das jedes Mal ausgeführt wird, wenn das System gestartet und ordnungsgemäß heruntergefahren wird. Wechseln Sie /boot/cmdline.txtbeim Starten des Systems zur Wiederherstellungspartition und wechseln Sie zurück, bevor Sie das System ordnungsgemäß herunterfahren.

Stellen Sie dann den Watchdog-Timer ein. Sie können die im BCM2835-Chip integrierte verwenden oder (bei Verwendung einer Revision 2-Karte) Ihre eigene mit zwei GPIO-Pins, dem Reset-Header P6 und einem 555-Chip, erstellen. Wenn das kritische Programm gestartet wird, starten Sie den Watchdog-Timer und treten Sie den Hund regelmäßig, wenn das System ordnungsgemäß funktioniert. Wenn das System ausfällt, wird der Watchdog-Timer ausgelöst und der Prozessor zurückgesetzt und an die Wiederherstellungspartition gesendet. Dies erfordert auch keine Benutzerinteraktion und bei Verwendung des integrierten Timers kein GPIO.

Mit dieser Methode können Sie auch eine Schaltfläche zum Zurücksetzen implementieren, die garantiert, dass das System manuell auf einer Rev. 2-Karte zur Wiederherstellung gesendet wird, indem eine Schaltfläche im P6-Header installiert wird.

Maxthon Chan
quelle
Ihre erste Antwort ist etwas näher an dem, was ich wahrscheinlich tun würde, aber ich mag die Idee, GPIOs im Userspace und in einem Watchdog zu verwenden. Während ich wahrscheinlich keine der Ideen im Großhandel verwenden werde, haben Sie mir einige gute Ideen gegeben. Vielen Dank!
Beatgammit
1

Ich habe eine Möglichkeit, dies zu tun, ohne den Kernel zu hacken, bei der das System vor einem vorzeitigen Neustart geschützt wird:

  1. Laden Sie das Upgrade-Image herunter, prüfen Sie es und erweitern Sie es in den Arbeitsbereich.
  2. Ändern Sie /boot/cmdline.txt so, dass beim nächsten Systemstart die Wiederherstellungspartition als Root-Block-Gerät verwendet wird.
  3. Installieren Sie das Upgrade vom Arbeitsbereich und stellen Sie sicher, dass es funktioniert.
  4. Wenn das Upgrade funktioniert, ändern Sie /boot/cmdline.txt zurück.
  5. Starten Sie bei Bedarf neu.

Ein fehlgeschlagenes Upgrade führt dazu, dass das System automatisch bei der Wiederherstellung gestartet wird. Kein GPIO erforderlich.

Maxthon Chan
quelle
Das einzige Problem hierbei ist (je nach System), dass ein Fehler möglicherweise Stunden nach Abschluss des Updates erkannt wird. Zu diesem Zeitpunkt hat der Benutzer keine Möglichkeit, zur Wiederherstellungspartition zurückzukehren.
1
@DanNixon Ich poste eine weitere Antwort, um dieses neue Problem zu beheben.
Maxthon Chan
1

Es gibt auch eine dritte mögliche Lösung, aber Sie müssen initrdeinige PC-Versionen der Linux-Distribution analysieren, um herauszufinden, wie der Syscall pivot_init()funktioniert. Ich bin nicht sicher, ob der Kernel von Pi diesen Systemaufruf hat. Wenn dies der Fall ist, ist diese Methode möglich, es ist auch kein Kernel-Hack erforderlich und es wird ein GPIO verwendet.

Dazu müssen Sie ein benutzerdefiniertes initProgramm in das Produktionssystem schreiben . Überprüfen Sie, ob der GPIO eingeschaltet ist. Wenn ja, pivot_root()zur Wiederherstellung. Dann exec()das Original, initdamit das System weiter bootet. Sie können im Produktionssystem einen Weg finden, um diese GPIO-Überwachung initneben dem Original init(PID = 1) laufen zu lassen (PID = 2 ) und das GPIO im Auge zu behalten und neu zu starten, um die Wiederherstellung durchzuführen, wenn Die Taste wird gedrückt.

Maxthon Chan
quelle