مرحبا. في SberDevices ، يشارك فريقنا في تطوير العديد من الأجهزة والبرامج الثابتة لهم بناءً على AOSP.
بدءًا من Android 8 (بعض البائعين بدءًا من الإصدار 7.1) ، يمتلك النظام آلية جديدة لتحديثات OTA ، ما يسمى بـ. تحديثات A / B السلسة عبر الهواء - تحديثات سلسة. في هذا المنشور ، سأصف المبادئ العامة لتشغيله ، وسأفكر في الآلية من وجهة نظر المطور ، وأقارنها أيضًا بالنهج القديم (الذي سنطلق عليه الاسترداد) لتطبيق التحديثات. سيكون كل ما يلي صحيحًا فقط لـ AOSP الخالص ، نظرًا لأن التنفيذ المحدد يعتمد على البائع.
OTA القائم على الاسترداد
يتم تسليم تحديثات Android في شكل أرشيف مضغوط مع تحديثات قائمة على الكتلة. في أيام KitKat ، كانت مجرد مجموعة من الملفات التي تم نسخها إلى الجهاز بواسطة البرنامج النصي المضمن. لن أتطرق إلى هذا الوضع بالتفصيل ، سأصف بإيجاز المبادئ الأساسية لعمله:
- يتم تنزيل أرشيف zip بواسطة النظام على الجهاز ؛
- يقوم النظام بإعادة التشغيل في وضع الاسترداد ؛
- التحقق من توافق التحديث مع الجهاز وتوقيعه ؛
- إذا كان كل شيء على ما يرام ، فسيتم تنفيذ البرنامج النصي المحدث من أرشيف zip ؛
- أثناء التحديث ، قد يتم إعادة تشغيل الجهاز عدة مرات (على سبيل المثال ، لتحديث شجرة الجهاز ) ؛
- إذا سارت الأمور على ما يرام ، فقم بالتمهيد إلى البرامج الثابتة الجديدة.
ما هي عيوب هذا المخطط؟
- الحاجة إلى حجز قدر كافٍ من الذاكرة الداخلية لأرشيف OTA. يتم استخدام قسم / ذاكرة التخزين المؤقت لهذا الغرض . بعض البائعين يستخدمون / بيانات ، لكن هذا نادر. نتيجة لذلك ، يتم ترك مساحة أقل للمستخدم (نعم ، لا يزال بإمكان التطبيقات استخدام مساحة في قسم / ذاكرة التخزين المؤقت ، ولكن مع بعض القيود).
- تستغرق إعادة التشغيل وتطبيق التحديث وقتًا ، وهو ما قد يكون مهمًا لبعض أنواع الأجهزة ، على سبيل المثال ، لأجهزة التلفزيون الذكية.
- قد ينتج عن مقاطعة عملية التحديث حلقة تمهيد .
- لا توجد طريقة للعودة إلى إصدار البرنامج الثابت القديم.
يتيح لك هذا الإزعاج تجاوز طريقة الترقية السلسة. دعونا نرى كيف يعمل.
سلس A / B OTA
المكونات والآليات الرئيسية المطلوبة لتنفيذ تحديثات A / B السلسة :
- ترميز فتحة ذاكرة فلاش ؛
- التفاعل مع اللودر ، وإدارة حالة الفتحات ؛
- تحديث محرك النظام الخفي ؛
- إنشاء أرشيف مضغوط مع تحديث. لن يتم النظر في هذا الجانب في هذه المقالة.
فتحات
المبدأ الأساسي لـ A / B OTA هو الشق . يجب أن تكون جميع الأقسام التي تحتاج إلى التحديث (يمكن أن تكون أي أقسام وليست أقسام نظام فقط) من نسختين أو في فتحات. يدعم تطبيق Android فتحتين مسماة A و B على التوالي . يقوم النظام بالتمهيد والعمل من الفتحة الحالية ، ويتم استخدام الثانية فقط في وقت التحديث. تتم إضافة لاحقة باسم الفتحة إلى اسم القسم.
يوجد أدناه جدول يقارن بين الخيارين لتنظيم الأقسام على الجهاز. يتم تمييز جميع الأقسام المشقوقة بخيار التثبيت بالفتحة بحيث يمكن للنظام تحديد الفتحة الصحيحة. اعتمادًا على مكان وصفها ، يمكن أن يكون هذا fstab
أو دتس .
التغييرات في جدول الأقسام
- لم تعد هناك حاجة إلى B / ذاكرة التخزين المؤقت . الآن يمكن حفظ التحديث إما في / البيانات ، أو وميضه على الفور في فتحة غير نشطة (المزيد عن ذلك أدناه).
- لم يعد قسم الاسترداد مستخدمًا أيضًا. ومع ذلك ، لا يزال وضع الاسترداد موجودًا ، فمن الضروري ، على سبيل المثال ، إعادة ضبط الجهاز على إعدادات المصنع (يمكن أن يؤدي ذلك إلى فريق إنقاذ ). أو لما يسمى ب. التحديث اليدوي ( التحميل الجانبي ) عبر adb . قرص الاسترداد موجود الآن داخل قسم التمهيد ، يتم مشاركة النواة.
- (android/recovery) cmdline ‑ skip_initramfs.
للوهلة الأولى ، يبدو أن مثل هذا المخطط ليس هو الأمثل ، لأنه من الضروري تخصيص ضعف مساحة النظام. لكننا تخلصنا من ذاكرة التخزين المؤقت / ، مما يعني أننا وفرنا بالفعل الكثير من الذاكرة. وبالتالي ، سيستغرق النظام أكثر قليلاً من خيار الاسترداد .
الميزة الرئيسية لتحديثات A / B هي القدرة على دفق البرامج الثابتة. إنه يضمن للمستخدم تحديثات سلسة وشفافة: لتحديث الجهاز ، يكفي إعادة التشغيل في فتحة جديدة. في هذا الوضع ، ليست هناك حاجة لتنزيل أرشيف مضغوط مسبقًا ، مع شغل مساحة في / البيانات . بدلاً من ذلك ، يكتب النظام على الفور كتل البيانات من ملف مُعد خصيصًا ( الحمولة، انظر أدناه) في كل قسم من الخانة غير النشطة. من وجهة نظر التنفيذ ، لا فرق بين تنزيل التحديث مقدمًا أو نقله على الفور إلى الفتحة.
تحتوي الفتحات على الحالات التالية:
- نشط - فتحة نشطة ، سيتم تحميل النظام منه عند إعادة التشغيل التالية ؛
- قابل للتمهيد - تم وميض التحديث بنجاح في الفتحة ، وتم التحقق من صحته ، ومطابقة مجاميع التجزئة ، وما إلى ذلك ؛
- ناجح - كان النظام قادرًا على التمهيد بنجاح في الفتحة الجديدة ؛
- غير قابل للتمهيد - الفتحة تالفة. يقوم النظام دائمًا بتحديد الفتحة على أنها غير قابلة للتمهيد قبل بدء عملية الترقية.
ويمكن لكل من فتحات يكون للتمهيد و ناجحة ، ولكن واحدا فقط هو نشط .
خوارزمية أداة تحميل التشغيل عند اختيار الفتحة:
- يكتشف محمل الإقلاع وجود فتحة واحدة أو أكثر قابلة للتمهيد .
- يتم تحديد الفتحة النشطة (أو الفتحة ذات الأولوية القصوى) من بينها.
- إذا كان النظام بالتمهيد بنجاح، يتم وضع علامة الفتحة كما ناجحة و نشطة .
- خلاف ذلك ، يتم وضع علامة على الفتحة على أنها غير قابلة للتمهيد ويتم إعادة تمهيد النظام.
تغيير حالات الفتحة أثناء التحديث:
المتطلبات الأساسية لـ Seamless A / B.
boot_control
لدعم تحديثات A / B ، يجب على البائع تنفيذ واجهة HAL خاصة - boot_control . يسمح لك بتغيير حالات الفتحات والحصول على معلومات عنها. للعمل الخارجي (على سبيل المثال ، عبر adb shell ) ، يتم استخدام الأداة المساعدة - bootctl . يتم استخدام الواجهة كوسيلة للاتصال بين نظام التشغيل ومحمل الإقلاع.
update_engine
المكون الرئيسي لدائرة A / B بأكملها. يتعامل مع التنزيل وتدفق التحديثات والتحقق من التوقيعات والمزيد. يغير حالات الفتحة عبر boot_control . يسمح لك بالتحكم في عملية تحديث الجهاز: إيقاف مؤقت ، استئناف ، إلغاء.
جاء المكون إلى Android من ChromeOS ، حيث تم استخدامه لفترة من الوقت. AOSP يدعم update_engine كما ثابت sideload التجمع. هي التي يتم استخدامها في الاسترداد ، لأن هذا الوضع لا يدعم الارتباط الديناميكي.
يمكن تقسيم عملية هذا المكون إلى الخطوات التالية:
- تحميل التحديث في الفتحة. يمكنك تنزيل كلاهما من حزمة تم تنزيلها مسبقًا مع تحديث ، أو مباشرة عبر الإنترنت عبر http / https. أثناء التنزيل ، يتم فحص التوقيع ، والمفتاح العام موجود بالفعل على الجهاز (/system/etc/update_engine/update-payload-key.pub.pem) ؛
- التحقق من التحديث الذي تم تنزيله ومقارنة مجاميع التجزئة ؛
- تنفيذ البرامج النصية بعد التثبيت .
هيكل حزمة الخدمة:
2009-01-01 00:00:00 ..... 360 360 META-INF/com/android/metadata
2009-01-01 00:00:00 ..... 107 107 care_map.txt
2009-01-01 00:00:00 ..... 384690699 384690699 payload.bin
2009-01-01 00:00:00 ..... 154 154 payload_properties.txt
2009-01-01 00:00:00 ..... 1675 943 META-INF/com/android/otacert
- care_map.txt - يستخدمه update_verifier (انظر أدناه) ؛
- payload_properties.txt - يحتوي على تجزئات وأحجام بيانات داخل الحمولة ؛
- payload.bin - حزمة التحديث ، تحتوي على كتل من جميع الأقسام والبيانات الوصفية والتوقيع.
update_engine_client
عميل لإدارة برنامج update_engine الخفي . يمكن للمورد الاتصال مباشرة لتطبيق التحديث.
update_verifier
أداة للتحقق من سلامة النظام في البداية (فتحة مع العلم النشط ، ولكنها لم تنجح بعد ). يتم تنفيذ التحكم في النزاهة باستخدام وحدة dm-verity kernel . إذا نجح الفحص ، تقوم الأداة بتمييز الفتحة الحالية على أنها ناجحة . وإلا ، فسيتم إعادة تشغيل النظام في الفتحة القديمة. يتم التحقق فقط من الكتل المحددة في ملف care_map.txt .
UpdateEngineApi
هناك Java API لتنفيذ خدمات تحديث البائعين . هناك أيضًا مثال على تنفيذ هذه الخدمة.
لنلقِ نظرة على مثال لبناء تحديث A / B في AOSP. للقيام بذلك ، قم بتحرير Makefile للنظام الأساسي الهدف:
# A/B
AB_OTA_UPDATER := true
# :
AB_OTA_PARTITIONS := boot system vendor
#
PRODUCT_PACKAGES := update_engine update_engine_client update_verifier
# recovery
TARGET_NO_RECOVERY := true
#, cache:
#BOARD_CACHEIMAGE_PARTITION_SIZE := ...
#BOARD_CACHEIMAGE_FILE_SYSTEM_TYPE := ...
بعد استدعاء make otapackage ، نحصل على أرشيف مضغوط مع التحديث. في هذا النموذج ، يكون مناسبًا بالفعل لوضع التحميل الجانبي . يمكننا إعادة التشغيل في وضع الاسترداد واستدعاء adb sideload ota.zip . هذه الطريقة مناسبة لتصحيح الأخطاء.
عادةً ما يكون تطبيق التحديث من داخل نظام الإنتاج خاصًا بالبائع. أسهل طريقة هي تحميل payload.bin إلى خادم http والاتصال بـ update_engine_client مباشرةً .
مثال على الاتصال:
update_engine_client \
--payload=http://path/to/payload.bin \
--update \
--headers=" \
FILE_HASH=ozGgyQEddkI5Zax+Wbjo6I/PCR8PEZka9gGd0nWa+oY= \
FILE_SIZE=282344983 \
METADATA_HASH=GLIKfE6KRwylWMHsNadG/Q8iy5f786WTatvMdBlpOPg= \
METADATA_SIZE=26723"
يتم تمرير محتوى ملف payload_properties.txt إلى المعلمة headers . في logcat ، يمكنك رؤية تقدم التحديث. إذا مررت بالمفتاح --follow ، فسيتم تكرار التقدم في stdout .
خاتمة
مزايا آلية التحديث الجديدة واضحة:
- يتم تحديث النظام في الخلفية دون مقاطعة عمل المستخدم. نعم ، ستظل بحاجة إلى إعادة التشغيل (إلى فتحة جديدة) ، ولكنها ستكون أسرع بكثير من إعادة التشغيل في الاسترداد لتطبيق التحديث ؛
- يتم تقليل احتمالية حدوث حلقة التمهيد (لا أحد محصن من الأخطاء في التنفيذ). يمكن مقاطعة عملية التحديث ، ولن تؤثر على الفتحة النشطة بأي شكل من الأشكال ؛
- يصبح من الممكن التراجع إلى إصدار البرنامج الثابت السابق. حتى إذا كان التحديث غير ناجح لسبب ما ، فسيعود النظام ببساطة إلى الإصدار القديم ؛
- بفضل التدفق ، سيتم تحديث الجهاز بشكل أسرع ؛
- اعتمادًا على التنفيذ ، يمكنك استبعاد المستخدم تمامًا من عملية التحديث.
من بين السلبيات ، سأفرد نقطتين:
- يصبح A / B OTA معتمدًا على تخطيط القرص الحالي ، لأن التحديث يحدث أثناء تشغيل النظام. بمعنى أنه يصبح من المستحيل تشغيل التحديث بالأقسام المتغيرة ؛
- التعقيد النسبي للتنفيذ.
ومع ذلك ، في رأيي ، تفوق الايجابيات. بالمناسبة، في منطقتنا أعلنت مؤخرا جهاز اننا نستخدم A / B تحديثات OTA.