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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

सीपीयू फ़्रीक्वेंसी ड्राइवर की जांच जल्द से जल्द करें

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

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

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

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

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

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

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

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

  • watchdog
  • reset
  • cpufreq

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

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

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

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

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

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

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

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

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

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

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

इन कार्रवाइयों को करने के लिए, डिवाइस 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 के सबसेट को मैनेज करने का आसान तरीका दिखाया गया है. इन्हें बोर्ड कॉन्फ़िगरेशन फ़ाइलों में स्थानीय तौर पर तय किया जाता है. ऊपर दी गई स्क्रिप्ट, चुने गए उपलब्ध कर्नल मॉड्यूल से हर सबसेट मॉड्यूल को ढूंढती है और भरती है. साथ ही, दूसरे चरण के लिए बाकी मॉड्यूल छोड़ देती है.

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

अगर उपयोगकर्ता की बिल्ड में डीबग मॉड्यूल लोड नहीं हो रहा है, तो उसे अनदेखा किया जा सकता है. इस गड़बड़ी को अनदेखा करने के लिए, 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 ब्लॉकलिस्ट सुविधा का इस्तेमाल करके, दूसरे चरण के बूट फ़्लो को अलग-अलग हिस्सों में बांटा जा सकता है. इससे, गै़र-ज़रूरी मॉड्यूल को बाद में लोड किया जा सकता है. किसी खास एचएएल के लिए इस्तेमाल किए जाने वाले मॉड्यूल को लोड करने में देरी की जा सकती है. ऐसा इसलिए किया जा सकता है, ताकि एचएएल शुरू होने पर ही मॉड्यूल लोड हों.

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

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

बूटलोडर में सीपीयू की फ़्रीक्वेंसी को सही वैल्यू पर सेट करें

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

बूटलोडर में बड़े सीपीयू की सीपीयू फ़्रीक्वेंसी को शुरू करता है

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

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

ड्राइवरों को पहले चरण की शुरुआत में फ़र्मवेयर लोड नहीं करना चाहिए

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