Montando partições antecipadamente

Os dispositivos habilitados para Treble devem habilitar a montagem do primeiro estágio para garantir que init possa carregar fragmentos de política do Security-Enhanced Linux (SELinux) que estão espalhados pelas partições system e vendor . Este acesso também permite o carregamento de módulos do kernel o mais rápido possível após a inicialização do kernel.

Para realizar a montagem antecipada, o Android deve ter acesso aos sistemas de arquivos nos quais os módulos residem. O Android 8.0 e superior suporta a montagem de /system , /vendor ou /odm já no primeiro estágio do init (ou seja, antes da inicialização do SElinux).

Entradas Fstab

No Android 9 e versões anteriores, os dispositivos podem especificar entradas fstab para partições montadas antecipadamente usando sobreposições de árvore de dispositivos (DTOs) . No Android 10 e versões posteriores, os dispositivos devem especificar entradas fstab para partições montadas antecipadamente usando um arquivo fstab no primeiro estágio ramdisk . O Android 10 apresenta os seguintes sinalizadores fs_mgr para uso no arquivo fstab :

  • first_stage_mount indica que uma partição será montada pelo primeiro estágio de inicialização.
  • logical indica que esta é uma partição dinâmica .
  • avb= vbmeta-partition-name especifica a partição vbmeta . O primeiro estágio init inicializa esta partição antes de montar outras partições. O argumento para esta flag pode ser omitido se a partição vbmeta para a entrada já tiver sido especificada por outra entrada fstab em uma linha anterior.

O exemplo a seguir mostra entradas fstab para configurar as partições system , vendor e product como partições lógicas (dinâmicas).

#<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

Neste exemplo, o fornecedor especifica a partição vbmeta usando o sinalizador fs_mgr avb=vbmeta , mas product omite o argumento vbmeta porque o fornecedor já adicionou vbmeta à lista de partições.

Dispositivos com Android 10 e superior devem colocar o arquivo fstab no ramdisk e na partição vendor .

Ramdisk

A localização do arquivo fstab no ramdisk depende de como um dispositivo usa o ramdisk.

Dispositivos com um ramdisk de inicialização devem colocar o arquivo fstab na raiz do ramdisk de inicialização. Se o dispositivo tiver um ramdisk de inicialização e um ramdisk de recuperação, nenhuma alteração será necessária no ramdisk de recuperação. Exemplo:

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

Dispositivos que usam recuperação como disco RAM devem usar o parâmetro de linha de comando do kernel androidboot.force_normal_boot=1 para decidir se inicializam no Android ou continuam inicializando na recuperação. Dispositivos iniciados com Android 12 ou superior com kernel versão 5.10 ou posterior devem usar bootconfig para passar o parâmetro androidboot.force_normal_boot=1 . Nesses dispositivos, o primeiro estágio init faz uma operação de alternância de raiz para /first_stage_ramdisk antes de montar as partições de montagem iniciais, portanto, os dispositivos devem colocar o arquivo fstab em $(TARGET_COPY_OUT_RECOVERY)/root/first_stage_ramdisk . Exemplo:

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

Fornecedor

Todos os dispositivos devem colocar uma cópia do arquivo fstab em /vendor/etc . Isso ocorre porque o primeiro estágio init libera o ramdisk após concluir a montagem inicial das partições e executar uma operação de switch root para mover a montagem em /system para / . Quaisquer operações subsequentes que precisem acessar arquivos fstab devem, portanto, usar a cópia em /vendor/etc . Exemplo:

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

Montando partições antecipadamente, VBoot 1.0

Os requisitos para montar partições antecipadamente com VBoot 1.0 incluem:

  1. Os caminhos dos nós do dispositivo devem usar seus links simbólicos by-name nas entradas fstab e devicetree. Por exemplo, em vez de especificar partições usando /dev/block/mmcblk0pX , certifique-se de que as partições sejam nomeadas e que o nó do dispositivo seja /dev/block/…./by-name/{system,vendor,odm} .
  2. Os caminhos fornecidos para PRODUCT_{SYSTEM,VENDOR}_VERITY_PARTITION e CUSTOM_IMAGE_VERITY_BLOCK_DEVICE na configuração do dispositivo para o produto (ou seja, em device/ oem / project /device.mk ) devem corresponder aos nós de dispositivo de bloco correspondentes especificados by-name no fstab /devicetree entradas. Exemplo:
    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. As entradas fornecidas por meio de sobreposições de árvore de dispositivos não devem ser repetidas nos fragmentos do arquivo fstab . Por exemplo, ao especificar uma entrada para montar /vendor na árvore de dispositivos, o arquivo fstab não deve repetir essa entrada.
  4. Partições que requerem verifyatboot não devem ser montadas antecipadamente (isso não é suportado).
  5. O modo/estado de verificação para partições verificadas deve ser especificado em kernel_cmdline usando a opção androidboot.veritymode (requisito existente).

Montando o devicetree antecipadamente, VBoot 1.0

No Android 8.xe superior, init analisa o devicetree e cria entradas fstab para montar a partição antecipadamente durante seu primeiro estágio. Uma entrada fstab assume o formato:

src mnt_point type mnt_flags fs_mgr_flags

As propriedades Devicetree são definidas para imitar esse formato:

  • As entradas fstab devem estar em /firmware/android/fstab na árvore de dispositivos e devem ter uma string compatível definida como android,fstab .
  • Cada nó em /firmware/android/fstab é tratado como uma única entrada fstab montagem inicial. Um nó deve ter as seguintes propriedades definidas:
    • dev deve apontar para o nó do dispositivo que representa o by-name partição
    • type deve ser o tipo de sistema de arquivos (como nos arquivos fstab )
    • mnt_flags deve ser a lista separada por vírgulas de sinalizadores de montagem (como em arquivos fstab )
    • fsmgr_flags deve ser a lista de fs_mgr flags do Android (como nos arquivos fstab )
  • As partições A/B devem ter uma opção slotselect fs_mgr .
  • As partições habilitadas para dm-verity devem ter uma opção verify fs_mgr .

Exemplo: /system e /vendor no N6P

O exemplo a seguir mostra a montagem antecipada do devicetree para partições system e vendor no 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";
        };
      };
    };
  };
};

Exemplo: /vendor no Pixel

O exemplo a seguir mostra a montagem antecipada do devicetree para /vendor no Pixel (lembre-se de adicionar slotselect para partições sujeitas a 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";
        };
      };
    };
  };
};

Montando partições antecipadamente, VBoot 2.0

VBoot 2.0 é a inicialização verificada do Android (AVB) . Os requisitos para montar partições antecipadamente com VBoot 2.0 são:

  1. Os caminhos do nó do dispositivo devem usar seus links simbólicos by-name nas entradas fstab e devicetree. Por exemplo, em vez de especificar partições usando /dev/block/mmcblk0pX , certifique-se de que as partições sejam nomeadas e que o nó do dispositivo seja /dev/block/…./by-name/{system,vendor,odm} .
  2. Variáveis ​​de sistema de compilação (como PRODUCT_{SYSTEM,VENDOR}_VERITY_PARTITION e CUSTOM_IMAGE_VERITY_BLOCK_DEVICE ) usadas para VBoot 1.0 NÃO são necessárias para VBoot 2.0. Em vez disso, as variáveis ​​de construção introduzidas no VBoot 2.0 (incluindo BOARD_AVB_ENABLE := true ) devem ser definidas; para obter uma configuração completa, consulte Construir integração de sistema para AVB .
  3. As entradas fornecidas por meio de sobreposições de árvore de dispositivos não devem ser repetidas nos fragmentos do arquivo fstab . Por exemplo, se você especificar uma entrada para montar /vendor na árvore de dispositivos, o arquivo fstab não deverá repetir essa entrada.
  4. O VBoot 2.0 não oferece suporte verifyatboot , esteja a montagem antecipada habilitada ou não.
  5. O modo/estado de verificação para partições verificadas deve ser especificado em kernel_cmdline usando a opção androidboot.veritymode (requisito existente). Certifique-se de incluir as seguintes correções para AVB:

Montando o devicetree antecipadamente, VBoot 2.0

A configuração no devicetree para VBoot 2.0 é a mesma do VBoot 1.0 , com as seguintes exceções:

  • O fsmgr_flag é alterado de verify para avb .
  • Todas as partições com metadados AVB devem estar na entrada VBMeta na árvore de dispositivos, mesmo quando a partição não estiver sendo montada antecipadamente (por exemplo, /boot ).

Exemplo: /system e /vendor no N5X

O exemplo a seguir mostra uma montagem antecipada do devicetree para as partições system e vendor no Nexus 5X. Observe que:

  • /system é montado com AVB e /vendor é montado sem verificação de integridade.
  • Como o Nexus 5X não tem partição /vbmeta , o vbmeta de nível superior reside no final da partição /boot (para obter detalhes, consulte a lista de alterações do 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";
            };
          };
        };
      };
    };
    

Exemplo: /vendor no Pixel

O exemplo a seguir mostra a montagem /vendor no início de um Pixel. Observe que:

  • Mais partições são especificadas na entrada vbmeta porque essas partições são protegidas por AVB .
  • Todas as partições AVB devem ser incluídas, mesmo que apenas /vendor seja montado antecipadamente.
  • Lembre-se de adicionar slotselect para partições sujeitas a 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";
            };
          };
        };
      };
    };