Android 10에서는 무선(OTA) 업데이트 중에 파티션을 만들고 크기를 조절하고 제거할 수 있는 사용자 공간 파티션 나누기 시스템인 동적 파티션을 지원합니다.
이 페이지에서는 비 A/B 기기를 업데이트하는 동안 OTA 클라이언트에서 동적 파티션의 크기를 조절하는 방법을 설명합니다.
비 A/B 기기의 경우 동적 파티션의 OTA 업데이트는 업데이트 패키지 내의 updater
를 사용하여 적용됩니다.
출시 기기 업데이트
이 섹션은 동적 파티션이 지원되는 상태로 출시되는 비 A/B 기기에 적용됩니다. 이러한 기기는 Android 10 이상 버전에서 업그레이드됩니다.
업데이트 패키지 생성
OTA 업데이트 패키지는 build/make/tools/releasetools
아래에 있는 ota_from_target_files
스크립트로 생성됩니다. 기본적으로 스크립트는 system
및 vendor
파티션을 업데이트하는 패키지를 생성합니다. 추가 동적 파티션(예: product
나 product_services
, odm
)이 있으면 이러한 파티션의 업데이트를 기기별 코드로 생성해야 합니다.
업데이트를 생성하려면 확장된 Python 모듈에서 FullOTA_GetBlockDifferences()
와 IncrementalOTA_GetBlockDifferences()
를 구현합니다. 이 두 함수는 BlockDifference
객체 목록을 반환하며 각 객체는 파티션에 적용될 업데이트 패치를 설명합니다. 이러한 두 함수로 반환되는 파티션은 수동으로 수정하거나 *_InstallBegin()
또는 *_InstallEnd()
와 같은 다른 위치에서 확인하면 안 됩니다.
업데이트 생성 예시:
# 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()]
업데이트 흐름
배경에서는 다음 함수가 edify 스크립트에 추가됩니다.
unmap_partition(name)
- 매핑된 경우 파티션을 매핑 해제하고 매핑되지 않은 경우 아무 작업도 하지 않습니다.
- 성공 시 문자열
t
를, 실패 시 빈 문자열을 반환합니다.
map_partition(name)
- 이미 매핑되지 않은 경우 파티션을 매핑합니다.
- 성공 시 매핑된 블록 기기의 절대 경로를, 실패 시 빈 문자열을 반환합니다.
update_dynamic_partitions(op_list)
- 동적 파티션 메타데이터에 주어진 작업 목록을 적용하며, 필요한 경우 파티션을 매핑 해제합니다.
- 성공 시
t
를, 실패 시 빈 문자열을 반환합니다.
update_dynamic_partitions
의 op_list
인수는 업데이트 패키지의 파일을 가리킵니다. 파일의 각 행은 작업을 지정합니다. 작업이 실패하면 update_dynamic_partitions
는 즉시 빈 문자열을 반환합니다. 작업은 다음과 같습니다.
resize partition-name size
- 파티션을 매핑 해제한 다음 size로 크기를 조절합니다.
remove partition_name
- 파티션을 매핑 해제한 다음 제거합니다.
add partition-name group-name
- 새 파티션을 지정된 그룹에 추가합니다.
- 그룹이 존재하지 않거나 파티션이 이미 존재하는 경우 취소합니다.
move partition-name group-name
- 파티션을 지정된 그룹으로 이동합니다.
- 그룹이 존재하지 않거나 파티션이 존재하지 않는 경우 취소합니다.
-
add_group group-name maximum-size
- 이름과 최대 크기가 주어진 그룹을 추가합니다.
- 그룹이 이미 존재하는 경우 취소합니다.
- maximum_size가 0이면 그룹의 파티션에 크기 제한이 없음을 의미합니다. 추가 테스트는 그룹의 파티션이 기기의 가용한 공간을 초과하지 않도록 해야 하는 경우에 필요합니다.
-
resize_group group-name maximum-size
- 그룹 크기를 주어진 최대 크기로 조절합니다.
- 그룹이 존재하지 않는 경우 취소합니다.
- maximum_size가 0이면 그룹의 파티션에 크기 제한이 없음을 의미합니다. 추가 테스트는 그룹의 파티션이 기기의 가용한 공간을 초과하지 않도록 해야 하는 경우에 필요합니다.
remove_group group-name
- 그룹을 삭제합니다.
- 그룹에 파티션이 있는 경우 취소합니다.
remove_all_groups
- 기기 매퍼에서 모든 파티션을 매핑 해제합니다.
- 모든 파티션과 그룹을 제거합니다.
증분 OTA
증분 OTA 업데이트는 다음 논리를 사용합니다.
- 그룹 축소를 위한 공간이 충분하도록 파티션을 축소 및 삭제하고 그룹 외부로 이동합니다.
- 그룹 확장을 위한 공간이 충분하도록 그룹을 축소합니다.
- 파티션 확장/추가를 위한 공간이 충분하도록 그룹을 확장합니다.
- 파티션을 확장 및 추가하고 새 그룹으로 이동합니다.
구체적으로 update-script
는 다음 논리로 생성됩니다.
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), …)
update_dynamic_partitions
의 op_list
파일은 다음 논리로 생성됩니다.
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
전체 OTA 업데이트는 다음 논리를 사용합니다.
- 모든 기존 그룹 및 파티션 삭제
- 그룹 추가
- 파티션 추가
구체적으로 update-script
는 다음 논리로 생성됩니다.
update_dynamic_partitions(op_list) for each adding partition: block_image_update(map_partition(name), …)
update_dynamic_partitions
의 op_list
파일은 다음 논리로 생성됩니다.
remove_all_groups for each adding group: add_group for each adding partition: add for each adding partition: resize