針對具有動態分區的 A/B 裝置適用的 OTA

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

本頁面說明如何在更新期間為支援動態分割區的 A/B 裝置調整動態分割區大小,適用於搭載 Android 9 以下版本的裝置。

背景

裝置上有一個 super 分區。這個分割區沒有插槽後置字串。區塊裝置必須與 fstab/miscblk_device 項目一起存在。舉例來說,如果 fstab 檔案列出以下項目:

/dev/block/bootdevice/by-name/misc    /misc    # Other fields

接著,super 的區塊裝置必須位於 /dev/block/bootdevice/by-name/super 中,但 super 分割區不需要列在 fstab 檔案中。

super 分區中,有兩個中繼資料插槽,編號分別為 0 和 1,對應分區的 A/B 插槽。在這個頁面中,中繼資料版位稱為「中繼資料 S」(來源) 和「中繼資料 T」(目標)。同樣地,分區會稱為 system_svendor_t 等。

升級之前,中繼資料 S 包含正在使用的動態分區相關資訊 (通常為 system_svendor_sproduct_s 等)。系統會在更新期間讀取這些分區的範圍,因此無法刪除。

分割區屬於更新群組。詳情請參閱「實作動態分區」。

裝置上的中繼資料範例如下。

  • 中繼資料 0
    • 群組 foo_a
      • 分割區 system_a
      • 分割區 product_services_a
      • 由 Foo 更新的其他分區
    • 群組 bar_a
      • 分割區 vendor_a
      • 分割區 product_a
      • 由 Bar 更新的其他分區
    • 群組 foo_b (上次升級時遺留)
    • 群組 bar_b (上次升級時遺留)
  • 中繼資料 1
    • 群組 foo_a (上次升級時遺留)
    • 群組 bar_a (上次升級時遺留)
    • 群組 foo_b
      • 分割區 system_b
      • 分割區 product_services_b
      • Foo 更新其他分區
    • 群組 bar_b
      • 分割區 vendor_b
      • 分割區 product_b
      • 由 Bar 更新的其他分區

您可以使用 lpdump 工具 (system/extras/partition_tools 底下的原始碼) 轉儲裝置上的中繼資料。例如:

lpdump --slot 0 /dev/block/bootdevice/by-name/super
lpdump --slot 1 /dev/block/bootdevice/by-name/super

更新流程

  1. 初始化 super 分區中繼資料。
    1. 從中繼資料 S 載入來源動態分區的範圍。接著 M 做為載入的中繼資料。
    2. 從 M 中移除目標群組和分區 (例如 foo_tbar_t),讓 M 只包含帶有 _s 後置詞的分區和群組。
    3. 根據更新資訊清單中的 dynamic_partition_metadata 欄位新增目標群組和分區。
      您可以在 new_partition_info 中找到每個分區的大小。
    4. 將 M 寫入中繼資料 T。
    5. 將裝置對應器中新增的分區對應為可寫入。
  2. 在區塊裝置上套用更新。
    1. 視需要將裝置對應器上的來源分區設為唯讀。這是側載作業的必要步驟,因為更新前並未對來源分區進行對應。
    2. 對目標版位的所有區塊裝置套用完整或差異更新。
    3. 接著掛接分區以執行安裝後指令碼,然後卸載分區。
  3. 取消對目標區隔的對應

更新前後,下列系統屬性應具有各自的值:

ro.boot.dynamic_partitions=true
ro.boot.dynamic_partitions_retrofit=true

將群組和分割區新增至更新資訊清單

在具有動態分區的 A/B 裝置上執行 OTA 更新,或是在 A/B 裝置上新增動態分區支援功能時,您需要在更新資訊清單中新增群組和分區。以下程式碼片段顯示更新資訊清單的其他資訊,以支援動態分區。如需各欄位的詳細說明文件,請參閱 update_metadata.proto

message DeltaArchiveManifest {
    optional DynamicPartitionMetadata dynamic_partition_metadata;
}

message DynamicPartitionMetadata {
    repeated DynamicPartitionGroup groups;
}

message DynamicPartitionGroup {
    required string name;
    optional uint64 size; // maximum size of group
    repeated string partition_names;
}