O Android 10 é compatível com partições dinâmicas , um sistema de particionamento de espaço do usuário que pode criar, redimensionar e destruir partições durante atualizações OTA (over-the-air).
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 atualizam para o Android 10.
Fundo
Durante uma atualização de um dispositivo A/B para dar suporte a partições dinâmicas, a tabela de partição GUID (GPT) no dispositivo é preservada, portanto, não há super
no dispositivo. Os metadados são armazenados em system_a
e system_b
, mas isso pode ser personalizado alterando BOARD_SUPER_PARTITION_METADATA_DEVICE
.
Em cada um dos dispositivos de bloco, existem dois slots de metadados. Apenas um slot de metadados em cada dispositivo de bloco é usado. Por exemplo, Metadados 0 em system_a
e Metadados 1 em system_b
correspondem a partições nos slots A e B, respectivamente. Em tempo de execução, não importa qual slot está sendo atualizado.
Nesta página, os slots de metadados são chamados de Metadados S (origem) e Metadados T (destino). Da mesma forma, as partições são chamadas de system_s
, vendor_t
e assim por diante.
Para obter mais informações sobre as configurações do sistema de compilação , consulte Atualizando dispositivos .
Para obter mais informações sobre como as partições pertencem a grupos de atualização , consulte Alterações na configuração da placa 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 Bar
- Partição lógica (dinâmica)
- Grupo
- Metadados 1 (não usado)
- 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 Bar
- Partição lógica (dinâmica)
- Grupo foo_b
Você pode usar a ferramenta lpdump
em system/extras/partition_tools
para despejar os metadados em seu dispositivo. Por exemplo:
lpdump --slot 0 /dev/block/by-name/system_a
lpdump --slot 1 /dev/block/by-name/system_b
Retrofit de uma atualização
Em dispositivos que executam o Android 9 e inferior, o cliente OTA no dispositivo não oferece suporte ao mapeamento de partições dinâmicas antes da atualização. Um conjunto adicional de patches é criado para que o mapeamento possa ser aplicado diretamente às partições físicas existentes.
O gerador OTA cria 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 correspondentes aos tamanhos dos dispositivos de bloco físico correspondentes ao sistema, fornecedor e assim por diante. Essas imagens são denominadas 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 mapear partições dinâmicas, todas as etapas pós-instalação são desabilitadas automaticamente para essas partições quando o pacote de atualização é gerado. Consulte Configurando a pós-instalação para obter 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 de retrofit, o cliente OTA é atualizado para trabalhar com partições dinâmicas. As extensões das partições de origem nunca abrangem as partições físicas de destino.
Fluxo de atualização usando um pacote de atualização regular
- Inicialize os metadados da
super
.- Construir novos metadados M a partir de Metadados S (metadados de origem). Por exemplo, se Metadata S usa [
system_s
,vendor_s
,product_s
] como dispositivos de bloco, então os novos metadados M usam [system_t
,vendor_t
,product_t
] como dispositivos de bloco. Todos os grupos e partições são descartados em M. - Adicione grupos de destino e partições 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
. - Escreva M em Metadados T.
- Mapeie as partições adicionadas no mapeador de dispositivos como graváveis.
- Construir novos metadados M a partir de Metadados S (metadados de origem). Por exemplo, se Metadata S usa [
- Aplique a atualização nos dispositivos de bloco.
- Se necessário, mapeie as partições de origem no mapeador de dispositivo como somente leitura. Isso é necessário para 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 de pós-instalação e, em seguida, desmonte as partições.
- Desmapeie as partições de destino.
Fluxo de atualização usando um pacote de atualização de retrofit
Se o pacote de atualização de retrofit for aplicado em um dispositivo que já habilita partições dinâmicas, o cliente OTA aplica o arquivo super.img
dividido em dispositivos de bloco diretamente. O fluxo de atualização é semelhante a uma atualização de retrofit. Consulte Retrofit de uma atualização para obter detalhes.
Por exemplo, suponha o seguinte:
- O slot A é o slot 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 físico system_b
, super_vendor.img
no físico vendor_b
e super_product.img
no físico product_b
. O dispositivo de bloco físico system_b
contém os metadados corretos para mapear o lógico system_b
, vendor_b
e product_b
no momento da inicialização.
Gerando pacotes de atualização
OTA incremental
Ao gerar OTAs incrementais para dispositivos de retrofit, as atualizações dependem se a compilação base define ou não PRODUCT_USE_DYNAMIC_PARTITIONS
e PRODUCT_RETROFIT_DYNAMIC_PARTITIONS
.
- Se a compilação base não definir as variáveis, esta é uma atualização de adaptação. O pacote de atualização contém o arquivo
super.img
dividido e desativa a etapa de pós-instalação. - Se a compilação base definir as variáveis, isso é o mesmo que 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 habilitada.
OTA completo
Dois pacotes OTA completos são gerados para dispositivos de retrofit.
-
$(PRODUCT)-ota-retrofit-$(TAG).zip
sempre contém splitsuper.img
e desativa a etapa de pós-instalação para atualização de retrofit.- Ele é gerado com um argumento adicional
--retrofit_dynamic_partitions
para o scriptota_from_target_files
. - Pode ser aplicado a todas as construções.
- Ele é gerado com um argumento adicional
-
$(PRODUCT)-ota-$(TAG).zip
contém imagens lógicas para atualizações futuras.- Aplique isso apenas a compilações com partições dinâmicas habilitadas. Veja os detalhes abaixo sobre como aplicar isso.
Rejeitando atualização não retrofit em compilações antigas
Aplique o pacote OTA completo regular apenas para compilações com partições dinâmicas habilitadas. Se o servidor OTA estiver configurado incorretamente e enviar esses pacotes para dispositivos com Android 9 ou inferior, os dispositivos não inicializarão. O cliente OTA no Android 9 e inferior não consegue diferenciar um pacote OTA de retrofit e um pacote OTA completo regular, portanto, o cliente não rejeitará o pacote completo.
Para evitar que o dispositivo aceite o pacote OTA completo, você pode exigir uma etapa de pós-instalação para verificar a configuração do dispositivo existente. Por 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 regular é aplicado em um dispositivo sem partições dinâmicas habilitadas, o cliente OTA executa check_dynamic_partitions
como uma etapa de pós-instalação e rejeita a atualização.