OEM ها و فروشندگان 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:
- سری پچ های هسته زیر را Cherrypick کنید (در صورت نیاز):
- اگر بدون ramdisk بوت میشوید و از "boot as recovery" استفاده میکنید، android-review.googlesource.com/#/c/158491/ را انتخاب کنید.
- برای راهاندازی dm-verity بدون ramdisk، cherrypick 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 را پس از نصب (اما قبل از راهاندازی مجدد) که در Compiling توضیح داده شده است انجام دهید. |
---|---|
به شدت برای هدف A/B توصیه می شود |
|
نمی توان برای هدف A/B تعریف کرد |
|
اختیاری برای ساخت اشکال زدایی | PRODUCT_PACKAGES_DEBUG += update_engine_client |
تنظیم پارتیشن ها (اسلات ها)
دستگاه های A/B نیازی به پارتیشن بازیابی یا کش ندارند زیرا اندروید دیگر از این پارتیشن ها استفاده نمی کند. اکنون پارتیشن داده برای بسته 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
را در خط فرمان هسته قرار دهد.
برای بهروزرسانیهای غیر A/B، پارتیشن بازیابی حاوی کدی است که برای اعمال بهروزرسانیها استفاده میشود. به روز رسانی A/B توسط update_engine
در حال اجرا در تصویر سیستم بوت شده معمولی اعمال می شود. هنوز یک حالت بازیابی برای اجرای بازنشانی داده های کارخانه و بارگذاری جانبی بسته های به روز رسانی (که نام "بازیابی" از آنجا آمده است) وجود دارد. کد و اطلاعات برای حالت بازیابی در پارتیشن بوت معمولی در یک ramdisk ذخیره می شود. برای بوت شدن در تصویر سیستم، بوت لودر به هسته میگوید که ramdisk را رد کند (در غیر این صورت دستگاه به حالت بازیابی راهاندازی میشود. حالت بازیابی کوچک است (و بیشتر آن از قبل روی پارتیشن بوت بود)، بنابراین پارتیشن بوت افزایش نمییابد. در اندازه
فستاب
آرگومان 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
نصب خواهد شد.
آرگومان های شکاف هسته
پسوند اسلات فعلی باید یا از طریق یک گره درخت دستگاه خاص (DT) ( /firmware/android/slot_suffix
) یا از طریق خط فرمان androidboot.slot_suffix
هسته یا آرگومان bootconfig ارسال شود.
به طور پیشفرض، فستبوت، اسلات فعلی دستگاه 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 تولید کنید
ابزارهای بسته 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
نباید توسط بقیه سیستم اصلاح شود. در طول به روز رسانی افزایشی یا دلتا ، داده های باینری از شکاف فعلی برای تولید داده ها در شکاف جدید استفاده می شود. هر گونه تغییری ممکن است باعث شود که دادههای اسلات جدید در طی فرآیند بهروزرسانی تأیید نشوند و بنابراین بهروزرسانی انجام نشود.
پیکربندی postinstallation
می توانید مرحله postinstall را برای هر پارتیشن به روز شده با استفاده از مجموعه ای از جفت های کلید-مقدار متفاوت پیکربندی کنید. برای اجرای برنامه ای که در /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 مراجعه کنید.