پیاده سازی A/B مجازی

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

پرچم بسازید

دستگاه هایی که از A/B مجازی استفاده می کنند باید به عنوان یک دستگاه A/B پیکربندی شوند و باید با پارتیشن های پویا راه اندازی شوند .

برای دستگاه‌هایی که با A/B مجازی راه‌اندازی می‌شوند، آنها را طوری تنظیم کنید که پیکربندی پایه دستگاه A/B مجازی را به ارث ببرند:

$(call inherit-product, \
    $(SRC_TARGET_DIR)/product/virtual_ab_ota.mk)

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

برای فعال کردن عکس‌های فوری فشرده شده با A/B مجازی، به جای آن پیکربندی پایه زیر را به ارث ببرید:

$(call inherit-product, \
    $(SRC_TARGET_DIR)/product/virtual_ab_ota/compression.mk)

کنترل بوت HAL

کنترل بوت HAL یک رابط برای مشتریان OTA برای کنترل اسلات های بوت فراهم می کند. A/B مجازی به ارتقاء نسخه جزئی کنترل بوت HAL نیاز دارد زیرا برای اطمینان از محافظت بوت لودر در هنگام چشمک زدن/بازنشانی کارخانه، به APIهای اضافی نیاز است. برای آخرین نسخه تعریف HAL ​​به IBootControl.hal و Types.hal مراجعه کنید.

// hardware/interfaces/boot/1.1/types.hal
enum MergeStatus : uint8_t {
    NONE, UNKNOWN, SNAPSHOTTED, MERGING, CANCELLED };

// hardware/interfaces/boot/1.1/IBootControl.hal
package android.hardware.boot@1.1;
interface IBootControl extends @1.0::IBootControl {
    setSnapshotMergeStatus(MergeStatus status)
        generates (bool success);
    getSnapshotMergeStatus()
        generates (MergeStatus status);
}
// Recommended implementation

Return<bool> BootControl::setSnapshotMergeStatus(MergeStatus v) {
    // Write value to persistent storage
    // e.g. misc partition (using libbootloader_message)
    // bootloader rejects wipe when status is SNAPSHOTTED
    // or MERGING
}

Fstab تغییر می کند

یکپارچگی پارتیشن ابرداده برای فرآیند بوت ضروری است، به خصوص بلافاصله پس از اعمال به روز رسانی OTA. بنابراین، پارتیشن ابرداده باید قبل از نصب first_stage_init بررسی شود. برای اطمینان از این اتفاق، پرچم check fs_mgr را به ورودی /metadata اضافه کنید. در ادامه مثالی ارائه می شود:

/dev/block/by-name/metadata /metadata ext4 noatime,nosuid,nodev,discard,sync wait,formattable,first_stage_mount,check

نیازهای هسته

برای فعال کردن عکس فوری، CONFIG_DM_SNAPSHOT را روی true تنظیم کنید.

برای دستگاه‌هایی که از F2FS استفاده می‌کنند، f2fs را اضافه کنید: برای رفع پین کردن فایل، پرچم FS_NOCOW_FL را به وصله هسته کاربر صادر کنید. f2fs را نیز اضافه کنید: از وصله هسته فایل پین شده تراز شده نیز پشتیبانی کنید .

A/B مجازی به ویژگی‌های اضافه شده در هسته نسخه 4.3 متکی است: بیت وضعیت سرریز در اهداف snapshot و snapshot-merge . همه دستگاه‌هایی که با اندروید 9 و جدیدتر راه‌اندازی می‌شوند باید از قبل دارای نسخه هسته 4.4 یا بالاتر باشند.

برای فعال کردن عکس های فوری فشرده، حداقل نسخه هسته پشتیبانی شده 4.19 است. CONFIG_DM_USER=m یا CONFIG_DM_USER=y را تنظیم کنید. در صورت استفاده از اولی (یک ماژول)، ماژول باید در ramdisk مرحله اول بارگذاری شود. این را می توان با افزودن خط زیر به Makefile دستگاه به دست آورد:

BOARD_GENERIC_RAMDISK_KERNEL_MODULES_LOAD := dm-user.ko

به روز رسانی در دستگاه هایی که به اندروید 11 ارتقا می یابند

هنگام ارتقاء به اندروید 11، دستگاه‌هایی که با پارتیشن‌های پویا راه‌اندازی شده‌اند، می‌توانند به صورت اختیاری A/B مجازی را بازسازی کنند. فرآیند به روز رسانی عمدتاً مانند دستگاه هایی است که با A/B مجازی راه اندازی می شوند، با برخی تفاوت های جزئی:

  • مکان فایل‌های COW - برای دستگاه‌های راه‌اندازی، مشتری OTA از تمام فضای خالی موجود در پارتیشن فوق‌العاده قبل از استفاده از فضا در /data می‌کند. برای دستگاه‌های مقاوم‌سازی، همیشه فضای کافی در پارتیشن فوق‌العاده وجود دارد تا فایل COW هرگز در /data ایجاد نشود.

  • پرچم‌های ویژگی زمان ساخت — برای دستگاه‌هایی که A/B مجازی را مقاوم‌سازی می‌کنند، PRODUCT_VIRTUAL_AB_OTA و PRODUCT_VIRTUAL_AB_OTA_RETROFIT روی true تنظیم می‌شوند، همانطور که در زیر نشان داده شده است:

    (call inherit-product, \
        (SRC_TARGET_DIR)/product/virtual_ab_ota_retrofit.mk)
    
  • اندازه پارتیشن فوق العاده - دستگاه هایی که با A/B مجازی راه اندازی می شوند، می توانند BOARD_SUPER_PARTITION_SIZE را به نصف برسانند، زیرا شکاف های B در پارتیشن فوق العاده قرار ندارند. دستگاه‌هایی که A/B مجازی را بازسازی می‌کنند، اندازه پارتیشن فوق‌العاده قدیمی را حفظ می‌کنند، بنابراین BOARD_SUPER_PARTITION_SIZE بزرگ‌تر یا مساوی 2 * مجموع (اندازه گروه‌های به‌روزرسانی) + سربار است، که به نوبه خود بزرگ‌تر یا مساوی 2 * مجموع (اندازه پارتیشن‌ها) است. + سربار .

تغییرات بوت لودر

در طول مرحله ادغام یک به روز رسانی، /data تنها نمونه کامل سیستم عامل اندروید را در خود نگه می دارد. پس از شروع مهاجرت، system بومی، vendor و پارتیشن‌های product ناقص هستند تا زمانی که کپی به پایان برسد. اگر دستگاه در طی این فرآیند، یا از طریق بازیابی یا از طریق گفتگوی تنظیمات سیستم، به حالت کارخانه بازنشانی شود، دستگاه غیر قابل بوت خواهد بود.

قبل از پاک کردن /data ، بسته به وضعیت دستگاه، ادغام را در بازیابی یا بازگشت به عقب تمام کنید:

  • اگر بیلد جدید قبلا با موفقیت بوت شده است، انتقال را تمام کنید.
  • در غیر این صورت، به شکاف قبلی برگردید:
    • برای پارتیشن های پویا، به حالت قبل برگردید.
    • برای پارتیشن های استاتیک، اسلات فعال را روی اسلات قدیمی قرار دهید.

هر دو bootloader و fastbootd می توانند پارتیشن /data را در صورت باز بودن قفل دستگاه پاک کنند. در حالی که fastbootd می تواند انتقال را مجبور به تکمیل کند، بوت لودر نمی تواند. بوت لودر نمی داند که آیا ادغام در حال انجام است یا خیر، یا اینکه چه بلوک هایی در /data پارتیشن های سیستم عامل را تشکیل می دهند. دستگاه‌ها باید با انجام موارد زیر از عدم کارکرد ناخودآگاه کاربر (آجرکاری) جلوگیری کنند:

  1. کنترل بوت HAL را پیاده سازی کنید تا بوت لودر بتواند مقدار تنظیم شده توسط setSnapshotMergeStatus() را بخواند.
  2. اگر وضعیت ادغام در حال MERGING است، یا اگر وضعیت ادغام SNAPSHOTTED است و شکاف به شکاف به‌روزرسانی شده جدید تغییر کرده است، درخواست‌های پاک کردن userdata ، metadata یا پارتیشنی که وضعیت ادغام را ذخیره می‌کند باید در بوت لودر رد شود.
  3. دستور fastboot snapshot-update cancel اجرا کنید تا کاربران بتوانند به بوت لودر سیگنال دهند که می خواهند از این مکانیسم حفاظتی عبور کنند.
  4. ابزارها یا اسکریپت های فلش سفارشی را تغییر دهید تا هنگام فلش کل دستگاه fastboot snapshot-update cancel شود. این مشکل ایمن است زیرا فلش کردن کل دستگاه باعث حذف OTA می شود. Tooling می تواند این دستور را در زمان اجرا با پیاده سازی fastboot getvar snapshot-update-status شناسایی کند. این دستور به تمایز بین شرایط خطا کمک می کند.

مثال

struct VirtualAbState {
    uint8_t StructVersion;
    uint8_t MergeStatus;
    uint8_t SourceSlot;
};

bool ShouldPreventUserdataWipe() {
    VirtualAbState state;
    if (!ReadVirtualAbState(&state)) ...
    return state.MergeStatus == MergeStatus::MERGING ||
           (state.MergeStatus == MergeStatus::SNAPSHOTTED &&
            state.SourceSlot != CurrentSlot()));
}

تغییرات ابزار Fastboot

اندروید 11 تغییرات زیر را در پروتکل fastboot اعمال می کند:

  • getvar snapshot-update-status - مقداری را که کنترل بوت HAL به بوت لودر ارسال کرده است برمی‌گرداند:
    • اگر حالت در حال MERGING باشد، بوت لودر باید merging را برگرداند.
    • اگر وضعیت SNAPSHOTTED باشد، بوت لودر باید به صورت snapshotted برگردد.
    • در غیر این صورت، بوت لودر نباید none را برگرداند.
  • snapshot-update merge — عملیات ادغام را تکمیل می کند و در صورت لزوم به بازیابی/fastbootd راه اندازی می شود. این دستور فقط در صورتی معتبر است که snapshot-update-status merging شود و فقط در fastbootd پشتیبانی می شود.
  • snapshot-update cancel — وضعیت ادغام کنترل بوت HAL را روی CANCELLED تنظیم می کند. وقتی دستگاه قفل است این دستور نامعتبر است.
  • erase یا wipe - erase یا wipe metadata ، داده های userdata ، یا پارتیشنی که وضعیت ادغام را برای کنترل بوت HAL نگه می دارد، باید وضعیت ادغام عکس فوری را بررسی کند. اگر وضعیت MERGING یا SNAPSHOTTED باشد، دستگاه باید عملیات را متوقف کند.
  • set_active - یک دستور set_active که شکاف فعال را تغییر می‌دهد باید وضعیت ادغام عکس فوری را بررسی کند. اگر وضعیت در حال MERGING است، دستگاه باید عملیات را متوقف کند. اسلات را می توان با خیال راحت در حالت SNAPSHOTTED تغییر داد.

این تغییرات برای جلوگیری از راه‌اندازی تصادفی دستگاه طراحی شده‌اند، اما می‌توانند ابزارهای خودکار را مختل کنند. هنگامی که دستورات به عنوان جزء فلش کردن همه پارتیشن ها استفاده می شود، مانند اجرای fastboot flashall ، توصیه می شود از جریان زیر استفاده کنید:

  1. پرس و جوی getvar snapshot-update-status .
  2. در صورت merging یا snapshotted ، snapshot-update cancel کنید.
  3. مراحل چشمک زن را ادامه دهید.

کاهش نیازهای ذخیره سازی

دستگاه‌هایی که فضای ذخیره‌سازی کامل A/B را به صورت فوق‌العاده ندارند، و انتظار دارند در صورت لزوم از /data استفاده کنند، اکیداً توصیه می‌شود از ابزار نقشه‌برداری بلوک استفاده کنند. ابزار نگاشت بلوک، تخصیص بلوک را بین ساخت‌ها ثابت نگه می‌دارد و نوشتن‌های غیر ضروری را در عکس فوری کاهش می‌دهد. این در زیر کاهش اندازه OTA مستند شده است.