Dynamische Partitionen implementieren

Die dynamische Partitionierung wird mit dem dm-linear Device Mapper-Modul im Linux-Kernel implementiert. Die Partition super enthält Metadaten mit den Namen und Blockbereichen jeder dynamischen Partition innerhalb von super. Während der ersten Phase von init werden diese Metadaten analysiert und validiert. Außerdem werden virtuelle Blockgeräte erstellt, die jede dynamische Partition repräsentieren.

Beim Anwenden eines Over-the-air-Updates werden dynamische Partitionen automatisch erstellt, bei Bedarf neu formatiert oder gelöscht. Bei A/B-Geräten gibt es zwei Kopien der Metadaten. Änderungen werden nur auf die Kopie angewendet, die den Ziel-Slot darstellt.

Da dynamische Partitionen im Nutzerbereich implementiert sind, können vom Bootloader benötigte Partitionen nicht dynamisch gestaltet werden. Beispiel: boot, dtbo und vbmeta werden vom Bootloader gelesen und müssen daher als physische Partitionen verbleiben.

Jede dynamische Partition kann einer Aktualisierungsgruppe angehören. Diese Gruppen begrenzen den maximalen Speicherplatz, den Partitionen in dieser Gruppe belegen können. Beispielsweise können system und vendor zu einer Gruppe gehören, die die Gesamtgröße von system und vendor einschränkt.

Dynamische Partitionen auf neuen Geräten implementieren

In diesem Abschnitt erfahren Sie, wie Sie dynamische Partitionen auf neuen Geräten implementieren, die mit Android 10 oder höher auf den Markt kommen. Informationen zum Aktualisieren vorhandener Geräte findest du unter Upgrade von Android-Geräten durchführen.

Partitionsänderungen

Erstellen Sie für Geräte mit Android 10 eine Partition mit dem Namen super. Die Partition super verarbeitet A/B-Slots intern, sodass A/B-Geräte keine separaten super_a- und super_b-Partitionen benötigen. Alle nur lesbaren AOSP-Partitionen, die nicht vom Bootloader verwendet werden, müssen dynamisch sein und aus der GUID-Partitionstabelle (GPT) entfernt werden. Anbieterspezifische Partitionen müssen nicht dynamisch sein und können in der GPT platziert werden.

Um die Größe von super zu schätzen, addieren Sie die Größen der Partitionen, die aus der GPT gelöscht werden. Bei A/B-Geräten sollte hier die Größe beider Slots angegeben werden. Abbildung 1 zeigt eine Beispielpartitionstabelle vor und nach der Umwandlung in dynamische Partitionen.

Layout der Partitionstabelle
Abbildung 1. Neues Layout der Tabelle für physische Partitionen bei der Umwandlung in dynamische Partitionen

Folgende dynamische Partitionen werden unterstützt:

  • System
  • Vendor
  • Produkt
  • System-Erw.
  • ODM

Bei Geräten, die mit Android 10 gestartet werden, muss die Kernel-Befehlszeilenoption androidboot.super_partition leer sein, damit der Befehl „sysprop ro.boot.super_partition“ leer ist.

Partitionsausrichtung

Das Device-Mapper-Modul funktioniert möglicherweise weniger effizient, wenn die super-Partition nicht richtig ausgerichtet ist. Die super-Partition MUSS an der von der Blockschicht festgelegten minimalen Größe der I/O-Anfrage ausgerichtet sein. Standardmäßig geht das Build-System (über lpmake, das das super-Partitions-Image generiert) davon aus, dass eine Ausrichtung von 1 MiB für jede dynamische Partition ausreicht. Anbieter sollten jedoch darauf achten, dass die super-Partition richtig ausgerichtet ist.

Die Mindestanfragegröße eines Blockgeräts können Sie anhand von sysfs ermitteln. Beispiel:

# ls -l /dev/block/by-name/super
lrwxrwxrwx 1 root root 16 1970-04-05 01:41 /dev/block/by-name/super -> /dev/block/sda17
# cat /sys/block/sda/queue/minimum_io_size
786432

Sie können die Ausrichtung der super-Partition auf ähnliche Weise prüfen:

# cat /sys/block/sda/sda17/alignment_offset

Der Ausrichtungsversatz MUSS 0 sein.

Änderungen an der Gerätekonfiguration

Fügen Sie das folgende Flag in device.mk hinzu, um die dynamische Partitionierung zu aktivieren:

PRODUCT_USE_DYNAMIC_PARTITIONS := true

Änderungen an der Boardkonfiguration

Sie müssen die Größe der super-Partition festlegen:

BOARD_SUPER_PARTITION_SIZE := <size-in-bytes>

Auf A/B-Geräten gibt das Build-System einen Fehler aus, wenn die Gesamtgröße der dynamischen Partitions-Images mehr als die Hälfte der Partitionsgröße super beträgt.

Sie können die Liste der dynamischen Partitionen so konfigurieren: Geben Sie für Geräte mit Updategruppen die Gruppen in der Variablen BOARD_SUPER_PARTITION_GROUPS an. Jeder Gruppenname hat dann eine BOARD_group_SIZE- und eine BOARD_group_PARTITION_LIST-Variable. Bei A/B-Geräten sollte die maximale Größe einer Gruppe nur einen Slot abdecken, da die Gruppennamen intern ein Slot-Suffix haben.

Hier ein Beispiel für ein Gerät, bei dem alle Partitionen in einer Gruppe namens example_dynamic_partitions zusammengefasst werden:

BOARD_SUPER_PARTITION_GROUPS := example_dynamic_partitions
BOARD_EXAMPLE_DYNAMIC_PARTITIONS_SIZE := 6442450944
BOARD_EXAMPLE_DYNAMIC_PARTITIONS_PARTITION_LIST := system vendor product

Hier ist ein Beispielgerät, bei dem System- und Produktdienste in group_foo und vendor, product und odm in group_bar abgelegt werden:

BOARD_SUPER_PARTITION_GROUPS := group_foo group_bar
BOARD_GROUP_FOO_SIZE := 4831838208
BOARD_GROUP_FOO_PARTITION_LIST := system product_services
BOARD_GROUP_BAR_SIZE := 1610612736
BOARD_GROUP_BAR_PARTITION_LIST := vendor product odm
  • Bei Geräten mit virtuellem A/B-Start darf die Summe der maximalen Größen aller Gruppen höchstens folgender Wert sein:
    BOARD_SUPER_PARTITION_SIZE – Overhead
    Weitere Informationen finden Sie unter Virtuelles A/B-Testen implementieren.
  • Bei Geräten mit A/B-Test muss die Summe der maximalen Größen aller Gruppen folgendermaßen lauten:
    BOARD_SUPER_PARTITION_SIZE ÷ 2 – Overhead
  • Bei Nicht-A/B-Geräten und nachgerüsteten A/B-Geräten muss die Summe der maximalen Größen aller Gruppen folgender Wert sein:
    BOARD_SUPER_PARTITION_SIZE – Overhead
  • Zum Zeitpunkt der Erstellung darf die Summe der Größen der Images jeder Partition in einer Updategruppe die maximale Größe der Gruppe nicht überschreiten.
  • Bei der Berechnung ist ein Overhead erforderlich, um Metadaten, Ausrichtungen usw. zu berücksichtigen. Ein angemessener Overhead ist 4 MiB. Sie können jedoch einen größeren Overhead auswählen, falls dies für das Gerät erforderlich ist.

Größe dynamischer Partitionen

Vor dynamischen Partitionen wurden Partitionsgrößen zugewiesen, um sicherzustellen, dass genügend Platz für zukünftige Updates vorhanden ist. Die tatsächliche Größe wurde unverändert übernommen und die meisten schreibgeschützten Partitionen hatten etwas freien Speicherplatz in ihrem Dateisystem. Bei dynamischen Partitionen kann dieser kostenlose Speicherplatz nicht verwendet werden und könnte zum Erweitern von Partitionen während einer Over-the-air-Aktualisierung verwendet werden. Es ist wichtig, dass Partitionen keinen Speicherplatz verschwenden und einer minimalen Größe zugewiesen werden.

Bei nur lesbaren Ext4-Images weist das Buildsystem automatisch die Mindestgröße zu, wenn keine hartcodierte Partitionsgröße angegeben ist. Das Build-System passt das Image so an, dass das Dateisystem möglichst wenig nicht genutzten Speicherplatz hat. So wird sichergestellt, dass auf dem Gerät kein Speicherplatz verschwendet wird, der für OTAs verwendet werden kann.

Darüber hinaus können Ext4-Images weiter komprimiert werden, indem die Deduplizierung auf Blockebene aktiviert wird. Verwenden Sie dazu die folgende Konfiguration:

BOARD_EXT4_SHARE_DUP_BLOCKS := true

Wenn die automatische Zuweisung einer Partitionsmindestgröße nicht gewünscht ist, gibt es zwei Möglichkeiten, die Partitionsgröße zu steuern. Mit BOARD_partitionIMAGE_PARTITION_RESERVED_SIZE können Sie einen Mindestwert für den freien Speicherplatz angeben. Mit BOARD_partitionIMAGE_PARTITION_SIZE können Sie dynamische Partitionen auf eine bestimmte Größe festlegen. Beides wird nur empfohlen, wenn es unbedingt erforderlich ist.

Beispiel:

BOARD_PRODUCTIMAGE_PARTITION_RESERVED_SIZE := 52428800

Dadurch wird das Dateisystem in product.img gezwungen, 50 MiB nicht verwendeten Speicherplatz zu haben.

Änderungen für „System als Root“

Auf Geräten, die mit Android 10 ausgeliefert werden, darf „system-as-root“ nicht verwendet werden.

Auf Geräten mit dynamischen Partitionen darf „system-as-root“ nicht verwendet werden, unabhängig davon, ob das Gerät mit dynamischen Partitionen gestartet wird oder diese nachträglich hinzugefügt werden. Der Linux-Kernel kann die Partition super nicht interpretieren und daher system nicht selbst bereitstellen. system wird jetzt von init der ersten Stufe bereitgestellt, das sich auf der Ramdisk befindet.

Legen Sie BOARD_BUILD_SYSTEM_ROOT_IMAGE nicht fest. In Android 10 wird das Flag BOARD_BUILD_SYSTEM_ROOT_IMAGE nur verwendet, um zu unterscheiden, ob das System vom Kernel oder vom init der ersten Stufe im Ramdisk bereitgestellt wird.

Wenn Sie BOARD_BUILD_SYSTEM_ROOT_IMAGE auf true setzen, tritt ein Buildfehler auf, wenn PRODUCT_USE_DYNAMIC_PARTITIONS ebenfalls true ist.

Wenn BOARD_USES_RECOVERY_AS_BOOT auf „wahr“ gesetzt ist, wird das Wiederherstellungs-Image als boot.img erstellt und enthält das RAM-Disk der Wiederherstellung. Zuvor wurde beim Bootloader der Kernel-Befehlszeilenparameter skip_initramfs verwendet, um zu entscheiden, in welchem Modus gestartet werden soll. Bei Android 10-Geräten darf der Bootloader skip_initramfs NICHT an die Kernel-Befehlszeile übergeben. Stattdessen sollte der Bootloader androidboot.force_normal_boot=1 übergeben, um die Wiederherstellung zu überspringen und Android normal zu starten. Geräte, die mit Android 12 oder höher gestartet werden, müssen androidboot.force_normal_boot=1 über bootconfig übergeben.

AVB-Konfigurationsänderungen

Wenn Sie Android Verified Boot 2.0 verwenden und das Gerät keine verketteten Partitionsbeschreibungen verwendet, sind keine Änderungen erforderlich. Wenn jedoch verkettete Partitionen verwendet werden und eine der überprüften Partitionen dynamisch ist, sind Änderungen erforderlich.

Hier ist eine Beispielkonfiguration für ein Gerät, das vbmeta für die Partitionen system und vendor verkettet.

BOARD_AVB_SYSTEM_KEY_PATH := external/avb/test/data/testkey_rsa2048.pem
BOARD_AVB_SYSTEM_ALGORITHM := SHA256_RSA2048
BOARD_AVB_SYSTEM_ROLLBACK_INDEX := $(PLATFORM_SECURITY_PATCH_TIMESTAMP)
BOARD_AVB_SYSTEM_ROLLBACK_INDEX_LOCATION := 1

BOARD_AVB_VENDOR_KEY_PATH := external/avb/test/data/testkey_rsa2048.pem
BOARD_AVB_VENDOR_ALGORITHM := SHA256_RSA2048
BOARD_AVB_VENDOR_ROLLBACK_INDEX := $(PLATFORM_SECURITY_PATCH_TIMESTAMP)
BOARD_AVB_VENDOR_ROLLBACK_INDEX_LOCATION := 1

Bei dieser Konfiguration erwartet der Bootloader am Ende der Partitionen system und vendor einen vbmeta-Fußzeile. Da diese Partitionen für den Bootloader nicht mehr sichtbar sind (sie befinden sich in super), sind zwei Änderungen erforderlich.

  • Fügen Sie der Partitionstabelle des Geräts die Partitionen vbmeta_system und vbmeta_vendor hinzu. Fügen Sie für A/B-Geräte vbmeta_system_a, vbmeta_system_b, vbmeta_vendor_a und vbmeta_vendor_b hinzu. Wenn Sie eine oder mehrere dieser Partitionen hinzufügen, sollten sie dieselbe Größe wie die vbmeta-Partition haben.
  • Benennen Sie die Konfigurationsflags um, indem Sie VBMETA_ hinzufügen, und geben Sie an, auf welche Partitionen sich die Verknüpfung erstreckt:
    BOARD_AVB_VBMETA_SYSTEM := system
    BOARD_AVB_VBMETA_SYSTEM_KEY_PATH := external/avb/test/data/testkey_rsa2048.pem
    BOARD_AVB_VBMETA_SYSTEM_ALGORITHM := SHA256_RSA2048
    BOARD_AVB_VBMETA_SYSTEM_ROLLBACK_INDEX := $(PLATFORM_SECURITY_PATCH_TIMESTAMP)
    BOARD_AVB_VBMETA_SYSTEM_ROLLBACK_INDEX_LOCATION := 1
    
    BOARD_AVB_VBMETA_VENDOR := vendor
    BOARD_AVB_VBMETA_VENDOR_KEY_PATH := external/avb/test/data/testkey_rsa2048.pem
    BOARD_AVB_VBMETA_VENDOR_ALGORITHM := SHA256_RSA2048
    BOARD_AVB_VBMETA_VENDOR_ROLLBACK_INDEX := $(PLATFORM_SECURITY_PATCH_TIMESTAMP)
    BOARD_AVB_VBMETA_VENDOR_ROLLBACK_INDEX_LOCATION := 1

Auf einem Gerät kann eine, beide oder keine dieser Partitionen verwendet werden. Änderungen sind nur bei der Verkettung an eine logische Partition erforderlich.

Änderungen am AVB-Bootloader

Wenn libavb im Bootloader eingebettet ist, fügen Sie die folgenden Patches hinzu:

Wenn Sie verkettete Partitionen verwenden, fügen Sie einen zusätzlichen Patch hinzu:

  • 49936b4c0109411fdd38bd4ba3a32a01c40439a9 – „libavb: Support vbmeta blobs in beginning of partition.“

Änderungen an der Kernel-Befehlszeile

Der Kernel-Befehlszeile muss der neue Parameter androidboot.boot_devices hinzugefügt werden. Damit werden /dev/block/by-name-Symlinks in init aktiviert. Es sollte die Gerätepfadkomponente zum zugrunde liegenden Symlink sein, der von ueventd erstellt wurde, also /dev/block/platform/device-path/by-name/partition-name. Geräte, die mit Android 12 oder höher gestartet werden, müssen bootconfig verwenden, um androidboot.boot_devices an init weiterzugeben.

Wenn der Symlink der Superpartition nach Name beispielsweise /dev/block/platform/soc/100000.ufshc/by-name/super ist, können Sie den Befehlszeilenparameter in der Datei „BoardConfig.mk“ so hinzufügen:

BOARD_KERNEL_CMDLINE += androidboot.boot_devices=soc/100000.ufshc
So fügen Sie den Parameter „bootconfig“ in der Datei „BoardConfig.mk“ hinzu:
BOARD_BOOTCONFIG += androidboot.boot_devices=soc/100000.ufshc

fstab-Änderungen

Der Gerätebaum und die Gerätebaum-Overlays dürfen keine fstab-Einträge enthalten. Verwenden Sie eine fstab-Datei, die Teil des RAM-Disks ist.

Für logische Partitionen müssen Änderungen an der Datei „fstab“ vorgenommen werden:

  • Das Feld „fs_mgr flags“ muss das Flag logical und das in Android 10 eingeführte Flag first_stage_mount enthalten, das angibt, dass eine Partition in der ersten Phase bereitgestellt werden soll.
  • Für eine Partition kann avb=vbmeta partition name als fs_mgr-Flag angegeben werden. Die angegebene vbmeta-Partition wird dann von der ersten Phase init initialisiert, bevor versucht wird, Geräte bereitzustellen.
  • Das Feld dev muss der Partitionsname sein.

In den folgenden fstab-Einträgen werden System, Anbieter und Produkt gemäß den oben genannten Regeln als logische Partitionen festgelegt.

#<dev>  <mnt_point> <type>  <mnt_flags options> <fs_mgr_flags>
system   /system     ext4    ro,barrier=1        wait,slotselect,avb=vbmeta,logical,first_stage_mount
vendor   /vendor     ext4    ro,barrier=1        wait,slotselect,avb,logical,first_stage_mount
product  /product    ext4    ro,barrier=1        wait,slotselect,avb,logical,first_stage_mount

Kopieren Sie die Datei „fstab“ in das RAM-Disk der ersten Phase.

SELinux-Änderungen

Das Blockgerät der Superpartition muss mit dem Label super_block_device gekennzeichnet sein. Wenn der Symlink der Superpartition nach Name beispielsweise /dev/block/platform/soc/100000.ufshc/by-name/super lautet, fügen Sie die folgende Zeile zu file_contexts hinzu:

/dev/block/platform/soc/10000\.ufshc/by-name/super   u:object_r:super_block_device:s0

fastbootd

Der Bootloader (oder ein anderes Flash-Tool, das nicht im Userspace ausgeführt wird) unterstützt keine dynamischen Partitionen und kann sie daher nicht flashen. Um dies zu beheben, müssen die Geräte eine User-Space-Implementierung des Fastboot-Protokolls namens „fastbootd“ verwenden.

Weitere Informationen zur Implementierung von fastbootd finden Sie unter Fastboot in den Userspace verschieben.

ADB Remount

Für Entwickler, die eng- oder userdebug-Builds verwenden, ist adb remount für schnelle Iterationen äußerst nützlich. Dynamische Partitionen stellen ein Problem für adb remount dar, da in den einzelnen Dateisystemen kein freier Speicherplatz mehr vorhanden ist. Um dieses Problem zu beheben, können Geräte overlayfs aktivieren. Solange in der Superpartition freier Speicherplatz vorhanden ist, erstellt adb remount automatisch eine temporäre dynamische Partition und verwendet overlayfs für Schreibvorgänge. Die temporäre Partition heißt scratch. Verwenden Sie diesen Namen also nicht für andere Partitionen.

Weitere Informationen zum Aktivieren von overlayfs finden Sie in der README-Datei für overlayfs in AOSP.

Android-Geräte aktualisieren

Wenn Sie ein Gerät auf Android 10 umstellen und die Unterstützung für dynamische Partitionen in die OTA-Aktualisierung aufnehmen möchten, müssen Sie die integrierte Partitionstabelle nicht ändern. Eine zusätzliche Konfiguration ist erforderlich.

Änderungen an der Gerätekonfiguration

Wenn Sie die dynamische Partitionierung nachträglich einrichten möchten, fügen Sie die folgenden Flags in device.mk hinzu:

PRODUCT_USE_DYNAMIC_PARTITIONS := true
PRODUCT_RETROFIT_DYNAMIC_PARTITIONS := true

Änderungen an der Boardkonfiguration

Sie müssen die folgenden Board-Variablen festlegen:

  • Legen Sie BOARD_SUPER_PARTITION_BLOCK_DEVICES auf die Liste der Blockgeräte fest, die zum Speichern von Ausdehnungen dynamischer Partitionen verwendet werden. Dies ist die Liste der Namen vorhandener physischer Partitionen auf dem Gerät.
  • Legen Sie BOARD_SUPER_PARTITION_partition_DEVICE_SIZE auf die Größe der einzelnen Blockgeräte in BOARD_SUPER_PARTITION_BLOCK_DEVICES fest. Dies ist eine Liste der Größen der vorhandenen physischen Partitionen auf dem Gerät. In vorhandenen Boardkonfigurationen ist das normalerweise BOARD_partitionIMAGE_PARTITION_SIZE.
  • Heben Sie die vorhandene BOARD_partitionIMAGE_PARTITION_SIZE für alle Partitionen in BOARD_SUPER_PARTITION_BLOCK_DEVICES auf.
  • Legen Sie BOARD_SUPER_PARTITION_SIZE auf die Summe von BOARD_SUPER_PARTITION_partition_DEVICE_SIZE fest.
  • Legen Sie BOARD_SUPER_PARTITION_METADATA_DEVICE auf das Blockgerät fest, auf dem die Metadaten der dynamischen Partition gespeichert sind. Dies muss einer der folgenden Werte sein: BOARD_SUPER_PARTITION_BLOCK_DEVICES. Normalerweise ist dies system.
  • Legen Sie jeweils BOARD_SUPER_PARTITION_GROUPS, BOARD_group_SIZE und BOARD_group_PARTITION_LIST fest. Weitere Informationen finden Sie unter Änderungen an der Boardkonfiguration auf neuen Geräten.

Wenn das Gerät beispielsweise bereits System- und Anbieterpartitionen hat und Sie diese in dynamische Partitionen konvertieren und während des Updates eine neue Produktpartition hinzufügen möchten, legen Sie diese Boardkonfiguration fest:

BOARD_SUPER_PARTITION_BLOCK_DEVICES := system vendor
BOARD_SUPER_PARTITION_METADATA_DEVICE := system

# Rename BOARD_SYSTEMIMAGE_PARTITION_SIZE to BOARD_SUPER_PARTITION_SYSTEM_DEVICE_SIZE.
BOARD_SUPER_PARTITION_SYSTEM_DEVICE_SIZE := <size-in-bytes>

# Rename BOARD_VENDORIMAGE_PARTITION_SIZE to BOARD_SUPER_PARTITION_VENDOR_DEVICE_SIZE
BOARD_SUPER_PARTITION_VENDOR_DEVICE_SIZE := <size-in-bytes>

# This is BOARD_SUPER_PARTITION_SYSTEM_DEVICE_SIZE + BOARD_SUPER_PARTITION_VENDOR_DEVICE_SIZE
BOARD_SUPER_PARTITION_SIZE := <size-in-bytes>

# Configuration for dynamic partitions. For example:
BOARD_SUPER_PARTITION_GROUPS := group_foo
BOARD_GROUP_FOO_SIZE := <size-in-bytes>
BOARD_GROUP_FOO_PARTITION_LIST := system vendor product

SELinux-Änderungen

Die Blockgeräte der Superpartition müssen mit dem Attribut super_block_device_type gekennzeichnet sein. Wenn das Gerät beispielsweise bereits die Partitionen system und vendor hat, die Sie als Blockgeräte zum Speichern von Ausdehnungen dynamischer Partitionen verwenden möchten, und ihre Symlinks nach Namen als system_block_device gekennzeichnet sind:

/dev/block/platform/soc/10000\.ufshc/by-name/system   u:object_r:system_block_device:s0
/dev/block/platform/soc/10000\.ufshc/by-name/vendor   u:object_r:system_block_device:s0

Fügen Sie dann device.te die folgende Zeile hinzu:

typeattribute system_block_device super_block_device_type;

Weitere Konfigurationen finden Sie unter Dynamische Partitionen auf neuen Geräten implementieren.

Weitere Informationen zu Nachrüstupdates finden Sie unter Over-the-air-Updates für A/B-Geräte ohne dynamische Partitionen.

Firmware-Images

Verwenden Sie für ein Gerät, das mit dynamischer Partitionsunterstützung gestartet wird, nicht den Userspace-Fastboot, um Firmware-Images zu flashen, da das Booten in den Userspace langsamer ist als andere Flashmethoden.

Um dieses Problem zu beheben, erstellt make dist jetzt ein zusätzliches super.img-Image, das direkt auf die Superpartition geflasht werden kann. Der Inhalt logischer Partitionen wird automatisch gebündelt. Das bedeutet, dass neben den Partitionsmetadaten super auch system.img, vendor.img usw. enthalten sind. Dieses Image kann ohne zusätzliche Tools oder mithilfe von fastbootd direkt auf die super-Partition geflasht werden. Nach dem Build wird super.img in ${ANDROID_PRODUCT_OUT} platziert.

Bei A/B-Geräten, die mit dynamischen Partitionen gestartet werden, enthält super.img Bilder im A-Steckplatz. Nachdem Sie das Super-Image direkt geflasht haben, markieren Sie Steckplatz A als bootfähig, bevor Sie das Gerät neu starten.

Für Retrofit-Geräte erstellt make dist eine Reihe von super_*.img-Images, die direkt auf die entsprechenden physischen Partitionen geflasht werden können. Beispiel: make dist erstellt super_system.img und super_vendor.img, wenn BOARD_SUPER_PARTITION_BLOCK_DEVICES der Systemanbieter ist. Diese Images werden im Ordner „OTA“ in target_files.zip abgelegt.

Device Mapper-Speichergeräteoptimierung

Die dynamische Partitionierung unterstützt eine Reihe nicht deterministischer Device-Mapper-Objekte. Möglicherweise werden nicht alle wie erwartet instanziiert. Daher müssen Sie alle Bereitstellungen verfolgen und die Android-Eigenschaften aller zugehörigen Partitionen mit den zugrunde liegenden Speichergeräten aktualisieren.

Ein Mechanismus in init überwacht die Bereitstellungen und aktualisiert die Android-Properties asynchron. Die Dauer kann nicht garantiert werden. Sie müssen also genügend Zeit einplanen, damit alle on property-Trigger reagieren können. Die Properties sind dev.mnt.blk.<partition>, wobei <partition> beispielsweise root, system, data oder vendor ist. Jede Property ist mit dem Namen des Basisspeichergeräts verknüpft, wie in diesen Beispielen gezeigt:

taimen:/ % getprop | grep dev.mnt.blk
[dev.mnt.blk.data]: [sda]
[dev.mnt.blk.firmware]: [sde]
[dev.mnt.blk.metadata]: [sde]
[dev.mnt.blk.persist]: [sda]
[dev.mnt.blk.root]: [dm-0]
[dev.mnt.blk.vendor]: [dm-1]

blueline:/ $ getprop | grep dev.mnt.blk
[dev.mnt.blk.data]: [dm-4]
[dev.mnt.blk.metadata]: [sda]
[dev.mnt.blk.mnt.scratch]: [sda]
[dev.mnt.blk.mnt.vendor.persist]: [sdf]
[dev.mnt.blk.product]: [dm-2]
[dev.mnt.blk.root]: [dm-0]
[dev.mnt.blk.system_ext]: [dm-3]
[dev.mnt.blk.vendor]: [dm-1]
[dev.mnt.blk.vendor.firmware_mnt]: [sda]

Mit der init.rc-Sprache können die Android-Properties im Rahmen der Regeln erweitert werden. Speichergeräte können von der Plattform nach Bedarf mit Befehlen wie diesen optimiert werden:

write /sys/block/${dev.mnt.blk.root}/queue/read_ahead_kb 128
write /sys/block/${dev.mnt.blk.data}/queue/read_ahead_kb 128

Sobald die Befehlsverarbeitung in der zweiten init-Phase beginnt, wird epoll loop aktiv und die Werte werden aktualisiert. Da Property-Trigger jedoch erst spät in init aktiv werden, können sie in den ersten Bootphasen nicht zum Bearbeiten von root, system oder vendor verwendet werden. Sie können davon ausgehen, dass der Standard-read_ahead_kb des Kernels ausreicht, bis die init.rc-Skripts in early-fs überschreiben können (wenn verschiedene Daemons und Einrichtungen gestartet werden). Daher empfiehlt Google, die Funktion on property in Kombination mit einem init.rc-kontrollierten Attribut wie sys.read_ahead_kb zu verwenden, um die Ausführung zu steuern und Race-Bedingungen zu vermeiden, wie in diesen Beispielen:

on property:dev.mnt.blk.root=* && property:sys.read_ahead_kb=*
    write /sys/block/${dev.mnt.blk.root}/queue/read_ahead_kb ${sys.read_ahead_kb:-2048}

on property:dev.mnt.blk.system=* && property:sys.read_ahead_kb=*
    write /sys/block/${dev.mnt.blk.system}/queue/read_ahead_kb ${sys.read_ahead_kb:-2048}

on property:dev.mnt.blk.vendor=* && property:sys.read_ahead_kb=*
    write /sys/block/${dev.mnt.blk.vendor}/queue/read_ahead_kb ${sys.read_ahead_kb:-2048}

on property:dev.mnt.blk.product=* && property:sys.read_ahead_kb=*
    write /sys/block/${dev.mnt.blk.system_ext}/queue/read_ahead_kb ${sys.read_ahead_kb:-2048}

on property:dev.mnt.blk.oem=* && property:sys.read_ahead_kb=*
    write /sys/block/${dev.mnt.blk.oem}/queue/read_ahead_kb ${sys.read_ahead_kb:-2048}

on property:dev.mnt.blk.data=* && property:sys.read_ahead_kb=*
    write /sys/block/${dev.mnt.blk.data}/queue/read_ahead_kb ${sys.read_ahead_kb:-2048}

on early-fs:
    setprop sys.read_ahead_kb ${ro.read_ahead_kb.boot:-2048}

on property:sys.boot_completed=1
   setprop sys.read_ahead_kb ${ro.read_ahead_kb.bootcomplete:-128}