OTA برای دستگاه های غیر A/B با پارتیشن های پویا

اندروید ۱۰ از پارتیشن‌های پویا پشتیبانی می‌کند، یک سیستم پارتیشن‌بندی فضای کاربری که می‌تواند در طول به‌روزرسانی‌های OTA پارتیشن‌ها را ایجاد، تغییر اندازه و از بین ببرد.

این صفحه نحوه تغییر اندازه پارتیشن‌های پویا توسط کلاینت‌های OTA را در طول به‌روزرسانی برای دستگاه‌های غیر A/B شرح می‌دهد.

برای دستگاه‌های غیر A/B، به‌روزرسانی OTA برای پارتیشن‌های پویا با استفاده از updater درون بسته‌ی به‌روزرسانی اعمال می‌شود.

دستگاه‌های پرتاب را به‌روزرسانی کنید

این بخش مربوط به دستگاه‌های غیر A/B است که با پشتیبانی از پارتیشن‌های پویا راه‌اندازی می‌شوند؛ این دستگاه‌ها از اندروید ۱۰ به نسخه‌های بالاتر ارتقا می‌یابند.

تولید بسته‌های به‌روزرسانی

بسته‌های به‌روزرسانی OTA توسط اسکریپت ota_from_target_files که در مسیر build/make/tools/releasetools قرار دارد، تولید می‌شوند. به طور پیش‌فرض، این اسکریپت بسته‌ای تولید می‌کند که پارتیشن‌های system و vendor را به‌روزرسانی می‌کند. اگر پارتیشن‌های پویای دیگری مانند product ، product_services یا odm وجود داشته باشد، به‌روزرسانی‌های آنها باید در کد مخصوص دستگاه تولید شود.

برای تولید به‌روزرسانی‌ها، در ماژول توسعه‌یافته پایتون، FullOTA_GetBlockDifferences() و IncrementalOTA_GetBlockDifferences() را پیاده‌سازی کنید. این دو تابع لیستی از اشیاء BlockDifference را برمی‌گردانند که هر کدام پچ به‌روزرسانی اعمال‌شده روی یک پارتیشن را توصیف می‌کنند. پارتیشن‌های برگردانده‌شده توسط این دو تابع نباید به‌صورت دستی تغییر داده شوند یا در جای دیگری، مثلاً در *_InstallBegin() یا *_InstallEnd() تأیید شوند.

مثالی از تولید به‌روزرسانی:

# 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()]

جریان به‌روزرسانی

در پشت صحنه، توابع زیر به اسکریپت edify اضافه می‌شوند:

  • unmap_partition(name)
    • اگر پارتیشن نگاشت شده است، آن را از نگاشت خارج کن، در غیر این صورت هیچ کاری انجام نده.
    • در صورت موفقیت، رشته t و در صورت شکست، یک رشته خالی را برمی‌گرداند.
  • map_partition(name)
    • اگر پارتیشن از قبل نگاشت نشده است، آن را نگاشت کنید.
    • در صورت موفقیت، مسیر مطلق دستگاه بلوک نگاشت‌شده را برمی‌گرداند، یا در صورت شکست، یک رشته خالی برمی‌گرداند.
  • update_dynamic_partitions(op_list)
    • لیست عملیات داده شده را روی فراداده‌های پارتیشن پویا اعمال کنید و در صورت لزوم، پارتیشن‌ها را از نگاشت خارج کنید.
    • در صورت موفقیت t و در صورت شکست یک رشته خالی برمی‌گرداند.

آرگومان op_list برای update_dynamic_partitions به یک فایل در بسته‌ی به‌روزرسانی اشاره می‌کند. هر خط در این فایل یک عملیات را مشخص می‌کند. اگر هر عملیاتی با شکست مواجه شود، update_dynamic_partitions بلافاصله یک رشته‌ی خالی برمی‌گرداند. عملیات‌ها عبارتند از:

  • resize partition-name size
    • پارتیشن را از حالت نگاشت خارج کنید، سپس اندازه آن را به size تغییر دهید.
  • remove partition_name
    • پارتیشن را از حالت فشرده خارج کنید، سپس آن را حذف کنید.
  • add partition-name group-name
    • یک پارتیشن جدید به گروه مشخص شده اضافه کنید.
    • اگر گروه وجود نداشته باشد یا پارتیشن از قبل وجود داشته باشد، لغو شود.
  • move partition-name group-name
    • پارتیشن را به گروه مشخص شده منتقل کنید.
    • اگر گروه یا پارتیشن وجود نداشته باشد، عملیات لغو می‌شود.
  • add_group group-name maximum-size
    • یک گروه با نام و حداکثر اندازه داده شده اضافه کنید.
    • اگر گروه از قبل وجود داشته باشد، لغو می‌شود.
    • مقدار maximum_size برابر با ۰ به این معنی است که هیچ محدودیتی برای اندازه پارتیشن‌های موجود در گروه وجود ندارد. برای اطمینان از اینکه پارتیشن‌های موجود در گروه از فضای موجود در دستگاه تجاوز نمی‌کنند، آزمایش‌های بیشتری لازم است.
  • resize_group group-name maximum-size
    • اندازه گروه را به حداکثر اندازه داده شده تغییر دهید.
    • اگر گروه وجود ندارد، لغو شود.
    • مقدار maximum_size برابر با ۰ به این معنی است که هیچ محدودیتی برای اندازه پارتیشن‌های موجود در گروه وجود ندارد. برای اطمینان از اینکه پارتیشن‌های موجود در گروه از فضای موجود در دستگاه تجاوز نمی‌کنند، آزمایش‌های بیشتری لازم است.
  • remove_group group-name
    • حذف یک گروه.
    • اگر پارتیشن‌هایی در گروه وجود داشته باشد، لغو می‌شود.
  • remove_all_groups
    • تمام پارتیشن‌ها را از device mapper از حالت نگاشت خارج کنید.
    • تمام پارتیشن‌ها و گروه‌ها را حذف کنید.

OTA افزایشی

به‌روزرسانی‌های OTA تدریجی از منطق زیر استفاده می‌کنند:

  1. پارتیشن‌ها را کوچک کنید/حذف کنید/پارتیشن‌ها را از گروه خارج کنید (به طوری که فضای کافی برای کوچک کردن گروه‌ها وجود داشته باشد)
  2. گروه‌ها را کوچک کنید (به طوری که فضای کافی برای رشد گروه‌ها وجود داشته باشد)
  3. گروه‌ها را افزایش دهید (به طوری که فضای کافی برای افزایش/اضافه کردن پارتیشن‌ها داشته باشیم)
  4. افزایش تعداد پارتیشن‌ها/اضافه کردن پارتیشن‌ها/انتقال پارتیشن‌ها به گروه جدید

به طور دقیق، update-script با این منطق تولید می‌شود:

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), …)

فایل op_list برای update_dynamic_partitions با این منطق تولید می‌شود:

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

به‌روزرسانی‌های کامل OTA از منطق زیر استفاده می‌کنند:

  1. حذف تمام گروه‌ها و پارتیشن‌های موجود
  2. اضافه کردن گروه‌ها
  3. اضافه کردن پارتیشن‌ها

به طور دقیق، update-script با این منطق تولید می‌شود:

update_dynamic_partitions(op_list)

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

فایل op_list برای update_dynamic_partitions با این منطق تولید می‌شود:

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