No Android 10, o sistema de arquivos raiz não está mais incluído em ramdisk.img
e, em vez disso, é mesclado em system.img
(ou seja, system.img
é sempre criado como se BOARD_BUILD_SYSTEM_ROOT_IMAGE
estivesse definido). Dispositivos lançados com Android 10:
- Use um layout de partição do sistema como raiz (aplicado automaticamente pela compilação, sem opções para alterar o comportamento).
- Deve usar um ramdisk, que é necessário para dm-linear.
- Deve definir
BOARD_BUILD_SYSTEM_ROOT_IMAGE
comofalse
. Esta configuração é usada apenas para diferenciar entre dispositivos que usam um ramdisk e dispositivos que não usam um ramdisk (e, em vez disso, montarsystem.img
diretamente).
O significado de uma configuração de sistema como raiz difere entre o Android 9 e o Android 10. Em uma configuração de sistema como raiz do Android 9, BOARD_BUILD_SYSTEM_ROOT_IMAGE
é definido como true
, o que força a compilação a mesclar o sistema de arquivos raiz em system.img
e então monte system.img
como o sistema de arquivos raiz (rootfs). Esta configuração é obrigatória para dispositivos lançados com Android 9, mas é opcional para dispositivos atualizados para Android 9 e para dispositivos que executam versões anteriores do Android. Em uma configuração de sistema como raiz do Android 10, a compilação sempre mescla $TARGET_SYSTEM_OUT
e $TARGET_ROOT_OUT
em system.img
; esta configuração é o comportamento padrão para todos os dispositivos que executam o Android 10.
O Android 10 faz mais alterações para oferecer suporte a partições dinâmicas , um sistema de particionamento de espaço do usuário que permite atualizações over-the-air (OTA) para criar, redimensionar ou destruir partições. Como parte dessa mudança, o kernel do Linux não pode mais montar a partição lógica do sistema em dispositivos que executam o Android 10, portanto, essa operação é realizada pelo primeiro estágio init.
As seções a seguir descrevem os requisitos do sistema como raiz para OTAs somente de sistema e fornecem orientação sobre a atualização de dispositivos para usar o sistema como raiz (incluindo alterações no layout da partição e requisitos do kernel dm-verity). Para obter detalhes sobre alterações no ramdisk, consulte Partições Ramdisk .
Sobre OTAs somente de sistema
OTAs somente de sistema, que permitem que versões do Android atualizem system.img
e product.img
sem alterar outras partições, exigem um layout de partição do sistema como raiz. Todos os dispositivos que executam o Android 10 devem usar um layout de partição do sistema como raiz para habilitar OTAs somente do sistema.
- Dispositivos A/B, que montam a partição
system
como rootfs, já usam o sistema como root e não requerem alterações para suportar OTAs do sistema. - Dispositivos não A/B, que montam a partição
system
em/system
, devem ser atualizados para usar um layout de partição do sistema como raiz para suportar OTAs do sistema.
Para obter detalhes sobre dispositivos A/B e não A/B, consulte Atualizações do sistema A/B (contínuas) .
Usando sobreposição de fornecedor
A sobreposição do fornecedor permite sobrepor alterações na partição vendor
no momento da inicialização do dispositivo. Uma sobreposição de fornecedor é um conjunto de módulos de fornecedor na partição product
que são sobrepostos na partição vendor
quando o dispositivo é inicializado, substituindo e adicionando aos módulos existentes.
Quando o dispositivo é inicializado, o processo init
conclui o primeiro estágio de montagem e lê as propriedades padrão. Em seguida, ele pesquisa /product/vendor_overlay/<target_vendor_version>
e monta cada subdiretório em seu diretório de partição vendor
correspondente, se as seguintes condições forem atendidas:
-
/vendor/<overlay_dir>
existe. -
/product/vendor_overlay/<target_vendor_version>/<overlay_dir>
tem o mesmo contexto de arquivo que/vendor/<overlay_dir>
. -
init
pode ser montado no contexto do arquivo de/vendor/<overlay_dir>
.
Implementando sobreposição de fornecedor
Instale arquivos de sobreposição do fornecedor em /product/vendor_overlay/<target_vendor_version>
. Esses arquivos se sobrepõem à partição vendor
quando o dispositivo é inicializado, substituindo arquivos com o mesmo nome e adicionando novos arquivos. A sobreposição do fornecedor não pode remover arquivos da partição vendor
.
Os arquivos de sobreposição do fornecedor devem ter o mesmo contexto de arquivo que os arquivos de destino que eles substituem na partição vendor
. Por padrão, os arquivos no diretório /product/vendor_overlay/<target_vendor_version>
possuem o contexto vendor_file
. Se houver incompatibilidades de contexto de arquivo entre os arquivos de sobreposição do fornecedor e os arquivos que eles substituem, especifique isso na política específica do dispositivo. O contexto do arquivo é definido no nível do diretório. Se o contexto de arquivo de um diretório de sobreposição de fornecedor não corresponder ao diretório de destino e o contexto de arquivo correto não for especificado na sepolicy específica do dispositivo, esse diretório de sobreposição de fornecedor não será sobreposto ao diretório de destino.
Para usar a sobreposição do fornecedor, o kernel deve ativar o OverlayFS configurando CONFIG_OVERLAY_FS=y
. Além disso, o kernel deve ser mesclado do kernel comum 4.4 ou posterior, ou corrigido com "overlayfs: override_creds=off option bypass creator_cred"
.
Exemplo de implementação de sobreposição de fornecedor
Este procedimento demonstra a implementação de uma sobreposição de fornecedor que sobrepõe os diretórios /vendor/lib/*
, /vendor/etc/*
e /vendor/app/*
.
Adicione arquivos de fornecedor pré-construídos em
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
Instale os arquivos pré-construídos do fornecedor em
product/vendor_overlay
emdevice/google/device/device.mk
:PRODUCT_COPY_FILES += \ $(call find-copy-subdir-files,*,device/google/device/vendor_overlay,$(TARGET_COPY_OUT_PRODUCT)/vendor_overlay)
Defina contextos de arquivo se os arquivos de partição
vendor
de destino tiverem contextos diferentes devendor_file
. Como/vendor/lib/*
usa o contextovendor_file
, este exemplo não inclui esse diretório.Adicione o seguinte 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
Permita que o processo
init
monte a sobreposição do fornecedor em contextos de arquivo diferentes devendor_file
. Como o processoinit
já tem permissão para montar no contextovendor_file
, este exemplo não define a política paravendor_file
.Adicione o seguinte a
device/google/device-sepolicy/public/init.te
:allow init vendor_configs_file:dir mounton; allow init vendor_app_file:dir mounton;
Validando a sobreposição do fornecedor
Para validar a configuração de sobreposição do fornecedor, adicione arquivos em /product/vendor_overlay/<target_vendor_version>/<overlay_dir>
e verifique se os arquivos estão sobrepostos aos arquivos em /vendor/<overlay_dir>
.
Para compilações userdebug
, existe um módulo de teste para Atest :
$ atest -v fs_mgr_vendor_overlay_test
Atualizando para o sistema como root
Para atualizar dispositivos não A/B para usar o sistema como raiz, você deve atualizar o esquema de particionamento para boot.img
e system.img
, configurar dm-verity e remover quaisquer dependências de inicialização nas pastas raiz específicas do dispositivo.
Atualizando partições
Ao contrário dos dispositivos A/B que reaproveitam /boot
como partição de recuperação , os dispositivos não A/B devem manter a partição /recovery
separada, pois não possuem a partição de slot de fallback (por exemplo, de boot_a
para boot_b
). Se /recovery
for removido em um dispositivo não A/B e tornado semelhante ao esquema A/B, o modo de recuperação poderá ser interrompido durante uma falha na atualização da partição /boot
. Por esse motivo, a partição /recovery
deve ser uma partição separada de /boot
para dispositivos não-A/B, o que implica que a imagem de recuperação continuará a ser atualizada de maneira diferida (ou seja, da mesma forma que em dispositivos rodando Android). 8.1.0 ou inferior).
A tabela a seguir lista as diferenças de partição de imagem para dispositivos não A/B antes e depois do Android 9.
Imagem | Ramdisk (antes das 9) | Sistema como root (após 9) |
---|---|---|
boot.img | Contém um kernel e um ramdisk.img : ramdisk.img -/ - init.rc - init - etc -> /system/etc - system/ (mount point) - vendor/ (mount point) - odm/ (mount point) ... | Contém apenas um kernel de inicialização normal. |
recovery.img | Contém um kernel de recuperação e um ramdisk.img de recuperação. | |
system.img | Contém o seguinte: system.img -/ - bin/ - etc - vendor -> /vendor - ... | Contém o conteúdo mesclado do system.img e ramdisk.img originais: system.img -/ - init.rc - init - etc -> /system/etc - system/ - bin/ - etc/ - vendor -> /vendor - ... - vendor/ (mount point) - odm/ (mount point) ... |
As próprias partições não mudam; tanto o ramdisk quanto o sistema como root usam o seguinte esquema de partição:
-
/boot
-
/system
-
/system
-
/recovery
-
/vendor
, etc.
Configurando dm-verity
No sistema como raiz, o kernel deve montar system.img
em /
(ponto de montagem) com dm-verity . AOSP suporta as seguintes implementações de dm-verity para system.img
.
vboot 1.0
Para vboot 1.0 , o kernel deve analisar os metadados específicos do Android em /system
e, em seguida, converter para parâmetros dm-verity para configurar o dm-verity (requer esses patches do kernel ). O exemplo a seguir mostra configurações relacionadas ao dm-verity para sistema como root na linha de comando do 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
Para vboot 2.0 ( AVB ), o bootloader deve integrar external/avb/libavb , que então analisa o descritor hashtree para /system
, converte-o em dm-verity params e finalmente passa os parâmetros para o kernel através da linha de comando do kernel. (Os descritores Hashtree de /system
podem estar em /vbmeta
ou no próprio /system
.)
O vboot 2.0 requer os seguintes patches de kernel:
- https://android-review.googlesource.com/#/c/kernel/common/+/158491/
- patches do kernel 4.4 , patches do kernel 4.9 , etc.
O exemplo a seguir mostra configurações relacionadas ao dm-verity para sistema como root na linha de comando do 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"
Usando pastas raiz específicas do dispositivo
Com o sistema como raiz, depois que a imagem genérica do sistema (GSI) é atualizada no dispositivo (e antes de executar os testes do Vendor Test Suite ), todas as pastas raiz específicas do dispositivo adicionadas com BOARD_ROOT_EXTRA_FOLDERS
desaparecem porque todo o conteúdo do diretório raiz foi substituído pelo GSI do sistema como raiz. A remoção dessas pastas pode fazer com que o dispositivo não seja inicializável se existir uma dependência nas pastas raiz específicas do dispositivo (por exemplo, elas são usadas como pontos de montagem).
Para evitar esse problema, não use BOARD_ROOT_EXTRA_FOLDERS
para adicionar pastas raiz específicas do dispositivo. Se você precisar especificar pontos de montagem específicos do dispositivo, use /mnt/vendor/<mount point>
(adicionado nestas changelists ). Esses pontos de montagem específicos do fornecedor podem ser especificados diretamente na árvore de dispositivos fstab
(para montagem de primeiro estágio) e no arquivo /vendor/etc/fstab.{ro.hardware}
sem configuração adicional (já que fs_mgr
os cria em /mnt/vendor/*
automaticamente).