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.
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
undvbmeta_vendor
hinzu. Fügen Sie für A/B-Gerätevbmeta_system_a
,vbmeta_system_b
,vbmeta_vendor_a
undvbmeta_vendor_b
hinzu. Wenn Sie eine oder mehrere dieser Partitionen hinzufügen, sollten sie dieselbe Größe wie dievbmeta
-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:
- 818cf56740775446285466eda984acedd4baeac0 – „libavb: Partitions-GUIDs nur abfragen, wenn sie von der Befehlszeile benötigt werden“
- 5abd6bc2578968d24406d834471adfd995a0c2e9 – „Zulassen, dass die Systempartition fehlt“
- 9ba3b6613b4e5130fa01a11d984c6b5f0eb3af05 – „Fix AvbSlotVerifyData->cmdline might be NULL“
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
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 Flagfirst_stage_mount
enthalten, das angibt, dass eine Partition in der ersten Phase bereitgestellt werden soll. -
Für eine Partition kann
avb=vbmeta partition name
alsfs_mgr
-Flag angegeben werden. Die angegebenevbmeta
-Partition wird dann von der ersten Phaseinit
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 inBOARD_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 normalerweiseBOARD_partitionIMAGE_PARTITION_SIZE
. - Heben Sie die vorhandene
BOARD_partitionIMAGE_PARTITION_SIZE
für alle Partitionen inBOARD_SUPER_PARTITION_BLOCK_DEVICES
auf. - Legen Sie
BOARD_SUPER_PARTITION_SIZE
auf die Summe vonBOARD_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 diessystem
. - Legen Sie jeweils
BOARD_SUPER_PARTITION_GROUPS
,BOARD_group_SIZE
undBOARD_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}