Partitionslayout

In Android 10 ist das Root-Dateisystem nicht mehr in ramdisk.img enthalten und wird stattdessen in system.img zusammengeführt (d. h. system.img wird immer so erstellt, als ob BOARD_BUILD_SYSTEM_ROOT_IMAGE festgelegt wäre). Geräte, die mit Android 10 starten:

  • Verwenden Sie ein System-als-Root-Partitionslayout (wird vom Build automatisch erzwungen, ohne Optionen zum Ändern des Verhaltens).
  • Es muss eine Ramdisk verwendet werden, die für dm-linear erforderlich ist.
  • BOARD_BUILD_SYSTEM_ROOT_IMAGE muss auf false gesetzt werden. Diese Einstellung dient nur zur Unterscheidung zwischen Geräten, die eine Ramdisk verwenden, und Geräten, die keine Ramdisk verwenden (und stattdessen system.img direkt mounten).

Die Bedeutung einer System-als-Root-Konfiguration unterscheidet sich zwischen Android 9 und Android 10. In einer Android 9-System-als-Root-Konfiguration ist BOARD_BUILD_SYSTEM_ROOT_IMAGE auf true gesetzt, was den Build dazu zwingt, das Root-Dateisystem dann in system.img zusammenzuführen Mounten Sie system.img als Root-Dateisystem (rootfs). Diese Konfiguration ist für Geräte, die mit Android 9 starten, obligatorisch , ist jedoch für Geräte, die auf Android 9 aktualisieren, und für Geräte, auf denen niedrigere Android-Versionen ausgeführt werden, optional . In einer Android 10-System-als-Root-Konfiguration führt der Build immer $TARGET_SYSTEM_OUT und $TARGET_ROOT_OUT in system.img zusammen; Diese Konfiguration ist das Standardverhalten für alle Geräte mit Android 10.

Android 10 nimmt weitere Änderungen vor, um dynamische Partitionen zu unterstützen, ein Userspace-Partitionierungssystem, das OTA-Updates (Over-the-Air) zum Erstellen, Ändern der Größe oder Zerstören von Partitionen ermöglicht. Im Rahmen dieser Änderung kann der Linux-Kernel die logische Systempartition auf Geräten mit Android 10 nicht mehr mounten, sodass dieser Vorgang von der ersten Init-Stufe übernommen wird.

In den folgenden Abschnitten werden die System-als-Root-Anforderungen für Nur-System-OTAs beschrieben und Anleitungen zum Aktualisieren von Geräten für die Verwendung von System-als-Root bereitgestellt (einschließlich Änderungen am Partitionslayout und dm-verity-Kernelanforderungen). Einzelheiten zu Änderungen an der Ramdisk finden Sie unter Ramdisk-Partitionen .

Über systemspezifische OTAs

Nur-System-OTAs, die es Android-Versionen ermöglichen, system.img und product.img zu aktualisieren, ohne andere Partitionen zu ändern, erfordern ein System-als-Root-Partitionslayout. Alle Geräte mit Android 10 müssen ein System-als-Root-Partitionslayout verwenden, um reine System-OTAs zu ermöglichen.

Einzelheiten zu A/B- und Nicht-A/B-Geräten finden Sie unter A/B (Seamless) System Updates .

Verwendung des Anbieter-Overlays

Mit der Herstellerüberlagerung können Sie Änderungen an der vendor beim Gerätestart überlagern. Ein Anbieter-Overlay ist eine Reihe von Anbietermodulen in der product , die beim Booten des Geräts auf der vendor überlagert werden und die vorhandenen Module ersetzen und ergänzen.

Wenn das Gerät startet, schließt der init Prozess die erste Mount-Phase ab und liest die Standardeigenschaften. Anschließend wird /product/vendor_overlay/<target_vendor_version> durchsucht und jedes Unterverzeichnis im entsprechenden vendor bereitgestellt, wenn die folgenden Bedingungen erfüllt sind:

  • /vendor/<overlay_dir> existiert.
  • /product/vendor_overlay/<target_vendor_version>/<overlay_dir> hat den gleichen Dateikontext wie /vendor/<overlay_dir> .
  • init darf im Dateikontext von /vendor/<overlay_dir> mounten.

Implementierung eines Anbieter-Overlays

Installieren Sie Anbieter-Overlay-Dateien in /product/vendor_overlay/<target_vendor_version> . Diese Dateien überlagern beim Booten des Geräts die vendor , ersetzen Dateien mit demselben Namen und fügen alle neuen Dateien hinzu. Das Anbieter-Overlay kann keine Dateien von der vendor entfernen.

Hersteller-Overlay-Dateien müssen denselben Dateikontext haben wie die Zieldateien, die sie in der vendor ersetzen. Standardmäßig haben die Dateien im Verzeichnis /product/vendor_overlay/<target_vendor_version> den Kontext vendor_file . Wenn zwischen den Overlay-Dateien des Herstellers und den durch sie ersetzten Dateien Dateikontextkonflikte bestehen, geben Sie dies in der gerätespezifischen Separierungsrichtlinie an. Der Dateikontext wird auf Verzeichnisebene festgelegt. Wenn der Dateikontext eines Anbieter-Overlay-Verzeichnisses nicht mit dem Zielverzeichnis übereinstimmt und der richtige Dateikontext nicht in der gerätespezifischen Sepolicy angegeben ist, wird dieses Anbieter-Overlay-Verzeichnis nicht über das Zielverzeichnis gelegt.

Um das Hersteller-Overlay zu verwenden, muss der Kernel OverlayFS aktivieren, indem er CONFIG_OVERLAY_FS=y festlegt. Außerdem muss der Kernel aus dem gemeinsamen Kernel 4.4 oder höher zusammengeführt oder mit "overlayfs: override_creds=off option bypass creator_cred" gepatcht werden.

Beispiel für die Implementierung eines Anbieter-Overlays

Dieses Verfahren veranschaulicht die Implementierung eines Anbieter-Overlays, das die Verzeichnisse /vendor/lib/* , /vendor/etc/* und /vendor/app/* überlagert.

  1. Fügen Sie vorgefertigte Herstellerdateien in device/<vendor>/<target>/vendor_overlay/<target_vendor_version>/ hinzu:

    device/google/device/vendor_overlay/28/lib/libfoo.so
    device/google/device/vendor_overlay/28/lib/libbar.so
    device/google/device/vendor_overlay/28/etc/baz.xml
    device/google/device/vendor_overlay/28/app/qux.apk
    
  2. Installieren Sie die vorgefertigten Herstellerdateien in „ product/vendor_overlay in device/google/device/device.mk “:

    PRODUCT_COPY_FILES += \
        $(call find-copy-subdir-files,*,device/google/device/vendor_overlay,$(TARGET_COPY_OUT_PRODUCT)/vendor_overlay)
    
  3. Definieren Sie Dateikontexte, wenn die Partitionsdateien vendor andere Kontexte als vendor_file haben. Da /vendor/lib/* den vendor_file Kontext verwendet, enthält dieses Beispiel dieses Verzeichnis nicht.

    Fügen Sie Folgendes zu device/google/device-sepolicy/private/file_contexts hinzu:

    /(product|system/product)/vendor_overlay/[0-9]+/etc(/.*)?   u:object_r:vendor_configs_file:s0
    /(product|system/product)/vendor_overlay/[0-9]+/app(/.*)?   u:object_r:vendor_app_file:s0
    
  4. Ermöglichen Sie dem init Prozess, das Anbieter-Overlay in anderen Dateikontexten als vendor_file bereitzustellen. Da der init Prozess bereits über die Berechtigung zum Mounten im vendor_file Kontext verfügt, wird in diesem Beispiel die Richtlinie für vendor_file nicht definiert.

    Fügen Sie Folgendes zu device/google/device-sepolicy/public/init.te hinzu:

    allow init vendor_configs_file:dir mounton;
    allow init vendor_app_file:dir mounton;
    

Validierung des Anbieter-Overlays

Um die Anbieter-Overlay-Konfiguration zu validieren, fügen Sie Dateien in /product/vendor_overlay/<target_vendor_version>/<overlay_dir> hinzu und prüfen Sie, ob die Dateien den Dateien in /vendor/<overlay_dir> überlagert sind.

Für userdebug Builds gibt es ein Testmodul für Atest :

$ atest -v fs_mgr_vendor_overlay_test

Aktualisierung auf System-als-Root

Um Nicht-A/B-Geräte so zu aktualisieren, dass sie „System als Root“ verwenden, müssen Sie das Partitionierungsschema für boot.img und system.img aktualisieren, dm-verity einrichten und alle Boot-Abhängigkeiten von den gerätespezifischen Root-Ordnern entfernen.

Partitionen aktualisieren

Im Gegensatz zu A/B-Geräten, die /boot als Wiederherstellungspartition verwenden, müssen Nicht-A/B-Geräte die /recovery Partition separat halten, da sie nicht über die Fallback-Slot-Partition verfügen (z. B. von boot_a nach boot_b ). Wenn /recovery auf einem Nicht-A/B-Gerät entfernt und dem A/B-Schema ähnlich gemacht wird, könnte der Wiederherstellungsmodus während einer fehlgeschlagenen Aktualisierung der /boot Partition unterbrochen werden. Aus diesem Grund muss die /recovery Partition für Nicht-A/B-Geräte eine von /boot getrennte Partition sein, was bedeutet, dass das Wiederherstellungsimage weiterhin verzögert aktualisiert wird (d. h. genauso wie bei Geräten mit Android). 8.1.0 oder niedriger).

In der folgenden Tabelle sind die Unterschiede bei der Bildpartition für Nicht-A/B-Geräte vor und nach Android 9 aufgeführt.

Bild Ramdisk (vor 9) System-as-root (nach 9)
boot.img Enthält einen Kernel und eine ramdisk.img :
ramdisk.img
  -/
    - init.rc
    - init
    - etc -> /system/etc
    - system/ (mount point)
    - vendor/ (mount point)
    - odm/ (mount point)
    ...
Enthält nur einen normalen Boot-Kernel.
recovery.img Enthält einen Wiederherstellungskernel und eine Wiederherstellungs ramdisk.img .
system.img Enthält Folgendes:
system.img
  -/
    - bin/
    - etc
    - vendor -> /vendor
    - ...
Enthält den zusammengeführten Inhalt der ursprünglichen system.img und ramdisk.img :
system.img
  -/
    - init.rc
    - init
    - etc -> /system/etc
    - system/
      - bin/
      - etc/
      - vendor -> /vendor
      - ...
    - vendor/ (mount point)
    - odm/ (mount point)
    ...

Die Partitionen selbst ändern sich nicht; Sowohl Ramdisk als auch System-as-Root verwenden das folgende Partitionsschema:

  • /boot
  • /system
  • /system
  • /recovery
  • /vendor usw.

dm-verity einrichten

Im System-als-Root-System muss der Kernel system.img unter / (Einhängepunkt) mit dm-verity mounten. AOSP unterstützt die folgenden dm-verity-Implementierungen für system.img .

vboot 1.0

Für vboot 1.0 muss der Kernel Android-spezifische Metadaten auf /system analysieren und dann in dm-verity-Parameter konvertieren, um dm-verity einzurichten (erfordert diese Kernel-Patches ). Das folgende Beispiel zeigt dm-verity-bezogene Einstellungen für „System-as-Root“ in der Kernel-Befehlszeile:

ro root=/dev/dm-0 rootwait skip_initramfs init=/init
dm="system none ro,0 1 android-verity /dev/sda34"
veritykeyid=id:7e4333f9bba00adfe0ede979e28ed1920492b40f

vboot 2.0

Für vboot 2.0 ( AVB ) muss der Bootloader external/avb/libavb integrieren, das dann den Hashtree-Deskriptor für /system analysiert, ihn in dm-verity params konvertiert und die Parameter schließlich über die Kernel-Befehlszeile an den Kernel übergibt. (Hashtree-Deskriptoren von /system können sich auf /vbmeta oder auf /system selbst befinden.)

vboot 2.0 erfordert die folgenden Kernel-Patches:

Das folgende Beispiel zeigt dm-verity-bezogene Einstellungen für „System-as-Root“ in der Kernel-Befehlszeile:

ro root=/dev/dm-0 rootwait  skip_initramfs init=/init

dm="1 vroot none ro 1,0 5159992 verity 1
PARTUUID=00000016-0000-0000-0000-000000000000
PARTUUID=00000016-0000-0000-0000-000000000000 4096 4096 644999 644999
sha1 d80b4a8be3b58a8ab86fad1b498640892d4843a2
8d08feed2f55c418fb63447fec0d32b1b107e42c 10 restart_on_corruption
ignore_zero_blocks use_fec_from_device
PARTUUID=00000016-0000-0000-0000-000000000000 fec_roots 2 fec_blocks
650080 fec_start 650080"

Verwendung gerätespezifischer Stammordner

Bei System-as-Root sind alle mit BOARD_ROOT_EXTRA_FOLDERS hinzugefügten gerätespezifischen Stammordner verschwunden, nachdem das generische Systemabbild (GSI) auf dem Gerät geflasht wurde (und bevor Vendor Test Suite- Tests ausgeführt werden), da der gesamte Inhalt des Stammverzeichnisses ersetzt wurde durch das System-as-Root-GSI. Das Entfernen dieser Ordner kann dazu führen, dass das Gerät nicht mehr bootfähig ist, wenn eine Abhängigkeit von den gerätespezifischen Stammordnern besteht (sie werden beispielsweise als Bereitstellungspunkte verwendet).

Um dieses Problem zu vermeiden, verwenden Sie BOARD_ROOT_EXTRA_FOLDERS nicht, um gerätespezifische Stammordner hinzuzufügen. Wenn Sie gerätespezifische Mount-Punkte angeben müssen, verwenden Sie /mnt/vendor/<mount point> (in diesen Änderungslisten hinzugefügt). Diese herstellerspezifischen Mount-Punkte können direkt sowohl im fstab Gerätebaum (für die Mount-Phase der ersten Stufe) als auch in der Datei /vendor/etc/fstab.{ro.hardware} ohne zusätzliche Einrichtung angegeben werden (da fs_mgr sie unter /mnt/vendor/* automatisch).