على الشركات المصنّعة للأجهزة الأصلية ومورّدي نظام التشغيل على الشريحة الذين يريدون تنفيذ تحديثات نظام A/B التأكّد من أنّ برنامج التشغيل الأوّلي ينفّذ طبقة تجريد الأجهزة (HAL) الخاصة بـ boot_control ويمرّر المَعلمات الصحيحة إلى نواة النظام.
تنفيذ طبقة تجريد الأجهزة (HAL) الخاصة بالتحكّم في بدء التشغيل
يجب أن تنفّذ برامج تحميل التشغيل المتوافقة مع نظام التشغيل A/B واجهة boot_control
HAL في
hardware/libhardware/include/hardware/boot_control.h
. يمكنك اختبار عمليات التنفيذ باستخدام الأداة المساعدة system/extras/bootctl
وsystem/extras/tests/bootloader/
.
يجب أيضًا تنفيذ آلة الحالة الموضّحة أدناه:

إعداد النواة
لتنفيذ تحديثات النظام من النوع أ/ب، اتّبِع الخطوات التالية:
-
اختَر سلسلة تصحيحات النواة التالية (إذا لزم الأمر):
- إذا كنت تريد التشغيل بدون ramdisk واستخدام "boot as recovery"، يمكنك اختيار التغيير من android-review.googlesource.com/#/c/158491/.
- لإعداد dm-verity بدون ramdisk، يجب اختيار android-review.googlesource.com/#/q/status:merged+project:kernel/common+branch:android-3.18+topic:A_B_Changes_3.18.
-
تأكَّد من أنّ وسيطات سطر أوامر النواة تتضمّن الوسيطات الإضافية التالية:
... حيث تمثّل قيمة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>
معرّف المفتاح العام المستخدَم للتحقّق من توقيع جدول verity (للحصول على التفاصيل، يُرجى الاطّلاع على dm-verity). -
أضِف شهادة X .509 التي تحتوي على المفتاح العام إلى سلسلة مفاتيح النظام:
-
انسخ شهادة X .509 المنسَّقة بتنسيق
.der
إلى جذر الدليلkernel
. إذا كانت شهادة .X509 منسَّقة كملف.pem
، استخدِم الأمرopenssl
التالي للتحويل من تنسيق.pem
إلى تنسيق.der
:openssl x509 -in <x509-pem-certificate> -outform der -out <x509-der-certificate>
-
أنشئ
zImage
لتضمين الشهادة كجزء من سلسلة مفاتيح النظام. لإجراء عملية التحقّق، راجِع الإدخالprocfs
(يجب تفعيلKEYS_CONFIG_DEBUG_PROC_KEYS
): يشير تضمين شهادة X.509. بنجاح إلى توفّر المفتاح العام في سلسلة مفاتيح النظام (يشير التمييز إلى معرّف المفتاح العام).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
-
استبدِل المسافة بـ
#
ومرِّرها كـ<public-key-id>
في سطر أوامر النواة. على سبيل المثال، استخدِمAndroid:#7e4333f9bba00adfe0ede979e28ed1920492b40f
بدلاً من<public-key-id>
.
-
انسخ شهادة X .509 المنسَّقة بتنسيق
ضبط متغيرات الإنشاء
يجب أن تستوفي برامج تحميل التشغيل المتوافقة مع A/B معايير متغيرات الإصدار التالية:
يجب تحديد هدف اختبار أ/ب |
/device/google/marlin/+/android-7.1.0_r1/device-common.mk . يمكنك اختياريًا إجراء خطوة dex2oat بعد التثبيت (ولكن قبل إعادة التشغيل) الموضّحة في الترجمة البرمجية.
|
---|---|
يُنصح بشدة باستخدامه لاستهداف اختبار أ/ب |
|
لا يمكن تحديد استهداف اختبار أ/ب |
|
اختياري لإنشاءات تصحيح الأخطاء | PRODUCT_PACKAGES_DEBUG += update_engine_client |
ضبط الأقسام (الفتحات)
لا تحتاج الأجهزة التي تستخدم نظام التشغيل A/B إلى قسم استرداد أو قسم تخزين مؤقت لأنّ نظام التشغيل Android لم يعُد يستخدم هذين القسمين. يتم الآن استخدام قسم البيانات لحزمة OTA التي تم تنزيلها، كما أنّ رمز صورة الاسترداد يقع في قسم التشغيل. يجب تسمية جميع الأقسام التي يتم اختبارها بنظام A/B على النحو التالي (يتم دائمًا تسمية الخانات a
وb
وما إلى ذلك): boot_a
،
boot_b
، وsystem_a
، وsystem_b
، وvendor_a
،
وvendor_b
.
ذاكرة التخزين المؤقت
بالنسبة إلى التحديثات غير A/B، تم استخدام قسم ذاكرة التخزين المؤقت لتخزين حِزم التحديثات عبر الهواء التي تم تنزيلها ولتخزين الحِزم مؤقتًا أثناء تطبيق التحديثات. لم تكن هناك طريقة جيدة لتحديد حجم قسم ذاكرة التخزين المؤقت، إذ كان الحجم المطلوب يعتمد على التحديثات التي تريد تطبيقها. أسوأ الحالات هي أن يكون قسم ذاكرة التخزين المؤقت بحجم صورة النظام. مع تحديثات A/B، لا حاجة إلى تخزين الكتل (لأنّك تكتب دائمًا في قسم غير مستخدَم حاليًا)، ومع تحديثات A/B المتدفقة، لا حاجة إلى تنزيل حزمة OTA بأكملها قبل تطبيقها.
الاسترداد
يتم الآن تضمين قرص RAM للاسترداد في الملف boot.img
. عند الانتقال إلى وضع الاسترداد، لا يمكن لبرنامج التحميل وضع الخيار skip_initramfs
في سطر أوامر النواة.
بالنسبة إلى التحديثات غير من النوع أ/ب، يحتوي قسم الاسترداد على الرمز المستخدَم لتطبيق التحديثات. يتم تطبيق تحديثات A/B من خلال update_engine
التي تعمل في صورة نظام التمهيد العادية.
لا يزال هناك وضع استرداد يُستخدم لتنفيذ عملية إعادة ضبط الجهاز على الإعدادات الأصلية وتحميل حِزم التحديث بشكل جانبي (وهو مصدر اسم "الاسترداد"). يتم تخزين الرمز والبيانات الخاصة بوضع الاسترداد في قسم التشغيل العادي في ramdisk. ولتشغيل صورة النظام، يطلب برنامج التشغيل من النواة تخطّي ramdisk (وإلا سيتم تشغيل الجهاز في وضع الاسترداد). حجم وضع الاسترداد صغير (وقد كان جزء كبير منه متوفّرًا في قسم التشغيل)، وبالتالي لا يزداد حجم قسم التشغيل.
Fstab
يجب أن تكون الوسيطة slotselect
في السطر الخاص بالأقسام التي تم اختبارها باستخدام اختبار أ/ب. مثلاً:
<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
أو وسيطة bootconfig.
تومض fastboot تلقائيًا الفتحة الحالية على جهاز A/B. إذا كانت حزمة التحديث تحتوي أيضًا على صور للفتحة الأخرى غير الحالية، سيومض fastboot هذه الصور أيضًا. تشمل الخيارات المتاحة ما يلي:
-
--slot SLOT
. تجاوز السلوك التلقائي وإصدار أمر إلى fastboot لتثبيت الحزمة في الفتحة التي تم تمريرها كمعلَمة -
--set-active [SLOT]
. ضبط الفترة الزمنية على "نشطة" في حال عدم تحديد أي وسيط اختياري، يتم ضبط الخانة الحالية على أنّها نشطة. fastboot --help
. الحصول على تفاصيل حول الأوامر
إذا كان برنامج التحميل الأوّلي ينفّذ fastboot، يجب أن يتيح تنفيذ الأمر
set_active <slot>
الذي يضبط الفتحة النشطة الحالية على الفتحة المحدّدة (يجب أن يؤدي ذلك أيضًا إلى محو العلامة غير القابلة للتشغيل في تلك الفتحة وإعادة ضبط عدد المحاولات على القيم التلقائية). يجب أن يتيح برنامج التحميل أيضًا المتغيّرات التالية:
-
has-slot:<partition-base-name-without-suffix>
. تعرِض هذه السمة القيمة "yes" إذا كان القسم المحدّد يتيح استخدام مواضع الإعلانات، والقيمة "no" إذا كان لا يتيح ذلك. -
current-slot
: تعرض لاحقة الفتحة التي سيتم بدء التشغيل منها في المرة القادمة. -
slot-count
. تعرض هذه السمة عدد الفترات الزمنية المتاحة. في الوقت الحالي، يمكن استخدام خانتَين، لذا تكون هذه القيمة2
. -
slot-successful:<slot-suffix>
. تعرض هذه السمة القيمة "yes" إذا تم وضع علامة على الفتحة المحدّدة بأنّها تمهيد ناجح، أو القيمة "no" في الحالات الأخرى. -
slot-unbootable:<slot-suffix>
. تعرض هذه السمة القيمة "yes" إذا تم وضع علامة على الفتحة المحدّدة بأنّها غير قابلة للتشغيل، أو "no" في الحالات الأخرى. -
slot-retry-count:<slot-suffix>
. عدد المحاولات المتبقية لمحاولة تشغيل الفتحة المحدّدة.
لعرض جميع المتغيرات، شغِّل
fastboot getvar all
.
إنشاء حِزم OTA
تتّبع أدوات حزمة OTA الأوامر نفسها التي تتّبعها الأوامر الخاصة بالأجهزة غير المتوافقة مع تحديثات A/B. يجب إنشاء ملف target_files.zip
من خلال تحديد متغيرات الإصدار الخاصة باستهداف اختبار A/B. تتعرّف أدوات حزمة OTA تلقائيًا على الحِزم وتنشئها بالتنسيق المناسب لأداة التحديث A/B.
أمثلة:
-
لإنشاء حزمة OTA كاملة، اتّبِع الخطوات التالية:
./build/make/tools/releasetools/ota_from_target_files \ dist_output/tardis-target_files.zip \ ota_update.zip
-
لإنشاء تحديث عبر الهواء (OTA) تراكمي، اتّبِع الخطوات التالية:
./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
). يتم ضبط قائمة الأقسام التي يحدّد مولّد الحمولة تحديثًا لها من خلال المتغيّر AB_OTA_PARTITIONS
make.
على سبيل المثال، إذا تم تضمين زوج من الأقسام 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 الخاص بالمنتج):
-
أدرِج المكوّنات الأصلية في الإصدار لضمان تجميع النص البرمجي والثنائيات
وتضمينها في صورة النظام.
# A/B OTA dexopt package PRODUCT_PACKAGES += otapreopt_script
-
اربط برنامج نص التجميع بـ
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 عند التشغيل الأول.