STM32 Bootloader: So stellen Sie sicher, dass nur unbeschädigte Firmware bootet

Ich habe ein benutzerdefiniertes Board mit einem STM32F407 darauf. Da SWD nicht verfügbar ist, muss ich den Mikrocontroller über den UART-Bootloader programmieren.

Stellen Sie sich vor, dass die folgende Abfolge von Ereignissen stattfindet. Ich ziehe den BOOT0Pin hoch und nach dem Reset betritt der Mikrocontroller den Bootloader. Auf meine Aufforderung hin löscht der Bootloader den Flash des Mikrocontrollers. Ich gehe davon aus, dass jetzt alle Wörter im Gedächtnis sind 0xffffffff. Dann sende ich eine Folge von Schreibbefehlen, um den Flash zu schreiben, beginnend mit dem ersten Byte meines Firmware-Images und fortgesetzt bis zum letzten.

Wenn irgendwo in diesem Prozess der Strom ausfällt oder die Kommunikation unterbrochen wird, habe ich einen Mikrocontroller, der ein ungültiges Programm-Image im Flash hat. Wenn der Mikrocontroller anschließend wieder eingeschaltet wird, um BOOT0die Anwendung auszuführen, führt er eine im Wesentlichen beschädigte Firmware aus. Je nach Programmverhalten und angeschlossener Hardware können die Ergebnisse katastrophal sein.

Ich kann keine Unterstützung finden, um den Firmware-Start zu verhindern, wenn ein beschädigtes Image im STM32F407 vorhanden ist. Funktionierende Mechanismen könnten eine CRC-Prüfung sein, bevor die CPU zur Firmware springt, oder ein „Firmware-Startup sperren“-Bit im Flash, das beim Löschen zuerst gesetzt (gelöscht) und zuletzt im Aktualisierungsprozess gelöscht (0 geschrieben) wird. Allerdings finde ich keine derartigen Bestimmungen in der Hardware.

  • Schreiben Sie einen benutzerdefinierten Bootloader in Flash, der einmal programmiert werden muss. Die Reset-Vektoren sind so eingestellt, dass sie immer zum benutzerdefinierten Bootloader springen. Dieser prüft das Vorhandensein und verifiziert die Integrität der Firmware. Zu diesem Zweck muss die Firmware Größen- und Prüfsummeninformationen an einer Stelle enthalten, die dem benutzerdefinierten Bootloader bekannt ist. Diese Lösung hat den offensichtlichen Nachteil, dass ich diesen benutzerdefinierten Bootloader besorgen muss – ihn selbst schreiben oder etwas Vorhandenes anpassen – und dass der benutzerdefinierte Bootloader zuerst während der Produktion geladen werden muss.
  • Nehmen Sie an, dass ein gelöschter Flash zu einem Einfrieren des Prozessors führt. Ich bin noch nicht so überzeugt, dass das Booten in einen gelöschten Flash schnell zum Absturz führt. Selbst wenn der Prozessor beim Booten der Firmware hängen bleibt, kann ich den Bootloader immer noch aktivieren, indem ich /RSTniedrig, BOOT0hoch und dann loslasse /RST. Während der Aktualisierung wird nach dem Löschen die Firmware geschrieben, beginnend direkt nach dem anfänglichen SP/anfänglichen PC-Reset-Vektorpaar. Als letzter Schritt des Updates werden die initialen PC/SP in die ersten beiden 32-Bit-Worte des Flashs geschrieben. Das kritische Fenster ist jetzt nur noch das Schreiben dieser beiden Wörter, was die Ausfallwahrscheinlichkeit um Größenordnungen verringert.

Was sind sinnvolle Strategien, um mit dem angegebenen Problem umzugehen? Sind die oben vorgestellten Optionen realisierbar?

Fügen Sie einen selbst codierten persistenten L1-Bootloader hinzu, der die Integritätsprüfung implementiert.
Außerdem sieht es so aus, als hätte der STM32-Bootloader den Befehl "Get", mit dem Sie die Daten zurücklesen können, sodass Sie die Überprüfung des Programmierhosts implementieren können.
Danke, diese Lösung ist die erste in meiner Aufzählungsliste in der Frage. Kennen Sie Open-Source-Bootloader für die STM32-Familie, die hier gut passen würden?
Leider reicht es nicht aus, den Inhalt zu überprüfen. Beachten Sie Folgendes: Während des Updates wird die Stromversorgung unterbrochen. Der Mikrocontroller hat jetzt eine unvollständige Firmware. Wenn es das nächste Mal gestartet werden darf, wird es von einem beschädigten Firmware-Image ausgeführt.
Was ist Ihr katastrophales Ergebnis und unter welchen Umständen aktualisieren Sie die Firmware?
Der Mikrocontroller ist für die Steuerung von Hochleistungsmaschinen zuständig. Das katastrophale Ergebnis ist, dass diese Maschinerie als Folge einer beschädigten Firmware läuft, was zu Verletzungen oder Tod führt. Auf Benutzerwunsch kann die Firmware im Rahmen eines Softwareupdates des umschließenden Systems aktualisiert werden.
STM32 ist im Allgemeinen nicht für sicherheitskritische Anwendungen geeignet. electronic.stackexchange.com/questions/427067/…
Dann benötigen Sie unbedingt mindestens den Bootloader, der eine CRC-Prüfung durchführt, da es andere Fehlerquellen als ein fehlgeschlagenes Update geben kann.

Antworten (2)

Das Booten in einen gelöschten Flash führt schnell zum Absturz

Dies kann passieren oder auch nicht – je nachdem, was geschrieben wurde und was nicht. Beachten Sie, dass abhängig davon, wie der Flash aktualisiert wird und wann, möglicherweise keine gelöschte Flash-Seite vorhanden ist – nur einige mit neuen und einige mit alten Daten.

anfänglicher PC/SP [...] Das kritische Fenster ist jetzt nur noch das Schreiben dieser beiden Wörter

Stimmt, aber es besteht immer noch die Möglichkeit eines Ausfalls - nicht gut genug für sicherheitskritische Anwendungen.

Beachten Sie, dass Benutzer versucht sein könnten, ein Standard-STM32-Flashing-Tool anstelle Ihrer Software zu verwenden - es würde mit dem ROM-Bootloader gut funktionieren, aber Ihre Migrationen vollständig zunichte machen.

Schreiben Sie einen benutzerdefinierten Bootloader in Flash

Ich empfehle diesen Ansatz dringend, wenn die Ergebnisse unter Fehlerbedingungen katastrophal sein könnten.

Ihre erste Option ist trivial, die Zeit, die Sie hier bisher auf eine Antwort gewartet haben, hätte ungefähr 30 verschiedene Bootloader schreiben können. Sie haben bereits die Frage beantwortet, ob Sie den einmal programmierten Bootloader einfach einen CRC ausführen lassen könnten, wenn Sie die Zeit haben, oder eine Prüfsumme, wenn Sie es eilig haben, und ihn entweder verwenden oder nicht. Handvoll Code, Minuten zum Schreiben. Nun, wenn nicht, okay, das könnte ein Forschungsprojekt oder zumindest einige Experimente sein, die ziemlich sicher sind, dass ST dokumentiert, wie der Bootloader gestartet wird, sollte so einfach sein wie eine Verzweigung zu einer hohen Adresse oder eher das Lesen der magischen hohen Adresse plus 4 und bx to diese Adresse. (Dann sind Sie im Werks-Bootloader und müssen keinen schreiben/ersetzen).

Das Erstellen Ihres eigenen uart-basierten Bootloaders ist nicht schwierig, in etwa 30-50 Codezeilen, vielleicht ein paar Handvoll mehr. Ich habe XMODEM-, SREC- und IHEX-basierte geschrieben, die einfach da sitzen und darauf warten, dass Sie Firmware herunterladen, muss nicht komplizierter sein als das. kann eine haben, die Sie zu einer Protokolladresse machen, Daten mit einem Rahmen wie srec/ihex, aber vielleicht anders. eine weitere halbe Stunde bis eine Stunde Entwicklung (zuzüglich der Zeit, um zu lernen, wie man in der Anwendung flasht, was ziemlich einfach ist, denke ich, dass st es buchstabiert).

Wenn Sie Ihren eigenen Loader schreiben möchten, der flashen kann, dann möchten Sie entweder ein Dual-Banking-Gerät und der Checker/Loader befindet sich in einer Bank und die Anwendung in der anderen. Oder Sie machen den Lader zum Trampolin rammen. Ich bin mir ziemlich sicher, dass die Löschgröße auf diesen Teilen nur einen Bruchteil des gesamten Flashs ausmacht, sodass Sie auch ohne einen Dual-Banking-Flash Trampolin springen und das löschen könnten, was Sie nur als Anwendungsbereich definiert haben.

Sie könnten den niedrigsten Löschblock so einrichten, dass die Vektortabelle mit Reset auf den Boot-Checker zeigt, Sie könnten Ihre Anwendung ab dem nächsten Löschblock live schalten, wenn dies Platz für den Boot-Checker lässt, um im Laufe der Zeit zu wachsen. Ich gehe davon aus, dass Sie die VTOR-Steuerung haben, sodass Sie sich nicht mit den anderen Vektoren herumschlagen müssen, sondern sie in einer Endlosschleife im Checker enden lassen.

Nun, das schnelle und schmutzige, nichts davon tun zu müssen, bietet immer noch ein gewisses Risiko, aber weniger. Wenn das vordere Ende der Vektortabelle gelöscht wird und der Bootloader aufgerufen wird, sollten Sie dies bereits mit jungfräulichen Teilen gesehen haben, dass Sie boot0 nicht mit einem neuen Teil bestätigen müssen. Ich denke, es sind nur die ersten vier Wörter, aber Sie können das experimentell herausfinden. Wenn Sie also neue Firmware herunterladen, ändern Sie Ihr Programm so, dass es zuerst den ersten Block mit der Vektortabelle löscht, was Sie wahrscheinlich bereits tun, aber schreiben Sie diesen Block zuletzt, löschen und schreiben Sie den Rest der Anwendung, schreiben Sie den ersten Block zuletzt und nur diesen Zeitraum Zeit besteht die Gefahr eines Stromausfalls, eines Resets oder eines anderen Ereignisses, das ein beschädigtes Bild verursacht.

Endlich könnten Sie perfekten Code schreiben, der niemals ein Firmware-Update benötigt ... grins ... das würde es lösen ...

Dies sind COTS-Teile, also wie erwähnt nicht sicherheitskritisch. Aber Sie könnten ein paar Stunden dieser zusätzlichen Anstrengung investieren, um einigen zu helfen.

Dies bedeutet nicht unbedingt, dass, wenn Sie die Stromversorgung verlieren oder zum richtigen Zeitpunkt zurücksetzen, das Teil Ihren Backup-Bootloader nicht beschädigt oder löscht, dass Sie die Flash-Handbücher nicht so genau gelesen haben, aber wissen, dass einige Eeproms früher so funktionierten, wenn Sie genau richtig ausgeschaltet haben oder zeitgesteuerte Dinge genau richtig, könnten Sie Daten verlieren. Das Testen würde nicht beweisen, dass es niemals eine Möglichkeit gibt, aber Sie könnten eine Testvorrichtung einrichten, um ein Herunterladen/Löschen zu starten und das Teil zu einem zufälligen Zeitpunkt auszuschalten, wiederholen Sie es. Wiederholen Sie kurz die angegebene Anzahl von Blitzzyklen für das Teil. Überprüfen Sie jedes Mal, ob der Boot-Checker gestartet wurde und funktionierte (oder die Anwendung). allenfalls ein warmes wuscheliges Gefühl, aber kein Beweis.