Schnellstart zum Userspace

Fastboot ist der Name eines Bootloader-Moduls und -Modus. Android 10 und höher unterstützen Partitionen mit anpassbarer Größe, indem die Fastboot-Implementierung vom Bootloader in den Userspace verschoben wird. Durch diese Verschiebung kann der Flash-Code an einen gemeinsamen, wartungs- und testfähigen Speicherort verschoben werden, an dem nur die anbieterspezifischen Teile von Fastboot über eine Hardwareabstraktionsschicht (HAL) implementiert werden. Außerdem unterstützt Android 12 und höher das Flashen von Ramdisks über einen zusätzlichen Schnellstartbefehl.

Fastboot und Wiederherstellung zusammenführen

Da der Userspace-Schnellstart und die Wiederherstellung ähnlich sind, können Sie diese in einer Partition oder Binärdatei zusammenführen. Dies bietet Vorteile wie weniger Speicherplatz, insgesamt weniger Partitionen und einen gemeinsamen Kernel und Bibliotheken für Fastboot und Recovery.

Fastbootd ist der Name eines Userspace-Daemons und -Modus. Zur Unterstützung von fastbootd muss der Bootloader einen neuen BCB-Befehl (Boot Control Block) von boot-fastboot implementieren. Um den fastbootd-Modus aufzurufen, schreibt der Bootloader boot-fastboot in das Befehlsfeld der BCB-Nachricht und lässt das Feld recovery der BCB unverändert, um unterbrochene Wiederherstellungsaufgaben neu starten zu können. 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 analysiert dann die BCB-Nachricht und wechselt in den fastbootd-Modus.

ADB-Befehle

In diesem Abschnitt wird der Befehl adb zur Einbindung von fastbootd beschrieben. Der Befehl hat unterschiedliche Auswirkungen, je nachdem, ob er vom System oder von der Wiederherstellung ausgeführt wird.

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

Fastboot-Befehle

In diesem Abschnitt werden die Fastboot-Befehle für die Integration von fastbootd beschrieben, einschließlich neuer Befehle zum 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
  • Das Gerät wird im Wiederherstellungsmodus (Bootloader) neu gestartet.
  • Startet die Wiederherstellung direkt und ohne Neustart (fastbootd).
reboot fastboot Das Gerät wird neu gestartet und fastbootd wird angezeigt.
getvar is-userspace
  • Gibt yes (fastbootd) zurück.
  • Gibt no (Bootloader) zurück.
getvar is-logical:<partition> Gibt yes zurück, wenn es sich bei der angegebenen Partition um eine logische Partition handelt, 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 Suffix des aktuellen Slots, wenn es sich bei der Superpartition um eine A/B-Partition handelt (in der Regel ist das 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.
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 vorhanden 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. Mit einem optionalen wipe-Parameter werden die Metadaten des Geräts überschrieben, 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 (nicht unbedingt sicher). 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 wird das System über den angegebenen Steckplatz gestartet.

Bei der A/B-Unterstützung sind Slots duplizierte Partitionen, von denen unabhängig gestartet werden kann. Die Slots heißen a, b usw. und werden durch Hinzufügen der Suffixe _a, _b usw. zum Partitionsnamen unterschieden.

reboot Das Gerät wird normal neu gestartet.
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 RAM-Disks von Anbietern zu blinken.

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>

Unter Android 12 und höher verwenden, um das Flashen von RAM-Disks von Anbietern zu unterstützen.

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

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

fastboot flash vendor_boot:<foo> <vendor-ramdisk.img> Unter Android 12 und höher verwenden, um das Flashen von Anbieter-Ramdisks zu unterstützen.

Ruft das vendor_boot-Bild ab. Gibt einen Fehler zurück, wenn der Boot-Header des Anbieters Version 3 hat. Bei Version 4 wird das richtige Anbieter-Ramdisk-Fragment gefunden (falls verfügbar). Er ersetzt es durch das angegebene Bild, berechnet die Größe und den Versatz neu und blendet die neue vendor_boot image ein.

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

Fastboot und Bootloader

Der Bootloader flasht die Partitionen bootloader, radio und boot/recovery. Danach wird das Gerät in Fastboot (Userspace) gestartet und alle anderen Partitionen werden geflasht. Der Bootloader sollte die folgenden Befehle unterstützen.

Befehl Beschreibung
download Das Image wird zum Flashen heruntergeladen.
flash recovery <image>/ flash boot <image>/ flash bootloader <image>/ Flasht die recovery/boot-Partition und den Bootloader.
reboot Das Gerät wird neu gestartet.
reboot fastboot Das Gerät wird im Fastboot-Modus neu gestartet.
reboot recovery Das Gerät wird neu gestartet und die Wiederherstellung wird gestartet.
getvar Ruft eine Bootloadervariable 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 Geräten mit nachträglich hinzugefügten dynamischen Partitionen unterstützen das Fastboot-Tool und der Bootloader einen Zwangsmodus, um eine dynamische Partition direkt im Bootloader-Modus zu flashen. Wenn system beispielsweise eine dynamische Partition auf dem nachgerüsteten Gerät ist, kann der Bootloader mit dem Befehl fastboot --force flash system (anstelle von fastbootd) die Partition flashen.

Laden im Aus-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

Damit der Bootloader-Fastboot vollständig ersetzt werden kann, 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 sind nicht dokumentiert. Für die Verarbeitung solcher Befehle gibt die Fastboot HAL die erforderlichen OEM-Befehle an. OEMs können auch eigene Befehle implementieren.

Die Definition der Fastboot-HAL lautet:

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 das Fastboot HAL, das Boot Control HAL und das Health HAL Teil des Wiederherstellungs-Images sind.

  3. Fügen Sie alle gerätespezifischen SEPolicy-Berechtigungen hinzu, die von fastbootd benötigt werden. Beispielsweise benötigt fastbootd Schreibzugriff auf eine gerätespezifische Partition, um diese 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 Userspace-Fastboot zu validieren.

Ramdisks von Flash-Anbietern

Android 12 und höher unterstützen das Flashen von RAM-Disks mit einem zusätzlichen Fastboot-Befehl, der das vollständige vendor_boot-Image von einem Gerät abruft. Der Befehl fordert das hostseitige Fastboot-Tool auf, den Boot-Header des Anbieters zu lesen, das Image neu 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, ist das Flashen einzelner RAM-Disks von Anbietern im Bootloader-Modus keine vom Anbieter unterstützte Option.

Änderungen am Bootloader

Die Befehle getvar:max-fetch-size und fetch:name sind in fastbootd implementiert. Wenn Sie Anbieter-RAM-Disks im Bootloader flashen möchten, 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 größer als diesen Wert abrufen.

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

  • Auf dem Gerät wird ein debugbarer Build ausgeführt.
  • Das Gerät ist entsperrt (Bootstatus orange).
  • Der abgerufene Partitionsname ist 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)

Daher 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. Für offset ist das 0 und für size der berechnete Wert von partition_size - offset.

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

Mit fetch:foo wird beispielsweise die gesamte foo-Partition mit dem Offset 0 abgerufen.

Treiberänderungen

Dem Fastboot-Tool wurden Befehle hinzugefügt, um Treiberänderungen zu implementieren. Jeder Befehl ist mit seiner 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 Größe des Chunks zu bestimmen.
    • Ruft getvar partition-size:vendor_boot[_a] auf, um die Größe der gesamten Partition zu ermitteln.
    • Ruft fastboot fetch vendor_boot[_a]:offset:size für jeden Block auf. (Die Chunk-Größe ist größer als die Größe vendor_boot, sodass normalerweise nur ein Block vorhanden ist.)
    • Die Daten werden zu out.img zusammengefügt.
  • fastboot flash vendor_boot:default vendor-ramdisk.img

    Dies ist eine spezielle Variante des Befehls „flash“. Es ruft das vendor_boot-Image ab, als wäre fastboot fetch aufgerufen worden.

    • Wenn der Boot-Header des Anbieters die Version 3 hat, geschieht Folgendes:
      • Ersetzt das RAM-Disk des Anbieters durch das angegebene Image.
      • Das neue vendor_boot-Bild wird kurz eingeblendet.
    • Wenn der Boot-Header des Anbieters Version 4 hat, geschieht Folgendes:
      • Ersetzt das 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, als wäre fastboot fetch aufgerufen worden.

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

      • Sucht das Anbieter-Ramdisk-Fragment mit dem Namen ramdisk_<var>&lt;foo></var>. Wenn sie nicht gefunden wird oder mehrere Übereinstimmungen vorhanden sind, wird ein Fehler zurückgegeben.
      • Ersetzt das RAM-Disk-Fragment des Anbieters durch das angegebene Image.
      • Größe und Offset in der Anbieter-Ramdisk-Tabelle werden neu berechnet.
      • Zeigt das neue vendor_boot-Image an.
    • Wenn <foo> nicht angegeben ist, wird versucht, ramdisk_ zu finden.

mkbootimg

Der Name default ist ab Android 12 für die Benennung von Ramdisk-Fragmenten von Anbietern reserviert. Die Semantik von flash vendor_boot:default für Fastboot bleibt gleich, aber Sie dürfen Ihre Ramdisk-Fragmente nicht default nennen.

SELinux-Änderungen

In fastbootd.te wurde eine Änderung vorgenommen, um das Flashen von Anbieter-Ramdisks zu unterstützen.