Disposizione delle partizioni

In Android 10, il file system root non è più incluso in ramdisk.img ed è invece unito in system.img (ovvero, system.img viene sempre creato come se fosse impostato BOARD_BUILD_SYSTEM_ROOT_IMAGE ). Dispositivi che si avviano con Android 10:

  • Utilizzare un layout della partizione system-as-root (applicato automaticamente dalla build senza opzioni per modificare il comportamento).
  • È necessario utilizzare un ramdisk, richiesto per dm-linear.
  • È necessario impostare BOARD_BUILD_SYSTEM_ROOT_IMAGE su false . Questa impostazione viene utilizzata solo per distinguere tra dispositivi che utilizzano un ramdisk e dispositivi che non utilizzano un ramdisk (e invece montano direttamente system.img ).

Il significato di una configurazione sistema come root differisce tra Android 9 e Android 10. In una configurazione sistema come root Android 9, BOARD_BUILD_SYSTEM_ROOT_IMAGE è impostato su true , il che forza la build a unire il file system root in system.img quindi montare system.img come file system root (rootfs). Questa configurazione è obbligatoria per i dispositivi avviati con Android 9 ma è facoltativa per i dispositivi che eseguono l'aggiornamento ad Android 9 e per i dispositivi che eseguono versioni precedenti di Android. In una configurazione di sistema Android 10 come root, la build unisce sempre $TARGET_SYSTEM_OUT e $TARGET_ROOT_OUT in system.img ; questa configurazione è il comportamento predefinito per tutti i dispositivi con Android 10.

Android 10 apporta ulteriori modifiche per supportare le partizioni dinamiche , un sistema di partizionamento dello spazio utente che consente aggiornamenti over-the-air (OTA) per creare, ridimensionare o distruggere le partizioni. Come parte di questa modifica, il kernel Linux non può più montare la partizione di sistema logica sui dispositivi che eseguono Android 10, quindi questa operazione viene gestita dalla prima fase init.

Le sezioni seguenti descrivono i requisiti system-as-root per OTA solo di sistema, forniscono indicazioni sull'aggiornamento dei dispositivi per utilizzare system-as-root (comprese le modifiche al layout delle partizioni e i requisiti del kernel dm-verity). Per dettagli sulle modifiche a ramdisk, vedere Partizioni Ramdisk .

Informazioni sulle OTA solo di sistema

Gli OTA solo di sistema, che consentono alle versioni Android di aggiornare system.img e product.img senza modificare altre partizioni, richiedono un layout della partizione system-as-root. Tutti i dispositivi che eseguono Android 10 devono utilizzare un layout di partizione system-as-root per abilitare OTA solo di sistema.

  • I dispositivi A/B, che montano la partizione system come rootfs, utilizzano già system-as-root e non richiedono modifiche per supportare le OTA di sistema.
  • I dispositivi non A/B, che montano la partizione system in /system , devono essere aggiornati per utilizzare un layout di partizione system-as-root per supportare le OTA di sistema.

Per dettagli sui dispositivi A/B e non A/B, fare riferimento ad Aggiornamenti di sistema A/B (seamless) .

Utilizzo della sovrapposizione del fornitore

La sovrapposizione del fornitore consente di sovrapporre le modifiche alla partizione vendor al momento dell'avvio del dispositivo. Un overlay del fornitore è un insieme di moduli del fornitore nella partizione product che vengono sovrapposti alla partizione vendor all'avvio del dispositivo, sostituendo e aggiungendo ai moduli esistenti.

Quando il dispositivo si avvia, il processo init completa il montaggio della prima fase e legge le proprietà predefinite. Quindi cerca /product/vendor_overlay/<target_vendor_version> e monta ciascuna sottodirectory nella directory della partizione vendor corrispondente, se sono soddisfatte le seguenti condizioni:

  • /vendor/<overlay_dir> esiste.
  • /product/vendor_overlay/<target_vendor_version>/<overlay_dir> ha lo stesso contesto di file di /vendor/<overlay_dir> .
  • init può essere montato nel contesto del file di /vendor/<overlay_dir> .

Implementazione della sovrapposizione del fornitore

Installa i file di overlay del fornitore in /product/vendor_overlay/<target_vendor_version> . Tali file si sovrappongono alla partizione vendor all'avvio del dispositivo, sostituendo i file con lo stesso nome e aggiungendo eventuali nuovi file. L'overlay del fornitore non può rimuovere file dalla partizione vendor .

I file sovrapposti del fornitore devono avere lo stesso contesto di file dei file di destinazione che sostituiscono nella partizione vendor . Per impostazione predefinita, i file nella directory /product/vendor_overlay/<target_vendor_version> hanno il contesto vendor_file . Se sono presenti discrepanze nel contesto dei file tra i file overlay del fornitore e i file che sostituiscono, specificarlo nella sepolicy specifica del dispositivo. Il contesto del file è impostato a livello di directory. Se il contesto del file di una directory di sovrapposizione del fornitore non corrisponde alla directory di destinazione e il contesto del file corretto non è specificato nella sepolicy specifica del dispositivo, la directory di sovrapposizione del fornitore non viene sovrapposta alla directory di destinazione.

Per utilizzare l'overlay del fornitore, il kernel deve abilitare OverlayFS impostando CONFIG_OVERLAY_FS=y . Inoltre, il kernel deve essere unito dal kernel comune 4.4 o successivo o patchato con "overlayfs: override_creds=off option bypass creator_cred" .

Esempio di implementazione della sovrapposizione del fornitore

Questa procedura dimostra l'implementazione di un overlay del fornitore che si sovrappone alle directory /vendor/lib/* , /vendor/etc/* e /vendor/app/* .

  1. Aggiungi file del fornitore predefiniti in device/<vendor>/<target>/vendor_overlay/<target_vendor_version>/ :

    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. Installa i file del fornitore predefiniti su 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. Definire i contesti dei file se i file della partizione vendor di destinazione hanno contesti diversi da vendor_file . Poiché /vendor/lib/* utilizza il contesto vendor_file , questo esempio non include quella directory.

    Aggiungi quanto segue device/google/device-sepolicy/private/file_contexts :

    /(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. Consentire al processo init di montare l'overlay del fornitore su contesti di file diversi da vendor_file . Poiché il processo init dispone già dell'autorizzazione per il montaggio nel contesto vendor_file , questo esempio non definisce la politica per vendor_file .

    Aggiungi quanto segue a device/google/device-sepolicy/public/init.te :

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

Convalida della sovrapposizione del fornitore

Per convalidare la configurazione dell'overlay del fornitore, aggiungere i file in /product/vendor_overlay/<target_vendor_version>/<overlay_dir> e verificare se i file sono sovrapposti ai file in /vendor/<overlay_dir> .

Per le build userdebug , c'è un modulo di test per Atest :

$ atest -v fs_mgr_vendor_overlay_test

Aggiornamento a system-as-root

Per aggiornare i dispositivi non A/B per utilizzare system-as-root, è necessario aggiornare lo schema di partizionamento per boot.img e system.img , configurare dm-verity e rimuovere eventuali dipendenze di avvio sulle cartelle root specifiche del dispositivo.

Aggiornamento delle partizioni

A differenza dei dispositivi A/B che riutilizzano /boot come partizione di ripristino , i dispositivi non A/B devono mantenere separata la partizione /recovery poiché non dispongono della partizione dello slot di fallback (ad esempio, da boot_a a boot_b ). Se /recovery viene rimosso su un dispositivo non A/B e reso simile allo schema A/B, la modalità di ripristino potrebbe interrompersi durante un aggiornamento non riuscito della partizione /boot . Per questo motivo, la partizione /recovery deve essere una partizione separata da /boot per i dispositivi non A/B, il che implica che l'immagine di ripristino continuerà ad essere aggiornata in modo differito (ovvero, come nei dispositivi con Android 8.1.0 o precedente).

La tabella seguente elenca le differenze nella partizione delle immagini per i dispositivi non A/B prima e dopo Android 9.

Immagine Ramdisk (prima delle 9) Sistema come root (dopo 9)
boot.img Contiene un kernel e un ramdisk.img :
ramdisk.img
  -/
    - init.rc
    - init
    - etc -> /system/etc
    - system/ (mount point)
    - vendor/ (mount point)
    - odm/ (mount point)
    ...
Contiene solo un normale kernel di avvio.
recovery.img Contiene un kernel di ripristino e un ramdisk.img di ripristino.
system.img Contiene quanto segue:
system.img
  -/
    - bin/
    - etc
    - vendor -> /vendor
    - ...
Contiene il contenuto unito di system.img originale e ramdisk.img :
system.img
  -/
    - init.rc
    - init
    - etc -> /system/etc
    - system/
      - bin/
      - etc/
      - vendor -> /vendor
      - ...
    - vendor/ (mount point)
    - odm/ (mount point)
    ...

Le partizioni stesse non cambiano; sia ramdisk che system-as-root utilizzano il seguente schema di partizione:

  • /boot
  • /system
  • /system
  • /recovery
  • /vendor , ecc.

Configurazione di dm-verity

In system-as-root, il kernel deve montare system.img in / (punto di montaggio) con dm-verity . AOSP supporta le seguenti implementazioni dm-verity per system.img .

vboot 1.0

Per vboot 1.0 , il kernel deve analizzare i metadati specifici di Android su /system , quindi convertirli in parametri dm-verity per configurare dm-verity (richiede queste patch del kernel ). L'esempio seguente mostra le impostazioni relative a dm-verity per system-as-root nella riga di comando del kernel:

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

Per vboot 2.0 ( AVB ), il bootloader deve integrare external/avb/libavb , che poi analizza il descrittore hashtree per /system , lo converte in dm-verity params e infine passa i parametri al kernel attraverso la riga di comando del kernel. (I descrittori Hashtree di /system potrebbero trovarsi su /vbmeta o su /system stesso.)

vboot 2.0 richiede le seguenti patch del kernel:

L'esempio seguente mostra le impostazioni relative a dm-verity per system-as-root nella riga di comando del kernel:

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"

Utilizzo di cartelle root specifiche del dispositivo

Con system-as-root, dopo che l' immagine di sistema generica (GSI) è stata flashata sul dispositivo (e prima di eseguire i test di Vendor Test Suite ), tutte le cartelle root specifiche del dispositivo aggiunte con BOARD_ROOT_EXTRA_FOLDERS vengono perse perché l'intero contenuto della directory root è stato sostituito dal GSI system-as-root. La rimozione di queste cartelle potrebbe rendere non avviabile il dispositivo se esiste una dipendenza dalle cartelle root specifiche del dispositivo (ad esempio, vengono utilizzate come punti di montaggio).

Per evitare questo problema, non utilizzare BOARD_ROOT_EXTRA_FOLDERS per aggiungere cartelle root specifiche del dispositivo. Se è necessario specificare punti di montaggio specifici del dispositivo, utilizzare /mnt/vendor/<mount point> (aggiunto in questi elenchi di modifiche ). Questi punti di montaggio specifici del fornitore possono essere specificati direttamente sia nell'albero dei dispositivi fstab (per il montaggio della prima fase) che nel file /vendor/etc/fstab.{ro.hardware} senza alcuna configurazione aggiuntiva (poiché fs_mgr li crea in /mnt/vendor/* automaticamente).