Google si impegna a promuovere l'equità razziale per le comunità nere. Vedi come.
Questa pagina è stata tradotta dall'API Cloud Translation.
Switch to English

Layout della partizione

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

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

Il significato di una configurazione di sistema come root differisce tra Android 9 e Android 10. In una configurazione di sistema come root di Android 9, BOARD_BUILD_SYSTEM_ROOT_IMAGE è impostato su true , il che forza la build a unire il file system di root in system.img quindi montare system.img come file system root (rootfs). Questa configurazione è obbligatoria per i dispositivi che si avviano con Android 9 ma è facoltativa per i dispositivi che eseguono l'aggiornamento a Android 9 e per i dispositivi che eseguono versioni inferiori di Android. In una configurazione di sistema Android-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 su dispositivi che eseguono Android 10, quindi questa operazione è gestita dal primo stadio init.

Le seguenti sezioni descrivono i requisiti di sistema come root per OTA solo di sistema, forniscono indicazioni sull'aggiornamento dei dispositivi per utilizzare il sistema come root (comprese le modifiche al layout delle partizioni e i requisiti del kernel dm-verity) e le modifiche di dettaglio a ramdisk in Android 10 .

Informazioni sulle OTA di solo sistema

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

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

Per i dettagli sui dispositivi A / B e non A / B, consultare Aggiornamenti del sistema A / B (senza interruzioni) .

Utilizzo dell'overlay del fornitore

L'overlay fornitore consente di sovrapporre le modifiche alla partizione vendor all'avvio del dispositivo. Una sovrapposizione fornitore è un insieme di moduli fornitore nella partizione del product che si sovrappongono alla partizione vendor all'avvio del dispositivo, sostituendo e aggiungendo ai moduli esistenti.

All'avvio del dispositivo, 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 corrispondente directory di partizione del vendor , 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ò montare sul contesto file di /vendor/<overlay_dir> .

Implementazione dell'overlay del fornitore

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

I file di overlay del fornitore devono avere lo stesso contesto di file dei file di destinazione che sostituiscono nella partizione del vendor . Per impostazione predefinita, i file nella directory /product/vendor_overlay/<target_vendor_version> hanno il contesto vendor_file . Se vi sono discrepanze nel contesto dei file tra i file di 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 overlay del fornitore non corrisponde alla directory di destinazione e il contesto di file corretto non è specificato nella sepolicy specifica del dispositivo, quella directory di overlay del fornitore non viene sovrapposta alla directory di destinazione.

Per usare 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 dell'overlay del fornitore

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

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

    Aggiungi quanto segue a 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 di init ha già l'autorizzazione per il montaggio sul 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 dell'overlay 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 build di userdebug , esiste 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 , impostare dm-verity e rimuovere eventuali dipendenze di avvio dalle 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 hanno la partizione 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 alla 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 la stessa dei dispositivi che eseguono Android 8.1.0 o inferiore).

La tabella seguente elenca le differenze di partizione dell'immagine per i dispositivi non A / B prima e dopo Android 9.

Immagine Ramdisk (prima delle 9) System-as-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 kernel di avvio normale.
recovery.img Contiene un kernel di ripristino e un ramdisk.img 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 stesse partizioni non cambiano; sia ramdisk che system-as-root usano il seguente schema di partizione:

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

Impostazione di dm-verity

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

vboot 1.0

Per vboot 1.0 , il kernel deve analizzare metadati specifici di Android su /system , quindi convertirli in parametri dm-verity per impostare 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 quindi analizza il descrittore hashtree per /system , lo converte in parametri dm-verity e infine passa i parametri al kernel attraverso la riga di comando del kernel. (I descrittori di /system Hashtree potrebbero essere 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 radice specifiche del dispositivo

Con system-as-root, dopo che l' immagine di sistema generica (GSI) è stata caricata sul dispositivo (e prima di eseguire i test di Vendor Test Suite ), tutte le cartelle radice specifiche del dispositivo aggiunte con BOARD_ROOT_EXTRA_FOLDERS sono sparite perché l'intero contenuto della directory radice è stato sostituito dal sistema GSI come root. La rimozione di queste cartelle potrebbe rendere il dispositivo non avviabile se esiste una dipendenza dalle cartelle radice 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> (aggiunti in questi elenchi modifiche ). Questi punti di montaggio specifici del fornitore possono essere specificati direttamente sia nell'albero dei dispositivi di fstab (per il montaggio del primo stadio) che nel file /vendor/etc/fstab.{ro.hardware} senza un'installazione aggiuntiva (poiché fs_mgr li crea in /mnt/vendor/* automaticamente).

ramdisk

In Android 10, il ramdisk del primo stadio contiene il file binario init del primo stadio (che esegue il montaggio anticipato come specificato dalle voci fstab) e i file fstab del fornitore. (Come in Android 9, system.img contiene i contenuti di $TARGET_ROOT_OUT .)

  • Per i dispositivi con un boot-ramdisk (non A / B), il primo stadio init è un eseguibile statico situato in /init . Questi dispositivi montano system.img come /system , quindi eseguono un'operazione switch root per spostare il mount su /system su / . Il contenuto del ramdisk viene liberato al termine del montaggio.
  • Per i dispositivi che utilizzano il ripristino come ramdisk, init del primo stadio si trova in /init all'interno del ramdisk di ripristino. Questi dispositivi prima /first_stage_ramdisk root in /first_stage_ramdisk per rimuovere i componenti di ripristino dall'ambiente, quindi procedono allo stesso modo dei dispositivi con un boot-ramdisk (ovvero monta system.img come /system , cambia root per spostare quel mount su / , e contenuti gratuiti del ramdisk dopo il montaggio). Se androidboot.force_normal_boot=1 è presente nella riga di comando del kernel, i dispositivi si avviano normalmente (su Android) invece di avviarsi in modalità di recupero.

Al termine del primo stadio, init esegue /system/bin/init con l'argomento selinux_setup per compilare e caricare SELinux sul sistema. Infine, init esegue di nuovo /system/bin/init con l'argomento second_stage . A questo punto, la fase principale di init viene eseguita e continua il processo di avvio utilizzando gli script init.rc

Layout delle partizioni (dispositivi non A / B)

Le seguenti sezioni descrivono in dettaglio le differenze nei layout delle partizioni per i dispositivi non A / B prima e dopo Android 10.

boot.img

ramdisk
(Android 8.xe versioni precedenti)
Sistema come root
(Android 9)
ramdisk
(Android 10)

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 kernel di avvio normale.

Contiene un kernel e ramdisk.img .

ramdisk.img
  -/
    - init
    - vendor fstab files
    - system/ (mount point)
    - vendor/ (mount point)
    - odm/ (mount point)
    ...
    

recovery.img

Contiene un kernel di ripristino e un ramdisk.img ripristino

system.img

ramdisk
(Android 8.xe versioni precedenti)
Sistema come root
(Android 9)
ramdisk
(Android 10)

Contiene un system.img .

system.img
  -/
    - bin/
    - etc
    - vendor -> /vendor
    - ...
   

Contiene i contenuti uniti di $TARGET_SYSTEM_OUT e $TARGET_ROOT_OUT .

system.img
  -/
    - init.rc
    - init
    - etc -> /system/etc
    - system/
      - bin/
      - etc/
      - vendor -> /vendor
      - ...
    - vendor/ (mount point)
    - odm/ (mount point)
    ...
    

Contiene i contenuti uniti di $TARGET_SYSTEM_OUT e $TARGET_ROOT_OUT .

system.img
  -/
    - init.rc
    - init -> /system/bin/init
    - etc -> /system/etc
    - system/
      - bin/
      - etc/
      - vendor -> /vendor
      - ...
    - vendor/ (mount point)
    - odm/ (mount point)
    ...
    

Layout delle partizioni (dispositivi A / B)

Le seguenti sezioni descrivono le differenze nei layout delle partizioni per i dispositivi A / B prima e dopo Android 10.

boot.img

Sistema come root
(Android 9)
ramdisk
(Android 10)
Contiene il kernel di avvio normale e recovery-ramdisk ( BOARD_USES_RECOVERY_AS_BOOT := true ).

Recovery-ramdisk viene utilizzato solo per l'avvio in recovery.
Contiene il kernel di avvio normale e recovery-ramdisk ( BOARD_USES_RECOVERY_AS_BOOT := true ).

Recovery-ramdisk viene utilizzato per l'avvio sia in recovery che in Android.
ramdisk.img
  -/
    - init -> /system/bin/init
    - first_stage_ramdisk
       - vendor fstab files
    - etc -> /system/etc
    - system/ (mount point)
    - vendor/ (mount point)
    - odm/ (mount point)
    ...
    

system.img

Contiene i contenuti uniti di $TARGET_SYSTEM_OUT e $TARGET_ROOT_OUT .

system.img
  -/
    - init.rc
    - init -> /system/bin/init
    - etc -> /system/etc
    - system/
      - bin/
      - etc/
      - vendor -> /vendor
      - ...
    - vendor/ (mount point)
    - odm/ (mount point)
    ...