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
您可以使用system/extras/partition_tools
下的lpdump
工具轉儲裝置上的元資料。例如:
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
包含插槽 0 處的活動元資料。 -
system_a
、vendor_a
和product_a
用作塊設備。
當 OTA 用戶端收到改造更新套件時,它會在實體system_b
上應用super_system.img
,在實體vendor_b
上套用super_vendor.img
,在實體product_b
上應用super_product.img
。實體塊設備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
始終包含 splitsuper.img
並停用用於改造更新的安裝後步驟。- 它是透過
ota_from_target_files
腳本的附加參數--retrofit_dynamic_partitions
產生的。 - 它可以應用於所有建置。
- 它是透過
-
$(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
作為安裝後步驟並拒絕更新。