वर्चुअल ए/बी लागू करना

किसी नए डिवाइस पर वर्चुअल A/B लागू करने के लिए, या लॉन्च किए गए डिवाइस को फिर से फिट करने के लिए, आपको डिवाइस-विशिष्ट कोड में परिवर्तन करना होगा।

झंडे बनाएँ

डिवाइस जो वर्चुअल ए/बी का उपयोग करते हैं उन्हें ए/बी डिवाइस के रूप में कॉन्फ़िगर किया जाना चाहिए और गतिशील विभाजन के साथ लॉन्च होना चाहिए।

वर्चुअल A/B के साथ लॉन्च होने वाले उपकरणों के लिए, उन्हें वर्चुअल A/B डिवाइस बेस कॉन्फ़िगरेशन इनहेरिट करने के लिए सेट करें:

$(call inherit-product, \
    $(SRC_TARGET_DIR)/product/virtual_ab_ota.mk)

वर्चुअल A/B के साथ लॉन्च होने वाले उपकरणों को BOARD_SUPER_PARTITION_SIZE के लिए केवल आधे बोर्ड आकार की आवश्यकता है क्योंकि B स्लॉट अब सुपर में नहीं हैं। यानी, BOARD_SUPER_PARTITION_SIZE योग (अपडेट समूहों का आकार) + ओवरहेड से अधिक या बराबर होना चाहिए, जो बदले में योग (विभाजन का आकार) + ओवरहेड से अधिक या बराबर होना चाहिए।

Android 13 और उच्चतर के लिए, वर्चुअल A/B के साथ कंप्रेस्ड स्नैपशॉट को सक्षम करने के लिए, निम्नलिखित बेस कॉन्फ़िगरेशन इनहेरिट करें:

$(call inherit-product, $(SRC_TARGET_DIR)/product/generic_ramdisk.mk)
$(call inherit-product, \
    $(SRC_TARGET_DIR)/product/virtual_ab_ota/android_t_baseline.mk)

यह नो-ऑप कम्प्रेशन विधि का उपयोग करते हुए वर्चुअल A/B के साथ यूजरस्पेस स्नैपशॉट को सक्षम करता है। फिर आप संपीड़न विधि को समर्थित विधियों में से एक, gz और brotli में कॉन्फ़िगर कर सकते हैं।

PRODUCT_VIRTUAL_AB_COMPRESSION_METHOD := gz

Android 12 के लिए, वर्चुअल A/B के साथ कंप्रेस्ड स्नैपशॉट को सक्षम करने के लिए, निम्नलिखित बेस कॉन्फ़िगरेशन इनहेरिट करें:

$(call inherit-product, $(SRC_TARGET_DIR)/product/generic_ramdisk.mk)
$(call inherit-product, \
    $(SRC_TARGET_DIR)/product/virtual_ab_ota/compression.mk)

एक्सओआर संपीड़न

एंड्रॉइड 13 और उच्चतर में अपग्रेड करने वाले उपकरणों के लिए, एक्सओआर संपीड़न सुविधा डिफ़ॉल्ट रूप से सक्षम नहीं है। XOR कम्प्रेशन को सक्षम करने के लिए, निम्न को डिवाइस की .mk फ़ाइल में जोड़ें।

PRODUCT_VENDOR_PROPERTIES += ro.virtual_ab.compression.xor.enabled=true

android_t_baseline.mk से इनहेरिट करने वाले उपकरणों के लिए XOR संपीड़न डिफ़ॉल्ट रूप से सक्षम है।

यूजरस्पेस विलय

Android 13 और बाद के संस्करण में अपग्रेड करने वाले उपकरणों के लिए, डिवाइस-मैपर लेयरिंग में वर्णित यूजरस्पेस मर्ज प्रक्रिया डिफ़ॉल्ट रूप से सक्षम नहीं है। यूजरस्पेस मर्ज को सक्षम करने के लिए, निम्न पंक्ति को डिवाइस की .mk फ़ाइल में जोड़ें:

PRODUCT_VENDOR_PROPERTIES += ro.virtual_ab.userspace.snapshots.enabled=true

उपयोक्तास्थान विलय 13 और उच्चतर के साथ लॉन्च होने वाले उपकरणों पर डिफ़ॉल्ट रूप से सक्षम है।

बूट नियंत्रण एचएएल

बूट नियंत्रण HAL बूट स्लॉट को नियंत्रित करने के लिए OTA क्लाइंट के लिए एक इंटरफ़ेस प्रदान करता है। वर्चुअल ए/बी को बूट कंट्रोल एचएएल के मामूली संस्करण के उन्नयन की आवश्यकता है क्योंकि फ्लैशिंग/फैक्टरी रीसेट के दौरान बूटलोडर को सुरक्षित रखने के लिए अतिरिक्त एपीआई की आवश्यकता होती है। HAL परिभाषा के नवीनतम संस्करण के लिए IBootControl.hal और type.hal देखें।

// hardware/interfaces/boot/1.1/types.hal
enum MergeStatus : uint8_t {
    NONE, UNKNOWN, SNAPSHOTTED, MERGING, CANCELLED };

// hardware/interfaces/boot/1.1/IBootControl.hal
package android.hardware.boot@1.1;
interface IBootControl extends @1.0::IBootControl {
    setSnapshotMergeStatus(MergeStatus status)
        generates (bool success);
    getSnapshotMergeStatus()
        generates (MergeStatus status);
}
// Recommended implementation

Return<bool> BootControl::setSnapshotMergeStatus(MergeStatus v) {
    // Write value to persistent storage
    // e.g. misc partition (using libbootloader_message)
    // bootloader rejects wipe when status is SNAPSHOTTED
    // or MERGING
}

फस्टैब बदल जाता है

बूट प्रक्रिया के लिए मेटाडेटा विभाजन की अखंडता आवश्यक है, विशेष रूप से ओटीए अपडेट लागू होने के ठीक बाद। इसलिए, मेटाडेटा विभाजन को first_stage_init आरोहित करने से पहले जांचना चाहिए। यह सुनिश्चित करने के लिए, /metadata के लिए प्रविष्टि में check fs_mgr फ़्लैग जोड़ें। निम्नलिखित उदाहरण प्रदान करता है:

/dev/block/by-name/metadata /metadata ext4 noatime,nosuid,nodev,discard,sync wait,formattable,first_stage_mount,check

कर्नेल आवश्यकताएँ

स्नैपशॉटिंग सक्षम करने के लिए, CONFIG_DM_SNAPSHOT को true पर सेट करें।

F2FS का उपयोग करने वाले उपकरणों के लिए, f2fs शामिल करें: फ़ाइल पिनिंग को ठीक करने के लिए उपयोगकर्ता कर्नेल पैच को FS_NOCOW_FL फ़्लैग निर्यात करेंF2fs शामिल करें: संरेखित पिन की गई फ़ाइल कर्नेल पैच का भी समर्थन करें

वर्चुअल ए/बी कर्नेल संस्करण 4.3 में जोड़ी गई सुविधाओं पर निर्भर करता है: snapshot और snapshot-merge लक्ष्यों में अतिप्रवाह स्थिति बिट। Android 9 और बाद के संस्करण के साथ लॉन्च होने वाले सभी उपकरणों में पहले से ही कर्नेल संस्करण 4.4 या बाद का संस्करण होना चाहिए।

कंप्रेस्ड स्नैपशॉट को सक्षम करने के लिए, न्यूनतम समर्थित कर्नेल संस्करण 4.19 है। CONFIG_DM_USER=m या CONFIG_DM_USER=y सेट करें। यदि पूर्व (एक मॉड्यूल) का उपयोग कर रहे हैं, तो मॉड्यूल को पहले चरण के रैमडिस्क में लोड किया जाना चाहिए। इसे डिवाइस मेकफ़ाइल में निम्न पंक्ति जोड़कर प्राप्त किया जा सकता है:

BOARD_GENERIC_RAMDISK_KERNEL_MODULES_LOAD := dm-user.ko

Android 11 में अपग्रेड करने वाले उपकरणों पर रेट्रोफिटिंग

एंड्रॉइड 11 में अपग्रेड करते समय, डायनेमिक पार्टीशन के साथ लॉन्च किए गए डिवाइस वैकल्पिक रूप से वर्चुअल ए/बी को फिर से फिट कर सकते हैं। कुछ मामूली अंतरों के साथ, अपडेट प्रक्रिया अधिकांशत: वर्चुअल A/B के साथ लॉन्च होने वाले उपकरणों के समान ही है:

  • COW फ़ाइलों का स्थान - लॉन्च उपकरणों के लिए, OTA क्लाइंट /data में स्थान का उपयोग करने से पहले सुपर विभाजन में सभी उपलब्ध खाली स्थान का उपयोग करता है। रेट्रोफिट उपकरणों के लिए, सुपर पार्टीशन में हमेशा पर्याप्त जगह होती है ताकि COW फ़ाइल कभी भी /data पर न बने।

  • बिल्ड-टाइम फ़ीचर फ़्लैग — वर्चुअल A/B को फिर से फ़िट करने वाले उपकरणों के लिए, PRODUCT_VIRTUAL_AB_OTA और PRODUCT_VIRTUAL_AB_OTA_RETROFIT दोनों को true पर सेट किया गया है, जैसा कि नीचे दिखाया गया है:

    (call inherit-product, \
        (SRC_TARGET_DIR)/product/virtual_ab_ota_retrofit.mk)
    
  • सुपर पार्टीशन आकार — वर्चुअल A/B के साथ लॉन्च होने वाले डिवाइस BOARD_SUPER_PARTITION_SIZE आधे में काट सकते हैं क्योंकि B स्लॉट सुपर पार्टीशन में नहीं हैं। वर्चुअल ए/बी को रेट्रोफिट करने वाले उपकरण पुराने सुपर विभाजन आकार को बनाए रखते हैं, इसलिए BOARD_SUPER_PARTITION_SIZE 2 * योग (अपडेट समूहों का आकार) + ओवरहेड से अधिक या बराबर है, जो बदले में 2 * योग (विभाजन का आकार) से अधिक या बराबर है। + उपरि

बूटलोडर बदलता है

किसी अद्यतन के मर्ज चरण के दौरान, /data Android OS का एकमात्र संपूर्ण उदाहरण रखता है। माइग्रेशन प्रारंभ होने के बाद, मूल system , vendor , और product विभाजन तब तक अपूर्ण रहते हैं जब तक कि प्रतिलिपि समाप्त नहीं हो जाती। यदि डिवाइस को इस प्रक्रिया के दौरान फ़ैक्टरी-रीसेट किया जाता है, या तो पुनर्प्राप्ति द्वारा या सिस्टम सेटिंग्स संवाद के माध्यम से, तो डिवाइस अनबूटेबल होगा।

/data मिटाने से पहले, डिवाइस की स्थिति के आधार पर रिकवरी या रोलबैक में मर्ज को पूरा करें:

  • यदि नया बिल्ड पहले सफलतापूर्वक बूट हो गया है, तो माइग्रेशन समाप्त करें।
  • अन्यथा, पुराने स्लॉट में रोलबैक करें:
    • गतिशील विभाजन के लिए, पिछली स्थिति में वापस रोल करें।
    • स्थिर विभाजन के लिए, सक्रिय स्लॉट को पुराने स्लॉट पर सेट करें।

डिवाइस अनलॉक होने पर बूटलोडर और fastbootd दोनों /data विभाजन को मिटा सकते हैं। जबकि fastbootd माइग्रेशन को पूरा करने के लिए बाध्य कर सकता है, बूटलोडर नहीं कर सकता। बूटलोडर यह नहीं जानता है कि विलय प्रगति पर है या नहीं, या /data में कौन से ब्लॉक ओएस विभाजन का गठन करते हैं। डिवाइस को निम्न कार्य करके उपयोगकर्ता को अनजाने में डिवाइस को निष्क्रिय (ब्रिकिंग) करने से रोकना चाहिए:

  1. बूट नियंत्रण HAL लागू करें ताकि बूटलोडर setSnapshotMergeStatus() विधि द्वारा निर्धारित मान को पढ़ सके।
  2. यदि मर्ज की स्थिति MERGING है, या यदि मर्ज की स्थिति SNAPSHOTTED है और स्लॉट नए अपडेट किए गए स्लॉट में बदल गया है, तो बूटलोडर में userdata , metadata , या मर्ज स्थिति को संग्रहीत करने वाले विभाजन को मिटाने के अनुरोध को अस्वीकार कर दिया जाना चाहिए।
  3. fastboot snapshot-update cancel कमांड को लागू करें ताकि उपयोगकर्ता बूटलोडर को संकेत दे सकें कि वे इस सुरक्षा तंत्र को बायपास करना चाहते हैं।
  4. संपूर्ण डिवाइस को फ्लैश करते समय fastboot snapshot-update cancel करने के लिए कस्टम फ्लैशिंग टूल या स्क्रिप्ट को संशोधित करें। यह जारी करने के लिए सुरक्षित है क्योंकि पूरे डिवाइस को फ्लैश करने से ओटीए हट जाता है। टूलिंग इस कमांड को रनटाइम पर fastboot getvar snapshot-update-status लागू करके पता लगा सकता है। यह आदेश त्रुटि स्थितियों के बीच अंतर करने में मदद करता है।

उदाहरण

struct VirtualAbState {
    uint8_t StructVersion;
    uint8_t MergeStatus;
    uint8_t SourceSlot;
};

bool ShouldPreventUserdataWipe() {
    VirtualAbState state;
    if (!ReadVirtualAbState(&state)) ...
    return state.MergeStatus == MergeStatus::MERGING ||
           (state.MergeStatus == MergeStatus::SNAPSHOTTED &&
            state.SourceSlot != CurrentSlot()));
}

फास्टबूट टूलींग परिवर्तन

एंड्रॉइड 11 फास्टबूट प्रोटोकॉल में निम्नलिखित बदलाव करता है:

  • getvar snapshot-update-status - वह मान लौटाता है जो बूट नियंत्रण HAL ने बूटलोडर को संप्रेषित किया था:
    • यदि स्थिति MERGING है, तो बूटलोडर को merging वापस करना चाहिए।
    • यदि स्थिति SNAPSHOTTED है, तो बूटलोडर को snapshotted वापस करना चाहिए।
    • अन्यथा, बूटलोडर को none लौटाना चाहिए।
  • snapshot-update merge — एक मर्ज ऑपरेशन को पूरा करता है, यदि आवश्यक हो तो रिकवरी/फास्टबूट में बूटिंग करता है। यह कमांड केवल तभी मान्य है जब snapshot-update-status merging है, और केवल फास्टबूट में समर्थित है।
  • snapshot-update cancel — बूट नियंत्रण HAL की मर्ज स्थिति को CANCELLED पर सेट करता है। डिवाइस लॉक होने पर यह आदेश अमान्य है।
  • erase या wipemetadata , userdata को erase या wipe , या बूट नियंत्रण के लिए मर्ज स्थिति रखने वाला विभाजन HAL को स्नैपशॉट मर्ज स्थिति की जांच करनी चाहिए। अगर स्थिति MERGING या SNAPSHOTTED है, तो डिवाइस को ऑपरेशन रद्द करना चाहिए।
  • set_active — एक set_active कमांड जो सक्रिय स्लॉट को बदलता है, उसे स्नैपशॉट मर्ज स्थिति की जाँच करनी चाहिए। अगर स्थिति MERGING है, तो डिवाइस को ऑपरेशन रद्द करना चाहिए। SNAPSHOTTED स्थिति में स्लॉट को सुरक्षित रूप से बदला जा सकता है।

इन परिवर्तनों को डिवाइस को गलती से बूट करने योग्य बनाने से रोकने के लिए डिज़ाइन किया गया है, लेकिन वे स्वचालित टूलींग के लिए विघटनकारी हो सकते हैं। जब सभी विभाजनों को फ्लैश करने के घटक के रूप में कमांड का उपयोग किया जाता है, जैसे कि fastboot flashall चलाना, निम्नलिखित प्रवाह का उपयोग करने की अनुशंसा की जाती है:

  1. क्वेरी getvar snapshot-update-status
  2. यदि merging या snapshotted , तो snapshot-update cancel जारी करें।
  3. झिलमिलाते कदमों से आगे बढ़ो।

भंडारण आवश्यकताओं को कम करना

ऐसे डिवाइस जिनके पास सुपर में आवंटित पूर्ण ए/बी स्टोरेज नहीं है, और आवश्यकता के अनुसार /data उपयोग करने की उम्मीद कर रहे हैं, ब्लॉक मैपिंग टूल का उपयोग करने के लिए दृढ़ता से अनुशंसा की जाती है। ब्लॉक मैपिंग टूल स्नैपशॉट में अनावश्यक लेखन को कम करते हुए ब्लॉक आवंटन को बिल्ड के बीच संगत रखता है। इसे Reducing OTA Size के तहत प्रलेखित किया गया है।

ओटीए संपीड़न के तरीके

विभिन्न प्रदर्शन मेट्रिक्स के लिए ओटा पैकेज को ट्यून किया जा सकता है। एंड्रॉइड वर्तमान में कुछ समर्थित संपीड़न विधियों ( gz , lz4 , और none ) प्रदान करता है जिनमें इंस्टॉल समय, गाय स्थान उपयोग, बूट समय और स्नैपशॉट मर्ज समय के बीच ट्रेडऑफ़ हैं। संपीड़न के साथ वर्चुअल ab के लिए सक्षम किया गया डिफ़ॉल्ट विकल्प gz compression method है। (नोट: संपीड़न विधियों के बीच सापेक्ष प्रदर्शन सीपीयू की गति और भंडारण प्रवाह के आधार पर भिन्न होता है जो डिवाइस के आधार पर बदल सकता है। नीचे उत्पन्न सभी ओटीए पैकेज पोस्टइंस्टॉल अक्षम के साथ हैं, जो बूट समय को थोड़ा धीमा कर देगा। पूर्ण ओटीए का कुल गतिशील विभाजन आकार संपीड़न के बिना 4.81GB है)

1. Pixel 6 Pro पर इंक्रीमेंटल OTA

स्थापना के बाद के चरण के बिना समय स्थापित करें गाय स्थान उपयोग ओटीए बूट समय पोस्ट करें स्नैपशॉट मर्ज समय
gz 24 मि 1.18 जीबी 40.2 सेकंड 45.5 सेकंड
lz4 13 मि 1.49 जीबी 37.4 सेकंड 37.1 सेकंड
कोई नहीं 13 मि 2.90 जीबी 37.6 सेकंड 40.7 सेकंड

2. पिक्सेल 6 प्रो पर पूर्ण ओटीए

स्थापना के बाद के चरण के बिना समय स्थापित करें गाय स्थान उपयोग ओटीए बूट समय पोस्ट करें स्नैपशॉट मर्ज समय
gz 23 मि 2.79 जीबी 24.9 सेकंड 41.7 सेकंड
lz4 12 मि 3.46 जीबी 20.0 सेकंड 25.3 सेकंड
कोई नहीं दस मिनट 4.85 जीबी 20.6 सेकंड 29.8 सेकंड