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 não A/B.
Para dispositivos não A/B, a atualização OTA para partições dinâmicas é aplicada
usando o updater
dentro do pacote de atualização.
Atualizar dispositivos de inicialização
Esta seção se aplica a dispositivos que não são A/B que são iniciados com suporte a partições dinâmicas. Esses dispositivos são atualizados do Android 10 para versões mais recentes.
Gerar pacotes de atualização
Os pacotes de atualização OTA são gerados pelo
script ota_from_target_files
, localizado em
build/make/tools/releasetools
. Por padrão, o script
gera um pacote que atualiza as partições system
e
vendor
. Se houver outras partições
dinâmicas, como product
,
product_services
ou odm
, as
atualizações delas precisam ser geradas no
código específico do
dispositivo.
Para gerar atualizações, no módulo estendido do Python, implemente
FullOTA_GetBlockDifferences()
e
IncrementalOTA_GetBlockDifferences()
. Essas duas
funções retornam uma lista de objetos BlockDifference
,
cada uma descrevendo o patch de atualização que seria aplicado em uma
partição. As partições retornadas por essas duas funções não podem ser
modificadas manualmente ou verificadas em outro lugar, por exemplo, em
*_InstallBegin()
ou *_InstallEnd()
.
Exemplo de uma geração de atualização:
# device/yoyodyne/tardis/releasetools.py import os from common import BlockDifference, EmptyImage, GetUserImage # The joined list of user image partitions of source and target builds. # - Items should be added to the list if new dynamic partitions are added. # - Items should not be removed from the list even if dynamic partitions are # deleted. When generating an incremental OTA package, this script needs to # know that an image is present in source build but not in target build. USERIMAGE_PARTITIONS = [ "product", "odm", ] def GetUserImages(input_tmp, input_zip): return {partition: GetUserImage(partition, input_tmp, input_zip) for partition in USERIMAGE_PARTITIONS if os.path.exists(os.path.join(input_tmp, "IMAGES", partition + ".img"))} def FullOTA_GetBlockDifferences(info): images = GetUserImages(info.input_tmp, info.input_zip) return [BlockDifference(partition, image) for partition, image in images.items()] def IncrementalOTA_GetBlockDifferences(info): source_images = GetUserImages(info.source_tmp, info.source_zip) target_images = GetUserImages(info.target_tmp, info.target_zip) # Use EmptyImage() as a placeholder for partitions that will be deleted. for partition in source_images: target_images.setdefault(partition, EmptyImage()) # Use source_images.get() because new partitions are not in source_images. return [BlockDifference(partition, target_image, source_images.get(partition)) for partition, target_image in target_images.items()]
Atualizar fluxo
Nos bastidores, as seguintes funções são adicionadas ao script edify:
unmap_partition(name)
- Desmapeia a partição se ela estiver mapeada. Caso contrário, nada será feito.
- Retorna a string
t
em caso de sucesso ou uma string vazia em caso de falha.
map_partition(name)
- Mapeie a partição, se ela ainda não estiver mapeada.
- Retorna o caminho absoluto do dispositivo de bloco mapeado em caso de sucesso ou uma string vazia em caso de falha.
update_dynamic_partitions(op_list)
- Aplique a lista de operações especificada nos metadados de partição dinâmica, desmapeando as partições, se necessário.
-
Retorne
t
em caso de sucesso ou uma string vazia em caso de falha.
O argumento op_list
para
update_dynamic_partitions
aponta para um arquivo no
pacote de atualização. Cada linha no arquivo especifica uma operação. Se qualquer
operação falhar, update_dynamic_partitions
retornará imediatamente
uma string vazia. As operações são:
resize partition-name size
- Desfaça o mapeamento da partição e redimensione-a para size.
remove partition_name
- Desmapeie a partição e remova-a.
add partition-name group-name
- Adicione uma nova partição ao grupo especificado.
- Aborta se o grupo não existir ou se a partição já existir.
move partition-name group-name
- Mova a partição para o grupo especificado.
- Cancelar se o grupo ou a partição não existirem.
-
add_group group-name maximum-size
- Adicione um grupo com o nome e o tamanho máximo fornecidos.
- Cancelar se o grupo já existir.
- Um maximum_size de 0 significa que não há limites de tamanho nas partições do grupo. Outros testes são necessários para garantir que as partições no grupo não excedam o espaço disponível no dispositivo.
-
resize_group group-name maximum-size
- Redimensione o grupo para o tamanho máximo especificado.
- Cancelar se o grupo não existir.
- Um maximum_size de 0 significa que não há limites de tamanho nas partições do grupo. Outros testes são necessários para garantir que as partições no grupo não excedam o espaço disponível no dispositivo.
remove_group group-name
- Remover um grupo.
- Aborta se houver partições no grupo.
remove_all_groups
- Cancelar o mapeamento de todas as partições do mapeador do dispositivo.
- Remova todas as partições e grupos.
OTA incremental
As atualizações OTA incrementais usam a seguinte lógica:
- Reduzir partições/excluir partições/mover partições para fora do grupo (para que haja espaço suficiente para reduzir grupos)
- Reduzir grupos (para que haja espaço suficiente para aumentar os grupos)
- Aumente os grupos (para que tenhamos espaço suficiente para expandir/adicionar partições)
- Ampliar/adicionar/mover partições para um novo grupo
Em detalhes, update-script
é gerado com esta
lógica:
for each shrinking partition: block_image_update(map_partition(name), …) update_dynamic_partitions(op_list) for each growing / adding partition: block_image_update(map_partition(name), …)
O arquivo op_list
para
update_dynamic_partitions
é gerado com esta
lógica:
for each deleting partition: remove for each partition that changes groups: move to "default" for each shrinking partition: resize for each shrinking / removing group: resize_group / remove_group for each growing / adding group: resize_group / add_group for each adding partition: add for each growing / adding partition: resize for each partition that changes groups: move to target group
OTA completo
As atualizações OTA completas usam a seguinte lógica:
- Excluir todos os grupos e partições
- Adicionar grupos
- Adicionar partições
Em detalhes, update-script
é gerado com esta
lógica:
update_dynamic_partitions(op_list) for each adding partition: block_image_update(map_partition(name), …)
O arquivo op_list
para
update_dynamic_partitions
é gerado com esta
lógica:
remove_all_groups for each adding group: add_group for each adding partition: add for each adding partition: resize