پیاده‌سازی بخش‌های پویا

پارتیشن‌بندی پویا بااستفاده از واحد dm-linear device-mapper در هسته Linux پیاده‌سازی می‌شود. بخش super حاوی فراداده‌ای است که نام‌ها و محدوده‌های بلوک هر بخش پویا را در super فهرست می‌کند. در مرحله اول init، این فراداده تجزیه و اعتبارسنجی می‌شود و دستگاه‌های بلوک مجازی برای نشان دادن هر پارتیشن پویا ایجاد می‌شوند.

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

ازآنجایی‌که پارتیشن‌های پویا در فضای کاربر پیاده‌سازی می‌شوند، پارتیشن‌های موردنیاز توسط بارکننده نمی‌توانند پویا شوند. برای مثال، boot، dtbo، و vbmeta توسط راه‌انداز سیستم خوانده می‌شوند، و بنابراین باید به‌عنوان پارتیشن‌های فیزیکی باقی بمانند.

هر بخش پویا می‌تواند به یک گروه به‌روزرسانی تعلق داشته باشد. این گروه‌ها حداکثر فضایی را که پارتیشن‌های آن گروه می‌توانند مصرف کنند محدود می‌کنند. برای مثال، system و vendor می‌توانند به گروهی تعلق داشته باشند که اندازه کل system و vendor را محدود می‌کند.

پیاده‌سازی پارتیشن‌های پویا در دستگاه‌های جدید

این بخش جزئیات نحوه پیاده‌سازی پارتیشن‌های پویا در دستگاه‌های جدید راه‌اندازی‌شده با Android 10 و بالاتر را شرح می‌دهد. برای به‌روزرسانی دستگاه‌های موجود، به ارتقا دادن دستگاه‌های Android مراجعه کنید.

تغییرات پارتیشن

برای دستگاه‌هایی که با Android 10 عرضه می‌شوند، بخشی به‌نام super ایجاد کنید. بخش super جایگاه‌های A/B را به‌صورت داخلی مدیریت می‌کند، بنابراین دستگاه‌های A/B به بخش‌های جداگانه super_a و super_b نیاز ندارند. همه پارتیشن‌های فقط‌خواندنی AOSP که توسط بارکننده استفاده نمی‌شوند باید پویا باشند و باید از «جدول پارتیشن GUID» (GPT) برداشته شوند. بخش‌های مختص فروشنده لازم نیست پویا باشند و ممکن است در «جدول پارامترهای عمومی» قرار بگیرند.

برای تخمین اندازه super، اندازه‌های بخش‌هایی را که از GPT حذف می‌شوند اضافه کنید. برای دستگاه‌های A/B، این باید شامل اندازه هر دو جایگاه باشد. شکل ۱ نمونه‌ای از جدول پارتیشن را قبل و بعداز تبدیل به پارتیشن‌های پویا نشان می‌دهد.

چیدمان جدول پارتیشن
شکل ۱. چیدمان جدید جدول پارتیشن فیزیکی هنگام تبدیل به پارتیشن‌های پویا

پارتیشن‌های پویای پشتیبانی‌شده عبارت‌اند از:

  • سیستم
  • فروشنده
  • محصول
  • System Ext
  • سنجش درون‌دستگاهی

برای دستگاه‌هایی که با Android 10 عرضه می‌شوند، گزینه خط فرمان هسته androidboot.super_partition باید خالی باشد تا فرمان sysprop ro.boot.super_partition خالی باشد.

تراز پارتیشن

اگر بخش super به‌درستی تراز نشده باشد، ممکن است پودمان نگاشت دستگاه کارایی کمتری داشته باشد. بخش super باید با حداقل اندازه درخواست ورودی/خروجی که توسط لایه بلوک تعیین می‌شود، هم‌تراز باشد. به‌طور پیش‌فرض، سیستم ساخت (ازطریق lpmake، که تصویر پارتیشن super را تولید می‌کند) فرض می‌کند که تراز ۱ مگابایتی برای هر پارتیشن پویا کافی است. بااین‌حال، فروشندگان باید مطمئن شوند که پارتیشن super به‌درستی تراز شده است.

می‌توانید حداقل اندازه درخواست دستگاه بلوک را با بررسی sysfs تعیین کنید. برای مثال:

# ls -l /dev/block/by-name/super
lrwxrwxrwx 1 root root 16 1970-04-05 01:41 /dev/block/by-name/super -> /dev/block/sda17
# cat /sys/block/sda/queue/minimum_io_size
786432

می‌توانید تراز بخش super را به روش مشابهی درستی‌سنجی کنید:

# cat /sys/block/sda/sda17/alignment_offset

آفست تراز باید ۰ باشد.

تغییرات پیکربندی دستگاه

برای فعال کردن تقسیم‌بندی پویا، پرچم زیر را در device.mk اضافه کنید:

PRODUCT_USE_DYNAMIC_PARTITIONS := true

تغییرات پیکربندی برد

ملزم هستید اندازه پارتیشن super را تنظیم کنید:

BOARD_SUPER_PARTITION_SIZE := <size-in-bytes>

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

می‌توانید فهرست بخش‌های پویا را به‌صورت زیر پیکربندی کنید. برای دستگاه‌هایی که از گروه‌های به‌روزرسانی استفاده می‌کنند، گروه‌ها را در متغیر BOARD_SUPER_PARTITION_GROUPS فهرست کنید. هر نام گروه سپس دارای متغیر BOARD_group_SIZE و BOARD_group_PARTITION_LIST است. برای دستگاه‌های A/B، حداکثر اندازه گروه باید فقط یک جایگاه را پوشش دهد، زیرا نام‌های گروه به‌صورت داخلی با جایگاه پسوندگذاری می‌شوند.

در اینجا نمونه دستگاهی آورده شده است که همه پارتیشن‌ها را در گروهی به‌نام example_dynamic_partitions قرار می‌دهد:

BOARD_SUPER_PARTITION_GROUPS := example_dynamic_partitions
BOARD_EXAMPLE_DYNAMIC_PARTITIONS_SIZE := 6442450944
BOARD_EXAMPLE_DYNAMIC_PARTITIONS_PARTITION_LIST := system vendor product

در اینجا نمونه‌ای از دستگاهی ارائه شده است که خدمات سیستم و محصول را در group_foo، و vendor، product، و odm را در group_bar قرار می‌دهد:

BOARD_SUPER_PARTITION_GROUPS := group_foo group_bar
BOARD_GROUP_FOO_SIZE := 4831838208
BOARD_GROUP_FOO_PARTITION_LIST := system product_services
BOARD_GROUP_BAR_SIZE := 1610612736
BOARD_GROUP_BAR_PARTITION_LIST := vendor product odm
  • برای دستگاه‌های راه‌اندازی Virtual A/B، مجموع حداکثر اندازه همه گروه‌ها باید حداکثر:
    BOARD_SUPER_PARTITION_SIZE - سربار
    پیاده‌سازی Virtual A/B را ببینید.
  • برای دستگاه‌های راه‌اندازی A/B، مجموع حداکثر اندازه‌های همه گروه‌ها باید این باشد:
    BOARD_SUPER_PARTITION_SIZE / 2 - سربار
  • برای دستگاه‌های غیر A/B و دستگاه‌های A/B با نصب مجدد، مجموع حداکثر اندازه‌های همه گروه‌ها باید:
    BOARD_SUPER_PARTITION_SIZE - سربار باشد
  • در زمان ساخت، مجموع اندازه تصاویر هر بخش در یک گروه به‌روزرسانی نباید از حداکثر اندازه گروه بیشتر باشد.
  • سربار در محاسبه برای حساب فراداده، ترازها، و غیره لازم است. سربار معقول ۴ مبی‌بایت است، اما می‌توانید سربار بزرگ‌تری را براساس نیاز دستگاه انتخاب کنید.

اندازه پارتیشن‌های پویا

پیش‌از پارتیشن‌های پویا، اندازه‌های پارتیشن بیش‌از حد اختصاص داده می‌شد تا مطمئن شوند فضای کافی برای به‌روزرسانی‌های آینده دارند. اندازه واقعی همان‌طور که بود درنظر گرفته شد و اکثر پارتیشن‌های فقط خواندنی مقداری فضای خالی در سیستم فایل خود داشتند. در پارتیشن‌های پویا، آن فضای خالی غیرقابل‌استفاده است و می‌تواند برای بزرگ کردن پارتیشن‌ها درطول «به‌روزرسانی ازطریق شبکه» استفاده شود. بسیار مهم است که مطمئن شوید پارتیشن‌ها فضا را هدر نمی‌دهند و به حداقل اندازه ممکن اختصاص داده می‌شوند.

برای تصاویر ext4 فقط‌خواندنی، اگر اندازه پارتیشن کدبندی‌شده‌ای مشخص نشده باشد، سیستم ساخت به‌طور خودکار حداقل اندازه را تخصیص می‌دهد. سیستم ساخت تصویر را به‌گونه‌ای تنظیم می‌کند که سیستم فایل کمترین فضای استفاده‌نشده ممکن را داشته باشد. این کار تضمین می‌کند که دستگاه فضایی را که می‌تواند برای به‌روزرسانی‌های OTA استفاده شود هدر ندهد.

علاوه‌براین، با فعال کردن حذف تکراری در سطح بلوک، می‌توان تصاویر ext4 را بیشتر فشرده کرد. برای فعال کردن این ویژگی، از پیکربندی زیر استفاده کنید:

BOARD_EXT4_SHARE_DUP_BLOCKS := true

اگر تخصیص خودکار حداقل اندازه پارتیشن مطلوب نیست، دو روش برای کنترل اندازه پارتیشن وجود دارد. می‌توانید حداقل مقدار فضای آزاد را با BOARD_partitionIMAGE_PARTITION_RESERVED_SIZE مشخص کنید، یا می‌توانید BOARD_partitionIMAGE_PARTITION_SIZE را مشخص کنید تا بخش‌های پویا را به اندازه خاصی مجبور کنید. هیچ‌کدام از این‌ها توصیه نمی‌شود مگر اینکه ضروری باشد.

برای مثال:

BOARD_PRODUCTIMAGE_PARTITION_RESERVED_SIZE := 52428800

با این کار، سیستم فایل در product.img مجبور می‌شود ‫۵۰ مگابایت فضای استفاده‌نشده داشته باشد.

تغییرات سیستم به‌عنوان ریشه

دستگاه‌هایی که با Android 10 عرضه می‌شوند نباید از سیستم-به‌عنوان-ریشه استفاده کنند.

دستگاه‌های دارای پارتیشن‌های پویا (چه با پارتیشن‌های پویا راه‌اندازی شوند یا به آن‌ها مجهز شوند) نباید از system-as-root استفاده کنند. هسته Linux نمی‌تواند بخش super را تفسیر کند و بنابراین نمی‌تواند system را سوار کند. اکنون system توسط init مرحله اول که در ramdisk قرار دارد نصب شده است.

BOARD_BUILD_SYSTEM_ROOT_IMAGE تنظیم نشود. در Android 10، پرچم BOARD_BUILD_SYSTEM_ROOT_IMAGE فقط برای تشخیص اینکه سیستم توسط هسته یا توسط init مرحله اول در دیسک حافظه سوار شده است استفاده می‌شود.

تنظیم BOARD_BUILD_SYSTEM_ROOT_IMAGE روی true وقتی PRODUCT_USE_DYNAMIC_PARTITIONS هم true باشد باعث خطای ساخت می‌شود.

وقتی BOARD_USES_RECOVERY_AS_BOOT روی درست تنظیم شده باشد، تصویر بازیابی به‌عنوان boot.img ساخته می‌شود که حاوی ramdisk بازیابی است. قبلاً، bootloader از پارامتر خط فرمان هسته skip_initramfs برای تصمیم‌گیری درباره اینکه به کدام حالت بوت شود استفاده می‌کرد. برای دستگاه‌های Android 10، بارکننده نباید skip_initramfs را به خط فرمان هسته ارسال کند. درعوض، bootloader باید androidboot.force_normal_boot=1 را رد کند تا بازیابی را رد کند و Android عادی را راه‌اندازی کند. دستگاه‌هایی که با Android 12 یا نسخه‌های جدیدتر عرضه می‌شوند باید از bootconfig برای ارسال androidboot.force_normal_boot=1 استفاده کنند.

تغییرات پیکربندی AVB

هنگام استفاده از راه‌اندازی درستی‌سنجی‌شده Android نسخه ۲.۰، اگر دستگاه از توصیف‌کننده‌های بخش زنجیره‌ای استفاده نمی‌کند، هیچ تغییری لازم نیست. بااین‌حال، اگر از پارتیشن‌های زنجیره‌ای استفاده می‌کنید و یکی از پارتیشن‌های درستی‌سنجی‌شده پویا است، تغییرات لازم است.

در اینجا پیکربندی نمونه‌ای برای دستگاهی که vbmeta را برای system و vendor پارتیشن‌ها زنجیر می‌کند آورده شده است.

BOARD_AVB_SYSTEM_KEY_PATH := external/avb/test/data/testkey_rsa2048.pem
BOARD_AVB_SYSTEM_ALGORITHM := SHA256_RSA2048
BOARD_AVB_SYSTEM_ROLLBACK_INDEX := $(PLATFORM_SECURITY_PATCH_TIMESTAMP)
BOARD_AVB_SYSTEM_ROLLBACK_INDEX_LOCATION := 1

BOARD_AVB_VENDOR_KEY_PATH := external/avb/test/data/testkey_rsa2048.pem
BOARD_AVB_VENDOR_ALGORITHM := SHA256_RSA2048
BOARD_AVB_VENDOR_ROLLBACK_INDEX := $(PLATFORM_SECURITY_PATCH_TIMESTAMP)
BOARD_AVB_VENDOR_ROLLBACK_INDEX_LOCATION := 1

با این پیکربندی، بارکننده انتظار دارد vbmeta پانویس را در انتهای system و vendor پارتیشن پیدا کند. ازآنجایی‌که این پارتیشن‌ها دیگر برای بارکننده قابل‌مشاهده نیستند (در super قرار دارند)، دو تغییر لازم است.

  • ‫vbmeta_system و vbmeta_vendor پارتیشن را به جدول پارتیشن دستگاه اضافه کنید. برای دستگاه‌های A/B، vbmeta_system_a،‏ vbmeta_system_b، vbmeta_vendor_a، و vbmeta_vendor_b را اضافه کنید. اگر یک یا چندتا از این پارتیشن‌ها را اضافه می‌کنید، باید هم‌اندازه پارتیشن vbmeta باشند.
  • پرچم‌های پیکربندی را با افزودن VBMETA_ تغییر نام دهید و مشخص کنید که زنجیره‌سازی به کدام پارتیشن‌ها گسترش می‌یابد:
    BOARD_AVB_VBMETA_SYSTEM := system
    BOARD_AVB_VBMETA_SYSTEM_KEY_PATH := external/avb/test/data/testkey_rsa2048.pem
    BOARD_AVB_VBMETA_SYSTEM_ALGORITHM := SHA256_RSA2048
    BOARD_AVB_VBMETA_SYSTEM_ROLLBACK_INDEX := $(PLATFORM_SECURITY_PATCH_TIMESTAMP)
    BOARD_AVB_VBMETA_SYSTEM_ROLLBACK_INDEX_LOCATION := 1
    
    BOARD_AVB_VBMETA_VENDOR := vendor
    BOARD_AVB_VBMETA_VENDOR_KEY_PATH := external/avb/test/data/testkey_rsa2048.pem
    BOARD_AVB_VBMETA_VENDOR_ALGORITHM := SHA256_RSA2048
    BOARD_AVB_VBMETA_VENDOR_ROLLBACK_INDEX := $(PLATFORM_SECURITY_PATCH_TIMESTAMP)
    BOARD_AVB_VBMETA_VENDOR_ROLLBACK_INDEX_LOCATION := 1

دستگاه ممکن است از یکی، هر دو، یا هیچ‌کدام از این پارتیشن‌ها استفاده کند. تغییرات فقط هنگام زنجیره‌ای کردن به پارتیشن منطقی لازم است.

تغییرات راه‌انداز سیستم AVB

اگر بارکننده بوت libavb را جاسازی کرده است، وصله‌های زیر را اضافه کنید:

اگر از پارتیشن‌های زنجیره‌ای استفاده می‌کنید، وصله اضافی را اضافه کنید:

  • 49936b4c0109411fdd38bd4ba3a32a01c40439a9 — «libavb: پشتیبانی از لکه‌های vbmeta در ابتدای پارتیشن.»

تغییرات خط فرمان هسته

پارامتر جدیدی، androidboot.boot_devices، باید به خط فرمان هسته اضافه شود. ‫init از این برای فعال کردن پیوندهای نمادین /dev/block/by-name استفاده می‌کند. باید عنصر مسیر دستگاه به پیوند نمادین زیرین براساس نام ایجادشده توسط ueventd باشد، یعنی /dev/block/platform/device-path/by-name/partition-name. دستگاه‌هایی که با Android 12 یا نسخه‌های جدیدتر راه‌اندازی می‌شوند باید از bootconfig برای انتقال androidboot.boot_devices به init استفاده کنند.

برای مثال، اگر پیوند نمادین براساس نام پارتیشن ممتاز به‌صورت زیر باشد: /dev/block/platform/soc/100000.ufshc/by-name/super، می‌توانید پارامتر خط فرمان را در فایل BoardConfig.mk به‌صورت زیر اضافه کنید:

BOARD_KERNEL_CMDLINE += androidboot.boot_devices=soc/100000.ufshc
می‌توانید پارامتر bootconfig را به این صورت در فایل BoardConfig.mk اضافه کنید:
BOARD_BOOTCONFIG += androidboot.boot_devices=soc/100000.ufshc

تغییرات fstab

درخت دستگاه و رونهادهای درخت دستگاه نباید حاوی ورودی‌های fstab باشد. از فایل fstab استفاده کنید که بخشی از ramdisk خواهد بود.

برای پارتیشن‌های منطقی، باید تغییراتی در فایل fstab ایجاد شود:

  • فیلد پرچم‌های fs_mgr باید شامل پرچم logical و پرچم first_stage_mount باشد که در Android 10 معرفی شده است و نشان می‌دهد که یک پارتیشن باید در مرحله اول نصب شود.
  • یک پارتیشن ممکن است avb=vbmeta partition name را به‌عنوان پرچم fs_mgr مشخص کند و سپس پارتیشن vbmeta مشخص‌شده توسط مرحله اول init قبل‌از تلاش برای سوار کردن هر دستگاهی مقداردهی اولیه می‌شود.
  • فیلد dev باید نام پارتیشن باشد.

ورودی‌های fstab زیر سیستم، فروشنده، و محصول را به‌عنوان پارتیشن‌های منطقی مطابق با قوانین بالا تنظیم می‌کنند.

#<dev>  <mnt_point> <type>  <mnt_flags options> <fs_mgr_flags>
system   /system     ext4    ro,barrier=1        wait,slotselect,avb=vbmeta,logical,first_stage_mount
vendor   /vendor     ext4    ro,barrier=1        wait,slotselect,avb,logical,first_stage_mount
product  /product    ext4    ro,barrier=1        wait,slotselect,avb,logical,first_stage_mount

فایل fstab را در دیسک مجازی مرحله اول کپی کنید.

تغییرات SELinux

دستگاه بلوک پارتیشن فوق باید با برچسب super_block_device علامت‌گذاری شود. برای مثال، اگر پیوند نمادین براساس نام پارتیشن اصلی /dev/block/platform/soc/100000.ufshc/by-name/super باشد، خط زیر را به file_contexts اضافه کنید:

/dev/block/platform/soc/10000\.ufshc/by-name/super   u:object_r:super_block_device:s0

fastbootd

بارکننده (یا هر ابزار فلشینگ غیرکاربرفضایی) پارتیشن‌های پویا را درک نمی‌کند، بنابراین نمی‌تواند آن‌ها را فلش کند. برای رفع این مشکل، دستگاه‌ها باید از پیاده‌سازی فضای کاربر پروتکل fastboot، به‌نام fastbootd، استفاده کنند.

برای اطلاعات بیشتر درباره نحوه پیاده‌سازی fastbootd، به انتقال Fastboot به فضای کاربر مراجعه کنید.

adb remount

برای توسعه‌دهندگانی که از ساخت‌های eng یا userdebug استفاده می‌کنند، adb remount برای تکرار سریع بسیار مفید است. بخش‌های پویا برای adb remount مشکل ایجاد می‌کند زیرا دیگر فضای خالی در هر سیستم فایل وجود ندارد. برای رفع این مشکل، دستگاه‌ها می‌توانند overlayfs را فعال کنند. تا زمانی که فضای خالی در اَبَربخش وجود داشته باشد، adb remount به‌طور خودکار بخش پویای موقتی ایجاد می‌کند و از overlayfs برای نوشتن استفاده می‌کند. نام این بخش موقت scratch است، بنابراین از این نام برای بخش‌های دیگر استفاده نکنید.

برای اطلاعات بیشتر درباره نحوه فعال کردن overlayfs، به overlayfs README در AOSP مراجعه کنید.

ارتقا دادن دستگاه‌های Android

اگر دستگاهی را به Android 10 ارتقا دهید و بخواهید از پارتیشن‌های پویا در OTA پشتیبانی کنید، نیازی نیست جدول پارتیشن داخلی را تغییر دهید. پیکربندی اضافی لازم است.

تغییرات پیکربندی دستگاه

برای اصلاح کردن تقسیم‌بندی پویا، پرچم‌های زیر را در device.mk اضافه کنید:

PRODUCT_USE_DYNAMIC_PARTITIONS := true
PRODUCT_RETROFIT_DYNAMIC_PARTITIONS := true

تغییرات پیکربندی تابلو

ملزم هستید متغیرهای صفحه زیر را تنظیم کنید:

  • BOARD_SUPER_PARTITION_BLOCK_DEVICES را روی فهرست دستگاه‌های مسدودشده‌ای که برای ذخیره کردن گستره‌های پارتیشن‌های پویا استفاده می‌شود تنظیم کنید. این فهرست نام‌های پارتیشن‌های فیزیکی موجود در دستگاه است.
  • ‫BOARD_SUPER_PARTITION_partition_DEVICE_SIZE را به‌ترتیب روی اندازه‌های هر دستگاه بلوک در BOARD_SUPER_PARTITION_BLOCK_DEVICES تنظیم کنید. این فهرست اندازه‌های پارتیشن‌های فیزیکی موجود در دستگاه است. این معمولاً BOARD_partitionIMAGE_PARTITION_SIZE در پیکربندی‌های برد موجود است.
  • BOARD_partitionIMAGE_PARTITION_SIZE موجود را برای همه بخش‌ها در BOARD_SUPER_PARTITION_BLOCK_DEVICES لغو تنظیم کنید.
  • ‫BOARD_SUPER_PARTITION_SIZE را روی مجموع BOARD_SUPER_PARTITION_partition_DEVICE_SIZE تنظیم کنید.
  • ‫BOARD_SUPER_PARTITION_METADATA_DEVICE را روی دستگاه بلوکی تنظیم کنید که فراداده‌های پارتیشن پویا در آن ذخیره می‌شود. باید یکی از BOARD_SUPER_PARTITION_BLOCK_DEVICES باشد. معمولاً این مقدار روی system تنظیم شده است.
  • به‌ترتیب BOARD_SUPER_PARTITION_GROUPS، BOARD_group_SIZE، و BOARD_group_PARTITION_LIST تنظیم کنید. برای جزئیات بیشتر، تغییرات پیکربندی برد در دستگاه‌های جدید را ببینید.

برای مثال، اگر دستگاه ازقبل بخش‌های سیستم و فروشنده را دارد و می‌خواهید آن‌ها را به بخش‌های پویا تبدیل کنید و بخش محصول جدیدی را درطول به‌روزرسانی اضافه کنید، این پیکربندی برد را تنظیم کنید:

BOARD_SUPER_PARTITION_BLOCK_DEVICES := system vendor
BOARD_SUPER_PARTITION_METADATA_DEVICE := system

# Rename BOARD_SYSTEMIMAGE_PARTITION_SIZE to BOARD_SUPER_PARTITION_SYSTEM_DEVICE_SIZE.
BOARD_SUPER_PARTITION_SYSTEM_DEVICE_SIZE := <size-in-bytes>

# Rename BOARD_VENDORIMAGE_PARTITION_SIZE to BOARD_SUPER_PARTITION_VENDOR_DEVICE_SIZE
BOARD_SUPER_PARTITION_VENDOR_DEVICE_SIZE := <size-in-bytes>

# This is BOARD_SUPER_PARTITION_SYSTEM_DEVICE_SIZE + BOARD_SUPER_PARTITION_VENDOR_DEVICE_SIZE
BOARD_SUPER_PARTITION_SIZE := <size-in-bytes>

# Configuration for dynamic partitions. For example:
BOARD_SUPER_PARTITION_GROUPS := group_foo
BOARD_GROUP_FOO_SIZE := <size-in-bytes>
BOARD_GROUP_FOO_PARTITION_LIST := system vendor product

تغییرات SELinux

دستگاه‌های بلوک پارتیشن فوق باید با مشخصه super_block_device_type علامت‌گذاری شوند. برای مثال، اگر دستگاه ازقبل system و vendor پارتیشن دارد، می‌خواهید از آن‌ها به‌عنوان دستگاه‌های بلوکی برای ذخیره کردن گستره‌های پارتیشن‌های پویا استفاده کنید، و پیوندهای نمادین آن‌ها براساس نام به‌عنوان system_block_device علامت‌گذاری شده است:

/dev/block/platform/soc/10000\.ufshc/by-name/system   u:object_r:system_block_device:s0
/dev/block/platform/soc/10000\.ufshc/by-name/vendor   u:object_r:system_block_device:s0

سپس، خط زیر را به device.te اضافه کنید:

typeattribute system_block_device super_block_device_type;

برای پیکربندی‌های دیگر، به پیاده‌سازی پارتیشن‌های پویا در دستگاه‌های جدید مراجعه کنید.

برای اطلاعات بیشتر درباره به‌روزرسانی‌های مقاوم‌سازی، به OTA برای دستگاه‌های A/B بدون پارتیشن‌های پویا مراجعه کنید.

تصاویر کارخانه

برای دستگاهی که با پشتیبانی از افرازهای پویا راه‌اندازی می‌شود، از استفاده از راه‌اندازی سریع فضای کاربر برای فلاش کردن تصاویر کارخانه اجتناب کنید، زیرا راه‌اندازی در فضای کاربر کندتر از سایر روش‌های فلاش کردن است.

برای رفع این مشکل، make dist اکنون تصویر super.img دیگری می‌سازد که می‌تواند مستقیماً به پارتیشن super فلش شود. این ویژگی به‌طور خودکار محتوای پارتیشن‌های منطقی را دسته‌بندی می‌کند، یعنی علاوه‌بر فراداده پارتیشن super، حاوی system.img، vendor.img، و غیره است. این تصویر می‌تواند مستقیماً در پارتیشن super بدون هیچ ابزار اضافی یا استفاده از fastbootd فلش شود. پس‌از ساخت، super.img در ${ANDROID_PRODUCT_OUT} قرار می‌گیرد.

برای دستگاه‌های A/B که با افرازهای پویا راه‌اندازی می‌شوند، super.img حاوی تصاویر در جایگاه A است. پس‌از نوشتن مستقیم تصویر فوق، قبل‌از بازراه‌اندازی دستگاه، جایگاه A را به‌عنوان قابل‌راه‌اندازی علامت‌گذاری کنید.

برای دستگاه‌های پس‌از نصب، make dist مجموعه‌ای از super_*.img تصویر می‌سازد که می‌توانند مستقیماً در بخش‌های فیزیکی مربوطه فلش شوند. برای مثال، make dist ساخت super_system.img و super_vendor.img وقتی BOARD_SUPER_PARTITION_BLOCK_DEVICES فروشنده سیستم است. این تصاویر در پوشه OTA در target_files.zip قرار می‌گیرند.

تنظیم دستگاه ذخیره‌سازی نگاشت دستگاه

پارتیشن‌بندی پویا از تعدادی از اشیای نگاشت دستگاه غیرقطعی پشتیبانی می‌کند. ممکن است همه این موارد طبق انتظار نمونه‌سازی نشوند، بنابراین باید همه نصب‌ها را پیگیری کنید و ویژگی‌های Android همه پارتیشن‌های مرتبط را با دستگاه‌های ذخیره‌سازی زیرین آن‌ها به‌روز کنید.

سازوکاری در init وجود دارد که نصب‌ها را ردیابی می‌کند و به‌صورت ناهمزمان دارایی‌های Android را به‌روز می‌کند. مدت زمانی که این کار طول می‌کشد تضمین نمی‌شود که در یک دوره زمانی خاص باشد، بنابراین باید زمان کافی برای واکنش همه on property محرک‌ها درنظر بگیرید. دارایی‌ها dev.mnt.blk.<partition> است که در آن <partition>‏ root،‏ system،‏ data، یا vendor است، برای نمونه. هر دارایی با نام دستگاه ذخیره‌سازی پایه مرتبط است، همان‌طور که در این مثال‌ها نشان داده شده است:

taimen:/ % getprop | grep dev.mnt.blk
[dev.mnt.blk.data]: [sda]
[dev.mnt.blk.firmware]: [sde]
[dev.mnt.blk.metadata]: [sde]
[dev.mnt.blk.persist]: [sda]
[dev.mnt.blk.root]: [dm-0]
[dev.mnt.blk.vendor]: [dm-1]

blueline:/ $ getprop | grep dev.mnt.blk
[dev.mnt.blk.data]: [dm-4]
[dev.mnt.blk.metadata]: [sda]
[dev.mnt.blk.mnt.scratch]: [sda]
[dev.mnt.blk.mnt.vendor.persist]: [sdf]
[dev.mnt.blk.product]: [dm-2]
[dev.mnt.blk.root]: [dm-0]
[dev.mnt.blk.system_ext]: [dm-3]
[dev.mnt.blk.vendor]: [dm-1]
[dev.mnt.blk.vendor.firmware_mnt]: [sda]

زبان init.rc به دارایی‌های Android اجازه می‌دهد به‌عنوان بخشی از قوانین گسترش یابند، و دستگاه‌های ذخیره‌سازی می‌توانند درصورت نیاز با فرمان‌هایی مانند این موارد توسط پلاتفرم تنظیم شوند:

write /sys/block/${dev.mnt.blk.root}/queue/read_ahead_kb 128
write /sys/block/${dev.mnt.blk.data}/queue/read_ahead_kb 128

وقتی پردازش فرمان در مرحله دوم init شروع می‌شود، epoll loop فعال می‌شود و مقادیر شروع به به‌روزرسانی می‌کنند. بااین‌حال، چون راه‌اندازهای دارایی تا اواخر init فعال نیستند، نمی‌توان از آن‌ها در مراحل اولیه راه‌اندازی برای مدیریت root، system، یا vendor استفاده کرد. می‌توانید انتظار داشته باشید که پیش‌فرض هسته read_ahead_kb تا زمانی که برنامه‌های init.rc بتوانند در early-fs (زمانی که خدمات و امکانات مختلف شروع می‌شوند) آن را ملغی کنند کافی باشد. بنابراین، Google توصیه می‌کند که از ویژگی on property همراه با ویژگی تحت کنترل init.rc مثل sys.read_ahead_kb استفاده کنید تا زمان‌بندی عملیات را مدیریت کنید و از شرایط رقابتی جلوگیری کنید، مانند این مثال‌ها:

on property:dev.mnt.blk.root=* && property:sys.read_ahead_kb=*
    write /sys/block/${dev.mnt.blk.root}/queue/read_ahead_kb ${sys.read_ahead_kb:-2048}

on property:dev.mnt.blk.system=* && property:sys.read_ahead_kb=*
    write /sys/block/${dev.mnt.blk.system}/queue/read_ahead_kb ${sys.read_ahead_kb:-2048}

on property:dev.mnt.blk.vendor=* && property:sys.read_ahead_kb=*
    write /sys/block/${dev.mnt.blk.vendor}/queue/read_ahead_kb ${sys.read_ahead_kb:-2048}

on property:dev.mnt.blk.product=* && property:sys.read_ahead_kb=*
    write /sys/block/${dev.mnt.blk.system_ext}/queue/read_ahead_kb ${sys.read_ahead_kb:-2048}

on property:dev.mnt.blk.oem=* && property:sys.read_ahead_kb=*
    write /sys/block/${dev.mnt.blk.oem}/queue/read_ahead_kb ${sys.read_ahead_kb:-2048}

on property:dev.mnt.blk.data=* && property:sys.read_ahead_kb=*
    write /sys/block/${dev.mnt.blk.data}/queue/read_ahead_kb ${sys.read_ahead_kb:-2048}

on early-fs:
    setprop sys.read_ahead_kb ${ro.read_ahead_kb.boot:-2048}

on property:sys.boot_completed=1
   setprop sys.read_ahead_kb ${ro.read_ahead_kb.bootcomplete:-128}