تنفيذ تعديلات A/B

على مورّدي المصنّعين الأصليّين ومورّدي المنظومة على الرقاقة الذين يريدون تطبيق تحديثات نظام A/B التأكّد من برنامج الإقلاع. تنفذ HAL-control لـ Boot_control وتمرير المعلمات الصحيحة إلى النواة (النواة).

تنفيذ HAL للتحكم في التشغيل

يجب أن تنفّذ برامج الإقلاع المتوافقة مع A/B سياسة HAL boot_control على hardware/libhardware/include/hardware/boot_control.h يمكنك اختبار عمليات التنفيذ باستخدام system/extras/bootctl system/extras/tests/bootloader/

يجب أيضًا تنفيذ جهاز الحالة الموضح أدناه:

الشكل 1 الجهاز المستخدَم في حالة برنامج الإقلاع

إعداد النواة

لتطبيق تحديثات نظام A/B:

  1. Cherrypick سلسلة نواة اللاصقة التالية (إذا لزم الأمر):
  2. تأكَّد من أن وسيطات سطر أوامر النواة تحتوي على الوسيطات الإضافية التالية:
    skip_initramfs rootwait ro init=/init root="/dev/dm-0 dm=system none ro,0 1 android-verity <public-key-id> <path-to-system-partition>"
    ... حيث تكون القيمة <public-key-id> هي رقم تعريف المفتاح العام المُستخدَم والتحقق من توقيع جدول الحقيقة (لمزيد من التفاصيل، راجع dm-verity).
  3. أضِف شهادة X .509 التي تحتوي على المفتاح العام إلى سلسلة مفاتيح النظام:
    1. انسخ شهادة X .509 بالتنسيق .der إلى جذر دليل kernel. إذا تم تنسيق شهادة X509 كـ .pem، استخدِم الأمر openssl التالي للتحويل من تنسيق .pem إلى .der:
      openssl x509 -in <x509-pem-certificate> -outform der -out <x509-der-certificate>
    2. يمكنك إنشاء zImage لتضمين الشهادة كجزء من سلسلة مفاتيح النظام. لإثبات الملكية، راجِع الإدخال procfs (يتطلب ذلك. KEYS_CONFIG_DEBUG_PROC_KEYS التي سيتم تفعليها):
      angler:/# cat /proc/keys
      
      1c8a217e I------     1 perm 1f010000     0     0 asymmetri
      Android: 7e4333f9bba00adfe0ede979e28ed1920492b40f: X509.RSA 0492b40f []
      2d454e3e I------     1 perm 1f030000     0     0 keyring
      .system_keyring: 1/4
      يشير تضمين شهادة X.509 بنجاح إلى توفُّر المفتاح العام. في سلسلة مفاتيح النظام (يشير مفتاح التمييز إلى معرّف المفتاح العام)
    3. استبدال المسافة بـ # وتمريرها كـ <public-key-id> في سطر أوامر النواة. على سبيل المثال، تمرير Android:#7e4333f9bba00adfe0ede979e28ed1920492b40f بدلاً من <public-key-id>

ضبط متغيرات الإصدار

يجب أن تستوفي برامج الإقلاع المتوافقة مع A/B معايير متغيّرات الإصدار التالية:

يجب تحديد هدف A/B
  • AB_OTA_UPDATER := true

  • AB_OTA_PARTITIONS := \   boot \
      system \
      vendor
    وأقسام أخرى تم تحديثها من خلال update_engine (الراديو وبرنامج الإقلاع، etc.)
  • PRODUCT_PACKAGES += \
      update_engine \
      update_verifier
على سبيل المثال، راجع /device/google/marlin/+/android-7.1.0_r1/device-common.mk يمكنك اختياريًا تنفيذ خطوة dex2oat بعد التثبيت (ولكن لإعادة التشغيل مسبقًا) الموضّحة في تجميع المحتوى:
يُنصح بشدة باستخدام هدف أ/ب
  • تَعْرِيفْ TARGET_NO_RECOVERY := true
  • تَعْرِيفْ BOARD_USES_RECOVERY_AS_BOOT := true
  • عدم تحديد BOARD_RECOVERYIMAGE_PARTITION_SIZE
لا يمكن تحديد هدف A/B
  • BOARD_CACHEIMAGE_PARTITION_SIZE
  • BOARD_CACHEIMAGE_FILE_SYSTEM_TYPE
اختياري للإصدارات المخصصة لتصحيح الأخطاء PRODUCT_PACKAGES_DEBUG += update_engine_client

ضبط الأقسام (الخانات)

لا تحتاج أجهزة A/B إلى قسم مخصّص لاسترداد الحساب أو قسم لذاكرة التخزين المؤقت لأنّ Android لم يعُد يستخدمها. هذه الأقسام. يُستخدم قسم البيانات الآن لحزمة OTA التي تم تنزيلها، رمز صورة الاسترداد في قسم التشغيل. يجب تسمية جميع الأقسام ذات A/B-ed على النحو التالي (تُسمى الخانات دائمًا a وb وما إلى ذلك): boot_a, boot_b وsystem_a وsystem_b وvendor_a vendor_b

ذاكرة التخزين المؤقت

بالنسبة للتحديثات غير A/B، تم استخدام قسم ذاكرة التخزين المؤقت لتخزين حزم OTA التي تم تنزيلها تخزين الكتل مؤقتًا أثناء تطبيق التحديثات. لم تكن هناك أي طريقة جيدة لتغيير حجم ذاكرة التخزين المؤقت التقسيم: هو حجم حجم البيانات اللازم للاعتماد على التحديثات التي تريد تطبيقها. الأسوأ هي قسمًا لذاكرة التخزين المؤقت بحجم صورة النظام. وباستخدام تحديثات A/B، ما مِن حاجة إلى كتل مخبأة (لأنّك تكتب دائمًا على قسم غير مُستخدَم حاليًا) مع البث A/B، ما مِن حاجة إلى تنزيل حزمة التحديث عبر الهواء بالكامل قبل تطبيقها.

استعادة الكرة

أصبح قرص ذاكرة الوصول العشوائي المخصّص لاسترداد الحساب مضمَّنًا الآن في ملف boot.img. عند الذهاب إلى الاسترداد، فإن برنامج الإقلاع لا يمكنه تشغيل الخيار skip_initramfs سطر أوامر النواة.

بالنسبة إلى التحديثات غير A/B، يحتوي قسم الاسترداد على الرمز المستخدَم لتطبيق التحديثات. اختبار A/B يتم تطبيق التحديثات من خلال update_engine الذي يجري في صورة نظام التمهيد العادي. لا يزال هناك وضع استرداد يُستخدم لتنفيذ إعادة الضبط على الإعدادات الأصلية والتثبيت من مصدر غير معروف للتحديث. الحزم (التي يأتي منها اسم "recovery"). الرمز والبيانات لوضع الاسترداد في قسم التمهيد العادي في ذاكرة الوصول العشوائي (RAM)؛ لتشغيل صورة النظام، يطلب برنامج الإقلاع من النواة تخطي ذاكرة الوصول العشوائي (RAM) (وإلا يتم تشغيل الجهاز في وضع الاسترداد) الحالي. يكون وضع الاسترداد صغيرًا (وكان معظمه في قسم التمهيد)، لذلك عدم زيادة حجم القسم.

حساب Fstab

يجب أن تكون الوسيطة slotselect على سطر A/B-ed الأقسام. مثلاً:

<path-to-block-device>/vendor  /vendor  ext4  ro
wait,verify=<path-to-block-device>/metadata,slotselect

يجب تسمية أي قسم باسم vendor. يمكنك بدلاً من ذلك تقسيم vendor_a أو سيتم اختيار vendor_b وتثبيته على نقطة التثبيت /vendor.

وسيطات خانة النواة

يجب تمرير لاحقة الفتحة الحالية إما عبر عقدة شجرة أجهزة (DT) محددة (/firmware/android/slot_suffix) أو من خلال سطر أوامر androidboot.slot_suffix kernel أو وسيطة Bootconfig.

يؤدي استخدام Fastboot إلى وميض الفتحة الحالية تلقائيًا على جهاز A/B. إذا كانت حزمة التحديث أيضًا يحتوي على صور للخانة الأخرى غير الحالية، فإن Fastboot يضيء تلك الصور أيضًا. تشمل الخيارات المتاحة ما يلي:

  • --slot SLOT. تجاوز السلوك التلقائي ومطالبة Fastboot بتشغيل الخانة التي يتم تمريرها كـ وسيطة.
  • --set-active [SLOT]. اضبط الخانة على تفعيل. في حال عدم توفّر وسيطة اختيارية يتم ضبط الخانة الحالية على أنّها نشطة.
  • fastboot --help الحصول على تفاصيل حول الطلبات

إذا نفّذ برنامج الإقلاع برنامج Fastboot (Fastboot)، يجب أن يتوافق مع الأمر set_active <slot> الذي يضبط الخانة النشطة الحالية على الخانة المحدّدة (هذا أيضًا محو علامة عدم التشغيل في هذه الخانة وإعادة ضبط عدد مرات إعادة المحاولة على الإعدادات التلقائية القيم). يجب أن يتوافق برنامج الإقلاع أيضًا مع المتغيّرات التالية:

  • has-slot:<partition-base-name-without-suffix>. عرض "نعم" إذا كانت يدعم التقسيم الخانات، "لا" في الحالات الأخرى.
  • current-slot تعرض لاحقة الخانة التي سيتم تشغيلها من المرة التالية.
  • slot-count. تعرض عددًا صحيحًا يمثّل عدد الخانات المتاحة. تتوفّر خانتان حاليًا، وبالتالي هذه القيمة هي 2.
  • slot-successful:<slot-suffix>. عرض "نعم" إذا تم تحديد الخانة الإعلانية تم وضع علامة "لا" عليها كتمهيد بنجاح وإلا.
  • slot-unbootable:<slot-suffix>. عرض "نعم" إذا تم وضع علامة على الخانة المحددة غير قابل للتشغيل، "لا" وإلا.
  • slot-retry-count:<slot-suffix>. عدد مرات إعادة المحاولة المتبقية قم بتشغيل الخانة المحددة.

لعرض جميع المتغيرات، شغِّل fastboot getvar all

إنشاء حزم عبر الهواء

تتبع أدوات حزمة عبر الهواء نفس الأوامر التي تستخدمها أوامر للأجهزة بخلاف أجهزة A/B. يجب إنشاء الملف target_files.zip في تحديد متغيرات الإصدار لهدف A/B. تحدد أدوات حزمة OTA تلقائيًا وإنشاء الحزم بتنسيق أداة تحديث A/B.

أمثلة:

  • لإنشاء تحديث عبر الهواء بالكامل:
    ./build/make/tools/releasetools/ota_from_target_files \
        dist_output/tardis-target_files.zip \
        ota_update.zip
    
  • لإنشاء تحديث عبر الهواء بشكل متزايد:
    ./build/make/tools/releasetools/ota_from_target_files \
        -i PREVIOUS-tardis-target_files.zip \
        dist_output/tardis-target_files.zip \
        incremental_ota_update.zip
    

ضبط الأقسام

يمكن لـ update_engine تعديل أي زوج من أقسام A/B المحددة في القرص نفسه. يحتوي قسمان على بادئة مشتركة (مثل system أو boot). واللاحقة حسب الخانة (مثل _a). قائمة الأقسام التي تتضمن حمولة البيانات يحدد المُنشئ تحديثًا يتم ضبطه من خلال متغير make AB_OTA_PARTITIONS.

على سبيل المثال، إذا كان هناك قسمان bootloader_a تم تضمين booloader_b (_a و_b هما الخانة لاحقًا)، فيمكنك تحديث هذه الأقسام من خلال تحديد ما يلي على المنتج أو اللوحة التكوين:

AB_OTA_PARTITIONS := \
  boot \
  system \
  bootloader

يجب ألا يتم تعديل جميع الأقسام التي تم تحديثها من خلال update_engine من خلال بقية أقسام الموقع . أثناء التحديثات التزايدية أو التحديثات دلتا، يتم عرض البيانات الثنائية من الشريحة الحالية المستخدم لإنشاء البيانات في الفتحة الجديدة. قد يتسبب أي تعديل في نقل بيانات الخانة الجديدة تعذّر التحقق أثناء عملية التحديث، وبالتالي يتعذّر في التحديث.

ضبط إعدادات عمليات ما بعد التثبيت

يمكنك ضبط خطوة ما بعد التثبيت بشكل مختلف لكل قسم يتم تحديثه باستخدام مجموعة من أزواج المفتاح/القيمة. لتشغيل برنامج في /system/usr/bin/postinst في موقع في قسم النظام، يتم تحديد المسار المرتبط بجذر نظام الملفات في قسم النظام.

على سبيل المثال، تكون قيمة usr/bin/postinst هي system/usr/bin/postinst (إذا لم يكن كذلك باستخدام قرص RAM). بالإضافة إلى ذلك، حدِّد نوع نظام الملفات لتمريره إلى مكالمة نظام mount(2) أضِف ما يلي إلى المنتج أو الجهاز .mk ملف (إذا كان ذلك منطبقًا):

AB_OTA_POSTINSTALL_CONFIG += \
  RUN_POSTINSTALL_system=true \
  POSTINSTALL_PATH_system=usr/bin/postinst \
  FILESYSTEM_TYPE_system=ext4

تجميع التطبيقات

يمكن تجميع التطبيقات في الخلفية قبل إعادة التشغيل باستخدام صورة النظام الجديدة. لتجميع التطبيقات في الخلفية، أضِف ما يلي إلى إعداد الجهاز للمنتج (في قسم Device.mk للمنتج):

  1. قم بتضمين المكونات الأصلية في الإصدار لضمان أن البرنامج النصي للتجميع والبرامج الثنائية وتجميعها وإدراجها في صورة النظام.
      # A/B OTA dexopt package
      PRODUCT_PACKAGES += otapreopt_script
    
  2. يمكنك ربط النص البرمجي للتجميع ضِمن update_engine بحيث يتم تشغيله باعتباره خطوة ما بعد التثبيت.
      # A/B OTA dexopt update_engine hookup
      AB_OTA_POSTINSTALL_CONFIG += \
        RUN_POSTINSTALL_system=true \
        POSTINSTALL_PATH_system=system/bin/otapreopt_script \
        FILESYSTEM_TYPE_system=ext4 \
        POSTINSTALL_OPTIONAL_system=true
    

للحصول على مساعدة في تثبيت الملفات المحدّدة مسبقًا في قسم النظام الثاني غير المستخدَم، يمكنك الاطّلاع على التثبيت لأول مرة لملفات DEX_PREOPT: