Schnellstart zum Userspace

Android 10 und höher unterstützen Partitionen mit anpassbarer Größe, indem die Fastboot-Implementierung vom Bootloader in den Userspace verschoben wird. Diese Neupositionierung ermöglicht das Verschieben des Flash-Codes an einen verwaltbaren und testbaren gemeinsamen Ort, an dem nur die anbieterspezifischen Teile von Fastboot durch eine Hardwareabstraktionsschicht (HAL) implementiert werden. Außerdem unterstützt Android 12 und höher das Flashen von Ramdisks über einen zusätzlichen Fastboot-Befehl.

Schnellstart und Wiederherstellung vereinheitlichen

Da der Nutzerbereich bei Fastboot und Wiederherstellung ähnlich ist, können Sie diese in einer Partition oder Binärdatei zusammenführen. Dies bietet Vorteile wie die Verwendung von weniger Speicherplatz, insgesamt weniger Partitionen und die gemeinsame Nutzung von Kernel und Bibliotheken für Fastboot und Wiederherstellung.

Zur Unterstützung von fastbootd muss der Bootloader einen neuen BCB-Befehl (Boot Control Block) von boot-fastboot implementieren. Zum Aufrufen des fastbootd-Modus schreibt der Bootloader boot-fastboot in das Befehlsfeld der BCB-Nachricht und lässt das Feld recovery der BCB-Nachricht unverändert. So wird der Neustart unterbrochener Wiederherstellungsaufgaben ermöglicht. Die Felder status, stage und reserved bleiben ebenfalls unverändert. Der Bootloader wird in das Wiederherstellungs-Image geladen und gestartet, sobald im BCB-Befehlsfeld boot-fastboot angezeigt wird. Die Wiederherstellung parst die BCB-Nachricht und wechselt in den fastbootd-Modus.

ADB-Befehle

In diesem Abschnitt wird der Befehl adb zum Einbinden von fastbootd beschrieben. Der Befehl liefert unterschiedliche Ergebnisse, je nachdem, ob er vom System oder durch eine Wiederherstellung ausgeführt wird.

Befehl Beschreibung
reboot fastboot
  • Startet im fastbootd (System).
  • Öffnet fastbootd direkt ohne Neustart (Wiederherstellung).

Fastboot-Befehle

In diesem Abschnitt werden die Fastboot-Befehle zur Integration von fastbootd beschrieben, einschließlich neuer Befehle für das Flashen und Verwalten logischer Partitionen. Einige Befehle führen unterschiedliche Ergebnisse aus, je nachdem, ob sie vom Bootloader oder von fastbootd ausgeführt wurden.

Befehl Beschreibung
reboot recovery
  • Neustart zur Wiederherstellung (Bootloader).
  • Startet die Wiederherstellung direkt und ohne Neustart (fastbootd).
reboot fastboot Startet im fastbootd neu.
getvar is-userspace
  • Gibt yes (fastbootd) zurück.
  • Gibt no (Bootloader) zurück.
getvar is-logical:<partition> Gibt yes zurück, wenn die angegebene Partition eine logische Partition ist, andernfalls no. Logische Partitionen unterstützen alle unten aufgeführten Befehle.
getvar super-partition-name Gibt den Namen der Superpartition zurück. Der Name enthält das aktuelle Slotsuffix, wenn die Superpartition eine A/B-Partition ist. Dies ist normalerweise nicht der Fall.
create-logical-partition <partition> <size> Erstellt eine logische Partition mit dem angegebenen Namen und der angegebenen Größe. Der Name darf nicht bereits als logische Partition vorhanden sein.
delete-logical-partition <partition> Löscht die angegebene logische Partition, d. h. die Partition wird gelöscht.
resize-logical-partition <partition> <size> Ändert die Größe der logischen Partition auf die neue Größe, ohne ihren Inhalt zu ändern. Schlägt fehl, wenn nicht genügend Speicherplatz für die Größenänderung verfügbar ist.
update-super <partition> Führt Änderungen an den Superpartitions-Metadaten zusammen. Wenn eine Zusammenführung nicht möglich ist, z. B. weil das Format auf dem Gerät eine nicht unterstützte Version ist, schlägt dieser Befehl fehl. Ein optionaler wipe-Parameter überschreibt die Metadaten des Geräts, anstatt eine Zusammenführung durchzuführen.
flash <partition><filename> ] Schreibt eine Datei in eine Flash-Partition. Das Gerät muss entsperrt sein.
erase <partition> Löscht eine Partition (für sicheres Löschen nicht erforderlich). Das Gerät muss entsperrt sein.
getvar <variable> | all Zeigt eine Bootloader-Variable oder alle Variablen an. Wenn die Variable nicht vorhanden ist, wird ein Fehler zurückgegeben.
set_active <slot>

Legt den angegebenen A/B-Boot-Slot als active fest. Beim nächsten Startversuch startet das System vom angegebenen Slot aus.

Für die A/B-Unterstützung sind Slots duplizierte Partitionen, die unabhängig voneinander gestartet werden können. Slots heißen a, b usw. und unterscheiden sich durch Hinzufügen der Suffixe _a, _b usw. an den Partitionsnamen.

reboot Startet das Gerät normal neu.
reboot-bootloader (oder reboot bootloader) Startet das Gerät im Bootloader neu.
fastboot fetch vendor_boot <out.img>

Wird unter Android 12 und höher verwendet, um RAMdisks von Anbietern flashen zu können.

Ruft die gesamte Partitionsgröße und die Blockgröße ab. Ruft Daten für jeden Block ab und fügt sie dann zu <out.img> zusammen.

Weitere Informationen finden Sie unter fastboot fetch vendor_boot <out.img>.

fastboot flash vendor_boot:default <vendor-ramdisk.img>

Verwende diese Einstellung unter Android 12 und höher, um die RAM-Disks von Anbietern zu unterstützen.

Dies ist eine spezielle Variante des Flash-Befehls. Er führt eine fetch vendor_boot-Bildfunktion aus, so als würde fastboot fetch aufgerufen werden. Das neue vendor_boot-Image, das geflasht wird, hängt davon ab, ob die Boot-Header-Version Version 3 oder Version 4 ist.

Weitere Informationen finden Sie unter fastboot flash vendor_boot:default <vendor-ramdisk.img>.

fastboot flash vendor_boot:<foo> <vendor-ramdisk.img> Wird unter Android 12 und höher verwendet, um Ramdisks von Flash-Anbietern zu unterstützen.

Ruft das Image vendor_boot ab. Gibt einen Fehler zurück, wenn der Boot-Header des Anbieters Version 3 ist. Bei Version 4 wird das richtige Ramdisk-Fragment des Anbieters gefunden (falls verfügbar). Es ersetzt dieses durch das angegebene Bild, berechnet Größen und Offsets neu und aktiviert den neuen vendor_boot image.

Weitere Informationen finden Sie unter fastboot flash vendor_boot:<foo> <vendor-ramdisk.img>.

Fastboot und Bootloader

Der Bootloader lädt die Partitionen bootloader, radio und boot/recovery hoch. Das Gerät startet anschließend in Fastboot (userspace) und startet alle anderen Partitionen. Der Bootloader sollte die folgenden Befehle unterstützen.

Befehl Beschreibung
download Lädt das Image in Flash herunter
flash recovery <image>/ flash boot <image>/ flash bootloader <image>/ Flash-Partition und Bootloader für recovery/boot.
reboot Das Gerät wird neu gestartet.
reboot fastboot Startet im Schnellstartmodus neu.
reboot recovery Neustarts zur Wiederherstellung.
getvar Ruft eine Bootloader-Variable ab, die zum Flashen des Wiederherstellungs-/Boot-Images erforderlich ist (z. B. current-slot und max-download-size).
oem <command> Vom OEM definierter Befehl.

Dynamische Partitionen

Der Bootloader darf das Flashen oder Löschen dynamischer Partitionen nicht zulassen und muss bei solchen Vorgängen einen Fehler zurückgeben. Bei nachgerüsteten Geräten mit dynamischen Partitionen unterstützen das Fastboot-Tool (und Bootloader) einen erzwungenen Modus, mit dem eine dynamische Partition direkt im Bootloader-Modus geladen werden kann. Wenn system beispielsweise eine dynamische Partition auf dem nachgerüsteten Gerät ist, wird durch den Befehl fastboot --force flash system der Bootloader (anstelle von fastbootd) zum Flashen der Partition aktiviert.

Laden im deaktivierten Modus

Wenn ein Gerät das Laden im ausgeschalteten Modus unterstützt oder automatisch in einen speziellen Modus hochfährt, wenn der Strom eingeschaltet wird, müssen diese speziellen Modi durch eine Implementierung des fastboot oem off-mode-charge 0-Befehls umgangen werden, damit das Gerät so gestartet wird, als hätte der Nutzer die Ein/Aus-Taste gedrückt.

Fastboot OEM HAL

Um den Bootloader-Schnellstart vollständig zu ersetzen, muss Fastboot alle vorhandenen fastboot-Befehle verarbeiten. Viele dieser Befehle stammen von OEMs und sind dokumentiert, erfordern jedoch eine benutzerdefinierte Implementierung. Viele OEM-spezifische Befehle werden nicht dokumentiert. Zur Verarbeitung solcher Befehle gibt der Fastboot-HAL die erforderlichen OEM-Befehle an. OEMs können auch ihre eigenen Befehle implementieren.

Die Definition von Fastboot HAL lautet wie folgt:

import IFastbootLogger;

/**
 * IFastboot interface implements vendor specific fastboot commands.
 */
interface IFastboot {
    /**
     * Returns a bool indicating whether the bootloader is enforcing verified
     * boot.
     *
     * @return verifiedBootState True if the bootloader is enforcing verified
     * boot and False otherwise.
     */
    isVerifiedBootEnabled() generates (bool verifiedBootState);

    /**
     * Returns a bool indicating the off-mode-charge setting. If off-mode
     * charging is enabled, the device autoboots into a special mode when
     * power is applied.
     *
     * @return offModeChargeState True if the setting is enabled and False if
     * not.
     */
    isOffModeChargeEnabled() generates (bool offModeChargeState);

    /**
     * Returns the minimum battery voltage required for flashing in mV.
     *
     * @return batteryVoltage Minimum battery voltage (in mV) required for
     * flashing to be successful.
     */
    getBatteryVoltageFlashingThreshold() generates (int32_t batteryVoltage);

    /**
     * Returns the file system type of the partition. This is only required for
     * physical partitions that need to be wiped and reformatted.
     *
     * @return type Can be ext4, f2fs or raw.
     * @return result SUCCESS if the operation is successful,
     * FAILURE_UNKNOWN if the partition is invalid or does not require
     * reformatting.
     */
    getPartitionType(string partitionName) generates (FileSystemType type, Result result);

    /**
     * Executes a fastboot OEM command.
     *
     * @param oemCmd The oem command that is passed to the fastboot HAL.
     * @response result Returns the status SUCCESS if the operation is
     * successful,
     * INVALID_ARGUMENT for bad arguments,
     * FAILURE_UNKNOWN for an invalid/unsupported command.
     */
    doOemCommand(string oemCmd) generates (Result result);

};

Fastbootd aktivieren

So aktivieren Sie fastbootd auf einem Gerät:

  1. fastbootd zu PRODUCT_PACKAGES in device.mk hinzufügen: PRODUCT_PACKAGES += fastbootd.

  2. Achten Sie darauf, dass der Fastboot-HAL, der Bootsteuerungs-HAL und der System-HAL als Teil des Wiederherstellungs-Images verpackt sind.

  3. Fügen Sie alle für fastbootd erforderlichen gerätespezifischen SEPolicy-Berechtigungen hinzu. fastbootd benötigt beispielsweise Schreibzugriff auf eine gerätespezifische Partition, um diese Partition zu flashen. Darüber hinaus kann die Fastboot-HAL-Implementierung auch gerätespezifische Berechtigungen erfordern.

Führen Sie die Vendor Test Suite (VTS) aus, um den Schnellstart des Nutzerbereichs zu validieren.

Ramdisks von Flash-Anbietern

Android 12 und höher bieten Unterstützung für das Flashen von Ramdisks mit einem zusätzlichen Fastboot-Befehl, mit dem das vollständige vendor_boot-Image von einem Gerät abgerufen wird. Durch diesen Befehl wird das hostseitige Fastboot-Tool aufgefordert, den Boot-Header des Anbieters zu lesen, ein neues Image zu erstellen und das neue Image zu flashen.

Zum Abrufen des vollständigen vendor_boot-Images wurde der Befehl fetch:vendor_boot sowohl dem Fastboot-Protokoll als auch der Fastbootd-Implementierung des Protokolls in Android 12 hinzugefügt. Beachten Sie, dass Fastbootd dies implementiert, der Bootloader selbst aber möglicherweise nicht. OEMs können den Befehl fetch:vendor_boot in ihre Bootloader-Implementierung des Protokolls einfügen. Wenn der Befehl jedoch im Bootloader-Modus nicht erkannt wird, wird das Flashen von Ramdisks einzelner Anbieter im Bootloader-Modus nicht unterstützt.

Bootloader-Änderungen

Die Befehle getvar:max-fetch-size und fetch:name sind in fastbootd implementiert. Damit das Flashen von Ramdisks von Anbietern im Bootloader unterstützt wird, müssen Sie diese beiden Befehle implementieren.

Fastbootd-Änderungen

getvar:max-fetch-size ähnelt max-download-size. Sie gibt die maximale Größe an, die das Gerät in einer DATA-Antwort senden kann. Der Treiber darf keine Größe abrufen, die größer als dieser Wert ist.

fetch:name[:offset[:size]] führt eine Reihe von Prüfungen auf dem Gerät durch. Wenn alle der folgenden Bedingungen erfüllt sind, gibt der Befehl fetch:name[:offset[:size]] Daten zurück:

  • Auf dem Gerät wird ein Debug-fähiger Build ausgeführt.
  • Das Gerät ist entsperrt (Startstatus orange).
  • Der abgerufene Partitionsname lautet vendor_boot.
  • Der Wert für size liegt in „0 < size <= max-fetch-size“.

Wenn diese überprüft wurden, gibt fetch:name[:offset[:size]] die Partitionsgröße und den Offset-Wert zurück. Beachten Sie Folgendes:

  • fetch:name entspricht fetch:name:0, was fetch:name:0:partition_size entspricht.
  • fetch:name:offset entspricht fetch:name:offset:(partition_size - offset)

Dementsprechend ist fetch:name[:offset[:size]] = fetch:name:offset:(partition_size - offset).

Wenn offset oder partition_size (oder beide) nicht angegeben sind, werden die Standardwerte verwendet, wobei für offset der Wert 0 und für size der berechnete Wert von partition_size - offset verwendet wird.

  • Offset angegeben, Größe nicht angegeben: size = partition_size - offset
  • Keine Angabe: Standardwerte werden für beide verwendet, size = partition_size: 0.

fetch:foo ruft beispielsweise die gesamte Partition foo bei Versatz 0 ab.

Treiberänderungen

Dem Fastboot-Tool wurden Befehle hinzugefügt, um Treiberänderungen zu implementieren. Jede ist mit ihrer vollständigen Definition in der Tabelle der Fastboot-Befehle verknüpft.

  • fastboot fetch vendor_boot out.img

    • Ruft getvar max-fetch-size auf, um die Chunk-Größe zu ermitteln.
    • Ruft getvar partition-size:vendor_boot[_a] auf, um die Größe der gesamten Partition zu ermitteln.
    • Ruft für jeden Block fastboot fetch vendor_boot[_a]:offset:size auf. (Die Chunk-Größe ist größer als die Größe vendor_boot, sodass normalerweise nur ein Block vorhanden ist.)
    • Führt die Daten zu out.img zusammen.
  • fastboot flash vendor_boot:default vendor-ramdisk.img

    Dies ist eine spezielle Variante des Flash-Befehls. Er ruft das vendor_boot-Image ab, als ob fastboot fetch aufgerufen wurde.

    • Wenn der Anbieter-Boot mit Version 3 beginnt, geschieht Folgendes:
      • Ersetzt die anbieterseitige Ramdisk durch das angegebene Image.
      • Zeigt das neue vendor_boot-Image an.
    • Wenn der Boot-Header des Anbieters Version 4 lautet, geschieht Folgendes:
      • Ersetzt die gesamte Anbieter-RAMdisk durch das angegebene Image, sodass das angegebene Image das einzige Anbieter-RAMdisk-Fragment im vendor_boot-Image wird.
      • Berechnet die Größe und den Offset in der Ramdisk-Tabelle des Anbieters neu.
      • Zeigt das neue vendor_boot-Image an.
  • fastboot flash vendor_boot:foo vendor-ramdisk.img

    Ruft vendor_boot image ab, so als ob fastboot fetch aufgerufen wurde.

    • Wenn der Boot-Header des Anbieters Version 3 ist, wird ein Fehler zurückgegeben.
    • Wenn der Boot-Header des Anbieters Version 4 ist, geschieht Folgendes:

      • Ermittelt das Ramdisk-Fragment des Anbieters foo. Wenn sie nicht gefunden wird oder mehrere Übereinstimmungen vorhanden sind, wird ein Fehler zurückgegeben.
      • Ersetzt das Ramdisk-Fragment des Anbieters durch das angegebene Image.
      • Berechnet jede Größe und jeden Offset in der Ramdisk-Tabelle des Anbieters neu.
      • Zeigt das neue vendor_boot-Image an.

MKbootimg

Der Name default ist in Android 12 und höher für die Benennung von Ramdisk-Fragmenten von Anbietern reserviert. Die Fastboot-Semantik flash vendor_boot:default bleibt unverändert, Sie dürfen die Ramdisk-Fragmente jedoch nicht mit default benennen.

SELinux-Änderungen

In fastbootd.te wurde eine Änderung vorgenommen, um Flash-Anbieter-RAMdisks zu unterstützen.