OTA cho thiết bị A/B không có phân vùng động

Android 10 hỗ trợ phân vùng động, một hệ thống phân vùng không gian người dùng có thể tạo, đổi kích thước và xoá các phân vùng trong quá trình cập nhật qua mạng (OTA).

Trang này mô tả cách các ứng dụng OTA thay đổi kích thước phân vùng động trong quá trình cập nhật cho các thiết bị A/B không hỗ trợ phân vùng động và cách các ứng dụng OTA nâng cấp lên Android 10.

Thông tin khái quát

Trong quá trình cập nhật thiết bị A/B để hỗ trợ các phân vùng động, bảng phân vùng GUID (GPT) trên thiết bị sẽ được giữ nguyên, do đó, không có phân vùng super trên thiết bị. Siêu dữ liệu được lưu trữ tại system_asystem_b, nhưng bạn có thể tuỳ chỉnh bằng cách thay đổi BOARD_SUPER_PARTITION_METADATA_DEVICE.

Trong mỗi thiết bị khối, có 2 khe siêu dữ liệu. Chỉ một khe siêu dữ liệu trong mỗi thiết bị khối được sử dụng. Ví dụ: Siêu dữ liệu 0 tại system_a và Siêu dữ liệu 1 tại system_b tương ứng với các phân vùng tại các ngăn A và B. Tại thời gian chạy, không quan trọng là khe nào đang được cập nhật.

Trong trang này, các vị trí siêu dữ liệu được gọi là Siêu dữ liệu S (nguồn) và Siêu dữ liệu T (đích). Tương tự, các phân vùng được gọi là system_s, vendor_t, v.v.

Để biết thêm thông tin về cấu hình hệ thống bản dựng, hãy xem phần Nâng cấp thiết bị.

Để biết thêm thông tin về cách các phân vùng thuộc nhóm cập nhật, hãy xem Các thay đổi về cấu hình bảng đối với thiết bị mới.

Ví dụ về siêu dữ liệu trên thiết bị:

  • Thiết bị khối thực system_a
    • Siêu dữ liệu 0
      • Nhóm foo_a
        • Phân vùng logic (động) system_a
        • Phân vùng logic (động) product_services_a
        • Các phân vùng khác do Foo cập nhật
      • Nhóm bar_a
        • Phân vùng logic (động) vendor_a
        • Phân vùng logic (động) product_a
        • Các phân vùng khác do Bar cập nhật
    • Siêu dữ liệu 1 (không được dùng)
  • Thiết bị khối thực system_b
    • Siêu dữ liệu 0 (không dùng)
    • Siêu dữ liệu 1
      • Nhóm foo_b
        • Phân vùng logic (động) system_b
        • Phân vùng logic (động) product_services_b
        • Các phân vùng khác do Foo cập nhật
      • Group bar_b
        • Phân vùng logic (động) vendor_b
        • Phân vùng logic (động) product_b
        • Các phân vùng khác do Bar cập nhật

Bạn có thể dùng công cụ lpdump trong system/extras/partition_tools để kết xuất siêu dữ liệu trên thiết bị. Ví dụ:

lpdump --slot 0 /dev/block/by-name/system_a
lpdump --slot 1 /dev/block/by-name/system_b

Điều chỉnh bản cập nhật

Trên các thiết bị chạy Android 9 trở xuống, ứng dụng OTA trên thiết bị không hỗ trợ việc ánh xạ các phân vùng động trước khi cập nhật. Một tập hợp các bản vá bổ sung được tạo để có thể áp dụng ánh xạ trực tiếp cho các phân vùng thực hiện có.

Trình tạo OTA tạo tệp super.img cuối cùng chứa nội dung của tất cả các phân vùng động, sau đó chia hình ảnh thành nhiều hình ảnh có kích thước phù hợp với kích thước của các thiết bị khối vật lý tương ứng với hệ thống, nhà cung cấp, v.v. Các hình ảnh này có tên là super_system.img, super_vendor.img, v.v. Ứng dụng OTA sẽ áp dụng những hình ảnh này cho các phân vùng thực, thay vì áp dụng hình ảnh cho các phân vùng logic (động).

Vì ứng dụng OTA không biết cách ánh xạ các phân vùng động, nên tất cả các bước sau khi cài đặt sẽ tự động bị vô hiệu hoá đối với các phân vùng này khi gói cập nhật được tạo. Hãy xem phần Định cấu hình sau khi cài đặt để biết thêm thông tin.

Quy trình cập nhật giống như trong Android 9.

Trước khi cập nhật:

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

Sau khi cập nhật:

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

Các bản cập nhật trong tương lai sau khi trang bị thêm

Sau khi cập nhật bản sửa đổi, ứng dụng OTA sẽ được cập nhật để hoạt động với các phân vùng động. Phạm vi cho các phân vùng nguồn không bao giờ trải rộng trên các phân vùng vật lý đích.

Quy trình cập nhật bằng gói cập nhật thông thường

  1. Khởi chạy siêu dữ liệu phân vùng super.
    1. Tạo siêu dữ liệu mới M từ Siêu dữ liệu S (siêu dữ liệu nguồn). Ví dụ: nếu Siêu dữ liệu S sử dụng [system_s, vendor_s, product_s] làm thiết bị chặn, thì siêu dữ liệu M mới sẽ sử dụng [system_t, vendor_t, product_t] làm thiết bị chặn. Tất cả các nhóm và phân vùng đều bị loại bỏ trong M.
    2. Thêm các nhóm và phân vùng mục tiêu theo trường dynamic_partition_metadata trong tệp kê khai bản cập nhật. Bạn có thể xem kích thước của từng phân vùng trong new_partition_info.
    3. Viết M vào Siêu dữ liệu T.
    4. Ánh xạ các phân vùng đã thêm trên trình ánh xạ thiết bị dưới dạng có thể ghi.
  2. Áp dụng bản cập nhật trên các thiết bị chặn.
    1. Nếu cần, hãy ánh xạ các phân vùng nguồn trên trình ánh xạ thiết bị ở chế độ chỉ đọc. Điều này là cần thiết cho việc tải từ nguồn bên ngoài vì các phân vùng nguồn không được liên kết trước khi cập nhật.
    2. Áp dụng bản cập nhật đầy đủ hoặc bản cập nhật gia tăng cho tất cả các thiết bị khối tại khe cắm đích.
    3. Gắn các phân vùng để chạy tập lệnh sau khi cài đặt, rồi huỷ gắn các phân vùng.
  3. Huỷ liên kết các phân vùng đích.

Quy trình cập nhật bằng cách sử dụng gói cập nhật trang bị thêm

Nếu gói cập nhật chuyển đổi được áp dụng trên một thiết bị đã bật phân vùng động, thì ứng dụng OTA sẽ áp dụng tệp super.img được phân chia trực tiếp trên các thiết bị khối. Quy trình cập nhật tương tự như quy trình cập nhật trang bị thêm. Hãy xem phần Điều chỉnh một bản cập nhật để biết thông tin chi tiết.

Ví dụ: giả sử như sau:

  • Khe A là khe đang hoạt động.
  • system_a chứa siêu dữ liệu đang hoạt động tại khe 0.
  • system_a, vendor_aproduct_a được dùng làm thiết bị chặn.

Khi nhận được một gói cập nhật trang bị thêm, ứng dụng OTA sẽ áp dụng super_system.img trên system_b thực, super_vendor.img trên vendor_b thực và super_product.img trên product_b thực. Thiết bị khối thực system_b chứa siêu dữ liệu chính xác để liên kết system_b, vendor_bproduct_b logic tại thời điểm khởi động.

Tạo gói cập nhật

OTA gia tăng

Khi tạo OTA gia tăng cho các thiết bị trang bị thêm, các bản cập nhật sẽ phụ thuộc vào việc bản dựng cơ sở có xác định PRODUCT_USE_DYNAMIC_PARTITIONSPRODUCT_RETROFIT_DYNAMIC_PARTITIONS hay không.

  • Nếu bản dựng cơ sở không xác định các biến, thì đây là bản cập nhật trang bị thêm. Gói cập nhật chứa tệp super.img phân chia và vô hiệu hoá bước sau khi cài đặt.
  • Nếu bản dựng cơ sở xác định các biến, thì điều này cũng giống như một bản cập nhật thông thường với các phân vùng động. Gói cập nhật chứa hình ảnh cho các phân vùng logic (động). Bạn có thể bật bước sau khi cài đặt.

OTA đầy đủ

Hai gói OTA đầy đủ được tạo cho các thiết bị trang bị thêm.

  • $(PRODUCT)-ota-retrofit-$(TAG).zip luôn chứa super.img chia tách và vô hiệu hoá bước sau khi cài đặt để trang bị thêm bản cập nhật.
    • Thao tác này được tạo bằng một đối số bổ sung --retrofit_dynamic_partitions cho tập lệnh ota_from_target_files.
    • Bạn có thể áp dụng cho tất cả các bản dựng.
  • $(PRODUCT)-ota-$(TAG).zip chứa hình ảnh logic cho các bản cập nhật trong tương lai.
    • Chỉ áp dụng cho các bản dựng đã bật phân vùng động. Hãy xem thông tin chi tiết bên dưới về cách thực thi quy định này.

Từ chối bản cập nhật không tương thích trên các bản dựng cũ

Chỉ áp dụng gói OTA đầy đủ thông thường cho các bản dựng đã bật phân vùng động. Nếu máy chủ OTA được định cấu hình không chính xác và đẩy các gói này đến các thiết bị chạy Android 9 trở xuống, thì các thiết bị sẽ không khởi động được. Ứng dụng OTA trên Android 9 trở xuống không thể phân biệt giữa gói OTA trang bị thêm và gói OTA đầy đủ thông thường, vì vậy ứng dụng sẽ không từ chối gói đầy đủ.

Để ngăn thiết bị chấp nhận gói OTA đầy đủ, bạn có thể yêu cầu một bước sau khi cài đặt để kiểm tra cấu hình hiện có của thiết bị. Ví dụ:

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 \

Khi gói OTA thông thường được áp dụng trên một thiết bị không bật phân vùng động, ứng dụng OTA sẽ chạy check_dynamic_partitions dưới dạng một bước sau khi cài đặt và từ chối bản cập nhật.