Die dynamische Partitionierung wird mithilfe des dm-linearen Device-Mapper-Moduls im Linux-Kernel implementiert. Die super
Partition enthält Metadaten, die die Namen und Blockbereiche jeder dynamischen Partition innerhalb von super
auflisten. Während der ersten Stufe init
werden diese Metadaten analysiert und validiert, und es werden virtuelle Blockgeräte erstellt, um jede dynamische Partition darzustellen.
Bei der Anwendung eines OTA werden dynamische Partitionen je nach Bedarf automatisch erstellt, in der Größe geändert oder gelöscht. Für A/B-Geräte gibt es zwei Kopien der Metadaten und Änderungen werden nur auf die Kopie angewendet, die den Zielslot darstellt.
Da dynamische Partitionen im Userspace implementiert sind, können vom Bootloader benötigte Partitionen nicht dynamisch gemacht werden. Beispielsweise werden boot
, dtbo
und vbmeta
vom Bootloader gelesen und müssen daher als physische Partitionen verbleiben.
Jede dynamische Partition kann zu einer Update-Gruppe gehö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.
Implementieren Sie dynamische Partitionen auf neuen Geräten
In diesem Abschnitt erfahren Sie, wie Sie dynamische Partitionen auf neuen Geräten implementieren, die mit Android 10 und höher starten. Informationen zum Aktualisieren vorhandener Geräte finden Sie unter Aktualisieren von Android-Geräten .
Partitionsänderungen
Erstellen Sie für Geräte, die mit Android 10 starten, eine Partition mit dem Namen super
. Die super
verwaltet die A/B-Steckplätze intern, sodass A/B-Geräte keine separaten super_a
und super_b
Partitionen benötigen. Alle schreibgeschützten AOSP-Partitionen, die nicht vom Bootloader verwendet werden, müssen dynamisch sein und aus der GUID-Partitionstabelle (GPT) entfernt werden. Herstellerspezifische Partitionen müssen nicht dynamisch sein und können im GPT platziert werden.
Um die Größe von super
abzuschätzen, addieren Sie die Größen der Partitionen, die aus dem GPT gelöscht werden. Bei A/B-Geräten sollte dies die Größe beider Steckplätze umfassen. Abbildung 1 zeigt eine Beispielpartitionstabelle vor und nach der Konvertierung in dynamische Partitionen.
![Layout der Partitionstabelle](https://source.android.com/static/docs/core/ota/images/dynamic_partitions_table.png?authuser=6&hl=de)
Die unterstützten dynamischen Partitionen sind:
- System
- Verkäufer
- Produkt
- System-Ext
- 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 arbeitet möglicherweise weniger effizient, wenn die super
nicht richtig ausgerichtet ist. Die super
MUSS auf die minimale E/A-Anforderungsgröße ausgerichtet sein, die von der Blockschicht festgelegt wird. Standardmäßig geht das Build-System (über lpmake
, das das super
Partitions-Image generiert) davon aus, dass eine 1-MiB-Ausrichtung für jede dynamische Partition ausreichend ist. Allerdings sollten Anbieter sicherstellen, dass die super
richtig ausgerichtet ist.
Sie können die minimale Anforderungsgröße eines Blockgeräts ermitteln, indem Sie sysfs
überprüfen. Zum 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
auf ähnliche Weise überprüfen:
# cat /sys/block/sda/sda17/alignment_offset
Der Ausrichtungsoffset MUSS 0 sein.
Änderungen der Gerätekonfiguration
Um die dynamische Partitionierung zu aktivieren, fügen Sie das folgende Flag in device.mk
hinzu:
PRODUCT_USE_DYNAMIC_PARTITIONS := true
Änderungen an der Platinenkonfiguration
Sie müssen die Größe der super
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 Partitionsbilder mehr als die Hälfte der super
beträgt.
Sie können die Liste der dynamischen Partitionen wie folgt konfigurieren. Listen Sie für Geräte, die Aktualisierungsgruppen verwenden, die Gruppen in der Variablen BOARD_SUPER_PARTITION_GROUPS
auf. Jeder Gruppenname verfügt dann über eine BOARD_ group _SIZE
und BOARD_ group _PARTITION_LIST
. Bei A/B-Geräten sollte die maximale Größe einer Gruppe nur einen Steckplatz abdecken, da die Gruppennamen intern mit einem Steckplatzsuffix versehen sind.
Hier ist ein Beispielgerät, das alle Partitionen in einer Gruppe namens example_dynamic_partitions
ablegt:
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, das System- und Produktdienste in group_foo
und vendor
, product
“ und odm
in group_bar
platziert:
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
- Für virtuelle A/B-Startgeräte darf die Summe der maximalen Größen aller Gruppen höchstens betragen:
BOARD_SUPER_PARTITION_SIZE
– Overhead
Siehe Implementierung von Virtual A/B . - Für A/B-Startgeräte muss die Summe der maximalen Größen aller Gruppen sein:
BOARD_SUPER_PARTITION_SIZE
/ 2 - Overhead - Für Nicht-A/B-Geräte und Nachrüst-A/B-Geräte muss die Summe der maximalen Größen aller Gruppen sein:
BOARD_SUPER_PARTITION_SIZE
– Overhead - Zum Zeitpunkt der Erstellung darf die Summe der Größen der Images jeder Partition in einer Update-Gruppe die maximale Größe der Gruppe nicht überschreiten.
- Bei der Berechnung ist ein Mehraufwand erforderlich, um Metadaten, Ausrichtungen usw. zu berücksichtigen. Ein angemessener Overhead beträgt 4 MiB, Sie können jedoch je nach Bedarf des Geräts einen größeren Overhead auswählen.
Größe dynamischer Partitionen
Vor dynamischen Partitionen wurden die Partitionsgrößen überbelegt, um sicherzustellen, dass sie genügend Platz für zukünftige Updates hatten. Die tatsächliche Größe wurde unverändert übernommen und die meisten schreibgeschützten Partitionen verfügten über etwas freien Speicherplatz in ihrem Dateisystem. In dynamischen Partitionen ist dieser freie Speicherplatz unbrauchbar und könnte zum Erweitern von Partitionen während eines OTA verwendet werden. Es ist wichtig, sicherzustellen, dass Partitionen keinen Speicherplatz verschwenden und einer möglichst geringen Größe zugewiesen werden.
Für schreibgeschützte ext4-Images weist das Build-System automatisch die Mindestgröße zu, wenn keine fest codierte Partitionsgröße angegeben ist. Das Build-System passt das Image so an, dass das Dateisystem möglichst wenig ungenutzten Platz hat. Dadurch wird sichergestellt, dass das Gerät keinen Platz verschwendet, der für OTAs genutzt werden kann.
Darüber hinaus können ext4-Images durch die Aktivierung der Deduplizierung auf Blockebene weiter komprimiert werden. Um dies zu aktivieren, verwenden Sie die folgende Konfiguration:
BOARD_EXT4_SHARE_DUP_BLOCKS := true
Wenn die automatische Zuweisung der Mindestgröße einer Partition unerwünscht ist, gibt es zwei Möglichkeiten, die Partitionsgröße zu steuern. Sie können mit BOARD_ partition IMAGE_PARTITION_RESERVED_SIZE
eine Mindestmenge an freiem Speicherplatz angeben oder Sie können BOARD_ partition IMAGE_PARTITION_SIZE
angeben, um dynamische Partitionen auf eine bestimmte Größe zu erzwingen. Keines davon wird empfohlen, es sei denn, es ist notwendig.
Zum Beispiel:
BOARD_PRODUCTIMAGE_PARTITION_RESERVED_SIZE := 52428800
Dies zwingt das Dateisystem in product.img
dazu, über 50 MiB ungenutzten Speicherplatz zu verfügen.
System-als-Root-Änderungen
Geräte, die mit Android 10 gestartet werden, dürfen nicht „System-as-Root“ verwenden.
Geräte mit dynamischen Partitionen (unabhängig davon, ob sie mit dynamischen Partitionen gestartet oder nachgerüstet werden) dürfen kein System-als-Root verwenden. Der Linux-Kernel kann die super
nicht interpretieren und daher system
selbst nicht mounten. system
wird nun durch die erste Stufe init
gemountet, die 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 von der ersten init
-Stufe in der Ramdisk gemountet wird.
Das Festlegen BOARD_BUILD_SYSTEM_ROOT_IMAGE
auf true
führt zu einem Buildfehler, wenn PRODUCT_USE_DYNAMIC_PARTITIONS
ebenfalls true
ist.
Wenn BOARD_USES_RECOVERY_AS_BOOT
auf „true“ gesetzt ist, wird das Wiederherstellungsabbild als boot.img erstellt, das die Ramdisk der Wiederherstellung enthält. Bisher verwendete der Bootloader den Kernel-Befehlszeilenparameter skip_initramfs
, um zu entscheiden, in welchem Modus gebootet 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 normales Android zu starten. Geräte, die mit Android 12 oder höher gestartet werden, müssen bootconfig verwenden, um androidboot.force_normal_boot=1
zu übergeben.
AVB-Konfigurationsänderungen
Wenn das Gerät bei Verwendung von Android Verified Boot 2.0 keine verketteten Partitionsdeskriptoren verwendet, ist keine Änderung 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 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 system
und vendor
eine vbmeta-Fußzeile zu finden. Da diese Partitionen für den Bootloader nicht mehr sichtbar sind (sie befinden sich in super
), sind zwei Änderungen erforderlich.
- Fügen Sie die Partitionen
vbmeta_system
undvbmeta_vendor
zur Partitionstabelle des Geräts 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 diese 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 Verkettung 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
Ein Gerät kann eine, beide oder keine dieser Partitionen verwenden. Änderungen sind nur bei der Verkettung mit einer logischen Partition erforderlich.
Änderungen am AVB-Bootloader
Wenn der Bootloader libavb eingebettet hat, schließen Sie die folgenden Patches ein:
- 818cf56740775446285466eda984acedd4baeac0 – „libavb: Fragt Partitions-GUIDs nur ab, wenn die Cmdline sie benötigt.“
- 5abd6bc2578968d24406d834471adfd995a0c2e9 – „Systempartition darf nicht vorhanden sein“
- 9ba3b6613b4e5130fa01a11d984c6b5f0eb3af05 – „Fix AvbSlotVerifyData->cmdline könnte NULL sein“
Wenn Sie verkettete Partitionen verwenden, fügen Sie einen zusätzlichen Patch hinzu:
- 49936b4c0109411fdd38bd4ba3a32a01c40439a9 – „libavb: Unterstützt vbmeta-Blobs am Anfang der Partition.“
Änderungen an der Kernel-Befehlszeile
Ein neuer Parameter, androidboot.boot_devices
, muss zur Kernel-Befehlszeile hinzugefügt werden. Dies wird von init
verwendet, um /dev/block/by-name
-Symlinks zu aktivieren. Es sollte die Gerätepfadkomponente zum zugrunde liegenden By-Name-Symlink sein, der von ueventd
erstellt wurde, /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
zu übergeben.
Wenn der Symlink für den Superpartitionsnamen beispielsweise /dev/block/platform/ soc/100000.ufshc /by-name/super
lautet, können Sie den Befehlszeilenparameter wie folgt in die Datei BoardConfig.mk einfügen:
BOARD_KERNEL_CMDLINE += androidboot.boot_devices=soc/100000.ufshcSie können den Bootconfig-Parameter wie folgt in die Datei BoardConfig.mk einfügen:
BOARD_BOOTCONFIG += androidboot.boot_devices=soc/100000.ufshc
fstab ändert sich
Der Gerätebaum und die Gerätebaum-Overlays dürfen keine fstab-Einträge enthalten. Verwenden Sie eine fstab-Datei, die Teil der Ramdisk sein wird.
Für logische Partitionen müssen Änderungen an der fstab-Datei vorgenommen werden:
- Das Feld „fs_mgr flags“ muss das
logical
Flag und das in Android 10 eingeführte Flagfirst_stage_mount
“ enthalten, das angibt, dass eine Partition in der ersten Stufe gemountet werden soll. - Eine Partition kann
avb= vbmeta partition name
alsfs_mgr
Flag angeben und dann wird die angegebenevbmeta
Partition durch die ersteinit
Stufe initialisiert, bevor versucht wird, Geräte zu mounten. - Das
dev
Feld muss der Partitionsname sein.
Die folgenden fstab-Einträge legen System, Hersteller und Produkt als logische Partitionen gemäß den oben genannten Regeln fest.
#<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 fstab-Datei in die Ramdisk der ersten Stufe.
SELinux-Änderungen
Das Superpartitionsblockgerät muss mit der Bezeichnung super_block_device
gekennzeichnet sein. Wenn der Symlink für den Superpartitionsnamen 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 zum Userspace gehört) versteht dynamische Partitionen nicht und kann sie daher nicht flashen. Um dieses Problem zu lösen, müssen Geräte eine User-Space-Implementierung des Fastboot-Protokolls namens fastbootd verwenden.
Weitere Informationen zur Implementierung von fastbootd finden Sie unter Fastboot in den User Space verschieben .
ADB-Remount
Für Entwickler, die eng- oder userdebug-Builds verwenden, ist adb remount
für eine schnelle Iteration äußerst nützlich. Dynamische Partitionen stellen beim adb remount
ein Problem dar, da in jedem Dateisystem nicht mehr freier Speicherplatz 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 trägt den Namen „ scratch
, also verwenden Sie diesen Namen nicht für andere Partitionen.
Weitere Informationen zum Aktivieren von Overlayfs finden Sie in der Overlayfs-README-Datei in AOSP.
Aktualisieren Sie Android-Geräte
Wenn Sie ein Gerät auf Android 10 aktualisieren und die Unterstützung dynamischer Partitionen in den OTA einbinden möchten, müssen Sie die integrierte Partitionstabelle nicht ändern. Es ist eine zusätzliche Konfiguration erforderlich.
Änderungen der Gerätekonfiguration
Um die dynamische Partitionierung nachzurüsten, fügen Sie die folgenden Flags in device.mk
hinzu:
PRODUCT_USE_DYNAMIC_PARTITIONS := true PRODUCT_RETROFIT_DYNAMIC_PARTITIONS := true
Änderungen an der Platinenkonfiguration
Sie müssen die folgenden Board-Variablen festlegen:
- Setzen Sie
BOARD_SUPER_PARTITION_BLOCK_DEVICES
auf die Liste der Blockgeräte, die zum Speichern von Bereichen dynamischer Partitionen verwendet werden. Dies ist die Liste der Namen vorhandener physischer Partitionen auf dem Gerät. - Stellen Sie
BOARD_SUPER_PARTITION_ partition _DEVICE_SIZE
jeweils auf die Größe jedes Blockgeräts inBOARD_SUPER_PARTITION_BLOCK_DEVICES
ein. Dies ist die Liste der Größen vorhandener physischer Partitionen auf dem Gerät. In vorhandenen Board-Konfigurationen ist dies normalerweiseBOARD_ partition IMAGE_PARTITION_SIZE
. - Setzen Sie die vorhandene
BOARD_ partition IMAGE_PARTITION_SIZE
für alle Partitionen inBOARD_SUPER_PARTITION_BLOCK_DEVICES
zurück. - Setzen Sie
BOARD_SUPER_PARTITION_SIZE
auf die Summe vonBOARD_SUPER_PARTITION_ partition _DEVICE_SIZE
. - Legen Sie
BOARD_SUPER_PARTITION_METADATA_DEVICE
auf das Blockgerät fest, auf dem dynamische Partitionsmetadaten gespeichert sind. Es muss eines vonBOARD_SUPER_PARTITION_BLOCK_DEVICES
sein. Normalerweise ist dies aufsystem
eingestellt. - Legen Sie
BOARD_SUPER_PARTITION_GROUPS
,BOARD_ group _SIZE
bzw.BOARD_ group _PARTITION_LIST
fest. Weitere Informationen finden Sie unter „Änderungen der Platinenkonfiguration bei neuen Geräten“ .
Wenn das Gerät beispielsweise bereits über System- und Herstellerpartitionen verfügt und Sie diese während des Updates in dynamische Partitionen umwandeln und eine neue Produktpartition hinzufügen möchten, legen Sie diese Platinenkonfiguration 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 Superpartitionsblockgeräte müssen mit dem Attribut super_block_device_type
gekennzeichnet sein. Wenn das Gerät beispielsweise bereits über system
und vendor
verfügt, möchten Sie diese als Blockgeräte verwenden, um Bereiche dynamischer Partitionen zu speichern, und ihre symbolischen Links nach Namen werden als system_block_device
markiert:
/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 die folgende Zeile zu device.te
hinzu:
typeattribute system_block_device super_block_device_type;
Weitere Konfigurationen finden Sie unter Implementieren dynamischer Partitionen auf neuen Geräten .
Weitere Informationen zu Retrofit-Updates finden Sie unter OTA für A/B-Geräte ohne dynamische Partitionen .
Fabrikbilder
Vermeiden Sie bei einem Gerätestart mit Unterstützung für dynamische Partitionen die Verwendung von Userspace-Fastboot zum Flashen von Factory-Images, da das Booten in den Userspace langsamer ist als bei anderen Flash-Methoden.
Um dieses Problem zu beheben, erstellt make dist
jetzt ein zusätzliches super.img
Image, das direkt auf die Superpartition geflasht werden kann. Es bündelt automatisch den Inhalt logischer Partitionen, d. h. es enthält zusätzlich zu den super
system.img
, vendor.img
usw. Dieses Image kann ohne zusätzliche Tools oder die Verwendung von fastbootd direkt auf die super
geflasht werden. Nach dem Build wird super.img
in ${ANDROID_PRODUCT_OUT}
platziert.
Bei A/B-Geräten, die mit dynamischen Partitionen starten, enthält super.img
Bilder im A-Slot. Nachdem Sie das Super-Image direkt geflasht haben, markieren Sie Steckplatz A als bootfähig, bevor Sie das Gerät neu starten.
Für Nachrüstgeräte erstellt make dist
einen Satz super_*.img
Images, die direkt auf die entsprechenden physischen Partitionen geflasht werden können. Beispielsweise erstellt make dist
super_system.img
und super_vendor.img
, wenn BOARD_SUPER_PARTITION_BLOCK_DEVICES
der Systemanbieter ist. Diese Bilder werden im OTA-Ordner in target_files.zip
abgelegt.
Optimierung des Device Mapper-Speichergeräts
Die dynamische Partitionierung berücksichtigt eine Reihe nichtdeterministischer Device-Mapper-Objekte. Da diese möglicherweise nicht alle wie erwartet instanziiert werden, 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
verfolgt die Bereitstellungen und aktualisiert die Android-Eigenschaften asynchron. Es kann nicht garantiert werden, dass dies innerhalb eines bestimmten Zeitraums dauert. Sie müssen daher genügend Zeit einplanen, damit alle Auslöser on property
reagieren können. Die Eigenschaften sind dev.mnt.blk. <partition>
wobei <partition>
beispielsweise root
, system
, data
oder vendor
ist. Jede Eigenschaft ist mit dem Namen des Basisspeichergeräts verknüpft, wie in den folgenden 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 Sprache init.rc
können die Android-Eigenschaften im Rahmen der Regeln erweitert werden, und 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 Stufe init
beginnt, wird die epoll loop
aktiv und die Werte werden aktualisiert. Da Eigenschaftsauslöser jedoch erst in der Late- init
aktiv sind, können sie in den ersten Startphasen nicht zur Verarbeitung root
, system
oder vendor
verwendet werden. Sie können davon ausgehen, dass die Kernel-Standardeinstellung read_ahead_kb
ausreicht, bis die init.rc
Skripte in early-fs
überschreiben können (wenn verschiedene Daemons und Einrichtungen gestartet werden). Daher empfiehlt Google, dass Sie die on property
Funktion in Verbindung mit einer init.rc
-gesteuerten Eigenschaft wie sys.read_ahead_kb
verwenden, um das Timing der Vorgänge zu steuern und Race Conditions zu verhindern, wie in den folgenden 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}