O Android 10 oferece suporte a partições dinâmicas, um sistema de particionamento no espaço do usuário que pode criar, redimensionar e destruir partições durante atualizações OTA.
Esta página descreve como os clientes OTA redimensionam partições dinâmicas durante uma atualização para dispositivos A/B iniciados sem suporte a partições dinâmicas e como os clientes OTA fazem upgrade para o Android 10.
Contexto
Durante uma atualização de um dispositivo A/B para oferecer suporte a partições dinâmicas, a
tabela de partições GUID (GPT) no dispositivo é preservada. Por isso, não há
partição super
no dispositivo. Os metadados são armazenados em
system_a
e system_b
, mas isso pode ser
personalizado mudando BOARD_SUPER_PARTITION_METADATA_DEVICE
.
Em cada um dos dispositivos de bloco, há dois slots de metadados. Apenas um
slot de metadados em cada dispositivo de bloco é usado. Por exemplo, os metadados 0 em
system_a
e os metadados 1 em system_b
correspondem às partições nos slots A e B, respectivamente. No
momento da execução, não importa qual slot está sendo atualizado.
Nesta página, os slots de metadados são chamados de Metadata S
(origem) e Metadata T (destino). Da mesma forma, as partições são chamadas de system_s
, vendor_t
e assim por diante.
Para mais informações sobre as configurações do sistema de build, consulte Atualizar dispositivos.
Para mais informações sobre como as partições pertencem a grupos de atualização, consulte Mudanças de configuração do dispositivo para novos dispositivos.
Um exemplo de metadados em um dispositivo é:
- Dispositivo de bloco físico
system_a
- Metadados 0
- Grupo
foo_a
- Partição lógica (dinâmica)
system_a
- Partição lógica (dinâmica)
product_services_a
- Outras partições atualizadas por Foo
- Partição lógica (dinâmica)
- Grupo
bar_a
- Partição lógica (dinâmica)
vendor_a
- Partição lógica (dinâmica)
product_a
- Outras partições atualizadas por barra
- Partição lógica (dinâmica)
- Grupo
- Metadados 1 (não usados)
- Metadados 0
- Dispositivo de bloco físico
system_b
- Metadados 0 (não usados)
- Metadados 1
- Grupo foo_b
- Partição lógica (dinâmica)
system_b
- Partição lógica (dinâmica)
product_services_b
- Outras partições atualizadas por Foo
- Partição lógica (dinâmica)
- Grupo bar_b
- Partição lógica (dinâmica)
vendor_b
- Partição lógica (dinâmica)
product_b
- Outras partições atualizadas por barra
- Partição lógica (dinâmica)
- Grupo foo_b
Você pode usar a ferramenta lpdump
em
system/extras/partition_tools
para despejar os metadados no
seu dispositivo. Exemplo:
lpdump --slot 0 /dev/block/by-name/system_a
lpdump --slot 1 /dev/block/by-name/system_b
Retrofit para uma atualização
Em dispositivos com Android 9 e versões anteriores, o cliente OTA no dispositivo não oferece suporte ao mapeamento de partições dinâmicas antes da atualização. Um conjunto extra de patches é criado para que o mapeamento possa ser aplicado diretamente às partições físicas atuais.
O gerador OTA gera o arquivo super.img
final que
contém o conteúdo de todas as partições dinâmicas e, em seguida, divide a imagem
em várias imagens que correspondem aos tamanhos dos dispositivos de bloco físico
correspondentes ao sistema, fornecedor etc. Essas imagens são chamadas de super_system.img
, super_vendor.img
e assim por diante.
O cliente OTA aplica essas imagens às partições físicas, em vez
de aplicar as imagens às partições lógicas (dinâmicas).
Como o cliente OTA não sabe como mapear partições dinâmicas, todas as etapas pós-instalação são desativadas automaticamente para essas partições quando o pacote de atualização é gerado. Consulte Como configurar a pós-instalação para mais detalhes.
O fluxo de atualização é o mesmo do Android 9.
Antes da atualização:
ro.boot.dynamic_partitions= ro.boot.dynamic_partitions_retrofit=
Após a atualização:
ro.boot.dynamic_partitions=true ro.boot.dynamic_partitions_retrofit=true
Atualizações futuras após o retrofit
Após a atualização do retrofit, o cliente OTA é atualizado para funcionar com partições dinâmicas. As extensões das partições de origem nunca se estendem entre partições físicas de destino.
Fluxo de atualização usando um pacote de atualização regular
- Inicializar os metadados da partição
super
.-
Criar novos metadados M a partir de metadados S (metadados de origem).
Por exemplo, se o Metadata S usa [
system_s
,vendor_s
,product_s
] como dispositivos de bloqueio, o novo Metadata M usa [system_t
,vendor_t
,product_t
] como dispositivos de bloqueio. Todos os grupos e partições são descartados em M. -
Adicione grupos e partições de destino de acordo com o
campo
dynamic_partition_metadata
no manifesto de atualização. O tamanho de cada partição pode ser encontrado emnew_partition_info
. - Gravar M em Metadata T.
- Mapeie as partições adicionadas no mapeador de dispositivos como graváveis.
-
Criar novos metadados M a partir de metadados S (metadados de origem).
Por exemplo, se o Metadata S usa [
- Aplique a atualização nos dispositivos de bloco.
- Se necessário, mapeie as partições de origem no mapeador do dispositivo como somente leitura. Isso é necessário para o sideload porque as partições de origem não são mapeadas antes da atualização.
- Aplique uma atualização completa ou delta a todos os dispositivos de bloco no slot de destino.
- Monte as partições para executar o script pós-instalação e, em seguida, desmonte as partições.
- Desmapear as partições de destino.
Atualizar o fluxo usando um pacote de atualização de retrofit
Se o pacote de atualização da Retrofit for aplicado a um dispositivo que já
ativa partições dinâmicas, o cliente OTA aplicará o arquivo
super.img
dividido diretamente aos dispositivos em bloco. O fluxo de atualização é semelhante a uma atualização de retrofit. Consulte
Como fazer o ajuste de uma atualização novamente
para ver mais detalhes.
Por exemplo, suponha que:
- O slot A é o ativo.
-
system_a
contém os metadados ativos no slot 0. -
system_a
,vendor_a
eproduct_a
são usados como dispositivos de bloco.
Quando o cliente OTA recebe um pacote de atualização de retrofit, ele aplica
super_system.img
no system_b
físico,
super_vendor.img
no vendor_b
físico e
super_product.img
no product_b
físico.
O dispositivo de bloco físico system_b
contém os metadados
corretos para mapear o system_b
,
vendor_b
e product_b
lógicos no momento da inicialização.
Gerar pacotes de atualização
OTA incremental
Ao gerar OTAs incrementais para dispositivos de retrofit, as atualizações
dependem de o build de base definir
PRODUCT_USE_DYNAMIC_PARTITIONS
e
PRODUCT_RETROFIT_DYNAMIC_PARTITIONS
.
-
Se o build de base não definir as variáveis, essa será uma
atualização de retroajuste. O pacote de atualização contém o arquivo
super.img
dividido e desativa a etapa pós-instalação. - Se o build base definir as variáveis, isso será igual a uma atualização típica com partições dinâmicas. O pacote de atualização contém as imagens para partições lógicas (dinâmicas). A etapa pós-instalação pode ser ativada.
OTA completo
Dois pacotes OTA completos são gerados para dispositivos de retrofit.
-
$(PRODUCT)-ota-retrofit-$(TAG).zip
sempre contém osuper.img
dividido e desativa a etapa pós-instalação para a atualização de retrofitting.-
Ele é gerado com um argumento
--retrofit_dynamic_partitions
adicional para o scriptota_from_target_files
. - Ele pode ser aplicado a todos os builds.
-
Ele é gerado com um argumento
-
$(PRODUCT)-ota-$(TAG).zip
contém imagens lógicas para atualizações futuras.- Aplique isso apenas a builds com partições dinâmicas ativadas. Confira os detalhes abaixo sobre como fazer isso.
Rejeitar a atualização não retrofit em builds antigos
Aplique o pacote OTA completo normal apenas a builds com partições dinâmicas ativadas. Se o servidor OTA estiver configurado incorretamente e enviar esses pacotes para dispositivos com o Android 9 ou versões anteriores, os dispositivos não vão inicializar. O cliente OTA no Android 9 e versões anteriores não consegue identificar a diferença entre um pacote OTA de retrofit e um pacote OTA completo normal. Portanto, o cliente não rejeita o pacote completo.
Para impedir que o dispositivo aceite o pacote OTA completo, você pode exigir uma etapa pós-instalação para verificar a configuração do dispositivo. Exemplo:
device/device_name/dynamic_partitions/check_dynamic_partitions
#!/system/bin/sh DP_PROPERTY_NAME="ro.boot.dynamic_partitions" DP_RETROFIT_PROPERTY_NAME="ro.boot.dynamic_partitions_retrofit" DP_PROPERTY=$(getprop ${DP_PROPERTY_NAME}) DP_RETROFIT_PROPERTY=$(getprop ${DP_RETROFIT_PROPERTY_NAME}) if [ "${DP_PROPERTY}" != "true" ] || [ "${DP_RETROFIT_PROPERTY}" != "true" ] ; then echo "Error: applied non-retrofit update on build without dynamic" \ "partitions." echo "${DP_PROPERTY_NAME}=${DP_PROPERTY}" echo "${DP_RETROFIT_PROPERTY_NAME}=${DP_RETROFIT_PROPERTY}" exit 1 fi
device/device_name/dynamic_partitions/Android.mk
LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE:= check_dynamic_partitions LOCAL_MODULE_TAGS := optional LOCAL_MODULE_CLASS := EXECUTABLES LOCAL_SRC_FILES := check_dynamic_partitions LOCAL_PRODUCT_MODULE := true include $(BUILD_PREBUILT)
device/device_name/device.mk
PRODUCT_PACKAGES += check_dynamic_partitions # OPTIONAL=false so that the error in check_dynamic_partitions will be # propagated to OTA client. AB_OTA_POSTINSTALL_CONFIG += \ RUN_POSTINSTALL_product=true \ POSTINSTALL_PATH_product=bin/check_dynamic_partitions \ FILESYSTEM_TYPE_product=ext4 \ POSTINSTALL_OPTIONAL_product=false \
Quando o pacote OTA normal é aplicado em um dispositivo sem partições
dinâmicas ativadas, o cliente OTA executa
check_dynamic_partitions
como uma etapa pós-instalação e
rejeita a atualização.