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

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

झंडे बनाएं

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

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

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

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

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

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

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

PRODUCT_VIRTUAL_AB_COMPRESSION_METHOD := lz4

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

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

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

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

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

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

उपयोक्तास्थान विलय

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

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

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

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

बूट नियंत्रण HAL OTA क्लाइंट को बूट स्लॉट को नियंत्रित करने के लिए एक इंटरफ़ेस प्रदान करता है। वर्चुअल ए/बी को बूट नियंत्रण एचएएल के एक छोटे संस्करण के उन्नयन की आवश्यकता होती है क्योंकि फ्लैशिंग/फ़ैक्टरी रीसेट के दौरान बूटलोडर की सुरक्षा सुनिश्चित करने के लिए अतिरिक्त एपीआई की आवश्यकता होती है। HAL परिभाषा के नवीनतम संस्करण के लिए IBootControl.hal और types.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
}

Fstab परिवर्तन

मेटाडेटा विभाजन की अखंडता बूट प्रक्रिया के लिए आवश्यक है, विशेष रूप से ओटीए अद्यतन लागू होने के ठीक बाद। इसलिए, मेटाडेटा विभाजन को 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 लक्ष्य में अतिप्रवाह स्थिति बिट। एंड्रॉइड 9 और उसके बाद के संस्करण के साथ लॉन्च होने वाले सभी उपकरणों में पहले से ही कर्नेल संस्करण 4.4 या बाद का होना चाहिए।

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

BOARD_GENERIC_RAMDISK_KERNEL_MODULES_LOAD := dm-user.ko

एंड्रॉइड 11 पर अपग्रेड करने वाले उपकरणों पर रेट्रोफ़िट

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

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

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

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

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

अपडेट के मर्ज चरण के दौरान, /data एंड्रॉइड ओएस का एकमात्र संपूर्ण उदाहरण रखता है। एक बार माइग्रेशन शुरू होने पर, मूल 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 या wipe - metadata , userdata , या बूट नियंत्रण HAL के लिए मर्ज स्थिति रखने वाले विभाजन को मिटाने या मिटाने erase स्नैपशॉट मर्ज स्थिति wipe जाँच होनी चाहिए। यदि स्थिति MERGING या SNAPSHOTTED है, तो डिवाइस को ऑपरेशन रोक देना चाहिए।
  • set_active - एक set_active कमांड जो सक्रिय स्लॉट को बदलता है, उसे स्नैपशॉट मर्ज स्थिति की जांच करनी चाहिए। यदि स्थिति MERGING है, तो डिवाइस को ऑपरेशन रद्द कर देना चाहिए। स्लॉट को SNAPSHOTTED स्थिति में सुरक्षित रूप से बदला जा सकता है।

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

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

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

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

ओटीए संपीड़न विधियाँ

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

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 सेकंड

Pixel 6 Pro पर पूर्ण OTA

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