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

قم بإعداد النواة
لتنفيذ تحديثات نظام A/B:
- اختر سلسلة تصحيحات kernel التالية (إذا لزم الأمر):
- في حالة التشغيل بدون قرص ذاكرة الوصول العشوائي واستخدام "التمهيد كاسترداد"، اختر android-review.googlesource.com/#/c/158491/ .
- لإعداد dm-verity بدون قرص ذاكرة الوصول العشوائي، Cherrypick android-review.googlesource.com/#/q/status:merged+project:kernel/common+branch:android-3.18+topic:A_B_Changes_3.18 .
- تأكد من أن وسيطات سطر أوامر kernel تحتوي على الوسائط الإضافية التالية:
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 ) . - أضف شهادة .X509 التي تحتوي على المفتاح العام إلى حلقة مفاتيح النظام:
- انسخ شهادة .X509 المنسقة بتنسيق
.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
):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
يشير التضمين الناجح لشهادة .X509 إلى وجود المفتاح العام في حلقة مفاتيح النظام (يشير التمييز إلى معرف المفتاح العام). - استبدل المسافة بـ
#
وقم بتمريرها كـ<public-key-id>
في سطر أوامر kernel. على سبيل المثال، قم بتمريرAndroid:#7e4333f9bba00adfe0ede979e28ed1920492b40f
بدلاً من<public-key-id>
.
- انسخ شهادة .X509 المنسقة بتنسيق
تعيين متغيرات البناء
يجب أن تستوفي أدوات تحميل التشغيل التي تدعم A/B معايير متغير البناء التالية:
يجب تحديد هدف A/B |
/device/google/marlin/+/android-7.1.0_r1/device-common.mk . يمكنك اختياريًا إجراء خطوة ما بعد التثبيت (لكن ما قبل إعادة التشغيل) dex2oat الموضحة في Compiling . |
---|---|
يوصى به بشدة لهدف A/B |
|
لا يمكن تحديد هدف A/B |
|
اختياري لبنيات التصحيح | 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 ليست هناك حاجة لتنزيل حزمة OTA بأكملها قبل تطبيقها.
استعادة
قرص ذاكرة الوصول العشوائي للاسترداد موجود الآن في ملف boot.img
. عند الدخول في عملية الاسترداد، لا يمكن لمحمل التشغيل وضع خيار skip_initramfs
في سطر أوامر kernel.
بالنسبة للتحديثات غير A/B، يحتوي قسم الاسترداد على الكود المستخدم لتطبيق التحديثات. يتم تطبيق تحديثات A/B بواسطة update_engine
الذي يعمل في صورة النظام الذي تم تشغيله بشكل عادي. لا يزال هناك وضع استرداد يُستخدم لتنفيذ إعادة ضبط بيانات المصنع والتحميل الجانبي لحزم التحديث (ومن هنا جاء اسم "الاسترداد"). يتم تخزين التعليمات البرمجية والبيانات الخاصة بوضع الاسترداد في قسم التمهيد العادي في قرص ذاكرة الوصول العشوائي؛ للإقلاع في صورة النظام، يخبر محمل الإقلاع النواة بتخطي قرص ذاكرة الوصول العشوائي (وإلا فإن الجهاز يدخل في وضع الاسترداد. وضع الاسترداد صغير (وكان الكثير منه موجودًا بالفعل على قسم التمهيد)، لذا لا يزيد قسم التمهيد في الحجم.
فستاب
يجب أن تكون وسيطة 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
.
وسيطات فتحة Kernel
يجب تمرير لاحقة الفتحة الحالية إما من خلال عقدة شجرة جهاز معينة (DT) ( /firmware/android/slot_suffix
) أو من خلال سطر أوامر androidboot.slot_suffix
kernel أو وسيطة bootconfig.
افتراضيًا، يقوم fastboot بوميض الفتحة الحالية على جهاز A/B. إذا كانت حزمة التحديث تحتوي أيضًا على صور للفتحة الأخرى غير الحالية، فسيقوم Fastboot بوميض تلك الصور أيضًا. تشمل الخيارات المتاحة ما يلي:
-
--slot SLOT
. قم بتجاوز السلوك الافتراضي ومطالبة fastboot بوميض الفتحة التي تم تمريرها كوسيطة. -
--set-active [ SLOT ]
. اضبط الفتحة على أنها نشطة. إذا لم يتم تحديد وسيطة اختيارية، فسيتم تعيين الفتحة الحالية على أنها نشطة. -
fastboot --help
. الحصول على تفاصيل حول الأوامر.
إذا كان محمل الإقلاع يطبق 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
. عدد مرات إعادة المحاولة المتبقية لمحاولة تشغيل الفتحة المحددة.
لعرض جميع المتغيرات، قم بتشغيل 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
.
على سبيل المثال، إذا تم تضمين زوج من الأقسام 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 .