कैननिकल बूट की वजह

Android 9 में, बूटलोडर के बूट होने की वजह के स्पेसिफ़िकेशन में ये बदलाव किए गए हैं.

बूट करने की वजहें

बूटलोडर, डिवाइस के रीबूट होने की वजह का पता लगाने के लिए, खास तौर पर उपलब्ध हार्डवेयर और मेमोरी संसाधनों का इस्तेमाल करता है. इसके बाद, Android को लॉन्च करने के लिए, कमांड लाइन में androidboot.bootreason=<reason> जोड़कर, इस वजह की जानकारी देता है. init इसके बाद, इस कमांड लाइन को Android प्रॉपर्टी bootloader_boot_reason_prop (ro.boot.bootreason) में भेजने के लिए, इसका अनुवाद करता है. Android 12 या इसके बाद के वर्शन वाले डिवाइसों के लिए, 5.10 या इसके बाद के वर्शन वाले कर्नेल का इस्तेमाल करके, androidboot.bootreason=<reason> को कर्नेल कमांड लाइन के बजाय, बूटकॉन्फ़िगरेशन में जोड़ा जाता है.

बूट होने की वजह से जुड़ी खास बातें

Android के पिछले वर्शन में, बूट होने की वजह बताने के लिए एक फ़ॉर्मैट तय किया गया था. इसमें कोई स्पेस नहीं होता था और सभी शब्द छोटे अक्षरों में होते थे. साथ ही, इसमें कुछ ज़रूरी शर्तें शामिल होती थीं. जैसे, kernel_panic, watchdog, cold/warm/hard की शिकायत करने के लिए. इस फ़ॉर्मैट में, बूट होने की अन्य वजहें भी बताई जा सकती थीं. इस ढीली शर्त की वजह से, बूट होने की वजह बताने वाली सैकड़ों कस्टम (और कभी-कभी बेमतलब) स्ट्रिंग का इस्तेमाल होने लगा. इस वजह से, स्थिति को मैनेज करना मुश्किल हो गया. Android के मौजूदा रिलीज़ के हिसाब से, बूटलोडर के ज़रिए फ़ाइल किए गए ऐसे कॉन्टेंट की संख्या बहुत ज़्यादा है जिसे समझना मुश्किल है या जो काम का नहीं है. इस वजह से, bootloader_boot_reason_prop के लिए नीति का पालन करने में समस्याएं आ रही हैं.

Android 9 रिलीज़ होने के बाद, Android टीम को पता चला है कि लेगसी bootloader_boot_reason_prop का इस्तेमाल काफ़ी ज़्यादा किया जा रहा है. साथ ही, रनटाइम के दौरान इसे फिर से नहीं लिखा जा सकता. इसलिए, बूट होने की वजह की जानकारी में कोई भी सुधार, बूटलोडर डेवलपर के साथ इंटरैक्शन और मौजूदा सिस्टम में बदलाव करने के बाद ही किया जाना चाहिए. इसके लिए, Android टीम:

  • बूटलोडर डेवलपर से जुड़कर, उन्हें इन कामों के लिए बढ़ावा देना:
    • bootloader_boot_reason_prop के लिए, कैननिकल, पार्स की जा सकने वाली, और पहचानी जा सकने वाली वजहें दें.
    • system/core/bootstat/bootstat.cpp kBootReasonMap सूची में शामिल हों.
  • system_boot_reason_prop (sys.boot.reason) का ऐसा सोर्स जोड़ना जिसे कंट्रोल किया जा सकता है और रनटाइम के दौरान फिर से लिखा जा सकता है. सिस्टम ऐप्लिकेशन का एक सीमित सेट (जैसे, bootstat और init) इस प्रॉपर्टी को फिर से लिख सकता है. हालांकि, सभी ऐप्लिकेशन को इसे पढ़ने के लिए, sepolicy से जुड़े अधिकार दिए जा सकते हैं.
  • उपयोगकर्ताओं को बताएं कि सिस्टम को बूट करने की वजह बताने वाली प्रॉपर्टी system_boot_reason_prop में मौजूद कॉन्टेंट पर भरोसा करने से पहले, वे उपयोगकर्ता डेटा के माउंट होने तक इंतज़ार करें.

इतनी देर क्यों? bootloader_boot_reason_prop, डिवाइस के चालू होने के शुरुआती समय में उपलब्ध होता है. हालांकि, Android की सुरक्षा नीति के तहत, ज़रूरत के हिसाब से इसे ब्लॉक किया जाता है. ऐसा इसलिए किया जाता है, क्योंकि यह गलत, समझने में मुश्किल, और गैर-कैनोनिकल जानकारी दिखाता है. ज़्यादातर मामलों में, सिर्फ़ उन डेवलपर को यह जानकारी ऐक्सेस करनी चाहिए जिन्हें बूट सिस्टम के बारे में काफ़ी जानकारी है. system_boot_reason_prop के साथ बूट करने की वजह के लिए, बेहतर, पार्स किया जा सकने वाला, और कैननिकल एपीआई को भरोसेमंद तरीके से और सटीक तरीके से सिर्फ़ इसके बाद चुना जा सकता है, जब उपयोगकर्ता डेटा माउंट हो गया हो. खास तौर से:

  • उपयोगकर्ता डेटा के माउंट होने से पहले, system_boot_reason_prop में bootloader_boot_reason_prop की वैल्यू होगी.
  • उपयोगकर्ता डेटा माउंट होने के बाद, system_boot_reason_prop को ज़्यादा सटीक जानकारी देने या नीति का पालन करने के लिए अपडेट किया जा सकता है.

इस वजह से, Android 9, बूट की वजह को आधिकारिक तौर पर हासिल करने से पहले की समयावधि को बढ़ा देता है. इस वजह से, इसे बूट (bootloader_boot_reason_prop के साथ) में तुरंत सटीक होने से बदलकर, उपयोगकर्ता का डेटा माउंट किए जाने के बाद ही उपलब्ध कराया जाता है (system_boot_reason_prop के साथ).

Bootstat लॉजिक, ज़्यादा जानकारी देने वाले और ज़रूरी शर्तों को पूरा करने वाले bootloader_boot_reason_prop पर निर्भर करता है. जब वह प्रॉपर्टी, अनुमान लगाने लायक फ़ॉर्मैट का इस्तेमाल करती है, तो इससे कंट्रोल किए गए सभी रीबूट और शटडाउन के मामलों की सटीकता बढ़ जाती है. इससे system_boot_reason_prop की सटीकता और मतलब बेहतर और बड़ा हो जाता है.

डिवाइस के चालू होने की वजह का कैननिकल फ़ॉर्मैट

Android 9 में bootloader_boot_reason_prop के लिए, बूट होने की वजह का कैननिकल फ़ॉर्मैट इस सिंटैक्स का इस्तेमाल करता है:

<reason>,<subreason>,<detail>…

फ़ॉर्मैटिंग के नियम:

  • लोअर केस
  • कोई खाली जगह नहीं (अंडरलाइन का इस्तेमाल करें)
  • प्रिंट किए जा सकने वाले सभी वर्ण
  • कॉमा से अलग किए गए reason, subreason, और एक या इससे ज़्यादा detail इंस्टेंस.
    • ज़रूरी reason, जो सबसे ज़्यादा प्राथमिकता वाली वजह बताता है कि डिवाइस को रीस्टार्ट या बंद क्यों करना पड़ा.
    • ज़रूरी नहीं है कि subreason का इस्तेमाल किया जाए. इससे यह जानकारी मिलती है कि डिवाइस को रीस्टार्ट या बंद क्यों करना पड़ा (या डिवाइस को किसने रीस्टार्ट या बंद किया).
    • एक या उससे ज़्यादा वैकल्पिक detail वैल्यू. detail किसी सबसिस्टम पर ले जा सकता है, ताकि यह पता लगाया जा सके कि subreason किस सिस्टम की वजह से हुआ है. एक से ज़्यादा detail वैल्यू दी जा सकती हैं. आम तौर पर, ये वैल्यू अहमियत के हिसाब से क्रम में होनी चाहिए. हालांकि, एक जैसी अहमियत वाली कई detail वैल्यू की रिपोर्ट भी की जा सकती है.

bootloader_boot_reason_prop के लिए कोई वैल्यू न डालने पर, इसे अमान्य माना जाता है. ऐसा इसलिए, क्योंकि इससे अन्य एजेंट, बूट होने की वजह को बाद में इंजेक्ट कर सकते हैं.

वजह बताने से जुड़ी ज़रूरी शर्तें

reason (टर्मिनेशन या कॉमा से पहले का पहला स्पैन) के लिए दी गई वैल्यू, नीचे दिए गए सेट में से किसी एक में होनी चाहिए. इसे कोर, स्ट्रॉन्ग, और ब्लंट वजहों में बांटा गया है:

  • kernel set:
    • "watchdog"
    • "kernel_panic"
  • ज़्यादा सेट:
    • "recovery"
    • "bootloader"
  • ब्लंट सेट:
    • "cold". आम तौर पर, इससे सभी डिवाइसों का पूरा रीसेट होता है. इसमें मेमोरी भी शामिल है.
    • "hard". आम तौर पर, इससे पता चलता है कि हार्डवेयर की स्थिति को रीसेट कर दिया गया है और ramoops में मौजूद कॉन्टेंट को बनाए रखा जाना चाहिए.
    • "warm". आम तौर पर, इससे पता चलता है कि मेमोरी और डिवाइसों में कुछ जानकारी सेव रहती है. साथ ही, ramoops (pstore कर्नेल में ड्राइवर देखें) बैकिंग स्टोर में, हमेशा सेव रहने वाला कॉन्टेंट होता है.
    • "shutdown"
    • "reboot". आम तौर पर इसका मतलब है कि ramoops की स्थिति के बारे में जानकारी नहीं है और हार्डवेयर की स्थिति के बारे में जानकारी नहीं है. यह वैल्यू, cold, hard, और warm वैल्यू के तौर पर काम करती है. इनसे यह पता चलता है कि डिवाइस को कितनी बार रीसेट किया गया है.

बूटलोडर को एक कर्नेल सेट या ब्लंट सेट reason देना होगा. अगर subreason तय किया जा सकता है, तो हमारा सुझाव है कि आप subreason दें. उदाहरण के लिए, पावर बटन को दबाकर रखने पर, डिवाइस को ramoops बैकअप के साथ या उसके बिना भी बूट किया जा सकता है. ऐसे में, डिवाइस को बूट करने की वजह के तौर पर "reboot,longkey" दिखेगा.

कोई भी फ़र्स्ट-स्पैन reason, किसी भी subreason या detail का हिस्सा नहीं हो सकता. हालांकि, उपयोगकर्ता स्पेस से, कोर सेट की वजहें नहीं दी जा सकतीं. इसलिए, "watchdog" का फिर से इस्तेमाल किया जा सकता है. इसके लिए, सोर्स की जानकारी (उदाहरण के लिए, "reboot,watchdog,service_manager_unresponsive" या "reboot,software,watchdog") के साथ-साथ, साफ़ तौर पर बताई गई वजह भी दी जा सकती है.

बूट होने में हुई देरी की वजहों को समझने के लिए, किसी विशेषज्ञ के अंदरूनी ज्ञान की ज़रूरत नहीं होनी चाहिए और/या यह जानकारी, आसानी से समझी जा सकने वाली रिपोर्ट के ज़रिए दी जानी चाहिए. उदाहरण: "shutdown,vbxd" (खराब), "shutdown,uv" (बेहतर), "shutdown,undervoltage" (प्राथमिकता).

वजह-उपवजह के कॉम्बिनेशन

Android, reason-subreason के ऐसे कॉम्बिनेशन का सेट रिज़र्व रखता है जिन्हें सामान्य इस्तेमाल में ज़्यादा इस्तेमाल नहीं किया जाना चाहिए. हालांकि, अगर कॉम्बिनेशन से जुड़ी स्थिति के बारे में सटीक जानकारी मिलती है, तो हर मामले के हिसाब से इनका इस्तेमाल किया जा सकता है. रिज़र्व किए गए कॉम्बिनेशन के उदाहरण:

  • "reboot,userrequested"
  • "shutdown,userrequested"
  • "shutdown,thermal" (thermald से)
  • "shutdown,battery"
  • "shutdown,battery,thermal" (BatteryStatsService से)
  • "reboot,adb"
  • "reboot,shell"
  • "reboot,bootloader"
  • "reboot,recovery"

ज़्यादा जानकारी के लिए, system/core/bootstat/bootstat.cpp में kBootReasonMap और Android सोर्स रिपॉज़िटरी में, उससे जुड़े git के बदलावों का इतिहास देखें.

डिवाइस के बूट होने की वजहों की रिपोर्ट करना

बूट होने की सभी वजहें, बूटलोडर से या कैननिकल बूट होने की वजह के तौर पर रिकॉर्ड की गई वजहें, system/core/bootstat/bootstat.cpp के kBootReasonMap सेक्शन में रिकॉर्ड की जानी चाहिए. kBootReasonMap सूची में, नीतियों का पालन न करने और नीतियों का पालन करने से जुड़ी वजहें शामिल होती हैं. बूटलोडर डेवलपर को यहां सिर्फ़ नई वजहें रजिस्टर करनी चाहिए, जो नीति के मुताबिक हों. साथ ही, नीति का पालन न करने की वजहें तब तक रजिस्टर नहीं करनी चाहिए, जब तक कि प्रॉडक्ट पहले से ही शिप न हो गया हो और उसमें बदलाव न किया जा सके.

हमारा सुझाव है कि आप system/core/bootstat/bootstat.cpp में, मौजूदा और नीतियों का पालन करने वाली एंट्री का इस्तेमाल करें. साथ ही, नीतियों का पालन न करने वाली स्ट्रिंग का इस्तेमाल करने से पहले, सावधानी बरतें. दिशा-निर्देश के तौर पर, यह है:

  • ठीक है, ताकि bootloader से "kernel_panic" की शिकायत की जा सके. ऐसा इसलिए, क्योंकि bootstat, kernel_panic signatures के लिए ramoops की जांच कर सकता है, ताकि सब-वजहें, कैननिकल system_boot_reason_prop में बेहतर तरीके से शामिल की जा सकें.
  • kBootReasonMap में, नीतियों का पालन न करने वाली स्ट्रिंग की शिकायत करना ठीक नहीं है. जैसे, bootloader से "panic"). ऐसा करने पर, reason को बेहतर बनाने की सुविधा काम नहीं करेगी.

उदाहरण के लिए, अगर kBootReasonMap में "wdog_bark" है, तो bootloader डेवलपर को:

  • इसे "watchdog,bark" में बदलें और सूची में kBootReasonMap में जोड़ें.
  • देखें कि टेक्नोलॉजी के बारे में जानकारी न रखने वाले लोगों के लिए, "bark" का क्या मतलब है. साथ ही, यह भी तय करें कि क्या कोई ऐसा subreason उपलब्ध है जो ज़्यादा काम का हो.

बूट करने की वजह के मुताबिक होने की पुष्टि करना

फ़िलहाल, Android ऐसा कोई चालू CTS टेस्ट उपलब्ध नहीं कराता है जो बूटलोडर से मिलने वाली, बूट होने की सभी संभावित वजहों को सटीक तरीके से ट्रिगर या जांच कर सके. हालांकि, पार्टनर अब भी काम करने की जांच करने के लिए, पैसिव टेस्ट चला सकते हैं.

इसलिए, बूटलोडर से जुड़ी शर्तों का पालन करने के लिए, बूटलोडर डेवलपर को ऊपर बताए गए नियमों और दिशा-निर्देशों का पालन करना होगा. हम ऐसे डेवलपर से अनुरोध करते हैं कि वे AOSP (खास तौर पर system/core/bootstat/bootstat.cpp) में योगदान दें. साथ ही, इस फ़ोरम का इस्तेमाल, बूट होने से जुड़ी समस्याओं के बारे में चर्चा करने के लिए करें.