No Android 10, o sistema de arquivos raiz não está mais
incluído em ramdisk.img
. Em vez disso, ele é mesclado em
system.img
. Ou seja, system.img
é sempre criado como
se BOARD_BUILD_SYSTEM_ROOT_IMAGE
tivesse sido definido. Dispositivos
lançados com o Android 10:
- Use um layout de partição de sistema como raiz (forçado automaticamente pelo build sem opções para mudar o comportamento).
- É necessário usar um ramdisk, que é obrigatório para dm-linear.
- Defina
BOARD_BUILD_SYSTEM_ROOT_IMAGE
comofalse
. Essa configuração é usada apenas para diferenciar dispositivos que usam um ramdisk e dispositivos que não usam um ramdisk (e montamsystem.img
diretamente).
O significado de uma configuração do sistema como raiz é diferente entre o Android 9 e
o Android 10. Em uma configuração do sistema como raiz
do Android 9, BOARD_BUILD_SYSTEM_ROOT_IMAGE
é definido como
true
, o que força o build a mesclar o sistema de arquivos raiz em
system.img
e, em seguida, montar system.img
como o sistema de arquivos
raiz (rootfs). Essa configuração é obrigatória para dispositivos
lançados com o Android 9, mas é opcional para dispositivos que estão sendo atualizados para
o Android 9 e para dispositivos que executam versões anteriores do Android. Em uma configuração
do sistema como raiz do Android 10, o build sempre
mescla $TARGET_SYSTEM_OUT
e $TARGET_ROOT_OUT
em
system.img
. Essa configuração é o comportamento padrão para todos os dispositivos
que executam o Android 10.
O Android 10 faz outras mudanças para oferecer suporte a partições dinâmicas, um sistema de particionamento no espaço do usuário que permite que as atualizações over the air (OTA) criem, redimensionem ou destruam partições. Como parte dessa mudança, o kernel do Linux não pode mais montar a partição do sistema lógico em dispositivos com o Android 10. Portanto, essa operação é processada pela inicialização do primeiro estágio.
As seções a seguir descrevem os requisitos do sistema como raiz para OTAs somente do sistema e fornecem orientações sobre como atualizar dispositivos para usar o sistema como raiz, incluindo mudanças no layout da partição e requisitos do kernel dm-verity. Para detalhes sobre as mudanças no ramdisk, consulte Partições de ramdisk.
Sobre as OTAs somente do sistema
As OTAs exclusivas do sistema, que permitem que as 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 com o Android
10 precisam usar um layout de partição do sistema como raiz para
ativar as OTAs somente do sistema.
- Dispositivos A/B, que montam a partição
system
como rootfs, já usam o sistema como raiz e não exigem mudanças para oferecer suporte a OTAs do sistema. - Os dispositivos que não são A/B, que montam a partição
system
em/system
, precisam ser atualizados para usar um layout de partição do sistema como raiz para oferecer suporte a OTAs do sistema.
Para saber mais sobre dispositivos A/B e não A/B, consulte Atualizações do sistema A/B (seamless).
Usar a sobreposição do fornecedor (<=AOSP 14)
A sobreposição do fornecedor permite que você faça mudanças na partição vendor
no momento da inicialização do dispositivo. Uma sobreposição de fornecedor é um conjunto de módulos de fornecedores na
partição product
que são sobrepostos à partição vendor
quando o dispositivo é inicializado, substituindo e adicionando aos módulos existentes.
Quando o dispositivo é inicializado, o processo init
conclui a montagem da primeira
etapa e lê as propriedades padrão. Em seguida, ele procura
/product/vendor_overlay/<target_vendor_version>
e monta
cada subdiretório no diretório de partição vendor
correspondente,
se as seguintes condições forem atendidas:
/vendor/<overlay_dir>
já existe./product/vendor_overlay/<target_vendor_version>/<overlay_dir>
tem o mesmo contexto de arquivo que/vendor/<overlay_dir>
.init
tem permissão para montagem no contexto de arquivo de/vendor/<overlay_dir>
.
Implementar a sobreposição do fornecedor
Instale arquivos de sobreposição do fornecedor em
/product/vendor_overlay/<target_vendor_version>
. Esses arquivos
são sobrepostos à 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 precisam ter o mesmo contexto de arquivo dos arquivos de destino
que eles substituem na partição vendor
. Por padrão, os arquivos no
diretório /product/vendor_overlay/<target_vendor_version>
têm 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
sepolicy 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 precisa ativar o OverlayFS definindo
CONFIG_OVERLAY_FS=y
. Além disso, o kernel precisa ser mesclado do
kernel comum 4.4 ou mais recente ou corrigido com "overlayfs:
override_creds=off option bypass creator_cred"
.
Exemplo de implementação de sobreposição do 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 fornecedores pré-criados 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é-criados do fornecedor em
product/vendor_overlay
nodevice/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
-
Permitir 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 montagem 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;
Validar 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 eles são sobrepostos aos arquivos em
/vendor/<overlay_dir>
.
Para builds userdebug
, há um módulo de teste para Atest:
$ atest -v fs_mgr_vendor_overlay_test
Atualizar para o sistema como raiz
Para atualizar dispositivos que não são A/B para usar o sistema como raiz, é necessário atualizar o
esquema de particionamento para boot.img
e system.img
, configurar
o dm-verity e remover todas as dependências de inicialização nas pastas raiz
específicas do dispositivo.
Atualizar partições
Ao contrário dos dispositivos A/B que reutilizam /boot
como a partição
de recuperação,
os dispositivos não A/B precisam manter a partição /recovery
separada, já que não têm 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 for semelhante ao esquema A/B, o modo de recuperação
poderá falhar durante uma atualização com falha na partição /boot
. Por
esse motivo, a partição /recovery
precisa ser uma
partição separada de /boot
para dispositivos não A/B, o que implica
que a imagem de recuperação continua sendo atualizada de forma adiada, ou
seja, da mesma forma que em dispositivos com o Android 8.1.0 ou versões anteriores.
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 da versão 9) | Sistema como raiz (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 de system.img original e
ramdisk.img :
system.img -/ - init.rc - init - etc -> /system/etc - system/ - bin/ - etc/ - vendor -> /vendor - ... - vendor/ (mount point) - odm/ (mount point) ... |
As partições em si não mudam. O ramdisk e o sistema como raiz usam o seguinte esquema de partição:
/boot
/system
/system
/recovery
/vendor
etc.
Configurar o dm-verity
No sistema-como-raiz, o kernel precisa montar system.img
em
/
(ponto de montagem) com
dm-verity. O AOSP oferece suporte às seguintes implementações do dm-verity
para system.img
.
vboot 1.0
Para a vboot 1.0, o kernel precisa analisar
os metadados específicos do
Android em
/system
e, em seguida, convertê-los em
dm-verity params para configurar o dm-verity (requer
estes patches do kernel).
O exemplo a seguir mostra as configurações relacionadas à dm-verity para o sistema-como-raiz 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 o vboot 2.0
(AVB), o carregador de inicialização precisa integrar
external/avb/libavb, que analisa o
descriptor de hashtree para /system
, o converte
em
dm-verity params e, por fim, os transmite para o
kernel pela linha de comando. Os descritores de hashtree de /system
podem estar em /vbmeta
ou no próprio /system
.
O vboot 2.0 requer os seguintes patches do kernel:
- https://android-review.googlesource.com/#/c/kernel/common/+/158491/
- kernel 4.4 patches, kernel 4.9 patches etc.
O exemplo a seguir mostra as configurações relacionadas à dm-verity para o sistema-como-raiz 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"
Usar 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 da execução
dos testes do Conjunto de teste de fornecedores), todas
as pastas raiz específicas do dispositivo adicionadas com BOARD_ROOT_EXTRA_FOLDERS
são removidas porque todo o conteúdo do diretório raiz foi substituído pela
GSI do sistema como raiz. A remoção dessas pastas pode fazer com que o dispositivo
não possa ser inicializado se houver uma dependência das pastas raiz específicas do dispositivo
(por exemplo, se elas forem 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 a essas
listas de mudanças). Esses pontos de montagem específicos do fornecedor podem ser
especificados diretamente na árvore de dispositivos fstab
(para montagem
de primeira fase) e no arquivo /vendor/etc/fstab.{ro.hardware}
sem
configuração adicional, já que o fs_mgr
as cria automaticamente
no /mnt/vendor/*
.