Warum benötigen wir in Mikrocontrollern einen Bootloader, der von unserem Anwendungsprogramm getrennt ist?

28

Warum benötigen wir ein separates Programm im selben Flash-Programmspeicher eines Mikrocontrollers, insbesondere STM32F103, der als Bootloader bezeichnet wird?

Was ist das Besondere daran, es vom Hauptanwendungsprogramm getrennt zu halten?

Erledigt ein Bootloader eines mikroprozessorbasierten Systems (z. B. PowerPC MPC8270) im Allgemeinen die gleiche Aufgabe wie ein Mikrocontroller (z. B. ARM STM32F103) oder erledigt er grundsätzlich verschiedene Aufgaben, und dennoch werden beide als "Bootloader" bezeichnet? ?

Alt-Rose
quelle
2
Aus dem gleichen Grund haben Sie einzelne Chips und Teile und keine einzige riesige monolithische Struktur
Emobe
Das tust du nicht. Geben Sie einfach Ihr Programm mit den Schaltern und Leuchten an der Computerkonsole ein.
Hot Licks
1
Streng genommen benötigen Sie kein separates Bootloader-Programm auf einem Mikrocontroller. Am häufigsten entscheiden wir uns jedoch für eine zusätzliche Utility-Funktion. Wenn diese Funktionen nicht benötigt werden, können Sie den Bootloader entfernen. Der Mikrocontroller-Bootloader wird normalerweise verwendet, um ein neues Programm in Flash zu brennen. Es kann manchmal für Debugging-Funktionen, einige Support-Breakpoints und andere nützliche Funktionen verwendet werden. Auf einem Mikrocomputer lädt der Bootloader normalerweise Programme aus dem Massenspeicher und wird dort benötigt.
Ghellquist

Antworten:

55

Ein Bootloader auf einem Mikrocontroller ist für die Aktualisierung der Hauptfirmware über einen anderen Kommunikationskanal als den Programmierheader verantwortlich. Dies ist nützlich, um Firmware im Feld über BLE, UART, I2C, SD-Karten, USB usw. zu aktualisieren. Es wäre äußerst unpraktisch, wenn Kunden Programmierer kaufen müssten, um die Firmware auf ihren Geräten zu aktualisieren.

Der Grund, warum der Bootloader getrennt gehalten wird, liegt in der Zuverlässigkeit. Der Bootloader und der Anwendungscode befinden sich in separaten Abschnitten von Flash, sodass der Anwendungscode vom Bootloader gelöscht und neu geschrieben werden kann, ohne dass Änderungen am Bootloader-Code vorgenommen werden müssen.

Wenn der Bootloader und die Anwendung zusammengehalten würden, müsste der Bootloader-Code in den Arbeitsspeicher kopiert werden, bevor er ausgeführt werden kann, da bei einem Firmware-Update der Bootloader-Code in Flash gelöscht wird. Wenn die Stromversorgung mit dem Bootloader-Code im RAM unterbrochen und der Flash gelöscht würde, wäre das Gerät blockiert.

CurtisHx
quelle
3
Unser Grund ist derselbe. Sie befinden sich im selben Flash, aber der Bootloader ist auf Flash-Löschvorgänge ausgerichtet und intelligent genug, um nur den Flash zu löschen, der höher ist als seine eigenen Adressen.
Joshua
3
In einigen Fällen ist der Programmier-Header des Mikroprozessors möglicherweise tatsächlich nicht zugänglich, ohne dass das Gehäuse des Produkts demontiert werden muss. Daher ist die Neuprogrammierung über den Kommunikationsbus ohne zusätzliche Hardware ein Schlüsselfaktor für die Zuverlässigkeit.
John Go-Soco
6
@ alt-rose Der Bootloader und das Anwendungsprogramm sind separat kompilierte Programme mit jeweils eigenem Startcode und eigener main()Funktion. Beim Einschalten wird der Bootloader-Startcode ausgeführt und der Bootloader aufgerufen main(). Das Bootloader-Programm sucht nach einem gültigen Anwendungsprogramm und springt dann zum Startcode des Anwendungsprogramms, der das Anwendungsprogramm aufruft main(). Der Startcode jedes Programms initialisiert die C-Laufzeitumgebung für das jeweilige Programm (dh Variablen, Stapel usw. initialisieren), und in der Regel main()kehrt keines der Programme jemals zum Startcode zurück.
kkrambo
1
@ alt-rose: Genauso wie die CPU die Startadresse des Bootloaders erhält - nicht. Stattdessen gibt die CPU an, was sie als Startadresse des Bootloaders verwendet, und der Bootloader gibt an, was sie als Startadresse des Anwendungsprogramms verwendet.
MSalters
4
@kkrambo Obwohl dies im Allgemeinen zutrifft, gibt es keine Anforderung (und auch keine allgemeingültige Tatsache), dass ein Bootloader in C oder einer von C abgeleiteten Sprache mit einem mainüberhaupt geschrieben sein muss.
Yakk
26
  1. Damit sich der Ladevorgang von Fehlern erholen kann. Angenommen, während eines Upgrades liegt ein Kommunikationsfehler vor oder die Stromversorgung wird unterbrochen. Wenn der Bootloader Teil der Anwendung wäre, für die Sie ein Upgrade durchgeführt haben, könnte der Benutzer es nicht erneut versuchen, ohne spezielle Hardware einen Neustart des Bootloaders durchzuführen.

  2. Einige Mikrocontroller können keinen Code aus dem RAM ausführen. Wenn der Bootloader mit dem Rest der Software gemischt wäre, könnten Sie Ihre Software nicht aktualisieren, da Sie keine Flash-Seiten löschen können, die Sie gerade ausführen. Die Lösung besteht darin, zuerst den neuen Code in die zweite Hälfte des Flash zu brennen und dann dorthin zu springen. Der neue Code kopiert sich dann in die erste Hälfte des Flashs. Der Nachteil ist natürlich, dass das Brennen von Blitzlicht normalerweise langsam ist und dass der Ladevorgang jetzt, da Sie es zweimal ausführen müssen, möglicherweise bis zu doppelt so lange dauert. Durch diese Problemumgehung wird die Anwendungsgröße auf nicht mehr als die Hälfte des Gesamtblitzes begrenzt.

  3. Gut geschriebene Bootloader versuchen zu überprüfen, ob auf dem Gerät gültiger Code vorhanden ist, bevor sie versuchen, ihn auszuführen. Wenn der Bootloader und anderer Code gemischt würden, wie könnten Sie dann sicher sein, dass Ihre Validierungsroutine funktioniert, wenn nicht der gesamte Code geladen würde?

  4. Authentifizierung. Sichere Bootloader versuchen zu überprüfen, ob die geladene Anwendung mit einer digitalen Signatur übereinstimmt, bevor sie ausgeführt werden. Wenn der Bootloader und anderer Code jedoch gemischt wurden, können Sie nicht steuern, was auf dem Gerät ausgeführt wird, da Sie nach dem Laden des neuen Codes nicht steuern können, was beim Start geschieht.

user4574
quelle
4
Als Beispiel für Punkt 2, könnten einige Mikrocontroller nicht einmal haben zugänglich RAM beim Start: zum Beispiel des Raspberry Pi nutzt seine GPU den Bootloader von einer SD - Karte zu laden, die dann den ARM - Prozessor und Speicher ermöglicht.
ErikF
11

Sie sind in der Regel vorhanden, damit Sie Ihr Hauptanwendungsprogramm aktualisieren können.

Sie benötigen einen Code, der weiß, wie man einen Teil des internen Flashs löscht und neu programmiert. Dies kann nicht das Hauptprogramm sein, da es nicht neu programmiert werden kann, wenn es selbst gelöscht wird.

Colin
quelle
9

Der Bootloader ermöglicht es der MCU, mit etwas anderem zu kommunizieren, um ein neues Programm anzunehmen, es zu speichern und es nach einem Reset auszuführen. Wenn Sie keinen Bootloader hatten, benötigen Sie einen Programmer, um auf den Speicher zuzugreifen und das Programm zu installieren.

Kreuzung
quelle
2
Das wars so ziemlich. Die MCU kann Code nur über ein spezielles Programmiersubsystem (wie AVRICE oder JTAG) abrufen oder wenn bereits ein Bootloader in Flash vorhanden ist. Es ist eine Anwendungsentscheidung, wie komplex der Bootloader ist, z. B. können einige Systeme Code aus WiFi laden. Bei sehr Low-End-MCUs wie einem ATTiny sind ein Bootloader (und serielle Pins) ein großer Aufwand, sodass Sie immer einen Programmierer verwenden.
Rich
7

Neben den anderen korrekten Antworten zum Ermöglichen der Neuprogrammierung der Hauptfirmware vom Bootloader besteht ein weiterer Vorteil der Trennung des Bootloaders darin, dass Sie die Aufgaben "Einmal beim Booten ausführen" logisch von dem Code trennen können, den Sie zur Laufzeit benötigen. Nachdem der Bootloader seine anfänglichen Konfigurationsaufgaben abgeschlossen hat, kann die Hauptfirmware den Bootloader mit dem gesamten nicht mehr benötigten Code aus dem Speicher entfernen, wodurch erheblicher RAM-Speicherplatz gespart wird. Es ist möglich, dies auf andere Weise zu erreichen, aber die Aufteilung zwischen Bootloader und Firmware erleichtert es vielen Architekturen erheblich.

Nate S - Setzen Sie Monica wieder ein
quelle
1
Auf einem Mikrocontroller befindet sich der Code höchstwahrscheinlich nie im RAM, sodass er nicht entfernt werden kann. Sie können die Daten des Bootloaders natürlich aus dem RAM löschen.
Ben Voigt
@BenVoigt, es kommt auf den Mikrocontroller an. Bei einigen (in erster Linie bei denen mit NOR-Flash) können Sie direkt ohne Flash ausführen, bei anderen (in der Regel mit NAND-Flash, das immer häufiger verwendet wird) müssen Sie jedoch ohne RAM arbeiten. Manchmal ist nicht einmal ein Flash an Bord, und Sie müssen den Code von einem externen Flash-Chip in den lokalen SRAM kopieren, bevor Sie etwas ausführen können.
Nate S - Setzen Sie Monica
2

Die kurze Antwort ist, weil Software fantastisch ist.

Sie könnten alles haben, was der Bootloader "reine Hardware" macht. Aber es ist weitaus einfacher, die Aufgaben zu haben, die der Bootloader als Software schreibt und dann von der Hardware interpretiert.

Diese Aufgaben können das Einrichten der Hardware für die Ausführung der "echten" Software (z. B. auf einem Raspberry Pi (über @ErikF)) mit einem Protokoll zum Ersetzen des "echten" Programms vor dessen Ausführung umfassen (überprüfen Sie eine PIN, falls zutreffend) Dieser Pin wird gesetzt, dann wird das reale Programm neu gestartet oder sogar die Softwareumgebung für das "echte" Programm eingerichtet.

Wenn Sie eine ausführbare Datei ausführen, die vom Anwendungsladeprogramm verschoben wird, werden in einer Software mit geringerem Umfang beispielsweise Teile Ihrer Daten in den Arbeitsspeicher geladen, manchmal Adressen repariert, Argumente für Haupt- oder andere globale Aufgaben erstellt, die vom Betriebssystem bereitgestellten Bibliotheken werden hochgefahren springt dann an den Anfang des _mainCodes. Einige dieser Dinge können mit einem Bootloader erledigt werden.

In einem Mikrocontroller können einige der Aufgaben, die ein Bootloader ausführt, in das Programm aufgeteilt werden. Der Compiler für Ihre Plattform könnte den "Setup" -Code automatisch in jede ausführbare Datei einfügen.

Das Vorhandensein im Bootloader bedeutet jedoch, dass derselbe Compiler möglicherweise auf unterschiedlicher Hardware ausgeführt wird, da der Bootloader den Unterschied zwischen den Plattformen "verbergen" kann.

Hinzu kommt die Tatsache, dass ein Flash des Hauptprogramms den Bootloader nicht gefährdet (und die Fähigkeit, das Hauptprogramm zu reflashen), und ein nicht-trivialer Bootloader ist eine großartige Sache.

Yakk
quelle
-1

Eine Antwort, die nicht behandelt wurde, ist die Notwendigkeit der Trennung von Bedenken aufgrund der Einschränkungen der C-Sprache.

Im Allgemeinen werden Bootloader in einer Mischung aus Assembly und C geschrieben, wobei die Bootphase in Assembly sehr früh beginnt.

Dies geschieht, um bestimmte Dinge einzurichten, wie:

  • Zuweisen des C-Stacks
  • Lesen des Stapelzeigers in das Register
  • Lesen des Programmzählers in das Register
  • Reset-Vektoren deklarieren
  • Laden der zweiten Stufe (initramfs) in den RAM.

Dies ist eine sehr grobe Annäherung an die durchgeführten Schritte, und ich beschreibe den ARM-Startvorgang. Für x86 und andere Architekturen ist dies wieder anders.

Der Hauptgrund bleibt jedoch derselbe: Die Zuweisung des C-Stacks muss von der Baugruppe aus erfolgen.

BitShift
quelle
Warum die Gegenstimme? Dies ist sowohl relevant als auch genau.
BitShift
-1

Ein Teil der Frage, der bisher nicht beantwortet wurde, ist der Unterschied zwischen Bootloadern auf Mikrocontrollern und Mikroprozessorsystemen.

Mikrocontroller

Die meisten Mikrocontroller verfügen über einen integrierten ROM-Speicher, der ihren Programmcode enthält. Das Ändern dieses Codes erfordert normalerweise ein Programmiergerät, das mit der Programmierschnittstelle des Mikrocontrollers verbunden ist (z. B. ISP auf ATMega). Diese Programmierschnittstellen sind jedoch im Vergleich zu anderen Schnittstellen in der Regel nicht sehr benutzerfreundlich, da sie im gegebenen Kontext möglicherweise nicht sofort verfügbar sind. Während zum Beispiel fast jeder Computer über USB-Anschlüsse verfügt, ist die für ISP erforderliche SPI-Schnittstelle viel seltener und andere Schnittstellen wie die PID-Schnittstelle von ATXMega werden nur von dedizierter Programmierhardware unterstützt.

Wenn Sie beispielsweise die Software von einem normalen Computer ohne externe Hardware aktualisieren möchten, können Sie einen Bootloader verwenden, der von einer anderen Art von Schnittstelle (z. B. RS232, USB oder RS232 über USB wie beim Arduino) liest, um das Gerät zu programmieren über gemeinsame Schnittstellen.

Das heißt, wenn Sie diese Funktionalität nicht benötigen, ist der Bootloader völlig optional. Der Mikrocontroller kann seinen Code immer noch vollständig ohne den Bootloader ausführen.

Mikroprozessor

Bei einem Mikroprozessor liegen die Dinge etwas anders. Während die meisten Mikroprozessoren über ein ROM verfügen, das groß genug für einen Bootloader ist, sind diese ROMs bei weitem nicht groß genug, um ein volles Betriebssystem aufzunehmen. Der Zweck des Bootloaders besteht also darin, die Hardware zu initialisieren, nach einem bootfähigen Betriebssystem zu suchen, es zu laden und auszuführen. Daher ist der Bootloader für jeden einzelnen Boot entscheidend.

Auf x86 / x64-Systemen ist dieser Bootloader entweder das BIOS oder das UEFI (im Grunde genommen eine neuere Version eines BIOS).

Manchmal können sogar mehrere Bootloader in einer Kette ausgeführt werden. Wenn Sie beispielsweise über ein Dual-Boot-System mit Windows und Linux verfügen, kann dies zu folgenden Ergebnissen führen:

  • BIOS / UEFI startet und findet GRUB installiert. Anschließend wird GRUB (= Grand Unified Bootloader) geladen.
  • GRUB findet eine Art Linux und den Windows Bootloader. Der Benutzer wählt den Windows-Bootloader aus.
  • Der Windows-Bootloader startet und findet Windows 7 und Windows 10 installiert. Der Benutzer wählt Windows 10 aus.
  • Windows 10 bootet endlich.

In diesem Fall gab es also drei Softwareteile, die als Bootloader betrachtet werden können. Sowohl GRUB als auch der Windows-Bootloader dienen hauptsächlich dazu, dem Benutzer eine komfortablere Bootauswahl zu bieten, als dies das BIOS / UEFI tun würde. Außerdem können mehrere Betriebssysteme von derselben Festplatte oder sogar derselben Partition gestartet werden.

TLDR

Während also in beiden Systemen der Bootloader etwas Ähnliches tut (was dem Benutzer bei der Auswahl des zu bootenden Codes hilft), unterscheiden sich beide stark darin, wie sie dies erreichen und was sie genau tun.

Dakkaron
quelle
Während es nützlich ist, Systeme mit genügend nichtflüchtigem Direktzugriffsspeicher (ROM oder Flash) zu unterscheiden, um das gesamte Programm von jenen zu halten, die Code aus dem RAM ausführen müssen, gibt es Mikrocontroller beider Typen und Mikroprozessoren beider Typen.
Supercat
Natürlich ist der Unterschied zwischen einem Mikrocontroller und einem Mikroprozessor keine harte Grenze, und einige Mikrocontroller verhalten sich eher wie ein Mikroprozessor und umgekehrt. Deshalb habe ich das AtMega / Arduino und das x86 / x64 als Beispiele genommen, weil sie sich so verhalten.
Dakkaron
"Mikroprozessoren verfügen über ein ROM, das groß genug für einen Bootloader ist ... Auf x86 / x64-Systemen ist dieser Bootloader entweder das BIOS oder das UEFI" Nope. BIOS oder UEFI werden im Off-Chip-Flash-Speicher gespeichert. Das On-Chip-ROM ist für Funktionen auf noch niedrigerer Ebene vorgesehen, wie z. B. die Initialisierung des Mikrocodes.
Ben Voigt
@ Dakkaron: Ich würde die Grenze zwischen einem Mikroprozessor und einem Mikrocontroller ziehen, basierend darauf, ob der Chip für nicht-triviale Zwecke verwendet werden kann, ohne dass etwas anderes auf dem Adressbus steht. Die 8031 würde nicht in Frage kommen , außer , dass es funktionell 8051 ist (das ist auf jeden Fall ein Mikrocontroller) , die nicht angegeben , etwas Sinnvolles in dem internen ROM haben, aber ansonsten aus dem internen Speicher vollständig nutzbar sein entworfen werden würde). So etwas wie ein RCA / CDP 1802 würde sich nicht qualifizieren, obwohl es zum Ansteuern eines LED-Namensschilds verwendet werden kann ...
supercat
... ohne externes RAM und ROM, da RAMless / ROMless-Designs auf einfache Aufgaben beschränkt sind. Etwas wie ein TMS 32050, das, wenn ich mich erinnere, einen Bootloader und ein paar tausend Wörter 16-Bit-RAM-Wörter intern hat, würde sich jedoch als Mikrocontroller qualifizieren; Obwohl für viele Anwendungen mehr RAM erforderlich wäre, könnte eine Verbindung über UART mit einem anderen System viele Zwecke erfüllen, ohne dass sich etwas auf dem Speicherbus befindet.
Supercat