डिवाइस चालू होने में लगने वाले समय को ऑप्टिमाइज़ करना

इस पेज पर, बूट होने में लगने वाले समय को कम करने के सुझाव दिए गए हैं.

मॉड्यूल से डीबग सिंबल हटाएं

पक्का करें कि मॉड्यूल से डीबग सिंबल हटा दिए गए हों. ठीक उसी तरह जैसे प्रोडक्शन डिवाइस पर कर्नेल से डीबग सिंबल हटाए जाते हैं. मॉड्यूल से डीबग सिंबल हटाने से, बूट होने में लगने वाला समय कम हो जाता है. ऐसा इसलिए होता है, क्योंकि इससे ये चीज़ें कम हो जाती हैं:

  • फ़्लैश से बाइनरी पढ़ने में लगने वाला समय.
  • रैमडिस्क को डीकंप्रेस करने में लगने वाला समय.
  • मॉड्यूल लोड करने में लगने वाला समय.

मॉड्यूल से डीबग सिंबल हटाने पर, बूट होने में लगने वाले समय में कुछ सेकंड की बचत हो सकती है.

Android प्लैटफ़ॉर्म बिल्ड में, सिंबल हटाने की सुविधा डिफ़ॉल्ट रूप से चालू होती है. हालांकि, इसे साफ़ तौर पर चालू करने के लिए, डिवाइस के हिसाब से कॉन्फ़िगरेशन में डिवाइस/vendor/device में जाकर, BOARD_DO_NOT_STRIP_VENDOR_RAMDISK_MODULES सेट करें.

कर्नेल और रैमडिस्क के लिए LZ4 कंप्रेस करने की सुविधा का इस्तेमाल करना

LZ4 की तुलना में, Gzip कंप्रेस करने पर छोटा आउटपुट जनरेट करता है. हालांकि, Gzip की तुलना में LZ4 तेज़ी से डीकंप्रेस होता है. कर्नेल और मॉड्यूल के लिए, Gzip का इस्तेमाल करने पर स्टोरेज साइज़ में होने वाली कमी, LZ4 के डीकंप्रेस होने में लगने वाले समय के फ़ायदे की तुलना में ज़्यादा अहम नहीं है.

BOARD_RAMDISK_USE_LZ4 की मदद से, Android प्लैटफ़ॉर्म बिल्ड में LZ4 रैमडिस्क कंप्रेस करने की सुविधा जोड़ी गई है. डिवाइस के हिसाब से कॉन्फ़िगरेशन में, यह विकल्प सेट किया जा सकता है. कर्नेल defconfig की मदद से, कर्नेल कंप्रेस करने की सुविधा सेट की जा सकती है.

LZ4 पर स्विच करने से, बूट होने में लगने वाला समय 500 से 1000 मिलीसेकंड तक कम हो सकता है.

ड्राइवर में ज़्यादा लॉगिंग से बचना

ARM64 और ARM32 में, कॉल साइट से तय दूरी से ज़्यादा दूरी पर मौजूद फ़ंक्शन कॉल के लिए, जंप टेबल (जिसे प्रोसीज़र लिंकिंग टेबल या पीएलटी कहा जाता है) की ज़रूरत होती है, ताकि जंप के पूरे पते को एनकोड किया जा सके. मॉड्यूल डाइनैमिक तरीके से लोड होते हैं. इसलिए, मॉड्यूल लोड होने के दौरान, इन जंप टेबल को ठीक करना पड़ता है. जिन कॉल को रिलोकेट करने की ज़रूरत होती है उन्हें ईएलएफ़ फ़ॉर्मैट में, साफ़ तौर पर ऐडेंड (या संक्षेप में आरईएलए) वाली रिलोकेशन एंट्री कहा जाता है.

पीएलटी को असाइन करते समय, Linux कर्नेल मेमोरी साइज़ ऑप्टिमाइज़ेशन (जैसे, कैश हिट ऑप्टिमाइज़ेशन) करता है. इस अपस्ट्रीम कमिट के साथ, ऑप्टिमाइज़ेशन स्कीम में O(N^2) कॉम्प्लेक्सिटी होती है. यहां N, आरईएलए की संख्या है जिसका प्रकार R_AARCH64_JUMP26 या R_AARCH64_CALL26 है. इसलिए, इन टाइप के कम आरईएलए होने से, मॉड्यूल कॉन्टेंट लोड होने में लगने वाला समय कम करने में मदद मिलती है.

कोडिंग का एक सामान्य पैटर्न, R_AARCH64_CALL26 या R_AARCH64_JUMP26 आरईएलए की संख्या को बढ़ाता है. यह पैटर्न, ड्राइवर में ज़्यादा लॉगिंग है. आम तौर पर, printk() या किसी अन्य लॉगिंग स्कीम के हर कॉल से, CALL26/JUMP26 आरईएलए एंट्री जुड़ जाती है. अपस्ट्रीम कमिट में कमिट टेक्स्ट में, ध्यान दें कि ऑप्टिमाइज़ेशन के बावजूद, छह मॉड्यूल लोड होने में करीब 250 मिलीसेकंड लगते हैं. ऐसा इसलिए है, क्योंकि ये छह मॉड्यूल, सबसे ज़्यादा लॉगिंग वाले छह मॉड्यूल थे.

लॉगिंग कम करने से, बूट होने में लगने वाले समय में 100 से 300 मिलीसेकंड की बचत हो सकती है. यह बचत, मौजूदा लॉगिंग की मात्रा पर निर्भर करती है.

चुनिंदा तौर पर, एसिंक्रोनस प्रोबिंग की सुविधा चालू करना

जब कोई मॉड्यूल लोड होता है, तो अगर उस मॉड्यूल के साथ काम करने वाले डिवाइस को डीटी (डिवाइसट्री) से पहले ही पॉप्युलेट कर दिया गया है और ड्राइवर कोर में जोड़ दिया गया है, तो डिवाइस प्रोब, module_init() कॉल के कॉन्टेक्स्ट में किया जाता है. जब डिवाइस प्रोब, module_init() के कॉन्टेक्स्ट में किया जाता है, तो प्रोब पूरा होने तक मॉड्यूल लोड नहीं हो सकता. मॉड्यूल लोडिंग ज़्यादातर सीरियलाइज़ होती है. इसलिए, डिवाइस को प्रोब करने में ज़्यादा समय लगने से, बूट होने में लगने वाला समय बढ़ जाता है.

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

I2C जैसे धीमे बस से कनेक्ट किए गए डिवाइस, अपने प्रोब फ़ंक्शन में फ़र्मवेयर लोड करने वाले डिवाइस, और ज़्यादा हार्डवेयर इनिशियलाइज़ेशन करने वाले डिवाइसों की वजह से, टाइमिंग की समस्या हो सकती है. यह पता लगाने का सबसे अच्छा तरीका है कि यह समस्या कब होती है. इसके लिए, हर ड्राइवर के लिए प्रोब टाइम इकट्ठा करें और उसे क्रम से लगाएं.

किसी मॉड्यूल के लिए एसिंक्रोनस प्रोबिंग की सुविधा चालू करने के लिए, ड्राइवर कोड में सिर्फ़ PROBE_PREFER_ASYNCHRONOUS फ़्लैग सेट करना काफ़ी नहीं है. मॉड्यूल के लिए, आपको कर्नेल कमांड लाइन में module_name.async_probe=1 जोड़ना होगा या async_probe=1 को मॉड्यूल पैरामीटर के तौर पर पास करना होगा, जब आप मॉड्यूल को modprobe या insmod का इस्तेमाल करके लोड कर रहे हों.

एसिंक्रोनस प्रोबिंग की सुविधा चालू करने से, बूट होने में लगने वाले समय में 100 से 500 मिलीसेकंड की बचत हो सकती है. यह बचत, आपके हार्डवेयर/ड्राइवर पर निर्भर करती है.

अपने CPUfreq ड्राइवर को जल्द से जल्द प्रोब करना

आपका CPUfreq ड्राइवर जितनी जल्दी प्रोब करेगा, बूट होने के दौरान सीपीयू की फ़्रीक्वेंसी को उतनी ही जल्दी ज़्यादा किया जा सकेगा. यह फ़्रीक्वेंसी, ज़्यादा से ज़्यादा या थर्मल लिमिट के हिसाब से तय की जा सकती है. सीपीयू की स्पीड जितनी ज़्यादा होगी, बूट होने में लगने वाला समय उतना ही कम होगा. यह दिशा-निर्देश, DRAM, मेमोरी, और इंटरकनेक्ट फ़्रीक्वेंसी को कंट्रोल करने वाले devfreq ड्राइवर पर भी लागू होता है.

मॉड्यूल के लिए, लोड करने का क्रम, initcall लेवल और ड्राइवर के कंपाइल या लिंक ऑर्डर पर निर्भर कर सकता है. MODULE_SOFTDEP() एलियास का इस्तेमाल करके, पक्का करें कि cpufreq ड्राइवर, लोड होने वाले पहले कुछ मॉड्यूल में शामिल हो.

मॉड्यूल को जल्दी लोड करने के अलावा, आपको यह भी पक्का करना होगा कि CPUfreq ड्राइवर को प्रोब करने के लिए, सभी डिपेंडेंसी भी प्रोब हो गई हों. उदाहरण के लिए, अगर आपको अपने सीपीयू की फ़्रीक्वेंसी को कंट्रोल करने के लिए, क्लॉक या रेगुलेटर हैंडल की ज़रूरत है, तो पक्का करें कि उन्हें पहले प्रोब किया जाए. इसके अलावा, अगर बूट अप के दौरान आपके सीपीयू के ज़्यादा गर्म होने की संभावना है, तो आपको CPUfreq ड्राइवर से पहले थर्मल ड्राइवर लोड करने की ज़रूरत पड़ सकती है. इसलिए, यह पक्का करने के लिए ज़रूरी कदम उठाएं कि CPUfreq और उससे जुड़े devfreq ड्राइवर, जल्द से जल्द प्रोब करें.

CPUfreq ड्राइवर को जल्दी प्रोब करने से होने वाली बचत, बहुत कम से लेकर बहुत ज़्यादा तक हो सकती है. यह बचत, इस बात पर निर्भर करती है कि इन्हें कितनी जल्दी प्रोब किया जा सकता है और बूटलोडर, सीपीयू को किस फ़्रीक्वेंसी पर छोड़ता है.

मॉड्यूल को दूसरे चरण के init, वेंडर या vendor_dlkm पार्टिशन में ले जाना

पहले चरण की init प्रोसेस सीरियलाइज़ होती है. इसलिए, बूट प्रोसेस को पैरललाइज़ करने के ज़्यादा मौके नहीं मिलते. अगर पहले चरण की init प्रोसेस को पूरा करने के लिए, किसी मॉड्यूल की ज़रूरत नहीं है, तो उस मॉड्यूल को वेंडर या vendor_dlkm पार्टिशन में रखकर, दूसरे चरण की init प्रोसेस में ले जाएं.

दूसरे चरण की init प्रोसेस में जाने के लिए, पहले चरण की init प्रोसेस में कई डिवाइसों को प्रोब करने की ज़रूरत नहीं होती. सामान्य बूट फ़्लो के लिए, सिर्फ़ कंसोल और फ़्लैश स्टोरेज की क्षमताओं की ज़रूरत होती है.

ये ज़रूरी ड्राइवर लोड करें:

  • watchdog
  • reset
  • cpufreq

रिकवरी और उपयोगकर्ता स्पेस fastbootd मोड के लिए, पहले चरण की init प्रोसेस में ज़्यादा डिवाइसों को प्रोब करने की ज़रूरत होती है. जैसे, यूएसबी और डिसप्ले. इन मॉड्यूल की एक कॉपी, पहले चरण के रैमडिस्क और वेंडर या vendor_dlkm पार्टिशन में रखें. इससे, रिकवरी या fastbootd बूट फ़्लो के लिए, इन्हें पहले चरण की init प्रोसेस में लोड किया जा सकता है. हालांकि, सामान्य बूट फ़्लो के दौरान, पहले चरण की init प्रोसेस में रिकवरी मोड के मॉड्यूल लोड न करें. बूट होने में लगने वाले समय को कम करने के लिए, रिकवरी मोड के मॉड्यूल को दूसरे चरण की init प्रोसेस में डिफ़र किया जा सकता है. पहले चरण की init प्रोसेस में जिन अन्य मॉड्यूल की ज़रूरत नहीं है उन्हें वेंडर या vendor_dlkm पार्टिशन में ले जाना चाहिए.

लीफ़ डिवाइसों की सूची (उदाहरण के लिए, यूएफ़एस या सीरियल) दिए जाने पर, dev needs.sh स्क्रिप्ट, डिपेंडेंसी या सप्लायर (उदाहरण के लिए, क्लॉक, रेगुलेटर या gpio) को प्रोब करने के लिए ज़रूरी सभी ड्राइवर, डिवाइस, और मॉड्यूल ढूंढती है.

मॉड्यूल को दूसरे चरण की init प्रोसेस में ले जाने से, बूट होने में लगने वाला समय इन तरीकों से कम हो जाता है:

  • रैमडिस्क का साइज़ कम हो जाता है.
    • इससे, बूटलोडर के रैमडिस्क लोड करने पर, फ़्लैश रीड की स्पीड बढ़ जाती है. यह सीरियलाइज़ बूट स्टेप है.
    • इससे, कर्नेल के रैमडिस्क को डीकंप्रेस करने पर, डीकंप्रेशन की स्पीड बढ़ जाती है. यह सीरियलाइज़ बूट स्टेप है.
  • दूसरे चरण की init प्रोसेस, पैरलल में काम करती है. इससे, मॉड्यूल लोड होने में लगने वाला समय, दूसरे चरण की init प्रोसेस में किए जा रहे काम के साथ छिप जाता है.

मॉड्यूल को दूसरे चरण में ले जाने से, बूट होने में लगने वाले समय में 500 से 1000 मिलीसेकंड की बचत हो सकती है. यह बचत, इस बात पर निर्भर करती है कि दूसरे चरण की init प्रोसेस में कितने मॉड्यूल ले जाए जा सकते हैं.

मॉड्यूल लोड करने की लॉजिस्टिक्स

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

  • BOARD_VENDOR_RAMDISK_KERNEL_MODULES. यह रैमडिस्क में कॉपी किए जाने वाले मॉड्यूल की सूची है.
  • BOARD_VENDOR_RAMDISK_KERNEL_MODULES_LOAD. यह पहले चरण की init प्रोसेस में लोड किए जाने वाले मॉड्यूल की सूची है.
  • BOARD_VENDOR_RAMDISK_RECOVERY_KERNEL_MODULES_LOAD. यह उन मॉड्यूल की सूची है जिन्हें रैमडिस्क से रिकवरी या fastbootd चुनने पर लोड किया जाता है.
  • BOARD_VENDOR_KERNEL_MODULES. यह उन मॉड्यूल की सूची है जिन्हें /vendor/lib/modules/ डायरेक्ट्री में, वेंडर या vendor_dlkm पार्टिशन में कॉपी किया जाता है.
  • BOARD_VENDOR_KERNEL_MODULES_LOAD. यह दूसरे चरण की init प्रोसेस में लोड किए जाने वाले मॉड्यूल की सूची है.

रैमडिस्क में मौजूद बूट और रिकवरी मॉड्यूल को, वेंडर या vendor_dlkm पार्टिशन में /vendor/lib/modules पर भी कॉपी किया जाना चाहिए. इन मॉड्यूल को वेंडर पार्टिशन में कॉपी करने से, यह पक्का हो जाता है कि दूसरे चरण की init प्रोसेस के दौरान, मॉड्यूल दिखते रहें. यह डीबग करने और गड़बड़ी की रिपोर्ट के लिए modinfo इकट्ठा करने में मददगार होता है.

जब तक बूट मॉड्यूल सेट कम से कम हो, तब तक डुप्लीकेशन से वेंडर या vendor_dlkm पार्टिशन पर कम से कम जगह खर्च होनी चाहिए. पक्का करें कि वेंडर की modules.list फ़ाइल में, /vendor/lib/modules में मौजूद मॉड्यूल की फ़िल्टर की गई सूची हो. फ़िल्टर की गई सूची से यह पक्का हो जाता है कि मॉड्यूल को फिर से लोड करने से, बूट होने में लगने वाले समय पर असर न पड़े. यह एक महंगी प्रोसेस है.

पक्का करें कि रिकवरी मोड के मॉड्यूल, ग्रुप के तौर पर लोड हों. रिकवरी मोड के मॉड्यूल को, रिकवरी मोड में या हर बूट फ़्लो में दूसरे चरण की init प्रोसेस की शुरुआत में लोड किया जा सकता है.

डिवाइस की Board.Config.mk फ़ाइलों का इस्तेमाल करके, ये कार्रवाइयां की जा सकती हैं. इसके लिए, यहां दिया गया उदाहरण देखें:

# All kernel modules
KERNEL_MODULES := $(wildcard $(KERNEL_MODULE_DIR)/*.ko)
KERNEL_MODULES_LOAD := $(strip $(shell cat $(KERNEL_MODULE_DIR)/modules.load)

# First stage ramdisk modules
BOOT_KERNEL_MODULES_FILTER := $(foreach m,$(BOOT_KERNEL_MODULES),%/$(m))

# Recovery ramdisk modules
RECOVERY_KERNEL_MODULES_FILTER := $(foreach m,$(RECOVERY_KERNEL_MODULES),%/$(m))
BOARD_VENDOR_RAMDISK_KERNEL_MODULES += \
     $(filter $(BOOT_KERNEL_MODULES_FILTER) \
                $(RECOVERY_KERNEL_MODULES_FILTER),$(KERNEL_MODULES))

# ALL modules land in /vendor/lib/modules so they could be rmmod/insmod'd,
# and modules.list actually limits us to the ones we intend to load.
BOARD_VENDOR_KERNEL_MODULES := $(KERNEL_MODULES)
# To limit /vendor/lib/modules to just the ones loaded, use:
# BOARD_VENDOR_KERNEL_MODULES := $(filter-out \
#     $(BOOT_KERNEL_MODULES_FILTER),$(KERNEL_MODULES))

# Group set of /vendor/lib/modules loading order to recovery modules first,
# then remainder, subtracting both recovery and boot modules which are loaded
# already.
BOARD_VENDOR_KERNEL_MODULES_LOAD := \
        $(filter-out $(BOOT_KERNEL_MODULES_FILTER), \
        $(filter $(RECOVERY_KERNEL_MODULES_FILTER),$(KERNEL_MODULES_LOAD)))
BOARD_VENDOR_KERNEL_MODULES_LOAD += \
        $(filter-out $(BOOT_KERNEL_MODULES_FILTER) \
            $(RECOVERY_KERNEL_MODULES_FILTER),$(KERNEL_MODULES_LOAD))

# NB: Load order governed by modules.load and not by $(BOOT_KERNEL_MODULES)
BOARD_VENDOR_RAMDISK_KERNEL_MODULES_LOAD := \
        $(filter $(BOOT_KERNEL_MODULES_FILTER),$(KERNEL_MODULES_LOAD))

# Group set of /vendor/lib/modules loading order to boot modules first,
# then the remainder of recovery modules.
BOARD_VENDOR_RAMDISK_RECOVERY_KERNEL_MODULES_LOAD := \
    $(filter $(BOOT_KERNEL_MODULES_FILTER),$(KERNEL_MODULES_LOAD))
BOARD_VENDOR_RAMDISK_RECOVERY_KERNEL_MODULES_LOAD += \
    $(filter-out $(BOOT_KERNEL_MODULES_FILTER), \
    $(filter $(RECOVERY_KERNEL_MODULES_FILTER),$(KERNEL_MODULES_LOAD)))

इस उदाहरण में, बोर्ड कॉन्फ़िगरेशन फ़ाइलों में स्थानीय तौर पर तय किए जाने वाले BOOT_KERNEL_MODULES और RECOVERY_KERNEL_MODULES के सबसेट को आसानी से मैनेज करने का तरीका दिखाया गया है. पहले वाली स्क्रिप्ट, चुने गए उपलब्ध कर्नेल मॉड्यूल से सबसेट के हर मॉड्यूल को ढूंढती है और भरती है. इसके बाद, बचे हुए मॉड्यूल को दूसरे चरण की init प्रोसेस के लिए छोड़ देती है.

दूसरे चरण की init प्रोसेस के लिए, हमारा सुझाव है कि मॉड्यूल लोड करने की प्रोसेस को सेवा के तौर पर चलाएं, ताकि यह बूट फ़्लो को ब्लॉक न करे. मॉड्यूल लोड करने की प्रोसेस को मैनेज करने के लिए, शेल स्क्रिप्ट का इस्तेमाल करें, ताकि ज़रूरत पड़ने पर गड़बड़ी को ठीक करने और कम करने या मॉड्यूल लोड होने की प्रोसेस पूरी होने जैसी अन्य लॉजिस्टिक्स की जानकारी दी जा सके या उन्हें अनदेखा किया जा सके.

डीबग मॉड्यूल लोड होने में होने वाली गड़बड़ी को अनदेखा किया जा सकता है. यह गड़बड़ी, उपयोगकर्ता के बिल्ड में मौजूद नहीं होती. इस गड़बड़ी को अनदेखा करने के लिए, vendor.device.modules.ready प्रॉपर्टी सेट करें, ताकि init rc स्क्रिप्टिंग बूटफ़्लो के बाद के चरण, लॉन्च स्क्रीन पर जारी रहें. यहां दी गई स्क्रिप्ट का उदाहरण देखें, अगर आपके पास /vendor/etc/init.insmod.sh में यह कोड है:

#!/vendor/bin/sh
. . .
if [ $# -eq 1 ]; then
  cfg_file=$1
else
  # Set property even if there is no insmod config
  # to unblock early-boot trigger
  setprop vendor.common.modules.ready
  setprop vendor.device.modules.ready
  exit 1
fi

if [ -f $cfg_file ]; then
  while IFS="|" read -r action arg
  do
    case $action in
      "insmod") insmod $arg ;;
      "setprop") setprop $arg 1 ;;
      "enable") echo 1 > $arg ;;
      "modprobe") modprobe -a -d /vendor/lib/modules $arg ;;
     . . .
    esac
  done < $cfg_file
fi

हार्डवेयर rc फ़ाइल में, one shot सेवा को इसके साथ तय किया जा सकता है:

service insmod-sh /vendor/etc/init.insmod.sh /vendor/etc/init.insmod.<hw>.cfg
    class main
    user root
    group root system
    Disabled
    oneshot

मॉड्यूल को पहले चरण से दूसरे चरण में ले जाने के बाद, अतिरिक्त ऑप्टिमाइज़ेशन किए जा सकते हैं. दूसरे चरण के बूट फ़्लो को अलग-अलग हिस्सों में बांटने के लिए, modprobe ब्लॉकलिस्ट सुविधा का इस्तेमाल किया जा सकता है. इससे, गैर-ज़रूरी मॉड्यूल को बाद में लोड किया जा सकता है. किसी खास HAL के लिए इस्तेमाल किए जाने वाले मॉड्यूल को, HAL शुरू होने पर ही लोड करने के लिए डिफ़र किया जा सकता है.

बूट होने में लगने वाले समय को कम करने के लिए, मॉड्यूल लोड करने की सेवा में खास तौर पर उन मॉड्यूल को चुना जा सकता है जिन्हें लॉन्च स्क्रीन के बाद लोड करना ज़्यादा आसान होता है. उदाहरण के लिए, init बूट फ़्लो के साफ़ होने के बाद, वीडियो डिकोडर या वाई-फ़ाई के मॉड्यूल को साफ़ तौर पर देर से लोड किया जा सकता है. जैसे, sys.boot_complete Android प्रॉपर्टी सिग्नल. पक्का करें कि देर से लोड होने वाले मॉड्यूल के लिए, HALs तब तक ब्लॉक रहें, जब तक कर्नेल ड्राइवर मौजूद न हों.

इसके अलावा, बूट फ़्लो rc स्क्रिप्टिंग में init के wait<file>[<timeout>] कमांड का इस्तेमाल करके, चुने गए sysfs एंट्री के लिए इंतज़ार किया जा सकता है. इससे यह पता चलता है कि ड्राइवर मॉड्यूल ने प्रोब ऑपरेशन पूरे कर लिए हैं. इसका एक उदाहरण है, मेन्यू ग्राफ़िक्स दिखाने से पहले, रिकवरी या fastbootd के बैकग्राउंड में डिसप्ले ड्राइवर के लोड होने का इंतज़ार करना.

बूटलोडर में सीपीयू की फ़्रीक्वेंसी को सही वैल्यू पर इनिशियलाइज़ करना

बूट लूप टेस्ट के दौरान, थर्मल या पावर से जुड़ी समस्याओं की वजह से, हो सकता है कि सभी एसओसी/प्रॉडक्ट, सीपीयू को सबसे ज़्यादा फ़्रीक्वेंसी पर बूट न कर पाएं. हालांकि, पक्का करें कि बूटलोडर, सभी ऑनलाइन सीपीयू की फ़्रीक्वेंसी को किसी एसओसी या प्रॉडक्ट के लिए, सुरक्षित तरीके से ज़्यादा से ज़्यादा सेट करे. यह बहुत ज़रूरी है, क्योंकि पूरी तरह से मॉड्यूलर कर्नेल के साथ, init रैमडिस्क डीकंप्रेशन, CPUfreq ड्राइवर लोड होने से पहले होता है. इसलिए, अगर बूटलोडर, सीपीयू की फ़्रीक्वेंसी को कम रखता है, तो रैमडिस्क डीकंप्रेशन में, स्टैटिक तरीके से कंपाइल किए गए कर्नेल की तुलना में ज़्यादा समय लग सकता है. ऐसा इसलिए, क्योंकि सीपीयू इंटेंसिव काम (डीकंप्रेशन) करते समय, सीपीयू की फ़्रीक्वेंसी बहुत कम होगी. मेमोरी और इंटरकनेक्ट फ़्रीक्वेंसी पर भी यही नियम लागू होता है.

बूटलोडर में बड़े सीपीयू की फ़्रीक्वेंसी को इनिशियलाइज़ करना

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

पक्का करें कि बूटलोडर, बड़े सीपीयू को जिस फ़्रीक्वेंसी पर छोड़ता है, उस फ़्रीक्वेंसी पर उनकी परफ़ॉर्मेंस, छोटे सीपीयू की परफ़ॉर्मेंस के बराबर हो. उदाहरण के लिए, अगर बड़ी सीपीयू की परफ़ॉर्मेंस, एक ही फ़्रीक्वेंसी के लिए छोटे सीपीयू की परफ़ॉर्मेंस से दोगुनी है, लेकिन बूटलोडर, छोटे सीपीयू की फ़्रीक्वेंसी को 1.5 GHz और बड़े सीपीयू की फ़्रीक्वेंसी को 300 MHz पर सेट करता है, तो कर्नेल के किसी थ्रेड को बड़े सीपीयू पर ले जाने पर, बूट परफ़ॉर्मेंस कम हो जाएगी. इस उदाहरण में, अगर बड़े सीपीयू को 750 MHz पर बूट करना सुरक्षित है, तो आपको ऐसा करना चाहिए. भले ही, इसे साफ़ तौर पर इस्तेमाल करने की आपकी कोई योजना न हो.

ड्राइवर को पहले चरण की init प्रोसेस में फ़र्मवेयर लोड नहीं करना चाहिए

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