針對具有動態分區的 A/B 裝置進行 OTA

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

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

背景

裝置上只有一個 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 裝置上執行 OTA 更新時,您需要在更新資訊清單中新增群組和分區。以下程式碼片段顯示更新資訊清單的額外資訊,可支援動態分區。如需各個欄位的詳細說明文件,請參閱 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;
}