फ़ास्टबूट को यूज़रस्पेस में ले जाना

Fastboot, बूटलोडर मॉड्यूल और मोड का नाम है. Android 10 और इसके बाद के वर्शन में, साइज़ बदलने वाले पार्टीशन की सुविधा काम करती है. इसके लिए, फ़ास्टबूट को बूटलोडर से यूज़रस्पेस में ले जाया जाता है. इस रिलोकेशन की मदद से, फ़्लैशिंग कोड को ऐसी जगह पर ले जाया जा सकता है जहां उसे आसानी से मैनेज और टेस्ट किया जा सकता है. साथ ही, फ़ास्टबूट के सिर्फ़ वेंडर के हिसाब से बनाए गए हिस्सों को हार्डवेयर ऐब्स्ट्रैक्शन लेयर (एचएएल) के ज़रिए लागू किया जा सकता है. इसके अलावा, Android 12 और इसके बाद के वर्शन में, फ़ास्टबूट कमांड का इस्तेमाल करके रैमडिस्क फ़्लैश किए जा सकते हैं.

फ़ास्टबूट और रिकवरी को एक साथ इस्तेमाल करने की सुविधा

उपयोगकर्ता स्पेस फ़ास्टबूट और रिकवरी एक जैसे होते हैं. इसलिए, इन्हें एक ही पार्टीशन या बाइनरी में मर्ज किया जा सकता है. इससे कई फ़ायदे मिलते हैं. जैसे, कम जगह का इस्तेमाल, कुल मिलाकर कम पार्टीशन, और फ़ास्टबूट और रिकवरी के लिए एक ही कर्नल और लाइब्रेरी का इस्तेमाल.

Fastbootd, उपयोगकर्ताओं के लिए उपलब्ध डेमॉन और मोड का नाम है. fastbootd की सुविधा के लिए, बूटलोडर को fastbootd का नया बूट कंट्रोल ब्लॉक (बीसीबी) कमांड लागू करना होगा.boot-fastboot fastbootd मोड में जाने के लिए, बूटलोडर BCB मैसेज के कमांड फ़ील्ड में boot-fastboot लिखता है. साथ ही, BCB के recovery फ़ील्ड में कोई बदलाव नहीं करता है, ताकि बीच में रुक गई रिकवरी की किसी भी टास्क को फिर से शुरू किया जा सके. status, stage, और reserved फ़ील्ड में भी कोई बदलाव नहीं होता. बीसीबी कमांड फ़ील्ड में boot-fastboot दिखने पर, बूटलोडर रिकवरी इमेज को लोड करता है और बूट करता है. इसके बाद, रिकवरी BCB मैसेज को पार्स करती है और fastbootd मोड पर स्विच हो जाती है.

ADB कमांड

इस सेक्शन में, fastbootd को इंटिग्रेट करने के लिए adb कमांड के बारे में बताया गया है. सिस्टम या रिकवरी के ज़रिए कमांड को लागू करने पर, अलग-अलग नतीजे मिलते हैं.

निर्देश ब्यौरा
reboot fastboot
  • यह डिवाइस को fastbootd (सिस्टम) मोड में रीबूट करता है.
  • यह सीधे तौर पर fastbootd में बूट होता है. इसके लिए, रीबूट (रिकवरी) करने की ज़रूरत नहीं होती.

फ़ास्टबूट निर्देश

इस सेक्शन में, fastbootd को इंटिग्रेट करने के लिए फ़ास्टबूट कमांड के बारे में बताया गया है. इसमें लॉजिकल पार्टीशन को फ़्लैश करने और मैनेज करने के लिए नई कमांड भी शामिल हैं. कुछ कमांड के नतीजे अलग-अलग होते हैं. ऐसा इस बात पर निर्भर करता है कि उन्हें बूटलोडर ने लागू किया है या fastbootd ने.

निर्देश ब्यौरा
reboot recovery
  • यह डिवाइस को रिकवरी (बूटलोडर) मोड में रीबूट करता है.
  • यह डिवाइस को रीबूट किए बिना सीधे रिकवरी मोड में ले जाता है (fastbootd).
reboot fastboot यह डिवाइस को fastbootd मोड में रीबूट करता है.
getvar is-userspace
  • इसमें रिस्पॉन्स के तौर पर yes (fastbootd) मिलता है.
  • यह no (बूटलोडर) दिखाता है.
getvar is-logical:<partition> अगर दिया गया पार्टिशन लॉजिकल है, तो रिस्पॉन्स के तौर पर yes मिलता है. अगर पार्टिशन लॉजिकल नहीं है, तो ऐसा रिस्पॉन्स नहीं मिलता.no लॉजिकल पार्टीशन, यहां दी गई सभी कमांड के साथ काम करते हैं.
getvar super-partition-name सुपर पार्टीशन का नाम दिखाता है. अगर सुपर पार्टिशन एक A/B पार्टिशन है, तो नाम में मौजूदा स्लॉट का सफ़िक्स शामिल होता है. हालांकि, ऐसा आम तौर पर नहीं होता है.
create-logical-partition <partition> <size> यह दिए गए नाम और साइज़ के साथ एक लॉजिकल पार्टिशन बनाता है. यह नाम, किसी लॉजिकल पार्टिशन के तौर पर पहले से मौजूद नहीं होना चाहिए.
delete-logical-partition <partition> यह दिए गए लॉजिकल पार्टिशन को मिटा देता है. इस वजह से, इसका डेटा भी मिट जाता है.
resize-logical-partition <partition> <size> यह लॉजिकल पार्टिशन के कॉन्टेंट में बदलाव किए बिना, उसके साइज़ को नए साइज़ में बदलता है. अगर साइज़ में बदलाव करने के लिए, ज़रूरत के मुताबिक स्टोरेज नहीं है, तो इस स्थिति में प्रोसेस फ़ेल हो जाती है.
flash <partition><filename> ] यह कमांड, फ़्लैश पार्टीशन में कोई फ़ाइल लिखती है. डिवाइस अनलॉक होना चाहिए.
erase <partition> यह किसी पार्टीशन को मिटाता है. इसके लिए, सुरक्षित तरीके से मिटाने की ज़रूरत नहीं होती. डिवाइस अनलॉक होना चाहिए.
getvar <variable> | all इस कमांड से, बूटलोडर वैरिएबल या सभी वैरिएबल दिखते हैं. अगर वैरिएबल मौजूद नहीं है, तो गड़बड़ी का मैसेज दिखता है.
set_active <slot>

इससे दिए गए A/B बूटिंग स्लॉट को active के तौर पर सेट किया जाता है. बूट की अगली प्रोसेस में, सिस्टम उस स्लॉट से बूट होगा जिसे आपने चुना है.

A/B टेस्टिंग के लिए, स्लॉट पार्टिशन के डुप्लीकेट सेट होते हैं. इन्हें अलग-अलग बूट किया जा सकता है. स्लॉट के नाम a, b वगैरह होते हैं. साथ ही, इन्हें अलग-अलग करने के लिए, पार्टीशन के नाम में _a, _b वगैरह सफ़िक्स जोड़े जाते हैं.

reboot डिवाइस को सामान्य तरीके से रीबूट करता है.
reboot-bootloader (या reboot bootloader) यह डिवाइस को बूटलोडर मोड में रीबूट करता है.
fastboot fetch vendor_boot <out.img>

Android 12 और इसके बाद के वर्शन में इसका इस्तेमाल, वेंडर रैमडिस्क फ़्लैश करने की सुविधा के लिए किया जाता है.

इससे पूरे पार्टीशन का साइज़ और चंक का साइज़ मिलता है. हर चंक के लिए डेटा मिलता है. इसके बाद, डेटा को एक साथ जोड़कर <out.img>

ज़्यादा जानकारी के लिए, fastboot fetch vendor_boot <out.img> देखें.

fastboot flash vendor_boot:default <vendor-ramdisk.img>

Android 12 और उसके बाद के वर्शन में, वेंडर रैमडिस्क को फ़्लैश करने की सुविधा के लिए इसका इस्तेमाल करें.

यह फ़्लैश कमांड का एक खास वैरिएंट है. यह fetch vendor_boot इमेज फ़ंक्शन को इस तरह से लागू करता है जैसे fastboot fetch को कॉल किया गया हो. यह नई vendor_boot इमेज को फ़्लैश करता है. यह इस बात पर निर्भर करता है कि बूट हेडर का वर्शन 3 है या वर्शन 4.

ज़्यादा जानकारी के लिए, fastboot flash vendor_boot:default <vendor-ramdisk.img> देखें.

fastboot flash vendor_boot:<foo> <vendor-ramdisk.img> Android 12 और इसके बाद के वर्शन में, वेंडर रैमडिस्क को फ़्लैश करने की सुविधा के लिए इसका इस्तेमाल करें.

यह कुकी, vendor_boot इमेज फ़ेच करती है. अगर वेंडर बूट हेडर का वर्शन 3 है, तो यह फ़ंक्शन गड़बड़ी दिखाता है. अगर यह वर्शन 4 है, तो यह सही वेंडर रैमडिस्क फ़्रैगमेंट (अगर उपलब्ध हो) ढूंढता है. यह उस इमेज को दी गई इमेज से बदल देता है. साथ ही, साइज़ और ऑफ़सेट की फिर से गिनती करता है और नया vendor_boot image दिखाता है.

ज़्यादा जानकारी के लिए, fastboot flash vendor_boot:<foo> <vendor-ramdisk.img> देखें

फ़ास्टबूट और बूटलोडर

बूटलोडर, bootloader, radio, और boot/recovery पार्टिशन को फ़्लैश करता है. इसके बाद, डिवाइस फ़ास्टबूट (यूज़रस्पेस) में बूट होता है और अन्य सभी पार्टिशन को फ़्लैश करता है. बूटलोडर को इन निर्देशों के साथ काम करना चाहिए.

निर्देश ब्यौरा
download इससे इमेज को फ़्लैश में डाउनलोड किया जाता है.
flash recovery <image>/ flash boot <image>/ flash bootloader <image>/ यह recovery/boot पार्टिशन और बूटलोडर को फ़्लैश करता है.
reboot इससे डिवाइस रीबूट हो जाता है.
reboot fastboot यह डिवाइस को फ़ास्टबूट मोड में रीबूट करता है.
reboot recovery यह डिवाइस को रिकवरी मोड में रीबूट करता है.
getvar यह बूटलोडर वैरिएबल को फ़्लैश करता है. इसकी ज़रूरत रिकवरी/बूट इमेज को फ़्लैश करने के लिए होती है. उदाहरण के लिए, current-slot और max-download-size.
oem <command> ओईएम ने इस निर्देश को तय किया है.

डाइनैमिक पार्टिशन

बूटलोडर को डाइनैमिक पार्टिशन को फ़्लैश या मिटाने की अनुमति नहीं देनी चाहिए. साथ ही, अगर इन कार्रवाइयों को करने की कोशिश की जाती है, तो उसे गड़बड़ी का मैसेज ज़रूर दिखाना चाहिए. डाइनैमिक पार्टीशन की सुविधा वाले डिवाइसों के लिए, फ़ास्टबूट टूल और बूटलोडर, फ़ोर्स मोड के साथ काम करते हैं. इससे बूटलोडर मोड में रहते हुए, डाइनैमिक पार्टीशन को सीधे तौर पर फ़्लैश किया जा सकता है. उदाहरण के लिए, अगर रेट्रोफ़िट किए गए डिवाइस पर system एक डाइनैमिक पार्टीशन है, तो fastboot --force flash system कमांड का इस्तेमाल करने से बूटलोडर (fastbootd के बजाय) पार्टीशन को फ़्लैश कर पाता है.

डिवाइस बंद होने पर चार्जिंग

अगर कोई डिवाइस, बंद होने पर भी चार्ज होने की सुविधा के साथ काम करता है या पावर चालू होने पर अपने-आप किसी खास मोड में बूट हो जाता है, तो fastboot oem off-mode-charge 0 कमांड को इन खास मोड को बायपास करना होगा. इससे डिवाइस इस तरह बूट होगा जैसे उपयोगकर्ता ने पावर बटन दबाया हो.

Fastboot OEM HAL

बूटलोडर फ़ास्टबूट को पूरी तरह से बदलने के लिए, फ़ास्टबूट को सभी मौजूदा फ़ास्टबूट कमांड को हैंडल करना होगा. इनमें से कई कमांड, ओईएम से मिली हैं. इनके बारे में दस्तावेज़ में बताया गया है. हालांकि, इन्हें लागू करने के लिए कस्टम कोड की ज़रूरत होती है. कई ओईएम के लिए खास तौर पर बनाई गई कमांड के बारे में जानकारी नहीं दी गई है. इस तरह के निर्देशों को मैनेज करने के लिए, फ़ास्टबूट HAL, ज़रूरी ओईएम निर्देश तय करता है. ओईएम, अपने हिसाब से भी निर्देश लागू कर सकते हैं.

फ़ास्टबूट एचएएल की परिभाषा यहां दी गई है:

import IFastbootLogger;

/**
 * IFastboot interface implements vendor specific fastboot commands.
 */
interface IFastboot {
    /**
     * Returns a bool indicating whether the bootloader is enforcing verified
     * boot.
     *
     * @return verifiedBootState True if the bootloader is enforcing verified
     * boot and False otherwise.
     */
    isVerifiedBootEnabled() generates (bool verifiedBootState);

    /**
     * Returns a bool indicating the off-mode-charge setting. If off-mode
     * charging is enabled, the device autoboots into a special mode when
     * power is applied.
     *
     * @return offModeChargeState True if the setting is enabled and False if
     * not.
     */
    isOffModeChargeEnabled() generates (bool offModeChargeState);

    /**
     * Returns the minimum battery voltage required for flashing in mV.
     *
     * @return batteryVoltage Minimum battery voltage (in mV) required for
     * flashing to be successful.
     */
    getBatteryVoltageFlashingThreshold() generates (int32_t batteryVoltage);

    /**
     * Returns the file system type of the partition. This is only required for
     * physical partitions that need to be wiped and reformatted.
     *
     * @return type Can be ext4, f2fs or raw.
     * @return result SUCCESS if the operation is successful,
     * FAILURE_UNKNOWN if the partition is invalid or does not require
     * reformatting.
     */
    getPartitionType(string partitionName) generates (FileSystemType type, Result result);

    /**
     * Executes a fastboot OEM command.
     *
     * @param oemCmd The oem command that is passed to the fastboot HAL.
     * @response result Returns the status SUCCESS if the operation is
     * successful,
     * INVALID_ARGUMENT for bad arguments,
     * FAILURE_UNKNOWN for an invalid/unsupported command.
     */
    doOemCommand(string oemCmd) generates (Result result);

};

fastbootd मोड चालू करना

किसी डिवाइस पर fastbootd चालू करने के लिए:

  1. device.mk में PRODUCT_PACKAGES में fastbootd जोड़ें: PRODUCT_PACKAGES += fastbootd.

  2. पक्का करें कि फ़ास्टबूट HAL, बूट कंट्रोल HAL, और हेल्थ HAL को रिकवरी इमेज के हिस्से के तौर पर पैकेज किया गया हो.

  3. डिवाइस के हिसाब से, fastbootd के लिए ज़रूरी SEPolicy अनुमतियां जोड़ें. उदाहरण के लिए, fastbootd को किसी डिवाइस के खास पार्टिशन में डेटा लिखने का ऐक्सेस चाहिए, ताकि वह उस पार्टिशन को फ़्लैश कर सके. इसके अलावा, फ़ास्टबूट एचएएल को लागू करने के लिए, डिवाइस के हिसाब से अनुमतियों की भी ज़रूरत पड़ सकती है.

यूज़रस्पेस फ़ास्टबूट की पुष्टि करने के लिए, Vendor Test Suite (VTS) चलाएं.

फ़्लैश वेंडर रैमडिस्क

Android 12 और इसके बाद के वर्शन में, ramdisk फ़्लैश करने की सुविधा मिलती है. इसके लिए, फ़ास्टबूट कमांड का इस्तेमाल किया जाता है. यह कमांड, डिवाइस से पूरी vendor_boot इमेज को खींचती है. इस कमांड से, होस्ट-साइड फ़ास्टबूट टूल को वेंडर बूट हेडर पढ़ने, फिर से इमेज बनाने, और नई इमेज फ़्लैश करने का निर्देश मिलता है.

पूरी vendor_boot इमेज को पुल करने के लिए, fetch:vendor_boot कमांड को Android 12 में फ़ास्टबूट प्रोटोकॉल और प्रोटोकॉल के फ़ास्टबूटडी लागू करने वाले दोनों में जोड़ा गया था. ध्यान दें कि fastbootd does implement this, but the bootloader itself might not. ओईएम, प्रोटोकॉल के बूटलोडर को लागू करने के लिए, fetch:vendor_boot कमांड जोड़ सकते हैं. हालांकि, अगर बूटलोडर मोड में कमांड को नहीं पहचाना जाता है, तो बूटलोडर मोड में अलग-अलग वेंडर रैमडिस्क फ़्लैश करना, वेंडर की ओर से उपलब्ध कराया गया विकल्प नहीं है.

बूटलोडर में हुए बदलाव

fastbootd में, getvar:max-fetch-size और fetch:name कमांड लागू की जाती हैं. बूटलोडर में वेंडर रैमडिस्क फ़्लैश करने की सुविधा के लिए, आपको इन दो निर्देशों को लागू करना होगा.

Fastbootd में किए गए बदलाव

getvar:max-fetch-size, max-download-size से मिलता-जुलता है. इससे यह तय होता है कि डिवाइस, एक DATA रिस्पॉन्स में ज़्यादा से ज़्यादा कितना डेटा भेज सकता है. ड्राइवर को इस वैल्यू से ज़्यादा साइज़ फ़ेच नहीं करना चाहिए.

fetch:name[:offset[:size]] डिवाइस पर कई तरह की जांच करता है. अगर यहां दी गई सभी शर्तें पूरी होती हैं, तो fetch:name[:offset[:size]] कमांड डेटा दिखाती है:

  • डिवाइस पर डीबग करने लायक बिल्ड चल रहा है.
  • डिवाइस अनलॉक है (बूट की स्थिति नारंगी है).
  • फ़ेच किए गए पार्टीशन का नाम vendor_boot है.
  • size की वैल्यू, 0 < size <= max-fetch-size के बीच होनी चाहिए.

इनकी पुष्टि हो जाने के बाद, fetch:name[:offset[:size]] पार्टिशन का साइज़ और ऑफ़सेट दिखाता है. यहां दी गई बातों का ध्यान रखें:

  • fetch:name, fetch:name:0 के बराबर है. यह fetch:name:0:partition_size के बराबर है.
  • fetch:name:offset, fetch:name:offset:(partition_size - offset) के बराबर है

इसलिए, fetch:name[:offset[:size]] = fetch:name:offset:(partition_size - offset).

जब offset या partition_size (या दोनों) की वैल्यू नहीं दी जाती है, तो डिफ़ॉल्ट वैल्यू का इस्तेमाल किया जाता है. offset के लिए डिफ़ॉल्ट वैल्यू 0 होती है. वहीं, size के लिए डिफ़ॉल्ट वैल्यू, partition_size - offset की कैलकुलेट की गई वैल्यू होती है.

  • ऑफ़सेट तय किया गया है, लेकिन साइज़ तय नहीं किया गया है: size = partition_size - offset
  • दोनों में से कोई भी वैल्यू नहीं दी गई है: दोनों के लिए डिफ़ॉल्ट वैल्यू का इस्तेमाल किया जाता है. size = partition_size - 0.

उदाहरण के लिए, fetch:foo, ऑफ़सेट 0 पर पूरे foo पार्टीशन को फ़ेच करता है.

ड्राइवर में बदलाव

ड्राइवर में बदलाव लागू करने के लिए, फ़ास्टबूट टूल में कमांड जोड़ी गई थीं. हर कमांड, फ़ास्टबूट कमांड की टेबल में मौजूद उसकी पूरी परिभाषा से लिंक होती है.

  • fastboot fetch vendor_boot out.img

    • यह कुकी, चंक का साइज़ तय करने के लिए getvar max-fetch-size को कॉल करती है.
    • यह पूरे पार्टीशन का साइज़ तय करने के लिए, getvar partition-size:vendor_boot[_a] को कॉल करता है.
    • हर एक चंक के लिए fastboot fetch vendor_boot[_a]:offset:size कॉल. (चंक का साइज़, vendor_boot के साइज़ से ज़्यादा है. इसलिए, आम तौर पर सिर्फ़ एक चंक होता है.)
    • डेटा को एक साथ जोड़ता है, ताकि out.img.
  • fastboot flash vendor_boot:default vendor-ramdisk.img

    यह फ़्लैश कमांड का एक खास वैरिएंट है. यह vendor_boot इमेज को फ़ेच करता है, जैसे कि fastboot fetch को कॉल किया गया हो.

    • अगर वेंडर बूट हेडर वर्शन 3 है, तो यह ये काम करता है:
      • यह विकल्प, वेंडर रैमडिस्क को दी गई इमेज से बदलता है.
      • vendor_boot की नई इमेज फ़्लैश करता है.
    • अगर वेंडर बूट हेडर वर्शन 4 है, तो यह काम करता है:
      • यह वेंडर रैमडिस्क को दी गई इमेज से बदल देता है, ताकि दी गई इमेज, vendor_boot इमेज में वेंडर रैमडिस्क का सिर्फ़ एक फ़्रैगमेंट बन जाए.
      • यह वेंडर रैमडिस्क टेबल में साइज़ और ऑफ़सेट की फिर से गिनती करता है.
      • vendor_boot की नई इमेज फ़्लैश करता है.
  • fastboot flash vendor_boot:foo vendor-ramdisk.img

    यह vendor_boot image को फ़ेच करता है, जैसे कि fastboot fetch को कॉल किया गया हो.

    • अगर वेंडर बूट हेडर वर्शन 3 है, तो यह गड़बड़ी दिखाता है.
    • अगर वेंडर बूट हेडर वर्शन 4 है, तो यह काम करता है:

      • यह ramdisk_<var>&lt;foo></var> नाम वाले वेंडर रैमडिस्क फ़्रैगमेंट को ढूंढता है. अगर यह वैल्यू नहीं मिलती है या एक से ज़्यादा वैल्यू मिलती हैं, तो गड़बड़ी का मैसेज दिखता है.
      • यह विकल्प, वेंडर के रैमडिस्क फ़्रैगमेंट को दी गई इमेज से बदल देता है.
      • यह वेंडर रैमडिस्क टेबल में हर साइज़ और ऑफ़सेट को फिर से कैलकुलेट करता है.
      • vendor_boot की नई इमेज फ़्लैश करता है.
    • अगर <foo> नहीं दिया गया है, तो यह ramdisk_ को ढूंढने की कोशिश करता है.

mkbootimg

Android 12 और इसके बाद के वर्शन में, वेंडर रैमडिस्क फ़्रैगमेंट का नाम रखने के लिए default नाम रिज़र्व किया गया है. फ़ास्टबूट flash vendor_boot:default सिमैंटिक में कोई बदलाव नहीं हुआ है. हालांकि, आपको अपने रैमडिस्क फ़्रैगमेंट का नाम default नहीं रखना चाहिए.

SELinux में किए गए बदलाव

वेंडर के रैमडिस्क को फ़्लैश करने की सुविधा देने के लिए, fastbootd.te में बदलाव किया गया था.