Die dynamische Partitionierung wird mit dem dm-linearen Device-Mapper-Modul 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 virtuelle Blockgeräte werden erstellt, um jede dynamische Partition darzustellen.
Beim Anwenden eines OTA werden dynamische Partitionen 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 Zielsteckplatz 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 einer Aktualisierungsgruppe angehören. Diese Gruppen begrenzen den maximalen Speicherplatz, den Partitionen in dieser Gruppe verbrauchen können. system
und vendor
können beispielsweise zu einer Gruppe gehören, die die Gesamtgröße von system
und vendor
einschränkt.
Implementierung dynamischer Partitionen auf neuen Geräten
In diesem Abschnitt wird beschrieben, wie Sie dynamische Partitionen auf neuen Geräten implementieren, die mit Android 10 und höher gestartet werden. Informationen zum Aktualisieren vorhandener Geräte finden Sie unter Aktualisieren von Android-Geräten .
Partitionierungsänderungen
Erstellen Sie für Geräte, die mit Android 10 gestartet werden, eine Partition namens super
. Die super
Partition verwaltet A/B-Slots 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. Anbieterspezifische Partitionen müssen nicht dynamisch sein und können in der GPT platziert werden.
Um die Größe von super
abzuschätzen, addieren Sie die Größen der Partitionen, die aus der GPT gelöscht werden. Bei A/B-Geräten sollte dies die Größe beider Steckplätze beinhalten. Abbildung 1 zeigt eine beispielhafte Partitionstabelle vor und nach der Konvertierung in dynamische Partitionen.

Die unterstützten dynamischen Partitionen sind:
- System
- Verkäufer
- Produkt
- Systemext
- ODM
Für Geräte, 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 bestimmt wird. Standardmäßig geht das Build-System (über lpmake
, das das super
-Partitions-Image generiert) davon aus, dass ein 1-MiB-Alignment für jede dynamische Partition ausreicht. Anbieter sollten jedoch sicherstellen, dass die super
richtig ausgerichtet ist.
Sie können die minimale Anforderungsgröße eines Blockgeräts bestimmen, indem Sie sysfs
. 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
:
PRODUCT_USE_DYNAMIC_PARTITIONS := true
Board-Konfigurationsänderungen
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 dynamischer Partitions-Images mehr als die Hälfte der super
Partitionsgröße 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 hat dann eine BOARD_ group _SIZE
und BOARD_ group _PARTITION_LIST
. Bei A/B-Geräten sollte die maximale Größe einer Gruppe nur einen Slot umfassen, da die Gruppennamen intern Slot-suffixiert werden.
Hier ist ein Beispielgerät, das alle Partitionen in einer Gruppe namens example_dynamic_partitions
:
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 Produktservices in group_foo
und vendor
, product
und odm
in group_bar
:
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 sein:
BOARD_SUPER_PARTITION_SIZE
- Overhead
Siehe Implementieren 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 Build-Zeitpunkt 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 Overhead erforderlich, um Metadaten, Alignments usw. zu berücksichtigen. Ein angemessener Overhead beträgt 4 MiB, aber Sie können je nach Bedarf des Geräts einen größeren Overhead auswählen.
Dimensionierung dynamischer Partitionen
Vor dynamischen Partitionen wurden Partitionsgrößen überbelegt, um sicherzustellen, dass sie genügend Platz für zukünftige Updates hatten. Die tatsächliche Größe wurde unverändert genommen und die meisten schreibgeschützten Partitionen hatten eine gewisse Menge an freiem 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 Platz verschwenden und einer minimal möglichen 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 sich dem Image an, sodass das Dateisystem so wenig ungenutzten Platz wie möglich hat. Dadurch wird sichergestellt, dass das Gerät keinen Platz verschwendet, der für OTAs verwendet werden kann.
Darüber hinaus können ext4-Images weiter komprimiert werden, indem die Deduplizierung auf Blockebene aktiviert wird. Um dies zu aktivieren, verwenden Sie die folgende Konfiguration:
BOARD_EXT4_SHARE_DUP_BLOCKS := true
Wenn die automatische Zuweisung einer Mindestpartitionsgröße 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 zwingen. Beides wird nicht empfohlen, es sei denn, es ist notwendig.
Zum Beispiel:
BOARD_PRODUCTIMAGE_PARTITION_RESERVED_SIZE := 52428800
Dadurch wird das Dateisystem in product.img
, 50 MiB ungenutzten Speicherplatz zu haben.
System-als-Root-Änderungen
Geräte, die mit Android 10 gestartet werden, dürfen System-as-Root nicht verwenden.
Geräte mit dynamischen Partitionen (unabhängig davon, ob sie mit dynamischen Partitionen gestartet oder nachgerüstet werden) dürfen System-as-Root nicht verwenden. Der Linux-Kernel kann die super
nicht interpretieren und kann daher das system
selbst nicht einhängen. Das system
wird jetzt von der ersten Stufe init
gemountet, die sich auf der Ramdisk befindet.
Legen Sie BOARD_BUILD_SYSTEM_ROOT_IMAGE
nicht fest. In Android 10 wird das BOARD_BUILD_SYSTEM_ROOT_IMAGE
Flag nur verwendet, um zu unterscheiden, ob das System vom Kernel oder von der First-Stage- init
in der Ramdisk gemountet wird.
Das Festlegen von BOARD_BUILD_SYSTEM_ROOT_IMAGE
auf true
verursacht einen Build-Fehler, wenn PRODUCT_USE_DYNAMIC_PARTITIONS
ebenfalls true
ist .
Wenn BOARD_USES_RECOVERY_AS_BOOT
auf „true“ gesetzt ist, wird das Wiederherstellungs-Image als „boot.img“ erstellt, das die Ramdisk der Wiederherstellung enthält. Zuvor verwendete der Bootloader den Kernel-Befehlszeilenparameter skip_initramfs
, um zu entscheiden, in welchen 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
, um die Wiederherstellung zu überspringen und normales Android zu booten. 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 Sie Android Verified Boot 2.0 verwenden und das Gerät 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 eine vbmeta-Fußzeile am Ende der system
und vendor
. 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
. Fügen Sie für A/B-Gerätevbmeta_system_a
,vbmeta_system_b
,vbmeta_vendor_a
undvbmeta_vendor_b
. Wenn Sie eine oder mehrere dieser Partitionen hinzufügen, sollten sie dieselbe Größe wie dievbmeta
Partition haben. - Benennen Sie die Konfigurationsflags um, indem
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 beim Verketten mit einer logischen Partition erforderlich.
AVB-Bootloader ändert sich
Wenn der Bootloader libavb eingebettet hat, schließen Sie die folgenden Patches ein:
- 818cf56740775446285466eda984acedd4baeac0 – „libavb: Partitions-GUIDs nur abfragen, wenn die cmdline sie benötigt.“
- 5abd6bc2578968d24406d834471adfd995a0c2e9 – „Abwesenheit der Systempartition zulassen“
- 9ba3b6613b4e5130fa01a11d984c6b5f0eb3af05 – „AvbSlotVerifyData->cmdline kann 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
Der Kernel-Befehlszeile muss ein neuer Parameter, androidboot.boot_devices
, hinzugefügt werden. Dies wird von init
verwendet, um /dev/block/by-name
Symlinks zu aktivieren. Es sollte die Gerätepfadkomponente zum zugrunde liegenden symbolischen Link nach Name sein, der von ueventd
erstellt wurde, d. h. /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 der Superpartition nach Namen beispielsweise /dev/block/platform/ soc/100000.ufshc /by-name/super
, 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 Parameter bootconfig in der Datei BoardConfig.mk wie folgt hinzufügen:
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 der Ramdisk sein wird.
Für logische Partitionen müssen Änderungen an der fstab-Datei vorgenommen werden:
- Das Flag-Feld fs_mgr muss das
logical
Flag und das in Android 10 eingeführtefirst_stage_mount
Flag enthalten, das angibt, dass eine Partition in der ersten Phase bereitgestellt werden soll. - Eine Partition kann
avb= vbmeta partition name
alsfs_mgr
-Flag angeben, und dann wird die angegebenevbmeta
Partition durch die Erststufeninitialisierunginit
, bevor versucht wird, irgendwelche Geräte zu mounten. - Das
dev
-Feld muss der Partitionsname sein.
Die folgenden fstab-Einträge legen System, Hersteller und Produkt als logische Partitionen fest, die den obigen Regeln folgen.
#<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 Blockgerät der Superpartition muss mit dem Label super_block_device
gekennzeichnet sein. Wenn der Symlink der Superpartition nach Namen beispielsweise /dev/block/platform/ soc/100000.ufshc /by-name/super
lautet, fügen Sie die folgende Zeile zu file_contexts
:
/dev/block/platform/soc/10000\.ufshc/by-name/super u:object_r:super_block_device:s0
fastbootd
Der Bootloader (oder ein beliebiges Nicht-Userspace-Flashing-Tool) versteht dynamische Partitionen nicht und kann sie daher nicht flashen. Um dies zu beheben, müssen Geräte eine User-Space-Implementierung des Fastboot-Protokolls namens fastbootd verwenden.
Weitere Informationen zum Implementieren 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
äußerst nützlich für eine schnelle Iteration. Dynamische Partitionen stellen ein Problem für adb remount
da in jedem Dateisystem kein freier Speicherplatz mehr vorhanden ist. Um dies zu beheben, können Geräte Overlayfs aktivieren. Solange innerhalb 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
, 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 von Android-Geräten
Wenn Sie ein Gerät auf Android 10 aktualisieren und Unterstützung für dynamische Partitionen in das OTA aufnehmen möchten, müssen Sie die integrierte Partitionstabelle nicht ändern. Eine zusätzliche Konfiguration ist erforderlich.
Änderungen der Gerätekonfiguration
Um die dynamische Partitionierung nachzurüsten, fügen Sie die folgenden Flags in device.mk
:
PRODUCT_USE_DYNAMIC_PARTITIONS := true PRODUCT_RETROFIT_DYNAMIC_PARTITIONS := true
Board-Konfigurationsänderungen
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 Extents 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
auf die Größen der einzelnen Blockgeräte inBOARD_SUPER_PARTITION_BLOCK_DEVICES
ein. Dies ist die Liste der Größen vorhandener physischer Partitionen auf dem Gerät. Dies ist normalerweiseBOARD_ partition IMAGE_PARTITION_SIZE
in bestehenden Platinenkonfigurationen. - Vorhandene
BOARD_ partition IMAGE_PARTITION_SIZE
für alle Partitionen inBOARD_SUPER_PARTITION_BLOCK_DEVICES
. - Legen 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 werden. Es muss eines vonBOARD_SUPER_PARTITION_BLOCK_DEVICES
. Normalerweise ist dies aufsystem
eingestellt. - Legen Sie
BOARD_SUPER_PARTITION_GROUPS
,BOARD_ group _SIZE
bzw.BOARD_ group _PARTITION_LIST
. Einzelheiten finden Sie unter Änderungen der Platinenkonfiguration auf neuen Geräten .
Wenn das Gerät beispielsweise bereits über System- und Herstellerpartitionen verfügt und Sie diese in dynamische Partitionen konvertieren und während des Updates eine neue Produktpartition hinzufügen möchten, stellen Sie diese Platinenkonfiguration ein:
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 werden. Wenn das Gerät beispielsweise bereits über system
und vendor
verfügt, möchten Sie diese als Blockgeräte verwenden, um Extents dynamischer Partitionen zu speichern, und ihre Symlinks nach Namen sind als system_block_device
gekennzeichnet:
/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
:
typeattribute system_block_device super_block_device_type;
Informationen zu anderen 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ät, das mit Unterstützung für dynamische Partitionen gestartet wird, die Verwendung von Userspace-Fastboot zum Flashen von Factory-Images, da das Booten in den Userspace langsamer ist als andere Flash-Methoden.
Um dies zu beheben, erstellt make dist
jetzt ein zusätzliches super.img
-Image, das direkt auf die super-Partition geflasht werden kann. Es bündelt automatisch den Inhalt logischer Partitionen, d. h. es enthält zusätzlich zu den Metadaten der super
system.img
, vendor.img
usw. Dieses Image kann ohne zusätzliche Tools oder mit Fastbootd direkt auf die super
geflasht werden. Nach dem Build wird super.img
in ${ANDROID_PRODUCT_OUT}
.
Für A/B-Geräte, die mit dynamischen Partitionen gestartet werden, 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
eine Reihe von 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
.
Device-Mapper-Speichergerät-Tuning
Die dynamische Partitionierung berücksichtigt eine Reihe nicht deterministischer Device-Mapper-Objekte. Diese werden möglicherweise nicht alle wie erwartet instanziiert, daher müssen Sie alle Mounts verfolgen und die Android-Eigenschaften aller zugehörigen Partitionen mit ihren zugrunde liegenden Speichergeräten aktualisieren.
Ein Mechanismus innerhalb von init
verfolgt die Bereitstellungen und aktualisiert die Android-Eigenschaften asynchron. Es ist nicht garantiert, dass die dafür benötigte Zeit innerhalb eines bestimmten Zeitraums liegt, daher müssen Sie genügend Zeit bereitstellen, damit alle Trigger 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 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]
Die init.rc
Sprache ermöglicht es, die Android-Eigenschaften als Teil der Regeln zu erweitern, 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 von init
beginnt, wird die epoll loop
aktiv und die Werte werden aktualisiert. Da Eigenschaftsauslöser jedoch erst spät init
aktiv sind, können sie in den anfänglichen Boot-Phasen nicht verwendet werden, um root
, system
oder vendor
zu handhaben. Sie können davon ausgehen, dass der Kernel-Standard read_ahead_kb
ausreicht, bis die init.rc
early-fs
überschreiben können (wenn verschiedene Daemons und Einrichtungen starten). Daher empfiehlt Google, dass Sie die on property
in Verbindung mit einer init.rc
-kontrollierten Eigenschaft wie sys.read_ahead_kb
, um mit dem Timing der Vorgänge umzugehen und Race-Conditions zu verhindern, 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}