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

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

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

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

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

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

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

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

Gzip, LZ4 की तुलना में छोटा कंप्रेस किया गया आउटपुट जनरेट करता है. हालांकि, 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 ड्राइवर से पहले थर्मल ड्राइवर लोड करने पड़ें. इसलिए, यह पक्का करने के लिए अपनी पूरी कोशिश करें कि CPUfreq और काम के devfreq ड्राइवर, जितनी जल्दी हो सके उतनी जल्दी जांच कर लें.

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

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

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

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

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

  • watchdog
  • reset
  • cpufreq

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

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

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

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

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

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

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

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

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

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

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