Over-the-air-Updates implementieren

Damit OTA-Updates (Over-the-Air) implementiert werden können, muss der Bootloader während des Starts auf eine Recovery-RAM-Disk zugreifen können. Wenn auf dem Gerät ein unverändertes AOSP-Wiederherstellungsimage verwendet wird, liest der Bootloader die ersten 32 Bytes auf der Partition misc. Wenn die Daten dort mit boot-recovery übereinstimmen, wird das recovery-Image vom Bootloader gestartet. Mit dieser Methode können alle ausstehenden Wiederherstellungsarbeiten (z. B. Anwenden eines OTA oder Entfernen von Daten) abgeschlossen werden.

Details zum Inhalt eines Blocks im Flash-Speicher, der für die Kommunikation durch die Wiederherstellung und den Bootloader verwendet wird, finden Sie unter bootable/recovery/bootloader_message/bootloader_message.h.

Geräte mit A/B-Updates

Damit OTA-Updates auf Geräten, die A/B-Updates verwenden, unterstützt werden, muss der Bootloader des Geräts die folgenden Kriterien erfüllen.

Allgemeine Kriterien

  • Alle Partitionen, die über ein OTA-Update aktualisiert werden, sollten aktualisiert werden können, während das Hauptsystem gebootet wird (und nicht im Wiederherstellungsmodus).

  • Um die Partition system zu starten, übergibt der Bootloader den folgenden Wert an die Kernel-Befehlszeile: ro root=/dev/[node] rootwait init=/init.

  • Es liegt in der Verantwortung des Android-Frameworks, markBootSuccessful aus dem HAL aufzurufen. Der Bootloader sollte eine Partition niemals als erfolgreich gebootet markieren.

Unterstützung für Boot Control HAL

Der Bootloader muss das boot_control-HAL unterstützen, wie in hardware/libhardware/include/hardware/boot_control.h definiert. Der Updater fragt die Boot-Control-HAL ab, aktualisiert den nicht verwendeten Boot-Slot, ändert den aktiven Slot über die HAL und startet das Gerät mit dem aktualisierten Betriebssystem neu. Weitere Informationen finden Sie unter Boot-Control-HAL implementieren.

Unterstützung für Slots

Der Bootloader muss Funktionen für Partitionen und Slots unterstützen, darunter:

  • Partitionsnamen müssen ein Suffix enthalten, das angibt, welche Partitionen zu einem bestimmten Slot im Bootloader gehören. Für jede solche Partition gibt es eine entsprechende Variable has-slot:partition base name mit dem Wert yes. Slots werden alphabetisch als „a“, „b“, „c“ usw. benannt, entsprechend den Partitionen mit dem Suffix _a, _b, _c usw. Der Bootloader sollte das Betriebssystem darüber informieren, welcher Slot gebootet wurde, indem er die Befehlszeileneigenschaft androidboot.slot_suffix verwendet. Dieses Attribut wird über die Bootkonfiguration für Geräte festgelegt, die mit Android 12 oder höher auf den Markt kommen.

  • Der slot-retry-count-Wert wird entweder durch die Boot-Control-HAL über den setActiveBootSlot-Callback oder über den fastboot set_active-Befehl auf einen positiven Wert (normalerweise 3) zurückgesetzt. Wenn eine Partition geändert wird, die Teil eines Slots ist, löscht der Bootloader „successfully booted“ (erfolgreich gebootet) und setzt die Anzahl der Wiederholungsversuche für den Slot zurück.

Der Bootloader sollte auch festlegen, welcher Slot geladen werden soll. Die Abbildung zeigt ein Beispiel für einen Entscheidungsprozess.

Bootloader-Slotting-Ablauf
Abbildung 1. Bootloader-Slotting-Ablauf
  1. Legen Sie fest, welcher Slot versucht werden soll. Versuchen Sie nicht, einen Slot zu laden, der mit slot-unbootable gekennzeichnet ist. Dieser Slot sollte mit den von Fastboot zurückgegebenen Werten übereinstimmen und wird als aktueller Slot bezeichnet.

  2. Wenn der aktuelle Slot nicht als slot-successful markiert ist und ein slot-retry-count = 0 hat, markieren Sie den aktuellen Slot als slot-unbootable. Wählen Sie dann einen anderen Slot aus, der nicht mit unbootable, sondern mit slot-successful gekennzeichnet ist. Dieser Slot ist jetzt der ausgewählte Slot. Wenn kein aktueller Slot verfügbar ist, starte das Gerät im Wiederherstellungsmodus oder zeige dem Nutzer eine aussagekräftige Fehlermeldung an.

  3. Wählen Sie das entsprechende boot.img aus und geben Sie den Pfad zur richtigen Systempartition in der Kernel-Befehlszeile an.

  4. Füllen Sie den Kernel-Befehlszeilenparameter slot_suffix aus.

  5. Boot Wenn nicht mit slot-successful markiert, dekrementieren Sie slot-retry-count.

Das fastboot-Dienstprogramm bestimmt, welche Partition beim Ausführen von Flash-Befehlen geflasht wird. Wenn Sie beispielsweise zuerst den Befehl fastboot flash system system.img ausführen, wird zuerst die Variable current-slot abgefragt und das Ergebnis dann mit „system“ verkettet, um den Namen der Partition zu generieren, die geflasht werden soll (system_a, system_b usw.).

Wenn der aktuelle Slot mit dem Fastboot-Befehl set_active oder dem Boot-Control-HAL-Befehl setActiveBootSlot festgelegt wird, sollte der Bootloader den aktuellen Slot aktualisieren, slot-unbootable und slot-successful löschen und die Anzahl der Wiederholungsversuche zurücksetzen. Dies ist die einzige Möglichkeit, slot-unbootable zu löschen.

Geräte ohne A/B-Updates

Damit OTA-Updates auf Geräten unterstützt werden, die keine A/B-Updates verwenden (siehe Geräte, die nicht mit A/B-Updates aktualisiert werden können), muss der Bootloader des Geräts die folgenden Kriterien erfüllen.

  • Die Partition recovery sollte ein Image enthalten, das ein System-Image aus einer unterstützten Partition (cache, userdata) lesen und in die Partition system schreiben kann.

  • Der Bootloader sollte das direkte Booten in den Wiederherstellungsmodus unterstützen.

  • Wenn Funkbild-Updates unterstützt werden, sollte die Partition recovery auch das Flashen des Funks ermöglichen. Dazu gibt es zwei Möglichkeiten:

    • Der Bootloader flasht das Funkmodul. In diesem Fall sollte es möglich sein, über die Wiederherstellungspartition zurück in den Bootloader zu booten, um das Update abzuschließen.

    • Das Wiederherstellungs-Image flasht das Funkmodul. Diese Funktion kann als binäre Bibliothek oder als Dienstprogramm bereitgestellt werden.