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

إعداد النواة
لتنفيذ تحديثات نظام A/B:
-
اختَر بعناية سلسلة تصحيحات النواة التالية (إذا لزم الأمر):
- في حال التمهيد بدون استخدام ملف ramdisk واستخدام "التمهيد في وضع الاسترداد"، اختَر الإصدارات الأحدث من الرمز البرمجي 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.
-
تأكَّد من أنّ وسيطات سطر أوامر 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
): يشير تضمين شهادة .X509 بنجاح إلى توفّر المفتاح العام في سلسلة مفاتيح النظام (يشير التمييز إلى معرّف المفتاح العام).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>
في سطر أوامر kernel. على سبيل المثال، أرسِلAndroid:#7e4333f9bba00adfe0ede979e28ed1920492b40f
بدلاً من<public-key-id>
.
-
انسخ شهادة X509 .بتنسيق
ضبط متغيّرات التصميم
يجب أن تستوفي أداة تحميل البرامج الثابتة المتوافقة مع ميزة A/B المعايير التالية لمتغيّر الإنشاء:
يجب تحديده لاستهداف أ/ب |
/device/google/marlin/+/android-7.1.0_r1/device-common.mk . يمكنك اختياريًا تنفيذ خطوة dex2oat الموضّحة في
الترجمة بعد التثبيت (ولكن قبل إعادة التشغيل).
|
---|---|
يُنصح بشدة باستخدامها لاستهداف أ/ب |
|
لا يمكن تحديد استهداف A/B |
|
اختياري لإصدارات تصحيح الأخطاء | PRODUCT_PACKAGES_DEBUG += update_engine_client |
ضبط الأقسام (الخانات)
لا تحتاج أجهزة A/B إلى قسم استرداد أو قسم تخزين مؤقت لأنّ نظام التشغيل Android لم يعُد يستخدم
هذين القسمَين. يتم الآن استخدام قسم البيانات لحزمة OTA التي تم تنزيلها، ويتوفر код
صورة الاسترداد في قسم التمهيد. يجب تسمية جميع الأقسام التي تم تقسيمها إلى قسمَين اختباريَين
على النحو التالي (يتم دائمًا تسمية الخانات a
وb
وما إلى ذلك): boot_a
،
boot_b
، system_a
، system_b
، vendor_a
،
vendor_b
.
ذاكرة التخزين المؤقت
بالنسبة إلى التحديثات غير المستندة إلى تقنية A/B، كان يتم استخدام قسم ذاكرة التخزين المؤقت لتخزين حِزم OTA التي تم تنزيلها و لتخزين الكتل مؤقتًا أثناء تطبيق التحديثات. لم تكن هناك طريقة جيدة لتحديد حجم قسم ملف التخزين المؤقت ، إذ كان حجمه يعتمد على التعديلات التي تريد تطبيقها. سيكون أسوأ حالة هي قسم ذاكرة التخزين المؤقت بحجم ملف صورة النظام. باستخدام تحديثات A/B، ليس من الضروري تخزين الكتل (لأنّك تكتب دائمًا في قسم غير مستخدَم حاليًا) و باستخدام ميزة A/B للبث، ليس من الضروري تنزيل حزمة OTA بالكامل قبل تطبيقها.
الاسترداد
يتم الآن تضمين قرص ذاكرة الوصول العشوائي (RAM) لميزة الاسترداد في ملف boot.img
. عند الانتقال إلى وضع
الاسترداد، لا يمكن لمسؤول التمهيد ضبط الخيار skip_initramfs
على
سطر أوامر kernel.
بالنسبة إلى التحديثات غير المُدارة من خلال ميزة "التحديث الثنائي"، يحتوي قسم الاسترداد على الرمز المُستخدَم لتطبيق التحديثات. يتم تطبيق تحديثات A/B
من خلال تشغيل update_engine
في صورة النظام العادية التي يتم تشغيلها.
لا يزال هناك وضع الاسترداد الذي يُستخدَم لتنفيذ ميزة "إعادة الضبط على الإعدادات الأصلية" وتحميل حزم التحديثات من مصدر غير معروف (من هنا جاء اسم "وضع الاسترداد"). يتم تخزين التعليمات البرمجية والبيانات الخاصة بوضع الاسترداد
في قسم التشغيل العادي في ذاكرة وصول عشوائي (RAM). لبدء التشغيل إلى صورة النظام، يطلب ملف التمهيد
من النواة تخطّي ذاكرة الوصول العشوائي (RAM) (وإلا سيتم تشغيل الجهاز في وضع الاسترداد
). مساحة وضع الاسترداد صغيرة (وكان الكثير منها مضمّنًا في قسم التمهيد)، لذا لا يزداد حجم قسم التمهيد.
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
. الحصول على تفاصيل عن الطلبات
إذا كان مشغّل الإقلاع ينفِّذ وضع التشغيل السريع، يجب أن يكون متوافقًا مع الأمر
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
.
إنشاء حِزم عبر الهواء
تتبع أدوات حِزم 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
(إذا لم يكن
يتم استخدام قرص ذاكرة وصول عشوائي). بالإضافة إلى ذلك، حدِّد نوع نظام الملفات الذي سيتم تمريره إلى 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 في عملية التشغيل الأولى.