Android 10 admite particiones dinámicas , un sistema de partición del espacio de usuario que puede crear, cambiar el tamaño y destruir particiones durante las actualizaciones inalámbricas (OTA).
Esta página describe cómo los clientes OTA cambian el tamaño de las particiones dinámicas durante una actualización para dispositivos que no son A/B.
Para dispositivos que no son A/B, la actualización OTA para particiones dinámicas se aplica mediante el updater
dentro del paquete de actualización.
Actualizar dispositivos de lanzamiento
Esta sección se aplica a los dispositivos que no son A/B que se inician con soporte de particiones dinámicas; estos dispositivos se actualizan de Android 10 a versiones superiores.
Generar paquetes de actualización
Los paquetes de actualización OTA son generados por el script ota_from_target_files
, ubicado en build/make/tools/releasetools
. De forma predeterminada, el script genera un paquete que actualiza las particiones del system
y vendor
. Si hay particiones dinámicas adicionales, como product
, product_services
u odm
, sus actualizaciones deben generarse en código específico del dispositivo .
Para generar actualizaciones, en el módulo Python extendido, implemente FullOTA_GetBlockDifferences()
e IncrementalOTA_GetBlockDifferences()
. Estas dos funciones devuelven una lista de objetos BlockDifference
, cada uno de los cuales describe el parche de actualización que se aplicaría en una partición. Las particiones devueltas por estas dos funciones no deben modificarse manualmente ni verificarse en otro lugar, por ejemplo, en *_InstallBegin()
o *_InstallEnd()
.
Ejemplo de una generación de actualización:
# 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()]
Flujo de actualización
Detrás de escena, se agregan las siguientes funciones al script de edify:
-
unmap_partition(name)
- Desasignar la partición si está asignada; de lo contrario, no haga nada.
- Devuelve la cadena
t
en caso de éxito o una cadena vacía en caso de error.
-
map_partition(name)
- Asigne la partición si aún no está asignada.
- Devuelve la ruta absoluta del dispositivo de bloque mapeado en caso de éxito o una cadena vacía en caso de falla.
-
update_dynamic_partitions(op_list)
- Aplique la lista de operaciones dada en metadatos de partición dinámica, desasignando particiones si es necesario.
- Devuelve
t
en caso de éxito o una cadena vacía en caso de error.
El argumento op_list
para update_dynamic_partitions
apunta a un archivo en el paquete de actualización. Cada línea del archivo especifica una operación. Si alguna operación falla, update_dynamic_partitions
devuelve inmediatamente una cadena vacía. Las operaciones son:
-
resize partition-name size
- Quite el mapa de la partición, luego cambie su tamaño a size .
-
remove partition_name
- Desasignar la partición y luego eliminarla.
-
add partition-name group-name
- Agregue una nueva partición al grupo especificado.
- Abortar si el grupo no existe o si la partición ya existe.
-
move partition-name group-name
- Mueva la partición al grupo especificado.
- Abortar si el grupo no existe o la partición no existe.
-
add_group group-name maximum-size
- Agregue un grupo con el nombre dado y el tamaño máximo.
- Abortar si el grupo ya existe.
- Un maximum_size de 0 significa que no hay límites de tamaño en las particiones del grupo. Se requieren pruebas adicionales para garantizar que las particiones del grupo no excedan el espacio disponible en el dispositivo.
-
resize_group group-name maximum-size
- Cambie el tamaño del grupo al tamaño máximo dado.
- Abortar si el grupo no existe.
- Un maximum_size de 0 significa que no hay límites de tamaño en las particiones del grupo. Se requieren pruebas adicionales para garantizar que las particiones del grupo no excedan el espacio disponible en el dispositivo.
-
remove_group group-name
- Eliminar un grupo.
- Abortar si hay particiones en el grupo.
-
remove_all_groups
- Desasignar todas las particiones del mapeador de dispositivos.
- Elimina todas las particiones y grupos.
OTA incrementales
Las actualizaciones incrementales de OTA utilizan la siguiente lógica:
- Reducir particiones/eliminar particiones/mover particiones fuera del grupo (para que haya suficiente espacio para reducir grupos)
- Reducir grupos (para que haya suficiente espacio para hacer crecer los grupos)
- Hacer crecer grupos (para que tengamos suficiente espacio para hacer crecer/agregar particiones)
- Aumentar particiones/agregar particiones/mover particiones a un nuevo grupo
En detalle, update-script
se genera con 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), …)
El archivo op_list
para update_dynamic_partitions
se genera con 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
Las actualizaciones completas de OTA utilizan la siguiente lógica:
- Eliminar todos los grupos y particiones existentes
- Agregar grupos
- Agregar particiones
En detalle, update-script
se genera con esta lógica:
update_dynamic_partitions(op_list) for each adding partition: block_image_update(map_partition(name), …)
El archivo op_list
para update_dynamic_partitions
se genera con esta lógica:
remove_all_groups for each adding group: add_group for each adding partition: add for each adding partition: resize