ए/बी अपडेट लागू करें

ओईएम और एसओसी विक्रेता जो ए/बी सिस्टम अपडेट लागू करना चाहते हैं, उन्हें यह सुनिश्चित करना होगा कि उनका बूटलोडर बूट_कंट्रोल एचएएल लागू करता है और कर्नेल को सही पैरामीटर पास करता है।

बूट नियंत्रण एचएएल लागू करें

ए/बी-सक्षम बूटलोडर्स को hardware/libhardware/include/hardware/boot_control.h पर boot_control एचएएल लागू करना होगा। आप system/extras/bootctl उपयोगिता और system/extras/tests/bootloader/ का उपयोग करके कार्यान्वयन का परीक्षण कर सकते हैं।

आपको नीचे दिखाई गई राज्य मशीन को भी लागू करना होगा:

चित्र 1. बूटलोडर स्थिति मशीन

कर्नेल सेट करें

ए/बी सिस्टम अपडेट लागू करने के लिए:

  1. चेरी निम्नलिखित कर्नेल पैच श्रृंखला चुनें (यदि आवश्यक हो):
  2. सुनिश्चित करें कि कर्नेल कमांड लाइन तर्कों में निम्नलिखित अतिरिक्त तर्क शामिल हैं:
    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> कुंजी-आईडी> मान सार्वजनिक कुंजी की आईडी है जिसका उपयोग सत्यापन तालिका हस्ताक्षर को सत्यापित करने के लिए किया जाता है (विवरण के लिए, डीएम-वेरिटी देखें) .
  3. सिस्टम कीरिंग में सार्वजनिक कुंजी वाला .X509 प्रमाणपत्र जोड़ें:
    1. .der प्रारूप में स्वरूपित .X509 प्रमाणपत्र को kernel निर्देशिका के मूल में कॉपी करें। यदि .X509 प्रमाणपत्र को .pem फ़ाइल के रूप में स्वरूपित किया गया है, तो .pem से .der प्रारूप में कनवर्ट करने के लिए निम्नलिखित openssl कमांड का उपयोग करें:
      openssl x509 -in <x509-pem-certificate> -outform der -out <x509-der-certificate>
    2. सिस्टम कीरिंग के भाग के रूप में प्रमाणपत्र को शामिल करने के लिए 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 प्रमाणपत्र का सफल समावेश सिस्टम कीरिंग में सार्वजनिक कुंजी की उपस्थिति को इंगित करता है (हाइलाइट सार्वजनिक कुंजी आईडी को दर्शाता है)।
    3. स्पेस को # से बदलें और इसे कर्नेल कमांड लाइन में <public-key-id> के रूप में पास करें। उदाहरण के लिए, <public-key-id> के स्थान पर Android:#7e4333f9bba00adfe0ede979e28ed1920492b40f पास करें।

बिल्ड वेरिएबल सेट करें

ए/बी-सक्षम बूटलोडर्स को निम्नलिखित बिल्ड वेरिएबल मानदंडों को पूरा करना होगा:

ए/बी लक्ष्य के लिए परिभाषित होना चाहिए
  • AB_OTA_UPDATER := true
  • AB_OTA_PARTITIONS := \
    boot \
    system \
    vendor
    और अन्य विभाजन update_engine (रेडियो, बूटलोडर, आदि) के माध्यम से अद्यतन किए गए
  • PRODUCT_PACKAGES += \
    update_engine \
    update_verifier
उदाहरण के लिए, /device/google/marlin/+/android-7.1.0_r1/device-common.mk देखें। आप वैकल्पिक रूप से Compiling में वर्णित पोस्ट-इंस्टॉल (लेकिन प्री-रिबूट) dex2oat चरण का संचालन कर सकते हैं।
ए/बी लक्ष्य के लिए पुरजोर अनुशंसा की जाती है
  • TARGET_NO_RECOVERY := true
  • BOARD_USES_RECOVERY_AS_BOOT := true
  • BOARD_RECOVERYIMAGE_PARTITION_SIZE को परिभाषित न करें
A/B लक्ष्य के लिए परिभाषित नहीं किया जा सकता
  • BOARD_CACHEIMAGE_PARTITION_SIZE
  • BOARD_CACHEIMAGE_FILE_SYSTEM_TYPE
डिबग बिल्ड के लिए वैकल्पिक 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

ऐप्स संकलित करें

नई सिस्टम छवि के साथ रीबूट से पहले ऐप्स को पृष्ठभूमि में संकलित किया जा सकता है। पृष्ठभूमि में ऐप्स संकलित करने के लिए, उत्पाद के डिवाइस कॉन्फ़िगरेशन (उत्पाद के डिवाइस.एमके में) में निम्नलिखित जोड़ें:

  1. यह सुनिश्चित करने के लिए कि संकलन स्क्रिप्ट और बायनेरिज़ संकलित हैं और सिस्टम छवि में शामिल हैं, बिल्ड में मूल घटकों को शामिल करें।
      # A/B OTA dexopt package
      PRODUCT_PACKAGES += otapreopt_script
    
  2. संकलन स्क्रिप्ट को 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 फ़ाइलों की पहली बूट स्थापना देखें।