बूट टाइम ऑप्टिमाइज़ेशन

इस पेज पर, डिवाइस के चालू होने में लगने वाले समय को कम करने के बारे में सलाह दी गई है.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

अपने CPUfreq ड्राइवर की जांच जल्द से जल्द करें

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

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

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

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

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

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

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

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

  • watchdog
  • reset
  • cpufreq

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

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

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

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

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

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

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

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

दूसरे चरण के 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

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

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

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

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

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

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

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

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

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

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