OTA cho các thiết bị không phải A/B 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, thay đổi kích thước và hủy phân vùng trong quá trình cập nhật qua mạng (OTA).

Trang này mô tả cách máy khách 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ị không phải A/B.

Đối với các thiết bị không phải A/B, bản cập nhật OTA cho phân vùng động được áp dụng bằng updater bên trong gói cập nhật.

Cập nhật thiết bị khởi chạy

Phần này áp dụng cho các thiết bị không phải A/B khởi chạy có hỗ trợ phân vùng động; các thiết bị này nâng cấp từ Android 10 lên phiên bản cao hơn.

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

Các gói cập nhật OTA được tạo bởi tập lệnh ota_from_target_files , nằm trong build/make/tools/releasetools . Theo mặc định, tập lệnh tạo một gói cập nhật các phân vùng systemvendor . Nếu có các phân vùng động bổ sung, chẳng hạn như product , product_services hoặc odm , thì các bản cập nhật của chúng phải được tạo bằng mã dành riêng cho thiết bị .

Để tạo các bản cập nhật, trong mô-đun Python mở rộng, hãy triển khai FullOTA_GetBlockDifferences()IncrementalOTA_GetBlockDifferences() . Hai hàm này trả về một danh sách các đối tượng BlockDifference , mỗi đối tượng mô tả bản vá cập nhật sẽ được áp dụng trên một phân vùng. Các phân vùng được trả về bởi hai hàm này không nên được sửa đổi thủ công hoặc xác minh ở nơi khác, chẳng hạn như trong *_InstallBegin() hoặc *_InstallEnd() .

Ví dụ về thế hệ cập nhật:

# device/yoyodyne/tardis/releasetools.py

import os
from common import BlockDifference, EmptyImage, GetUserImage

# The joined list of user image partitions of source and target builds.
# - Items should be added to the list if new dynamic partitions are added.
# - Items should not be removed from the list even if dynamic partitions are
#   deleted. When generating an incremental OTA package, this script needs to
#   know that an image is present in source build but not in target build.
USERIMAGE_PARTITIONS = [
    "product",
    "odm",
]

def GetUserImages(input_tmp, input_zip):
  return {partition: GetUserImage(partition, input_tmp, input_zip)
          for partition in USERIMAGE_PARTITIONS
          if os.path.exists(os.path.join(input_tmp,
                                         "IMAGES", partition + ".img"))}

def FullOTA_GetBlockDifferences(info):
  images = GetUserImages(info.input_tmp, info.input_zip)
  return [BlockDifference(partition, image)
          for partition, image in images.items()]

def IncrementalOTA_GetBlockDifferences(info):
  source_images = GetUserImages(info.source_tmp, info.source_zip)
  target_images = GetUserImages(info.target_tmp, info.target_zip)

  # Use EmptyImage() as a placeholder for partitions that will be deleted.
  for partition in source_images:
    target_images.setdefault(partition, EmptyImage())

  # Use source_images.get() because new partitions are not in source_images.
  return [BlockDifference(partition, target_image, source_images.get(partition))
          for partition, target_image in target_images.items()]

Luồng cập nhật

Phía sau, các chức năng sau được thêm vào tập lệnh chỉnh sửa:

  • unmap_partition(name)
    • Bỏ ánh xạ phân vùng nếu được ánh xạ, nếu không thì không làm gì cả.
    • Trả về chuỗi t nếu thành công hoặc trả về chuỗi trống nếu thất bại.
  • map_partition(name)
    • Ánh xạ phân vùng nếu chưa được ánh xạ.
    • Trả về đường dẫn tuyệt đối của thiết bị khối được ánh xạ nếu thành công hoặc một chuỗi trống nếu thất bại.
  • update_dynamic_partitions(op_list)
    • Áp dụng danh sách thao tác đã cho trên siêu dữ liệu phân vùng động, hủy ánh xạ các phân vùng nếu cần.
    • Trả về t nếu thành công hoặc trả về một chuỗi trống nếu thất bại.

Đối số op_list của update_dynamic_partitions trỏ đến một tệp trong gói cập nhật. Mỗi dòng trong tệp chỉ định một thao tác. Nếu bất kỳ thao tác nào không thành công, update_dynamic_partitions sẽ ngay lập tức trả về một chuỗi trống. Các hoạt động là:

  • resize partition-name size
    • Bỏ ánh xạ phân vùng, sau đó thay đổi kích thước của nó thành size .
  • remove partition_name
    • Bỏ ánh xạ phân vùng, sau đó xóa nó.
  • add partition-name group-name
    • Thêm một phân vùng mới vào nhóm được chỉ định.
    • Hủy bỏ nếu nhóm không tồn tại hoặc nếu phân vùng đã tồn tại.
  • move partition-name group-name
    • Di chuyển phân vùng vào nhóm được chỉ định.
    • Hủy bỏ nếu nhóm không tồn tại hoặc phân vùng không tồn tại.
  • add_group group-name maximum-size
    • Thêm một nhóm với tên đã cho và kích thước tối đa.
    • Hủy bỏ nếu nhóm đã tồn tại.
    • maximum_size bằng 0 có nghĩa là không có giới hạn kích thước cho các phân vùng trong nhóm. Cần phải kiểm tra bổ sung để đảm bảo rằng các phân vùng trong nhóm không vượt quá dung lượng trống trên thiết bị.
  • resize_group group-name maximum-size
    • Thay đổi kích thước nhóm theo kích thước tối đa nhất định.
    • Hủy bỏ nếu nhóm không tồn tại.
    • maximum_size bằng 0 có nghĩa là không có giới hạn kích thước cho các phân vùng trong nhóm. Cần phải kiểm tra bổ sung để đảm bảo rằng các phân vùng trong nhóm không vượt quá dung lượng trống trên thiết bị.
  • remove_group group-name
    • Xóa một nhóm.
    • Hủy bỏ nếu có phân vùng trong nhóm.
  • remove_all_groups
    • Hủy ánh xạ tất cả các phân vùng khỏi trình ánh xạ thiết bị.
    • Loại bỏ tất cả các phân vùng và nhóm.

OTA gia tăng

Các bản cập nhật OTA gia tăng sử dụng logic sau:

  1. Thu nhỏ phân vùng/xóa phân vùng/di chuyển phân vùng ra khỏi nhóm (để có đủ không gian để thu nhỏ nhóm)
  2. Thu gọn nhóm (để có đủ không gian phát triển nhóm)
  3. Phát triển nhóm (để chúng tôi có đủ không gian để phát triển/thêm phân vùng)
  4. Tăng phân vùng/thêm phân vùng/di chuyển phân vùng sang nhóm mới

Cụ thể, update-script được tạo bằng logic này:

for each shrinking partition:
    block_image_update(map_partition(name), …)

update_dynamic_partitions(op_list)

for each growing / adding partition:
    block_image_update(map_partition(name), …)

Tệp op_list cho update_dynamic_partitions được tạo bằng logic này:

for each deleting partition:
    remove
for each partition that changes groups:
    move to "default"
for each shrinking partition:
    resize
for each shrinking / removing group:
    resize_group / remove_group
for each growing / adding group:
    resize_group / add_group
for each adding partition:
    add
for each growing / adding partition:
    resize
for each partition that changes groups:
    move to target group

OTA đầy đủ

Các bản cập nhật OTA đầy đủ sử dụng logic sau:

  1. Xóa tất cả các nhóm và phân vùng hiện có
  2. Thêm nhóm
  3. Thêm phân vùng

Cụ thể, update-script được tạo bằng logic này:

update_dynamic_partitions(op_list)

for each adding partition:
    block_image_update(map_partition(name), …)

Tệp op_list cho update_dynamic_partitions được tạo bằng logic này:

remove_all_groups
for each adding group:
    add_group
for each adding partition:
    add
for each adding partition:
    resize