Android 10 supporta le partizioni dinamiche , un sistema di partizionamento dello spazio utente in grado di creare, ridimensionare e distruggere le partizioni durante gli aggiornamenti over-the-air (OTA).
Questa pagina descrive come i client OTA ridimensionano le partizioni dinamiche durante un aggiornamento per dispositivi non A/B.
Per i dispositivi non A/B, l'aggiornamento OTA per le partizioni dinamiche viene applicato utilizzando il updater
all'interno del pacchetto di aggiornamento.
Aggiorna i dispositivi di lancio
Questa sezione si applica ai dispositivi non A/B che vengono avviati con il supporto delle partizioni dinamiche; questi dispositivi si aggiornano da Android 10 a versioni successive.
Genera pacchetti di aggiornamento
I pacchetti di aggiornamento OTA vengono generati dallo script ota_from_target_files
, situato in build/make/tools/releasetools
. Per impostazione predefinita, lo script genera un pacchetto che aggiorna il system
e le partizioni vendor
. Se sono presenti partizioni dinamiche aggiuntive, come product
, product_services
o odm
, i relativi aggiornamenti devono essere generati nel codice specifico del dispositivo .
Per generare aggiornamenti, nel modulo Python esteso, implementare FullOTA_GetBlockDifferences()
e IncrementalOTA_GetBlockDifferences()
. Queste due funzioni restituiscono un elenco di oggetti BlockDifference
, ciascuno dei quali descrive la patch di aggiornamento che verrebbe applicata su una partizione. Le partizioni restituite da queste due funzioni non devono essere modificate manualmente o verificate altrove, ad esempio in *_InstallBegin()
o *_InstallEnd()
.
Esempio di generazione di aggiornamenti:
# 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()]
Flusso di aggiornamento
Dietro le quinte, allo script edify vengono aggiunte le seguenti funzioni:
-
unmap_partition(name)
- Annulla la mappatura della partizione se mappata, altrimenti non fare nulla.
- Restituisce la stringa
t
in caso di successo o una stringa vuota in caso di fallimento.
-
map_partition(name)
- Mappare la partizione se non è già mappata.
- Restituisce il percorso assoluto del dispositivo a blocchi mappato in caso di successo o una stringa vuota in caso di fallimento.
-
update_dynamic_partitions(op_list)
- Applicare l'elenco di operazioni fornito sui metadati della partizione dinamica, annullando la mappatura delle partizioni se necessario.
- Restituisce
t
in caso di successo o una stringa vuota in caso di fallimento.
L'argomento op_list
di update_dynamic_partitions
punta a un file nel pacchetto di aggiornamento. Ogni riga nel file specifica un'operazione. Se un'operazione fallisce, update_dynamic_partitions
restituisce immediatamente una stringa vuota. Le operazioni sono:
-
resize partition-name size
- Annulla la mappatura della partizione, quindi ridimensionala alla size .
-
remove partition_name
- Annulla la mappatura della partizione, quindi rimuovila.
-
add partition-name group-name
- Aggiungi una nuova partizione al gruppo specificato.
- Interrompe se il gruppo non esiste o se la partizione esiste già.
-
move partition-name group-name
- Sposta la partizione nel gruppo specificato.
- Interrompe se il gruppo non esiste o la partizione non esiste.
-
add_group group-name maximum-size
- Aggiungi un gruppo con il nome specificato e la dimensione massima.
- Interrompere se il gruppo esiste già.
- Una maximum_size pari a 0 significa che non ci sono limiti di dimensione sulle partizioni nel gruppo. Sono necessari test aggiuntivi per garantire che le partizioni nel gruppo non superino lo spazio disponibile sul dispositivo.
-
resize_group group-name maximum-size
- Ridimensiona il gruppo alla dimensione massima specificata.
- Interrompere se il gruppo non esiste.
- Una maximum_size pari a 0 significa che non ci sono limiti di dimensione sulle partizioni nel gruppo. Sono necessari test aggiuntivi per garantire che le partizioni nel gruppo non superino lo spazio disponibile sul dispositivo.
-
remove_group group-name
- Rimuovere un gruppo.
- Interrompe se sono presenti partizioni nel gruppo.
-
remove_all_groups
- Annulla la mappatura di tutte le partizioni dal mappatore del dispositivo.
- Rimuovi tutte le partizioni e i gruppi.
OTA incrementale
Gli aggiornamenti OTA incrementali utilizzano la seguente logica:
- Riduci partizioni/elimina partizioni/sposta partizioni fuori gruppo (in modo che ci sia spazio sufficiente per ridurre i gruppi)
- Riduci i gruppi (in modo che ci sia spazio sufficiente per far crescere i gruppi)
- Aumenta i gruppi (in modo da avere abbastanza spazio per espandere/aggiungere partizioni)
- Aumenta le partizioni/aggiungi partizioni/sposta le partizioni in un nuovo gruppo
Nel dettaglio, update-script
viene generato con questa logica:
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), …)
Il file op_list
per update_dynamic_partitions
viene generato con questa logica:
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
Gli aggiornamenti OTA completi utilizzano la seguente logica:
- Elimina tutti i gruppi e le partizioni esistenti
- Aggiungi gruppi
- Aggiungi partizioni
Nel dettaglio, update-script
viene generato con questa logica:
update_dynamic_partitions(op_list) for each adding partition: block_image_update(map_partition(name), …)
Il file op_list
per update_dynamic_partitions
viene generato con questa logica:
remove_all_groups for each adding group: add_group for each adding partition: add for each adding partition: resize