O Android 10 oferece suporte a 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 over-the-air (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 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, os metadados 0 em system_a
e os 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 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 é:
-
system_a
de dispositivo de bloco físico_a- Metadados 0
- Grupo
foo_a
-
system_a
de partição lógica (dinâmica)_a - Partição lógica (dinâmica)
product_services_a
- Outras partições atualizadas por Foo
-
- Grupo
bar_a
-
vendor_a
de partição lógica (dinâmica)_a -
product_a
de partição lógica (dinâmica)_a - Outras partições atualizadas pelo Bar
-
- Grupo
- Metadados 1 (não usado)
- Metadados 0
-
system_b
de dispositivo de bloco físico_b- Metadados 0 (não usado)
- Metadados 1
- Grupo foo_b
-
system_b
de partição lógica (dinâmica)_b - Partição lógica (dinâmica)
product_services_b
- Outras partições atualizadas por Foo
-
- Barra de grupo_b
-
vendor_b
de partição lógica (dinâmica)_b -
product_b
de partição lógica (dinâmica)_b - Outras partições atualizadas pelo Bar
-
- Grupo foo_b
Você pode usar a ferramenta lpdump
em system/extras/partition_tools
para despejar os metadados no seu dispositivo. Por exemplo:
lpdump --slot 0 /dev/block/by-name/system_a
lpdump --slot 1 /dev/block/by-name/system_b
Retrofit 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 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 que correspondem 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 como 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 retrofit
Após a atualização de retrofit, o cliente OTA é atualizado para funcionar com partições dinâmicas. As extensões das partições de origem nunca se estendem pelas partições físicas de destino.
Fluxo de atualização usando um pacote de atualização regular
- Inicialize os metadados
super
.- Construa novos metadados M a partir de Metadados S (metadados de origem). Por exemplo, se os metadados S usarem [
system_s
,vendor_s
,product_s
] como dispositivos de bloco, então os novos metadados M usarão [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 nos metadados T.
- Mapeie as partições adicionadas no mapeador de dispositivos como graváveis.
- Construa novos metadados M a partir de Metadados S (metadados de origem). Por exemplo, se os metadados S usarem [
- Aplique a atualização nos dispositivos de bloco.
- Se necessário, mapeie as partições de origem no mapeador de dispositivos 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 desmonte as partições.
- Remova o mapeamento das partições de destino.
Fluxo de atualização usando um pacote de atualização de retrofit
Se o pacote de atualização de retroajuste for aplicado em um dispositivo que já permite partições dinâmicas, o cliente OTA aplica o arquivo super.img
dividido diretamente em dispositivos de bloco. 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 retroajuste, 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 os sistemas lógicos system_b
, vendor_b
e product_b
no momento da inicialização.
Gerar pacotes de atualização
OTA incremental
Ao gerar OTAs incrementais para dispositivos de retroajuste, as atualizações dependem de a construção base definir ou não PRODUCT_USE_DYNAMIC_PARTITIONS
e PRODUCT_RETROFIT_DYNAMIC_PARTITIONS
.
- Se a construção base não definir as variáveis, esta é uma atualização de retrofit. O pacote de atualização contém o arquivo
super.img
dividido e desativa a etapa pós-instalação. - Se a construção base definir as variáveis, isso será 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 de pós-instalação pode ser habilitada.
OTA completo
Dois pacotes OTA completos são gerados para dispositivos de retroajuste.
-
$(PRODUCT)-ota-retrofit-$(TAG).zip
sempre contémsuper.img
dividido e desativa a etapa pós-instalação para atualização de atualização.- É gerado com um argumento adicional
--retrofit_dynamic_partitions
para o scriptota_from_target_files
. - Pode ser aplicado a todas as construções.
- É gerado com um argumento adicional
-
$(PRODUCT)-ota-$(TAG).zip
contém imagens lógicas para atualizações futuras.- Aplique isto apenas a compilações com partições dinâmicas habilitadas. Veja detalhes abaixo sobre como fazer cumprir isso.
Rejeitar atualização não retrofit em compilações antigas
Aplique o pacote OTA completo regular apenas a compilações com partições dinâmicas habilitadas. Se o servidor OTA estiver configurado incorretamente e enviar esses pacotes para dispositivos que executam o Android 9 ou inferior, os dispositivos não conseguirão inicializar. O cliente OTA no Android 9 e versões anteriores não consegue distinguir entre um pacote OTA atualizado e um pacote OTA completo normal, portanto, o cliente não rejeitará o pacote completo.
Para evitar que o dispositivo aceite o pacote OTA completo, você pode exigir uma etapa pós-instalação para verificar a configuração existente do dispositivo. 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 pós-instalação e rejeita a atualização.