Android 10 支援動態分區,這是一種使用者空間分區系統,可在無線 (OTA) 更新期間建立、調整大小及刪除分區。
本頁說明 OTA 用戶端如何在非 A/B 裝置更新期間調整動態分區大小。
如果不是 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
,失敗時傳回空白字串。
要接收的 op_list
引數,
update_dynamic_partitions
指向
update 套件。檔案中的每一行都代表一項作業。如果有任何
作業失敗,立即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), …)
以下項目的 op_list
檔案:
這個程式碼已用於產生 update_dynamic_partitions
邏輯:
remove_all_groups for each adding group: add_group for each adding partition: add for each adding partition: resize