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

कर्नेल सेट अप करना
सिस्टम के A/B अपडेट लागू करने के लिए:
-
ज़रूरत पड़ने पर, कर्नेल पैच की इन सीरीज़ को चुनें:
- अगर बिना ramdisk के बूट किया जा रहा है और "बूट को रिकवरी के तौर पर इस्तेमाल करें" का इस्तेमाल किया जा रहा है, तो android-review.googlesource.com/#/c/158491/ को चुनें.
- रैमडिस्क के बिना dm-verity सेट अप करने के लिए, 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 सर्टिफ़िकेट जोड़ें:
-
.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 मोड वाले बूटलोडर को, बिल्ड वैरिएबल से जुड़ी इन शर्तों को पूरा करना होगा:
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 अपडेट के अलावा, अन्य अपडेट के लिए कैश मेमोरी पार्टिशन का इस्तेमाल, डाउनलोड किए गए ओटीए पैकेज को स्टोर करने और अपडेट लागू करते समय, ब्लॉक को कुछ समय के लिए स्टैश करने के लिए किया जाता था. कैश मेमोरी के partition का साइज़ तय करने का कोई अच्छा तरीका कभी नहीं था: यह कितना बड़ा होना चाहिए, यह इस बात पर निर्भर करता था कि आपको कौनसे अपडेट लागू करने हैं. सबसे खराब स्थिति में, कैश सेक्शन का साइज़ सिस्टम इमेज के बराबर हो सकता है. A/B अपडेट के साथ, ब्लॉक को स्टैश करने की ज़रूरत नहीं होती, क्योंकि हमेशा ऐसे पार्टीशन में लिखा जाता है जिसका फ़िलहाल इस्तेमाल नहीं किया जा रहा है. साथ ही, A/B स्ट्रीमिंग के साथ, पूरे ओटीए पैकेज को लागू करने से पहले उसे डाउनलोड करने की ज़रूरत नहीं होती.
रिकवरी
रिकवरी रैम डिस्क अब boot.img
फ़ाइल में मौजूद है. रिकवरी मोड में जाने पर, बूटलोडर skip_initramfs
विकल्प को कर्नेल कमांड लाइन पर नहीं डाल सकता.
A/B अपडेट के अलावा, अन्य अपडेट के लिए रिकवरी पार्टीशन में अपडेट लागू करने वाला कोड होता है. A/B
अपडेट, सामान्य रूप से बूट की गई सिस्टम इमेज में चल रहे update_engine
की मदद से लागू किए जाते हैं.
फ़ैक्ट्री डेटा रीसेट करने और अपडेट पैकेज को साइडलोड करने के लिए, अब भी रिकवरी मोड का इस्तेमाल किया जाता है. इसलिए, इसे "रिकवरी" मोड कहा जाता है. रिकवरी मोड का कोड और डेटा, रैमडिस्क में सामान्य बूट सेक्शन में सेव होता है. सिस्टम इमेज में बूट करने के लिए, बूटलोडर, कर्नेल को रैमडिस्क को स्किप करने के लिए कहता है. ऐसा न करने पर, डिवाइस रिकवरी मोड में बूट होता है. रिकवरी मोड छोटा होता है और इसका ज़्यादातर हिस्सा पहले से ही बूट पार्टिशन में होता है. इसलिए, बूट
पार्टिशन का साइज़ नहीं बढ़ता.
Fstab
A/B-एलिमेंट वाले partition के लिए, slotselect
आर्ग्युमेंट लाइन पर होना चाहिए. उदाहरण के लिए:
<path-to-block-device>/vendor /vendor ext4 ro wait,verify=<path-to-block-device>/metadata,slotselect
किसी भी पार्टीशन का नाम vendor
नहीं होना चाहिए. इसके बजाय, vendor_a
या
vendor_b
पार्टीशन को चुना जाएगा और /vendor
माउंट पॉइंट पर माउंट किया जाएगा.
Kernel स्लॉट के आर्ग्युमेंट
मौजूदा स्लॉट का सफ़िक्स, किसी डिवाइस ट्री (DT) नोड (/firmware/android/slot_suffix
) या androidboot.slot_suffix
कर्नेल कमांड लाइन या bootconfig आर्ग्युमेंट के ज़रिए पास किया जाना चाहिए.
डिफ़ॉल्ट रूप से, fastboot किसी A/B डिवाइस पर मौजूदा स्लॉट को फ़्लैश करता है. अगर अपडेट पैकेज में, मौजूदा स्लॉट के अलावा किसी दूसरे स्लॉट के लिए भी इमेज मौजूद हैं, तो फ़ास्टबूट उन इमेज को भी फ़्लैश करेगा. उपलब्ध विकल्पों में ये शामिल हैं:
-
--slot SLOT
. डिफ़ॉल्ट तरीके को बदलें और उस स्लॉट को फ़्लैश करने के लिए fastboot को निर्देश दें जो आर्ग्युमेंट के तौर पर दिया गया है. -
--set-active [SLOT]
. स्लॉट को 'चालू है' के तौर पर सेट करें. अगर कोई वैकल्पिक आर्ग्युमेंट नहीं दिया गया है, तो मौजूदा स्लॉट को 'चालू है' के तौर पर सेट किया जाता है. fastboot --help
. निर्देशों के बारे में जानकारी पाएं.
अगर बूटलोडर में 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
चलाएं.
ओटीए पैकेज जनरेट करना
ओटीए पैकेज टूल, उन ही कमांड का पालन करते हैं जो A/B डिवाइसों के लिए इस्तेमाल किए जाते हैं. 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
मेक वैरिएबल से कॉन्फ़िगर की जाती है.
उदाहरण के लिए, अगर एक जोड़ी सेक्शन bootloader_a
और
booloader_b
शामिल हैं (_a
और _b
स्लॉट के सफ़िक्स हैं), तो प्रॉडक्ट या बोर्ड के कॉन्फ़िगरेशन में ये बताकर, इन सेक्शन को अपडेट किया जा सकता है:
AB_OTA_PARTITIONS := \ boot \ system \ bootloader
update_engine
से अपडेट किए गए सभी पार्टीशन में, बाकी सिस्टम से बदलाव नहीं किया जाना चाहिए. इंक्रीमेंटल या डेल्टा अपडेट के दौरान, मौजूदा स्लॉट के बाइनरी डेटा का इस्तेमाल, नए स्लॉट में डेटा जनरेट करने के लिए किया जाता है. किसी भी तरह के बदलाव की वजह से, अपडेट की प्रोसेस के दौरान नए स्लॉट डेटा की पुष्टि नहीं हो पाएगी. इसलिए, अपडेट नहीं हो पाएगा.
postinstallation को कॉन्फ़िगर करना
अपडेट किए गए हर पार्टीशन के लिए, पोस्ट-इंस्टॉल चरण को अलग तरीके से कॉन्फ़िगर किया जा सकता है. इसके लिए, की-वैल्यू पेयर के सेट का इस्तेमाल करें. किसी नई इमेज में /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 फ़ाइलों को पहले बूट के दौरान इंस्टॉल करना लेख पढ़ें.