適用於沒有動態分區的 A/B 裝置 OTA

Android 10 支援 動態分區,也就是使用者空間分區 這個系統可以在無線更新 (OTA) 期間建立、調整及刪除分區。

本頁說明 OTA 用戶端如何在 A/B 裝置更新期間調整動態分區大小 ,以及 OTA 用戶端如何升級至 Android 10。

背景

在更新 A/B 裝置以支援動態分區時, 系統會保留裝置上的 GUID 分區表 (GPT),因此 裝置上有 super 個分區。中繼資料儲存位置 system_asystem_b,但這可以是 自訂 BOARD_SUPER_PARTITION_METADATA_DEVICE

每部區塊裝置中有兩個中繼資料版位。僅限 1 個 系統會使用每個區塊裝置的中繼資料版位舉例來說, 「system_a」與「system_b」的中繼資料 1 分別對應 A 和 B 運算單元的分區。在 也可以更新哪個版位

在此頁面中,中繼資料運算單元稱為「中繼資料 S」。 (來源) 和中繼資料 T (目標)。同樣地,分區 變更為 system_svendor_t 等。

如要進一步瞭解建構系統設定,請參閱: 升級裝置

詳情請參閱分區如何更新 群組,請參閱 桌遊 變更新裝置的設定。

以下舉例說明裝置上的中繼資料:

  • 實體區塊裝置 system_a
    • 中繼資料 0
      • 群組 foo_a
        • 邏輯 (動態) 分區 system_a
        • 邏輯 (動態) 分區 product_services_a
        • Foo 更新其他分區
      • 群組 bar_a
        • 邏輯 (動態) 分區 vendor_a
        • 邏輯 (動態) 分區 product_a
        • 已透過長條更新其他分區
    • 中繼資料 1 (未使用)
  • 實體區塊裝置 system_b
    • 中繼資料 0 (未使用)
    • 中繼資料 1
      • foo_b 群組
        • 邏輯 (動態) 分區 system_b
        • 邏輯 (動態) 分區 product_services_b
        • Foo 更新其他分區
      • 群組列_b
        • 邏輯 (動態) 分區 vendor_b
        • 邏輯 (動態) 分區 product_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.imgsuper_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

在 Retrofit 之後更新

更新 Retrofit 後,OTA 用戶端會更新為與 動態分區來源分區的範圍永不橫跨 跨目標實體分區

使用一般更新套件更新流程

  1. 初始化 super 分區中繼資料。
    1. 使用中繼資料 S 建構新的中繼資料 M (來源中繼資料)。 舉例來說,如果中繼資料 S 使用 [system_s、 以vendor_s的形式顯示product_s 裝置,新的中繼資料 M 會使用 [system_tvendor_t (product_t) 為區塊 裝置。M 中的所有群組和分區都會遭到捨棄。
    2. 根據以下資源新增目標群組和分區: 更新項目中的 dynamic_partition_metadata 欄位 資訊清單。您可以在 new_partition_info
    3. 將 M 寫入中繼資料 T。
    4. 將裝置對應工具上新增的分區對應到可寫入的分區。
  2. 在封鎖的裝置上套用更新。
    1. 如有需要,請在裝置對應工具上對應來源分區 並設為唯讀您必須進行側載,因為 系統不會在更新前對應來源分區。
    2. 對位於以下區域的所有封鎖裝置套用完整或差異更新 目標版位。
    3. 掛接分區以執行安裝後指令碼,然後 卸載分區。
  3. 取消對應目標分區。

使用 retrofit 更新套件更新流程

如果 Retrofit 更新套件套用至已安裝的裝置 即可啟用動態分區,OTA 用戶端會套用 super.img 檔案。更新內容 流程類似於 Retrofit 更新。詳情請見 翻新更新

舉例來說,假設:

  • 插槽 A 是有效運算單元。
  • system_a 包含版位 0 的有效中繼資料。
  • system_avendor_aproduct_a 會做為區塊裝置使用。

OTA 用戶端收到 Retrofit 更新套件時, 實體 system_b super_system.img, 實體 vendor_b 上的 super_vendor.img,和 super_product.img,位於實體 product_b。 實體區塊裝置「system_b」包含正確的 對應邏輯 system_bvendor_bproduct_b

產生更新套件

漸進式 OTA

為 Retrofit 裝置產生漸進式 OTA 時, 取決於基礎版本是否定義 「PRODUCT_USE_DYNAMIC_PARTITIONS」和 PRODUCT_RETROFIT_DYNAMIC_PARTITIONS

  • 如果基礎版本「並未」定義變數,則這是 重新校正更新。update 套件含有分割 super.img 檔案並停用安裝後步驟。
  • 如果基礎版本「確實」定義變數,這等同於 進行常見的更新作業更新套件 包含邏輯 (動態) 分區的圖片。 您可以啟用安裝後步驟

完整 OTA

系統會為 Retrofit 裝置產生兩個完整的 OTA 套件。

  • $(PRODUCT)-ota-retrofit-$(TAG).zip 一律包含 分割 super.img 並停用安裝後步驟 以進行整修更新
    • 此結構由額外引數產生 --retrofit_dynamic_partitions 設為 ota_from_target_files 指令碼。
    • 此設定可套用至所有版本。
  • $(PRODUCT)-ota-$(TAG).zip 包含以下項目的邏輯圖片: (日後更新)。
    • 僅將這項設定套用至含有動態分區的建構作業 請參閱下方說明,進一步瞭解如何執行這項作業。

拒絕舊版本的非 Retrofit 更新

僅將一般 OTA 套件套用至採用 是否已啟用動態分區如果 OTA 伺服器已設定完成 並正確將這些套件推送至搭載 Android 9 以上版本的裝置 且裝置無法啟動Android 9 和 Android 裝置的 OTA 用戶端 表示版本 OTA 套件與 一般完整 OTA 套件,這樣用戶端不會拒絕整個套件。

如要禁止裝置接受完整 OTA 套件,您可以 需要進行安裝後步驟,才能檢查現有裝置 此外還會從 0 自動調整資源配置 您完全不必調整資源調度設定例如:

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 做為安裝後步驟, 拒絕更新。