Implementieren dynamischer Partitionen

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.

Layout der Partitionstabelle
Abbildung 1. Neues Tabellenlayout für physische Partitionen bei 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 und vbmeta_vendor . Fügen Sie für A/B-Geräte vbmeta_system_a , vbmeta_system_b , vbmeta_vendor_a und vbmeta_vendor_b . 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 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:

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.ufshc
Sie 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ührte first_stage_mount Flag enthalten, das angibt, dass eine Partition in der ersten Phase bereitgestellt werden soll.
  • Eine Partition kann avb= vbmeta partition name als fs_mgr -Flag angeben, und dann wird die angegebene vbmeta Partition durch die Erststufeninitialisierung init , 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 in BOARD_SUPER_PARTITION_BLOCK_DEVICES ein. Dies ist die Liste der Größen vorhandener physischer Partitionen auf dem Gerät. Dies ist normalerweise BOARD_ partition IMAGE_PARTITION_SIZE in bestehenden Platinenkonfigurationen.
  • Vorhandene BOARD_ partition IMAGE_PARTITION_SIZE für alle Partitionen in BOARD_SUPER_PARTITION_BLOCK_DEVICES .
  • Legen Sie BOARD_SUPER_PARTITION_SIZE auf die Summe von BOARD_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 von BOARD_SUPER_PARTITION_BLOCK_DEVICES . Normalerweise ist dies auf system 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}