«سازندگان اصلی محصول» و فروشندگان SoC که میخواهند بهروزرسانیهای سیستم A/B را پیادهسازی کنند باید مطمئن شوند که بارکننده آنها «لایه انتزاعی سختافزار» boot_control را پیادهسازی میکند و پارامترهای صحیح را به هسته ارسال میکند.
پیادهسازی HAL کنترل راهاندازی
راهاندازهای سیستم با قابلیت A/B باید boot_control HAL را در
hardware/libhardware/include/hardware/boot_control.h پیادهسازی کنند. میتوانید پیادهسازیها را بااستفاده از
system/extras/bootctl
ابزار و
system/extras/tests/bootloader/ آزمایش کنید.
همچنین باید ماشین حالت نشاندادهشده در زیر را پیادهسازی کنید:
راهاندازی هسته
برای پیادهسازی بهروزرسانیهای سیستم A/B:
-
مجموعه وصلههای هسته زیر را انتخاب کنید (درصورت نیاز):
- اگر بدون دیسک حافظه راهاندازی میکنید و از «راهاندازی بهعنوان بازیابی» استفاده میکنید، 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>شناسه کلید عمومی استفادهشده برای درستیسنجی امضای جدول درستی است (برای جزئیات، به 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>در خط فرمان هسته ارسال کنید. برای مثال،Android:#7e4333f9bba00adfe0ede979e28ed1920492b40fرا بهجای<public-key-id>قرار دهید.
-
گواهینامه .X509 قالببندیشده در قالب
تنظیم متغیرهای ساخت
بوتلودرهای با قابلیت A/B باید معیارهای متغیر ساخت زیر را داشته باشند:
| باید برای هدف A/B تعریف شود |
/device/google/marlin/+/android-7.1.0_r1/device-common.mk مراجعه کنید. میتوانید بهصورت اختیاری مرحله dex2oat پساز نصب (اما قبلاز بازراهاندازی) را که در
گردآوری توضیح داده شده است انجام دهید.
|
|---|---|
| برای هدف A/B بهشدت توصیه میشود |
|
| برای هدف آزمایش A/B تعریف نشد |
|
| اختیاری برای ساختهای اشکالزدایی | 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، از افراز حافظه نهان برای ذخیره بستههای OTA بارگیریشده و برای ذخیره موقت بلوکها درحین اعمال بهروزرسانیها استفاده میشد. هیچوقت راه خوبی برای تعیین اندازه پارتیشن حافظه نهان وجود نداشت: اندازه موردنیاز آن به بهروزرسانیهایی که میخواستید اعمال کنید بستگی داشت. بدترین حالت این است که بخش حافظه نهان بهاندازه تصویر سیستم باشد. با بهروزرسانیهای A/B نیازی نیست بلوکها را ذخیره کنید (چون همیشه در پارتیشنی مینویسید که درحالحاضر استفاده نمیشود) و با A/B جاریسازی نیازی نیست بسته کامل OTA را قبلاز اعمال کردن آن بارگیری کنید.
بازیابی
دیسک RAM بازیابی اکنون در فایل boot.img قرار دارد. وقتی وارد حالت بازیابی میشوید، bootloader نمیتواند گزینه skip_initramfs را در خط فرمان هسته قرار دهد.
برای بهروزرسانیهای غیر A/B، پارتیشن بازیابی حاوی کدی است که برای اعمال بهروزرسانیها استفاده میشود. بهروزرسانیهای
A/B توسط update_engine که در تصویر سیستم راهاندازیشده معمولی اجرا میشود اعمال میشوند.
هنوز حالت بازیابیای وجود دارد که برای اجرای بازنشانی کارخانهای و بارگیری جانبی بستههای بهروزرسانی استفاده میشود (نام «بازیابی» از اینجا آمده است). کد و دادههای حالت بازیابی
در پارتیشن بوت معمولی در ramdisk ذخیره میشود؛ برای بوت کردن در تصویر سیستم،
bootloader به هسته میگوید ramdisk را رد کند (درغیراینصورت دستگاه در حالت بازیابی بوت میشود). حالت بازیابی کوچک است (و بخش زیادی از آن قبلاً در پارتیشن راهاندازی بوده است)، بنابراین اندازه پارتیشن راهاندازی افزایش نمییابد.
Fstab
متغیر مستقل slotselect باید در خط برای بخشهای
آزمایش A/B باشد. برای مثال:
<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. جزئیات فرمانها را دریافت کنید.
اگر bootloader از 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 را اجرا کنید.
تولید بستههای 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) است. فهرست پارتیشنهایی که تولیدکننده بار داده
بهروزرسانی را برای آنها تعریف میکند توسط متغیر 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
ترجمه برنامهها
برنامهها را میتوان قبلاز راهاندازی مجدد با تصویر سیستم جدید در پسزمینه کامپایل کرد. برای گردآوری برنامهها در پسزمینه، موارد زیر را به پیکربندی دستگاه محصول (در دستگاه محصول.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 در اولین راهاندازی مراجعه کنید.