Montaggio anticipato delle partizioni

I dispositivi abilitati per Treble devono abilitare il montaggio della prima fase per assicurarsi che init possa caricare frammenti di policy SELinux (Security-Enhanced Linux) distribuiti tra partizioni system e vendor . Questo accesso consente inoltre il caricamento dei moduli del kernel il più presto possibile dopo l'avvio del kernel.

Per eseguire il montaggio anticipato, Android deve avere accesso ai file system su cui risiedono i moduli. Android 8.0 e versioni successive supportano il montaggio di /system , /vendor o /odm già nella prima fase di init (ovvero prima che SElinux venga inizializzato).

Voci Fstab

In Android 9 e versioni precedenti, i dispositivi possono specificare le voci fstab per le partizioni montate in anticipo utilizzando gli overlay dell'albero dei dispositivi (DTO) . In Android 10 e versioni successive, i dispositivi devono specificare le voci fstab per le partizioni montate in anticipo utilizzando un file fstab nel ramdisk della prima fase. Android 10 introduce i seguenti flag fs_mgr da utilizzare nel file fstab :

  • first_stage_mount indica che una partizione verrà montata dal primo stage init.
  • logical indica che si tratta di una partizione dinamica .
  • avb= vbmeta-partition-name specifica la partizione vbmeta . La prima fase init inizializza questa partizione prima di montare altre partizioni. L'argomento per questo flag può essere omesso se la partizione vbmeta per la voce è già stata specificata da un'altra voce fstab in una riga precedente.

L'esempio seguente mostra le voci fstab per impostare le partizioni system , vendor e product come partizioni logiche (dinamiche).

#<dev>  <mnt_point> <type>  <mnt_flags options> <fs_mgr_flags>
system   /system     ext4    ro,barrier=1     wait,slotselect,avb=vbmeta_system,logical,first_stage_mount
vendor   /vendor     ext4    ro,barrier=1     wait,slotselect,avb=vbmeta,logical,first_stage_mount
product  /product    ext4    ro,barrier=1     wait,slotselect,avb,logical,first_stage_mount

In questo esempio, il fornitore specifica la partizione vbmeta utilizzando il flag fs_mgr avb=vbmeta , ma product omette l'argomento vbmeta perché il fornitore ha già aggiunto vbmeta all'elenco delle partizioni.

I dispositivi con Android 10 e versioni successive devono posizionare il file fstab nel ramdisk e nella partizione vendor .

Ramdisk

La posizione del file fstab nel ramdisk dipende da come un dispositivo utilizza ramdisk.

I dispositivi con un ramdisk di avvio devono posizionare il file fstab nella root del ramdisk di avvio. Se il dispositivo dispone sia di un ramdisk di avvio che di un ramdisk di ripristino, non sono necessarie modifiche al ramdisk di ripristino. Esempio:

PRODUCT_COPY_FILES +=  device/google/<product-name>/fstab.hardware:$(TARGET_COPY_OUT_RAMDISK)/fstab.$(PRODUCT_PLATFORM)

I dispositivi che utilizzano il ripristino come ramdisk devono utilizzare il parametro della riga di comando del kernel androidboot.force_normal_boot=1 per decidere se avviare Android o continuare l'avvio in ripristino. I dispositivi avviati con Android 12 o versioni successive con versione kernel 5.10 o successiva devono utilizzare bootconfig per passare il parametro androidboot.force_normal_boot=1 . In questi dispositivi, l'init della prima fase esegue un'operazione di commutazione root su /first_stage_ramdisk prima di montare le partizioni di montaggio iniziali, quindi i dispositivi devono posizionare il file fstab in $(TARGET_COPY_OUT_RECOVERY)/root/first_stage_ramdisk . Esempio:

PRODUCT_COPY_FILES +=  device/google/<product-name>/fstab.hardware:$(TARGET_COPY_OUT_RECOVERY)/root/first_stage_ramdisk/fstab.$(PRODUCT_PLATFORM)

Venditore

Tutti i dispositivi devono inserire una copia del file fstab in /vendor/etc . Questo perché la prima fase init libera il ramdisk dopo aver completato il montaggio iniziale delle partizioni ed esegue un'operazione di switch root per spostare il montaggio da /system a / . Qualsiasi operazione successiva che richieda l'accesso ai file fstab dovrà quindi utilizzare la copia in /vendor/etc . Esempio:

PRODUCT_COPY_FILES +=  device/google/<product-name>/fstab.hardware:$(TARGET_COPY_OUT_VENDOR)/etc/fstab.$(PRODUCT_PLATFORM)

Montaggio anticipato delle partizioni, VBoot 1.0

I requisiti per montare in anticipo le partizioni con VBoot 1.0 includono:

  1. I percorsi dei nodi del dispositivo devono utilizzare i collegamenti simbolici by-name nelle voci fstab e devicetree. Ad esempio, invece di specificare le partizioni utilizzando /dev/block/mmcblk0pX , assicurati che le partizioni siano nominate e che il nodo del dispositivo sia /dev/block/…./by-name/{system,vendor,odm} .
  2. I percorsi forniti per PRODUCT_{SYSTEM,VENDOR}_VERITY_PARTITION e CUSTOM_IMAGE_VERITY_BLOCK_DEVICE nella configurazione del dispositivo per il prodotto (ovvero in device/ oem / project /device.mk ) devono corrispondere ai nodi del dispositivo a blocchi corrispondenti specificati by-name in fstab /devicetree inserimenti. Esempio:
    PRODUCT_SYSTEM_VERITY_PARTITION := /dev/block/…./by-name/system
    PRODUCT_VENDOR_VERITY_PARTITION := /dev/block/…./by-name/vendor
    CUSTOM_IMAGE_VERITY_BLOCK_DEVICE := /dev/block/…./by-name/odm
    
  3. Le voci fornite tramite sovrapposizioni dell'albero dei dispositivi non devono ripetersi nei frammenti di file fstab . Ad esempio, quando si specifica una voce per montare /vendor nell'albero dei dispositivi, il file fstab non deve ripetere quella voce.
  4. Le partizioni che richiedono verifyatboot non devono essere montate anticipatamente (farlo non è supportato).
  5. La modalità/lo stato di verità per le partizioni verificate deve essere specificato in kernel_cmdline utilizzando l'opzione androidboot.veritymode (requisito esistente).

Montaggio anticipato di Devicetree, VBoot 1.0

In Android 8.x e versioni successive, init analizza il devicetree e crea voci fstab per montare la partizione in anticipo durante la sua prima fase. Una voce fstab assume la forma:

src mnt_point type mnt_flags fs_mgr_flags

Le proprietà Devicetree sono definite per imitare quel formato:

  • Le voci fstab devono trovarsi in /firmware/android/fstab nell'albero dei dispositivi e devono avere una stringa compatibile impostata su android,fstab .
  • Ogni nodo in /firmware/android/fstab viene trattato come una singola voce fstab montaggio anticipato. Per un nodo devono essere definite le seguenti proprietà:
    • dev deve puntare al nodo del dispositivo che rappresenta la partizione by-name
    • type deve essere il tipo di file system (come nei file fstab )
    • mnt_flags deve essere l'elenco separato da virgole dei flag di montaggio (come nei file fstab )
    • fsmgr_flags deve essere l'elenco dei fs_mgr flags Android (come nei file fstab )
  • Le partizioni A/B devono avere un'opzione slotselect fs_mgr .
  • Le partizioni abilitate per dm-verity devono avere un'opzione verify fs_mgr .

Esempio: /system e /vendor su N6P

L'esempio seguente mostra il montaggio anticipato di Devicetree per le partizioni system e vendor su Nexus 6P:

/ {
  firmware {
    android {
      compatible = "android,firmware";
      fstab {
        compatible = "android,fstab";
        system {
          compatible = "android,system";
          dev = "/dev/block/platform/soc.0/f9824900.sdhci/by-name/system";
          type = "ext4";
          mnt_flags = "ro,barrier=1,inode_readahead_blks=8";
          fsmgr_flags = "wait,verify";
        };
        vendor {
          compatible = "android,vendor";
          dev = "/dev/block/platform/soc.0/f9824900.sdhci/by-name/vendor";
          type = "ext4";
          mnt_flags = "ro,barrier=1,inode_readahead_blks=8";
          fsmgr_flags = "wait";
        };
      };
    };
  };
};

Esempio: /vendor su Pixel

L'esempio seguente mostra il montaggio anticipato di devicetree per /vendor su Pixel (ricordati di aggiungere slotselect per le partizioni soggette ad A/B):

/ {
  firmware {
    android {
      compatible = "android,firmware";
      fstab {
        compatible = "android,fstab";
        vendor {
          compatible = "android,vendor";
          dev = "/dev/block/platform/soc/624000.ufshc/by-name/vendor";
          type = "ext4";
          mnt_flags = "ro,barrier=1,discard";
          fsmgr_flags = "wait,slotselect,verify";
        };
      };
    };
  };
};

Montaggio anticipato delle partizioni, VBoot 2.0

VBoot 2.0 è l'avvio verificato per Android (AVB) . I requisiti per montare anticipatamente le partizioni con VBoot 2.0 sono:

  1. I percorsi dei nodi del dispositivo devono utilizzare i collegamenti simbolici by-name nelle voci fstab e devicetree. Ad esempio, invece di specificare le partizioni utilizzando /dev/block/mmcblk0pX , assicurati che le partizioni siano denominate e che il nodo del dispositivo sia /dev/block/…./by-name/{system,vendor,odm} .
  2. Le variabili di sistema di creazione (come PRODUCT_{SYSTEM,VENDOR}_VERITY_PARTITION e CUSTOM_IMAGE_VERITY_BLOCK_DEVICE ) utilizzate per VBoot 1.0 NON sono necessarie per VBoot 2.0. Invece, le variabili di build introdotte in VBoot 2.0 (incluso BOARD_AVB_ENABLE := true ) dovrebbero essere definite; per una configurazione completa, fare riferimento a Build System Integration for AVB .
  3. Le voci fornite tramite sovrapposizioni dell'albero dei dispositivi non devono ripetersi nei frammenti di file fstab . Ad esempio, se specifichi una voce per montare /vendor nell'albero dei dispositivi, il file fstab non deve ripetere quella voce.
  4. VBoot 2.0 non supporta verifyatboot , indipendentemente dal fatto che il montaggio anticipato sia abilitato o meno.
  5. La modalità/stato verity per le partizioni verificate deve essere specificato in kernel_cmdline utilizzando l'opzione androidboot.veritymode (requisito esistente). Assicurati di includere le seguenti correzioni per AVB:

Montaggio anticipato di Devicetree, VBoot 2.0

La configurazione in devicetree per VBoot 2.0 è la stessa di VBoot 1.0 , con le seguenti eccezioni:

  • Il fsmgr_flag viene cambiato da verify ad avb .
  • Tutte le partizioni con metadati AVB devono trovarsi nella voce VBMeta nell'albero dei dispositivi, anche quando la partizione non viene montata in anticipo (ad esempio, /boot ).

Esempio: /system e /vendor su N5X

L'esempio seguente mostra un montaggio iniziale di un albero dei dispositivi per le partizioni system e vendor su Nexus 5X. Notare che:

  • /system è montato con AVB e /vendor è montato senza verifica dell'integrità.
  • Poiché il Nexus 5X non ha una partizione /vbmeta , la vbmeta di livello superiore risiede alla fine della partizione /boot (per i dettagli, fare riferimento all'elenco delle modifiche AOSP ).
    / {
      firmware {
        android {
          compatible = "android,firmware";
          vbmeta {
            compatible = "android,vbmeta";
            parts = "boot,system,vendor";
          };
          fstab {
            compatible = "android,fstab";
            system {
              compatible = "android,system";
              dev = "/dev/block/platform/soc.0/f9824900.sdhci/by-name/system";
              type = "ext4";
              mnt_flags = "ro,barrier=1,inode_readahead_blks=8";
              fsmgr_flags = "wait,avb";
            };
            vendor {
              compatible = "android,vendor";
              dev = "/dev/block/platform/soc.0/f9824900.sdhci/by-name/vendor";
              type = "ext4";
              mnt_flags = "ro,barrier=1,inode_readahead_blks=8";
              fsmgr_flags = "wait";
            };
          };
        };
      };
    };
    

Esempio: /vendor su Pixel

L'esempio seguente mostra il montaggio iniziale /vendor su un Pixel. Notare che:

  • Nella voce vbmeta sono specificate più partizioni poiché tali partizioni sono protette da AVB .
  • Tutte le partizioni AVB devono essere incluse, anche se solo /vendor è stato montato in anticipo.
  • Ricordarsi di aggiungere slotselect per le partizioni soggette ad A/B.
    / {
      vbmeta {
        compatible = "android,vbmeta";
        parts = "vbmeta,boot,system,vendor,dtbo";
      };
      firmware {
        android {
          compatible = "android,firmware";
          fstab {
            compatible = "android,fstab";
            vendor {
              compatible = "android,vendor";
              dev = "/dev/block/platform/soc/624000.ufshc/by-name/vendor";
              type = "ext4";
              mnt_flags = "ro,barrier=1,discard";
              fsmgr_flags = "wait,slotselect,avb";
            };
          };
        };
      };
    };