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

कर्नेल की स्थापना
ए/बी सिस्टम अपडेट लागू करने के लिए:
- चेरी निम्नलिखित कर्नेल पैच श्रृंखला चुनें (यदि आवश्यक हो):
- यदि रैमडिस्क के बिना बूट किया जा रहा है और "रिकवरी के रूप में बूट करें" का उपयोग किया जा रहा है, तो चेरीपिक android-review.googlesource.com/#/c/158491/ ।
- रैमडिस्क के बिना डीएम-वेरिटी सेट करने के लिए, चेरीपिक 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
की आवश्यकता है):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
.X509 प्रमाणपत्र का सफल समावेश सिस्टम कीरिंग में सार्वजनिक कुंजी की उपस्थिति को इंगित करता है (हाइलाइट सार्वजनिक कुंजी आईडी को दर्शाता है)। - स्पेस को
#
से बदलें और इसे कर्नेल कमांड लाइन में<public-key-id>
के रूप में पास करें। उदाहरण के लिए,<public-key-id>
के स्थान परAndroid:#7e4333f9bba00adfe0ede979e28ed1920492b40f
पास करें।
-
बिल्ड वेरिएबल सेट करना
ए/बी-सक्षम बूटलोडर्स को निम्नलिखित बिल्ड वेरिएबल मानदंडों को पूरा करना होगा:
ए/बी लक्ष्य के लिए परिभाषित होना चाहिए |
/device/google/marlin/+/android-7.1.0_r1/device-common.mk देखें। आप वैकल्पिक रूप से Compiling में वर्णित पोस्ट-इंस्टॉल (लेकिन प्री-रिबूट) dex2oat चरण का संचालन कर सकते हैं। |
---|---|
ए/बी लक्ष्य के लिए पुरजोर अनुशंसा की जाती है |
|
A/B लक्ष्य के लिए परिभाषित नहीं किया जा सकता |
|
डिबग बिल्ड के लिए वैकल्पिक | PRODUCT_PACKAGES_DEBUG += update_engine_client |
विभाजन सेट करना (स्लॉट)
ए/बी उपकरणों को पुनर्प्राप्ति विभाजन या कैश विभाजन की आवश्यकता नहीं है क्योंकि एंड्रॉइड अब इन विभाजनों का उपयोग नहीं करता है। डेटा विभाजन अब डाउनलोड किए गए ओटीए पैकेज के लिए उपयोग किया जाता है, और पुनर्प्राप्ति छवि कोड बूट विभाजन पर है। ए/बी-एड वाले सभी विभाजनों को इस प्रकार नामित किया जाना चाहिए (स्लॉट को हमेशा a
, b
, आदि नाम दिया जाता है): boot_a
, boot_b
, system_a
, system_b
, vendor_a
, vendor_b
।
कैश
गैर-ए/बी अपडेट के लिए, कैश विभाजन का उपयोग डाउनलोड किए गए ओटीए पैकेजों को संग्रहीत करने और अपडेट लागू करते समय अस्थायी रूप से ब्लॉक को छिपाने के लिए किया गया था। कैश विभाजन को आकार देने का कोई अच्छा तरीका कभी नहीं था: इसे कितना बड़ा करना होगा यह इस पर निर्भर करता है कि आप कौन से अपडेट लागू करना चाहते हैं। सबसे खराब स्थिति सिस्टम छवि जितना बड़ा कैश विभाजन होगा। ए/बी अपडेट के साथ ब्लॉकों को छिपाने की कोई आवश्यकता नहीं है (क्योंकि आप हमेशा उस विभाजन पर लिख रहे हैं जो वर्तमान में उपयोग नहीं किया जाता है) और ए/बी स्ट्रीमिंग के साथ इसे लागू करने से पहले पूरे ओटीए पैकेज को डाउनलोड करने की कोई आवश्यकता नहीं है।
वसूली
पुनर्प्राप्ति RAM डिस्क अब boot.img
फ़ाइल में समाहित है। पुनर्प्राप्ति में जाने पर, बूटलोडर कर्नेल कमांड लाइन पर skip_initramfs
विकल्प नहीं डाल सकता है।
गैर-ए/बी अपडेट के लिए, पुनर्प्राप्ति विभाजन में अपडेट लागू करने के लिए उपयोग किया जाने वाला कोड होता है। ए/बी अपडेट नियमित बूट किए गए सिस्टम छवि में चल रहे update_engine
द्वारा लागू किए जाते हैं। फ़ैक्टरी डेटा रीसेट और अपडेट पैकेजों की साइडलोडिंग को लागू करने के लिए अभी भी एक रिकवरी मोड का उपयोग किया जाता है (जहां से "रिकवरी" नाम आया है)। पुनर्प्राप्ति मोड के लिए कोड और डेटा रैमडिस्क में नियमित बूट विभाजन में संग्रहीत किया जाता है; सिस्टम छवि में बूट करने के लिए, बूटलोडर कर्नेल को रैमडिस्क को छोड़ने के लिए कहता है (अन्यथा डिवाइस पुनर्प्राप्ति मोड में बूट हो जाता है। पुनर्प्राप्ति मोड छोटा है (और इसका अधिकांश भाग पहले से ही बूट विभाजन पर था), इसलिए बूट विभाजन आकार में नहीं बढ़ता है।
Fstab
ए/बी-एड विभाजन के लिए slotselect
तर्क लाइन पर होना चाहिए । उदाहरण के लिए:
<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
कर्नेल कमांड लाइन या बूटकॉन्फिग तर्क के माध्यम से पारित किया जाना चाहिए।
डिफ़ॉल्ट रूप से, फास्टबूट ए/बी डिवाइस पर वर्तमान स्लॉट को फ्लैश करता है। यदि अपडेट पैकेज में अन्य, गैर-वर्तमान स्लॉट के लिए छवियां भी हैं, तो फास्टबूट उन छवियों को भी फ्लैश करता है। उपलब्ध विकल्पों में शामिल हैं:
-
--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
। दिए गए स्लॉट को बूट करने का प्रयास करने के लिए शेष पुनर्प्रयासों की संख्या।
सभी वेरिएबल देखने के लिए fastboot getvar all
चलाएँ।
ओटीए पैकेज तैयार करना
ओटीए पैकेज टूल गैर-ए/बी उपकरणों के लिए कमांड के समान कमांड का पालन करते हैं। A/B लक्ष्य के लिए बिल्ड वेरिएबल्स को परिभाषित करके target_files.zip
फ़ाइल उत्पन्न की जानी चाहिए। ओटीए पैकेज टूल स्वचालित रूप से ए/बी अपडेटर के प्रारूप में पैकेजों की पहचान करते हैं और उत्पन्न करते हैं।
उदाहरण:
- पूर्ण ओटीए उत्पन्न करने के लिए:
./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
एक ही डिस्क में परिभाषित ए/बी विभाजन की किसी भी जोड़ी को अपडेट कर सकता है। विभाजनों की एक जोड़ी में एक सामान्य उपसर्ग (जैसे system
या boot
) और प्रति-स्लॉट प्रत्यय (जैसे _a
) होता है। विभाजन की सूची जिसके लिए पेलोड जनरेटर एक अद्यतन को परिभाषित करता है, 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
संकलन
नई सिस्टम छवि के साथ रीबूट से पहले एप्लिकेशन को पृष्ठभूमि में संकलित किया जा सकता है। पृष्ठभूमि में ऐप्स संकलित करने के लिए, उत्पाद के डिवाइस कॉन्फ़िगरेशन (उत्पाद के डिवाइस.एमके में) में निम्नलिखित जोड़ें:
- यह सुनिश्चित करने के लिए कि संकलन स्क्रिप्ट और बायनेरिज़ संकलित हैं और सिस्टम छवि में शामिल हैं, बिल्ड में मूल घटकों को शामिल करें।
# 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 फ़ाइलों की पहली बूट स्थापना देखें।