تنفيذ الظاهري أ / ب

لتنفيذ 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 يجب أن تكون أكبر من أو تساوي مجموع (حجم مجموعات التحديث) + النفقات العامة ، والتي بدورها يجب أن تكون أكبر من أو تساوي مجموع (حجم الأقسام) + النفقات العامة .

لتمكين اللقطات المضغوطة باستخدام Virtual A / B ، ورث التكوين الأساسي التالي بدلاً من ذلك:

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

التحكم في التمهيد HAL

يوفر HAL للتحكم في التمهيد واجهة لعملاء OTA للتحكم في فتحات التمهيد. يتطلب Virtual A / B ترقية إصدار ثانوي من HAL للتحكم في التمهيد لأنه يلزم وجود واجهات برمجة تطبيقات إضافية لضمان حماية أداة تحميل التشغيل أثناء الوميض / إعادة ضبط المصنع. راجع IBootControl.hal و types.hal للحصول على أحدث إصدار من تعريف 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

متطلبات Kernel

لتمكين الالتقاط ، اضبط CONFIG_DM_SNAPSHOT على true .

بالنسبة للأجهزة التي تستخدم F2FS ، قم بتضمين f2fs: تصدير علامة FS_NOCOW_FL إلى تصحيح kernel للمستخدم لإصلاح تثبيت الملف. قم بتضمين f2fs: دعم تصحيح نواة الملف المثبت المحاذاة أيضًا.

يعتمد Virtual A / B على الميزات المضافة في الإصدار 4.3 من kernel: بت حالة الفائض في snapshot وأهداف snapshot-merge . يجب أن تحتوي جميع الأجهزة التي تعمل بنظام Android 9 والإصدارات الأحدث على إصدار kernel 4.4 أو إصدار أحدث.

لتمكين اللقطات المضغوطة ، يكون الحد الأدنى لإصدار kernel المدعوم هو 4.19. اضبط CONFIG_DM_USER=m أو CONFIG_DM_USER=y . في حالة استخدام السابق (وحدة نمطية) ، يجب تحميل الوحدة في المرحلة الأولى ramdisk. يمكن تحقيق ذلك عن طريق إضافة السطر التالي إلى جهاز Makefile:

BOARD_GENERIC_RAMDISK_KERNEL_MODULES_LOAD := dm-user.ko

التعديل التحديثي على الأجهزة التي تقوم بالترقية إلى Android 11

عند الترقية إلى Android 11 ، يمكن للأجهزة التي تم إطلاقها باستخدام أقسام ديناميكية تعديل أ / ب الظاهري اختياريًا. تتشابه عملية التحديث في الغالب مع الأجهزة التي يتم تشغيلها باستخدام 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 * مجموع (حجم الأقسام) + النفقات العامة .

تغييرات Bootloader

أثناء خطوة الدمج لأحد التحديثات ، تحتفظ /data بالمثيل الكامل الوحيد لنظام التشغيل Android. بمجرد بدء الترحيل ، لا يكتمل system الأصلي vendor product حتى تنتهي النسخة. إذا تمت إعادة ضبط الجهاز إلى إعدادات المصنع أثناء هذه العملية ، إما عن طريق الاسترداد أو من خلال مربع حوار إعدادات الأنظمة ، فسيكون الجهاز غير قابل للتمهيد.

قبل المسح /data ، قم بإنهاء الدمج في الاسترداد أو التراجع حسب حالة الجهاز:

  • إذا تم تمهيد الإصدار الجديد بنجاح من قبل ، فقم بإنهاء الترحيل.
  • وإلا ، فارجع إلى الفتحة القديمة:
    • بالنسبة للأقسام الديناميكية ، ارجع إلى الحالة السابقة.
    • بالنسبة للأقسام الثابتة ، اضبط الفتحة النشطة على الفتحة القديمة.

يمكن لكل من أداة تحميل التشغيل و fastbootd مسح قسم /data إذا تم إلغاء قفل الجهاز. بينما يمكن أن يفرض fastbootd اكتمال الترحيل ، لا يستطيع برنامج bootloader ذلك. لا يعرف محمل الإقلاع ما إذا كان الدمج قيد التقدم أم لا ، أو ما هي الكتل الموجودة في /data التي تشكل أقسام نظام التشغيل. يجب أن تمنع الأجهزة المستخدم من جعل الجهاز غير قابل للتشغيل (طوب) دون علمه عن طريق القيام بما يلي:

  1. قم بتطبيق عنصر تحكم التمهيد HAL حتى يتمكن برنامج bootloader من قراءة القيمة التي تم تعيينها بواسطة أسلوب setSnapshotMergeStatus() .
  2. إذا كانت حالة الدمج MERGING ، أو إذا كانت حالة الدمج SNAPSHOTTED وتغيرت الفتحة إلى الفتحة المحدثة حديثًا ، فيجب userdata طلبات مسح بيانات المستخدم أو metadata أو القسم الذي يخزن حالة الدمج في أداة تحميل التشغيل.
  3. قم بتنفيذ الأمر fastboot snapshot-update cancel حتى يتمكن المستخدمون من إرسال إشارة إلى أداة تحميل التشغيل التي يريدون تجاوز آلية الحماية هذه.
  4. قم بتعديل أدوات الوميض المخصصة أو البرامج النصية لإصدار fastboot snapshot-update cancel عند وميض الجهاز بأكمله. هذا أمر آمن للإصدار لأن وميض الجهاز بأكمله يزيل OTA. يمكن للأدوات اكتشاف هذا الأمر في وقت التشغيل عن طريق تنفيذ 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

يقوم Android 11 بإجراء التغييرات التالية على بروتوكول Fastboot:

  • getvar snapshot-update-status - تُرجع القيمة التي أرسلها عنصر التحكم في التمهيد HAL إلى أداة تحميل التشغيل:
    • إذا كانت الحالة MERGING ، يجب أن يقوم برنامج bootloader بإرجاع merging .
    • إذا كانت الحالة SNAPSHOTTED ، يجب أن يقوم برنامج تحميل التشغيل بإرجاع snapshotted .
    • خلاف ذلك ، يجب أن يقوم برنامج bootloader بإرجاع none .
  • snapshot-update merge - يكمل عملية الدمج ، التمهيد إلى الاسترداد / fastbootd إذا لزم الأمر. يكون هذا الأمر صالحًا فقط إذا تم merging snapshot-update-status ، ويكون مدعومًا فقط في fastbootd.
  • snapshot-update cancel - يعيّن حالة دمج HAL للتحكم في التمهيد على CANCELLED . هذا الأمر غير صالح عند قفل الجهاز.
  • erase أو wipe - يجب أن يتحقق erase أو wipe metadata أو بيانات userdata أو القسم الذي يحمل حالة الدمج لعنصر التحكم في التمهيد من حالة دمج اللقطة. إذا كانت الحالة MERGING أو SNAPSHOTTED ، فيجب على الجهاز إجهاض العملية.
  • set_active - يجب أن يتحقق الأمر set_active الذي يغير الفتحة النشطة من حالة دمج اللقطة. إذا كانت الحالة MERGING ، فيجب على الجهاز إجهاض العملية. يمكن تغيير الفتحة بأمان في حالة SNAPSHOTTED .

تم تصميم هذه التغييرات لمنع جعل الجهاز غير قابل للتمهيد عن طريق الخطأ ، ولكنها قد تؤدي إلى تعطيل الأدوات الآلية. عند استخدام الأوامر كمكوِّن لوميض جميع الأقسام ، مثل تشغيل fastboot flashall ، يوصى باستخدام التدفق التالي:

  1. استعلام getvar snapshot-update-status .
  2. في حالة merging أو الالتقاط ، snapshot-update cancel snapshotted
  3. تابع الخطوات الوامضة.

تقليل متطلبات التخزين

يوصى بشدة بالأجهزة التي لا تحتوي على مساحة تخزين A / B كاملة مخصصة في Super ، وتتوقع استخدام /data حسب الضرورة ، لاستخدام أداة تعيين الكتلة. تحافظ أداة تعيين الكتلة على تناسق تخصيص الكتلة بين البنيات ، مما يقلل عمليات الكتابة غير الضرورية في اللقطة. هذا موثق ضمن تقليل حجم OTA .