Android 10 支援動態分割區,這是一種使用者空間分割系統,可在無線 (OTA) 更新期間建立、調整大小及毀損分割區。
本頁說明 OTA 用戶端如何在非 A/B 裝置更新期間調整動態分割區大小。
對於非 A/B 裝置,動態分割區的 OTA 更新會使用更新套件中的 updater 進行。
更新啟動裝置
本節適用於推出時支援動態分割區的非 A/B 裝置,這些裝置會從 Android 10 升級至較新版本。
產生更新套件
OTA 更新套件是由 ota_from_target_files 指令碼產生,該指令碼位於 build/make/tools/releasetools 下方。根據預設,指令碼會產生更新 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_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