Partitionslayout

In Android 10 ist das Stammdateisystem nicht mehr in ramdisk.img enthalten, sondern wird in system.img zusammengeführt (d. h. system.img wird immer so erstellt, als wäre BOARD_BUILD_SYSTEM_ROOT_IMAGE festgelegt). Geräte, die bei Markteinführung Android 10 nutzen:

  • Verwenden Sie ein System-as-Root-Partitionslayout (wird automatisch durch den Build erzwungen, ohne dass das Verhalten geändert werden kann).
  • Es muss eine Ramdisk verwendet werden, die für dm-linear erforderlich ist.
  • Sie müssen BOARD_BUILD_SYSTEM_ROOT_IMAGE auf false setzen. Diese Einstellung wird nur verwendet, um zwischen Geräten mit Ramdisk und Geräten ohne Ramdisk zu unterscheiden (die stattdessen system.img direkt einbinden).

Die Bedeutung einer System-as-Root-Konfiguration unterscheidet sich zwischen Android 9 und Android 10. In einer Android 9-Konfiguration mit System-as-Root wird BOARD_BUILD_SYSTEM_ROOT_IMAGE auf true festgelegt. Dadurch wird der Build gezwungen, das Root-Dateisystem in system.img zusammenzuführen und dann system.img als Root-Dateisystem (rootfs) bereitzustellen. Diese Konfiguration ist erforderlich für Geräte, die mit Android 9 auf den Markt kommen, aber optional für Geräte, die ein Upgrade auf Android 9 erhalten, und für Geräte mit niedrigeren Android-Versionen. In einer System-as-Root-Konfiguration für Android 10 werden $TARGET_SYSTEM_OUT und $TARGET_ROOT_OUT immer in system.img zusammengeführt. Diese Konfiguration ist das Standardverhalten für alle Geräte mit Android 10.

In Android 10 werden weitere Änderungen zur Unterstützung von dynamischen Partitionen vorgenommen. Dabei handelt es sich um ein Partitionierungssystem für den Nutzerbereich, das es ermöglicht, Partitionen per Over-the-Air-Update (OTA) zu erstellen, in der Größe zu ändern oder zu löschen. Im Rahmen dieser Änderung kann der Linux-Kernel die logische Systempartition auf Geräten mit Android 10 nicht mehr bereitstellen. Dieser Vorgang wird daher vom Init-Prozess der ersten Phase übernommen.

In den folgenden Abschnitten werden die System-as-Root-Anforderungen für reine System-OTAs beschrieben und es wird erläutert, wie Geräte für die Verwendung von System-as-Root aktualisiert werden (einschließlich Änderungen am Partitionslayout und dm-verity-Kernelanforderungen). Weitere Informationen zu Änderungen an der Ramdisk finden Sie unter Ramdisk-Partitionen.

OTA-Updates nur für das System

System-only-OTAs, mit denen Android-Releases system.img und product.img aktualisiert werden können, ohne andere Partitionen zu ändern, erfordern ein System-as-Root-Partitionslayout. Alle Geräte mit Android 10 müssen ein System-as-Root-Partitionslayout verwenden, um reine System-OTAs zu ermöglichen.

Weitere Informationen zu A/B- und Nicht-A/B-Geräten finden Sie unter A/B-Systemupdates (nahtlos).

Anbieter-Overlay verwenden (<=AOSP 14)

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

Wenn das Gerät hochfährt, schließt der init-Prozess die erste Phase des Mountings ab und liest die Standardeigenschaften. Anschließend wird nach /product/vendor_overlay/<target_vendor_version> gesucht und jedes Unterverzeichnis wird im entsprechenden vendor-Partitionsverzeichnis gemountet, wenn die folgenden Bedingungen erfüllt sind:

  • /vendor/<overlay_dir> ist vorhanden.
  • /product/vendor_overlay/<target_vendor_version>/<overlay_dir> hat denselben Dateikontext wie /vendor/<overlay_dir>.
  • init darf im Dateikontext von /vendor/<overlay_dir> eingebunden werden.

Anbieter-Overlay implementieren

Installieren Sie Anbieter-Overlay-Dateien in /product/vendor_overlay/<target_vendor_version>. Diese Dateien werden beim Starten des Geräts über die Partition vendor gelegt. Dateien mit demselben Namen werden ersetzt und neue Dateien werden hinzugefügt. Mit dem Anbieter-Overlay können keine Dateien aus der Partition vendor entfernt werden.

Vendor-Overlay-Dateien müssen denselben Dateikontext wie die Zieldateien haben, die sie in der Partition vendor ersetzen. Standardmäßig haben die Dateien im Verzeichnis /product/vendor_overlay/<target_vendor_version> den Kontext vendor_file. Wenn es zwischen Vendor-Overlay-Dateien und den Dateien, die sie ersetzen, Abweichungen im Dateikontext gibt, geben Sie dies in der gerätespezifischen SELinux-Richtlinie 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 das Anbieter-Overlay-Verzeichnis nicht auf das Zielverzeichnis gelegt.

Damit das Anbieter-Overlay verwendet werden kann, muss OverlayFS im Kernel durch Festlegen von CONFIG_OVERLAY_FS=y aktiviert werden. 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 von Vendor Overlays

In dieser Anleitung wird gezeigt, wie ein Anbieter-Overlay implementiert wird, das die Verzeichnisse /vendor/lib/*, /vendor/etc/* und /vendor/app/* überlagert.

  1. Fügen Sie vordefinierte Anbieterdateien 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 Anbieterdateien 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 Zieldateien der Partition vendor andere Kontexte als vendor_file haben. Da /vendor/lib/* den Kontext vendor_file verwendet, ist dieses Verzeichnis in diesem Beispiel nicht enthalten.

    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. Erlauben Sie dem init-Prozess, das Anbieter-Overlay in anderen Dateikontexten als vendor_file einzubinden. Da der init-Prozess bereits die Berechtigung hat, im vendor_file-Kontext einzubinden, wird in diesem Beispiel keine Richtlinie für vendor_file 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;

Anbieter-Overlay validieren

Wenn Sie die Anbieter-Overlay-Konfiguration validieren möchten, fügen Sie Dateien in /product/vendor_overlay/<target_vendor_version>/<overlay_dir> hinzu und prüfen Sie, ob die Dateien in /vendor/<overlay_dir> überschrieben werden.

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

$ atest -v fs_mgr_vendor_overlay_test

Update auf „system-as-root“

Wenn Sie Geräte, die nicht A/B-Geräte sind, so aktualisieren möchten, dass sie „System-as-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 Stammordnern entfernen.

Partitionen aktualisieren

Im Gegensatz zu A/B-Geräten, bei denen /boot als Wiederherstellungs-Partition verwendet wird, muss die /recovery-Partition bei Nicht-A/B-Geräten separat bleiben, da sie nicht über die Fallback-Slot-Partition verfügen (z. B. von boot_a zu boot_b). Wenn /recovery auf einem Nicht-A/B-Gerät entfernt und dem A/B-Schema angeglichen wird, kann der Wiederherstellungsmodus bei einem fehlgeschlagenen Update der /boot-Partition fehlschlagen. Aus diesem Grund muss die /recovery-Partition für Geräte, die keine A/B-Geräte sind, eine separate Partition von /boot sein. Das bedeutet, dass das Wiederherstellungsimage weiterhin verzögert aktualisiert wird (d. h. wie bei Geräten mit Android 8.1.0 oder niedriger).

In der folgenden Tabelle sind die Unterschiede bei den Image-Partitionen für Geräte ohne A/B-Partitionierung vor und nach Android 9 aufgeführt.

Bild Ramdisk (vor Android 9) System-as-root (nach Android 9)
boot.img Enthält einen Kernel und ein 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 die zusammengeführten Inhalte von Original 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

Bei „System-as-Root“ muss der Kernel system.img unter / (Bereitstellungspunkt) mit dm-verity bereitstellen. AOSP unterstützt die folgenden dm-verity-Implementierungen für system.img.

vboot 1.0

Bei vboot 1.0 muss der Kernel Android-spezifische Metadaten auf /system parsen 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 einbinden, das dann den Hashtree-Deskriptor für /system parst, in dm-verity-Parameter konvertiert und die Parameter schließlich über die Kernel-Befehlszeile an den Kernel übergibt. (Hashtree-Deskriptoren von /system befinden sich möglicherweise auf /vbmeta oder auf /system selbst.)

Für vboot 2.0 sind die folgenden Kernel-Patches erforderlich:

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"

Gerätespezifische Stammordner verwenden

Bei „System-as-Root“ sind alle gerätespezifischen Stammordner, die mit BOARD_ROOT_EXTRA_FOLDERS hinzugefügt wurden, nach dem Flashen des generischen Systemimages (GSI) auf dem Gerät (und vor dem Ausführen der Vendor Test Suite-Tests) nicht mehr vorhanden, da der gesamte Inhalt des Stammverzeichnisses durch das System-as-Root-GSI ersetzt wurde. Das Entfernen dieser Ordner kann dazu führen, dass das Gerät nicht mehr gestartet werden kann, wenn eine Abhängigkeit von den gerätespezifischen Stammordnern besteht (z. B. wenn sie als Mount-Punkte verwendet werden).

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