Android 10 支援動態分割區,這是一種使用者空間分割系統,可在無線 (OTA) 更新期間建立、調整大小及毀損分割區。
本頁說明 OTA 用戶端如何在更新期間調整 A/B 裝置的動態分割區大小 (這類裝置推出時不支援動態分割區),以及 OTA 用戶端如何升級至 Android 10。
背景
更新 A/B 裝置以支援動態分割區時,裝置上的 GUID 分割區表 (GPT) 會保留,因此裝置上不會有 super
分割區。中繼資料會儲存在 system_a
和 system_b
,但您可以變更 BOARD_SUPER_PARTITION_METADATA_DEVICE
來進行自訂。
每個區塊裝置都有兩個中繼資料位置。每個區塊裝置只會使用一個中繼資料位置。舉例來說,位於 system_a
的中繼資料 0 和位於 system_b
的中繼資料 1 分別對應 A 和 B 插槽中的分割區。在執行階段,更新哪個時段並不重要。
在這個頁面中,中繼資料插槽稱為「中繼資料 S」(來源) 和「中繼資料 T」(目標)。同樣地,分割區稱為 system_s
、vendor_t
等。
如要進一步瞭解建構系統設定,請參閱「升級裝置」。
如要進一步瞭解分割區如何屬於更新群組,請參閱新裝置的主機板設定變更。
裝置上的中繼資料範例如下:
- 實體區塊裝置
system_a
- 中繼資料 0
- 群組
foo_a
- 邏輯 (動態) 分區
system_a
- 邏輯 (動態) 分區
product_services_a
- Foo 更新的其他分割區
- 邏輯 (動態) 分區
- 群組
bar_a
- 邏輯 (動態) 分區
vendor_a
- 邏輯 (動態) 分區
product_a
- Bar 更新的其他分區
- 邏輯 (動態) 分區
- 群組
- 中繼資料 1 (未使用)
- 中繼資料 0
- 實體區塊裝置
system_b
- 中繼資料 0 (未使用)
- 中繼資料 1
- 群組 foo_b
- 邏輯 (動態) 分區
system_b
- 邏輯 (動態) 分區
product_services_b
- Foo 更新的其他分割區
- 邏輯 (動態) 分區
- 群組 bar_b
- 邏輯 (動態) 分區
vendor_b
- 邏輯 (動態) 分區
product_b
- Bar 更新的其他分區
- 邏輯 (動態) 分區
- 群組 foo_b
您可以使用 lpdump
工具 (位於 system/extras/partition_tools
下方),傾印裝置上的中繼資料。例如:
lpdump --slot 0 /dev/block/by-name/system_a
lpdump --slot 1 /dev/block/by-name/system_b
改造更新
在搭載 Android 9 以下版本的裝置上,裝置的 OTA 用戶端不支援在更新前對應動態分割區。系統會建立額外的一組修補程式,以便將對應直接套用至現有的實體分割區。
OTA 產生器會建構最終的 super.img
檔案,其中包含所有動態分割區的內容,然後將映像檔分割成多個映像檔,大小與系統、供應商等對應的實體區塊裝置相符。這些圖片的名稱為 super_system.img
、super_vendor.img
等。OTA 用戶端會將這些映像檔套用至實體分區,而非套用至邏輯 (動態) 分區。
由於 OTA 用戶端不知道如何對應動態分割區,因此在產生更新套件時,系統會自動停用這些分割區的所有安裝後步驟。詳情請參閱「設定安裝後作業」。
更新流程與 Android 9 相同。
更新前:
ro.boot.dynamic_partitions= ro.boot.dynamic_partitions_retrofit=
更新後:
ro.boot.dynamic_partitions=true ro.boot.dynamic_partitions_retrofit=true
加裝後續更新
完成更新後,OTA 用戶端會更新為可搭配動態分割區運作。來源分區的範圍絕不會跨越目標實體分區。
使用一般更新套件的更新流程
- 初始化
super
分區中繼資料。-
從中繼資料 S (來源中繼資料) 建構新的中繼資料 M。
舉例來說,如果中繼資料 S 使用 [
system_s
、vendor_s
、product_s
] 做為封鎖裝置,則新的中繼資料 M 會使用 [system_t
、vendor_t
、product_t
] 做為封鎖裝置。M 中會捨棄所有群組和分割區。 -
根據更新資訊清單中的
dynamic_partition_metadata
欄位,新增目標群組和分割區。您可以在new_partition_info
中查看每個分區的大小。 - 將 M 寫入中繼資料 T。
- 將裝置對應程式中新增的分割區對應為可寫入。
-
從中繼資料 S (來源中繼資料) 建構新的中繼資料 M。
舉例來說,如果中繼資料 S 使用 [
- 在封鎖的裝置上套用更新。
- 如有需要,請在裝置對應程式上將來源分割區對應為唯讀。更新前,來源磁碟分割區不會對應,因此側載時必須執行這項操作。
- 將完整或差異更新套用至目標插槽中的所有區塊裝置。
- 掛接分割區以執行安裝後指令碼,然後卸載分割區。
- 取消對應目標分割區。
使用後續更新套件的更新流程
如果裝置已啟用動態分割區,並套用改裝更新套件,OTA 用戶端會直接在區塊裝置上套用 super.img
分割檔案。更新流程與後續更新類似。詳情請參閱「更新後續安裝」。
舉例來說,假設:
- 插槽 A 是有效插槽。
-
system_a
包含 slot 0 的有效中繼資料。 -
「
system_a
」、「vendor_a
」和「product_a
」會做為區塊裝置使用。
當 OTA 用戶端收到改裝更新套件時,會套用
實體 super_system.img
system_b
、
實體 super_vendor.img
vendor_b
和
實體 super_product.img
product_b
。
實體區塊裝置 system_b
包含正確的中繼資料,可在啟動時對應邏輯 system_b
、vendor_b
和 product_b
。
產生更新套件
增量 OTA
為改裝裝置產生增量 OTA 時,更新取決於基本建構版本是否定義 PRODUCT_USE_DYNAMIC_PARTITIONS
和 PRODUCT_RETROFIT_DYNAMIC_PARTITIONS
。
-
如果基本建構未定義變數,這就是回溯更新。更新套件包含分割
super.img
檔案,並停用安裝後步驟。 - 如果基礎建構有定義變數,這與使用動態分割區的典型更新相同。更新套件包含邏輯 (動態) 分區的圖片。可以啟用安裝後步驟。
完整 OTA
系統會為改裝裝置產生兩個完整的 OTA 檔案包。
-
$(PRODUCT)-ota-retrofit-$(TAG).zip
一律包含 分割super.img
,並停用回溯更新的安裝後步驟。-
這是使用額外引數
--retrofit_dynamic_partitions
生成的ota_from_target_files
指令碼。 - 這項功能可套用至所有版本。
-
這是使用額外引數
-
$(PRODUCT)-ota-$(TAG).zip
包含日後更新的邏輯圖片。- 請只對已啟用動態分區的建構版本套用這項設定。詳情請參閱下文。
拒絕舊版建構作業的非回溯更新
只有在啟用動態分割區的建構版本中,才能套用一般完整 OTA 套件。如果 OTA 伺服器設定有誤,並將這些套件推送至搭載 Android 9 以下版本的裝置,裝置就會無法啟動。Android 9 以下版本的 OTA 用戶端無法分辨改裝 OTA 套件和一般完整 OTA 套件,因此不會拒絕完整套件。
如要防止裝置接受完整的 OTA 套件,可以要求在安裝後檢查現有的裝置設定。例如:
device/device_name/dynamic_partitions/check_dynamic_partitions
#!/system/bin/sh DP_PROPERTY_NAME="ro.boot.dynamic_partitions" DP_RETROFIT_PROPERTY_NAME="ro.boot.dynamic_partitions_retrofit" DP_PROPERTY=$(getprop ${DP_PROPERTY_NAME}) DP_RETROFIT_PROPERTY=$(getprop ${DP_RETROFIT_PROPERTY_NAME}) if [ "${DP_PROPERTY}" != "true" ] || [ "${DP_RETROFIT_PROPERTY}" != "true" ] ; then echo "Error: applied non-retrofit update on build without dynamic" \ "partitions." echo "${DP_PROPERTY_NAME}=${DP_PROPERTY}" echo "${DP_RETROFIT_PROPERTY_NAME}=${DP_RETROFIT_PROPERTY}" exit 1 fi
device/device_name/dynamic_partitions/Android.mk
LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE:= check_dynamic_partitions LOCAL_MODULE_TAGS := optional LOCAL_MODULE_CLASS := EXECUTABLES LOCAL_SRC_FILES := check_dynamic_partitions LOCAL_PRODUCT_MODULE := true include $(BUILD_PREBUILT)
device/device_name/device.mk
PRODUCT_PACKAGES += check_dynamic_partitions # OPTIONAL=false so that the error in check_dynamic_partitions will be # propagated to OTA client. AB_OTA_POSTINSTALL_CONFIG += \ RUN_POSTINSTALL_product=true \ POSTINSTALL_PATH_product=bin/check_dynamic_partitions \ FILESYSTEM_TYPE_product=ext4 \ POSTINSTALL_OPTIONAL_product=false \
如果裝置未啟用動態分割區,當套用一般 OTA 套件時,OTA 用戶端會以安裝後步驟的形式執行 check_dynamic_partitions
,並拒絕更新。