Android 10 支持動態分區,這是一種用戶空間分區系統,可以在無線 (OTA) 更新期間創建、調整大小和銷毀分區。
本頁面介紹了 OTA 客戶端如何在更新期間為不支持動態分區的 A/B 設備調整動態分區的大小,以及 OTA 客戶端如何升級到 Android 10。
背景
在更新 A/B 設備以支持動態分區期間,設備上的 GUID 分區表 (GPT) 被保留,因此設備上沒有super
分區。元數據存儲在system_a
和system_b
,但這可以通過更改BOARD_SUPER_PARTITION_METADATA_DEVICE
來定制。
在每個塊設備中,有兩個元數據槽。每個塊設備中只使用一個元數據槽。例如, system_b
system_a
元數據 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 客戶端收到改造更新包時,它會在物理super_vendor.img
上應用super_system.img
,在物理system_b
上應用vendor_b
,在物理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
始終包含拆分super.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
並拒絕更新。