जिन ओईएम और SoC वेंडर को A/B सिस्टम अपडेट लागू करने हैं उन्हें यह पक्का करना होगा कि उनका बूटलोडर, boot_control HAL को लागू करे और कर्नल को सही पैरामीटर भेजे.
बूट कंट्रोल HAL को लागू करना
A/B बूटलोडर के लिए, boot_control
एचएएल को hardware/libhardware/include/hardware/boot_control.h
पर लागू करना ज़रूरी है. system/extras/bootctl
यूटिलिटी और system/extras/tests/bootloader/
का इस्तेमाल करके, लागू किए गए बदलावों को टेस्ट किया जा सकता है.
आपको यहां दिखाई गई स्टेट मशीन को भी लागू करना होगा:

कर्नल सेट अप करना
A/B सिस्टम अपडेट लागू करने के लिए:
-
अगर ज़रूरी हो, तो कर्नेल पैच की इन सीरीज़ को चेरीपिक करें:
- अगर ramdisk के बिना बूट किया जा रहा है और "boot as recovery" का इस्तेमाल किया जा रहा है, तो cherrypick android-review.googlesource.com/#/c/158491/.
- ramdisk के बिना dm-verity सेट अप करने के लिए, android-review.googlesource.com/#/q/status:merged+project:kernel/common+branch:android-3.18+topic:A_B_Changes_3.18 को cherrypick करें.
-
पक्का करें कि कर्नल कमांड लाइन के तर्कों में ये अतिरिक्त तर्क शामिल हों:
... where theskip_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>
value is the ID of the public key used to verify the verity table signature (for details, see dm-verity). -
सार्वजनिक पासकोड वाले .X509 सर्टिफ़िकेट को सिस्टम कीरिंग में जोड़ें:
-
.der
फ़ॉर्मैट में फ़ॉर्मैट किए गए .X509 सर्टिफ़िकेट कोkernel
डायरेक्ट्री के रूट में कॉपी करें. अगर .X509 सर्टिफ़िकेट को.pem
फ़ाइल के तौर पर फ़ॉर्मैट किया गया है, तो.pem
से.der
फ़ॉर्मैट में बदलने के लिए, यहां दिया गयाopenssl
निर्देश इस्तेमाल करें: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>
के तौर पर पास करें. उदाहरण के लिए,<public-key-id>
के बजायAndroid:#7e4333f9bba00adfe0ede979e28ed1920492b40f
पास करें.
-
बिल्ड वैरिएबल सेट करना
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 अब इन पार्टीशन का इस्तेमाल नहीं करता. अब डेटा पार्टीशन का इस्तेमाल, डाउनलोड किए गए ओटीए पैकेज के लिए किया जाता है. साथ ही, रिकवरी इमेज कोड, बूट पार्टीशन पर होता है. जिन सभी पार्टीशन पर A/B टेस्टिंग की जाती है उनका नाम इस तरह होना चाहिए (स्लॉट के नाम हमेशा a
, b
वगैरह होते हैं): boot_a
,
boot_b
, system_a
, system_b
, vendor_a
,
vendor_b
.
कैश मेमोरी
A/B अपडेट के अलावा अन्य अपडेट के लिए, कैश मेमोरी पार्टिशन का इस्तेमाल डाउनलोड किए गए ओटीए पैकेज को सेव करने के लिए किया जाता था. साथ ही, अपडेट लागू करते समय ब्लॉक को कुछ समय के लिए सेव करने के लिए भी इसका इस्तेमाल किया जाता था. कैश मेमोरी के साइज़ को तय करने का कोई सही तरीका नहीं था. इसका साइज़ इस बात पर निर्भर करता था कि आपको कौनसे अपडेट लागू करने हैं. सबसे खराब स्थिति में, कैश मेमोरी का पार्टीशन सिस्टम इमेज जितना बड़ा हो सकता है. A/B अपडेट में, ब्लॉक को स्टैश करने की ज़रूरत नहीं होती. ऐसा इसलिए, क्योंकि हमेशा ऐसे पार्टीशन में लिखा जाता है जिसका इस्तेमाल फ़िलहाल नहीं किया जा रहा है. साथ ही, स्ट्रीमिंग A/B में, ओटीए पैकेज को लागू करने से पहले, उसे पूरा डाउनलोड करने की ज़रूरत नहीं होती.
रिकवरी
रिकवरी रैम डिस्क अब boot.img
फ़ाइल में शामिल है. रिकवरी मोड में जाने पर, बूटलोडर कर्नेल कमांड लाइन पर skip_initramfs
विकल्प नहीं डाल सकता.
A/B अपडेट के अलावा अन्य अपडेट के लिए, रिकवरी पार्टीशन में अपडेट लागू करने के लिए इस्तेमाल किया गया कोड होता है. A/B अपडेट, बूट किए गए सिस्टम की सामान्य इमेज में चल रहे update_engine
की मदद से लागू किए जाते हैं.
फ़ैक्ट्री डेटा रीसेट करने और अपडेट पैकेज को साइडलोड करने के लिए, अब भी रिकवरी मोड का इस्तेमाल किया जाता है. "रिकवरी" नाम यहीं से आया है. रिकवरी मोड का कोड और डेटा, रैमडिस्क में रेगुलर बूट पार्टीशन में सेव होता है. सिस्टम इमेज में बूट करने के लिए, बूटलोडर कर्नल को रैमडिस्क को स्किप करने के लिए कहता है. ऐसा न करने पर, डिवाइस रिकवरी मोड में बूट हो जाता है. रिकवरी मोड छोटा होता है और इसका ज़्यादातर हिस्सा पहले से ही बूट पार्टिशन पर होता है. इसलिए, बूट पार्टिशन का साइज़ नहीं बढ़ता.
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
माउंट पॉइंट पर माउंट किया जाएगा.
कर्नेल स्लॉट के आर्ग्युमेंट
मौजूदा स्लॉट का प्रत्यय, किसी डिवाइस ट्री (डीटी) नोड (/firmware/android/slot_suffix
) या androidboot.slot_suffix
कर्नेल कमांड लाइन या बूटकॉन्फ़िग आर्ग्युमेंट के ज़रिए पास किया जाना चाहिए.
डिफ़ॉल्ट रूप से, fastboot, A/B डिवाइस पर मौजूदा स्लॉट को फ़्लैश करता है. अगर अपडेट पैकेज में, दूसरे स्लॉट के लिए भी इमेज शामिल हैं, तो फ़ास्टबूट उन इमेज को भी फ़्लैश करता है. आपके पास ये विकल्प उपलब्ध हैं:
-
--slot SLOT
. डिफ़ॉल्ट तरीके को बदलें और फ़ास्टबूट को उस स्लॉट को फ़्लैश करने के लिए कहें जिसे आर्ग्युमेंट के तौर पर पास किया गया है. -
--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 पैकेज टूल, नॉन-ए/बी डिवाइसों के लिए इस्तेमाल की जाने वाली कमांड का ही पालन करते हैं. target_files.zip
फ़ाइल जनरेट करने के लिए, A/B टारगेट के लिए बिल्ड वैरिएबल तय करने होंगे. ओटीए पैकेज टूल, A/B अपडेटर के फ़ॉर्मैट में पैकेज की पहचान अपने-आप करते हैं और उन्हें जनरेट करते हैं.
उदाहरण:
-
पूरा ओटीए जनरेट करने के लिए:
./build/make/tools/releasetools/ota_from_target_files \ dist_output/tardis-target_files.zip \ ota_update.zip
-
इंक्रीमेंटल ओटीए जनरेट करने के लिए:
./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
है (अगर 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 फ़ाइलों को पहली बार बूट करने पर इंस्टॉल करना लेख पढ़ें.