การเพิ่มประสิทธิภาพเวลาในการบูต

หน้านี้มีเคล็ดลับในการปรับปรุงเวลาบูต

ลบสัญลักษณ์การแก้ไขข้อบกพร่องออกจากโมดูล

ตรวจสอบว่าคุณได้ลบสัญลักษณ์การแก้ไขข้อบกพร่องออกจากโมดูลด้วยเช่นกัน ซึ่งคล้ายกับวิธีลบสัญลักษณ์การแก้ไขข้อบกพร่องออกจากเคอร์เนลในอุปกรณ์ที่ใช้งานจริง การลบสัญลักษณ์การแก้ไขข้อบกพร่องออกจากโมดูลจะช่วยลดเวลาบูตด้วยการลดสิ่งต่อไปนี้

  • เวลาที่ใช้ในการอ่านไบนารีจากหน่วยความจำแฟลช
  • เวลาที่ใช้ในการคลายการบีบอัด ramdisk
  • เวลาที่ใช้ในการโหลดโมดูล

การลบสัญลักษณ์การแก้ไขข้อบกพร่องออกจากโมดูลอาจช่วยประหยัดเวลาได้หลายวินาทีระหว่างการบูต

ระบบจะเปิดใช้การลบสัญลักษณ์โดยค่าเริ่มต้นในการสร้างแพลตฟอร์ม Android แต่ หากต้องการเปิดใช้โดยชัดแจ้ง ให้ตั้งค่า BOARD_DO_NOT_STRIP_VENDOR_RAMDISK_MODULES ในการกำหนดค่าเฉพาะอุปกรณ์ ภายใต้ device/vendor/device

ใช้การบีบอัด LZ4 สำหรับเคอร์เนลและ ramdisk

Gzip จะสร้างเอาต์พุตที่บีบอัดแล้วซึ่งมีขนาดเล็กกว่าเมื่อเทียบกับ LZ4 แต่ LZ4 จะคลายการบีบอัดได้เร็วกว่า Gzip สำหรับเคอร์เนลและโมดูล การลดขนาดพื้นที่เก็บข้อมูลแบบสัมบูรณ์จากการใช้ Gzip ไม่ได้มีความสำคัญมากนักเมื่อเทียบกับประโยชน์ด้านเวลาในการคลายการบีบอัดของ LZ4

เราได้เพิ่มการรองรับการบีบอัด ramdisk LZ4 ลงในการสร้างแพลตฟอร์ม Android ผ่าน BOARD_RAMDISK_USE_LZ4 คุณสามารถตั้งค่าตัวเลือกนี้ในการกำหนดค่าเฉพาะอุปกรณ์ และตั้งค่าการบีบอัดเคอร์เนลได้ผ่าน kernel defconfig

การเปลี่ยนไปใช้ LZ4 จะช่วยลดเวลาบูตได้ 500-1,000 มิลลิวินาที

หลีกเลี่ยงการบันทึกมากเกินไปในไดรเวอร์

ใน ARM64 และ ARM32 การเรียกใช้ฟังก์ชันที่อยู่ห่างจากตำแหน่งที่เรียกใช้มากกว่าระยะทางที่กำหนดจะต้องใช้ตารางการข้าม (เรียกว่าตารางการลิงก์ขั้นตอนหรือ PLT) เพื่อให้สามารถเข้ารหัสที่อยู่การข้ามแบบเต็มได้ เนื่องจากระบบจะโหลดโมดูลแบบไดนามิก จึงต้องแก้ไขตารางการข้ามเหล่านี้ระหว่างการโหลดโมดูล การเรียกใช้ที่ต้องมีการย้ายตำแหน่งเรียกว่ารายการย้ายตำแหน่งที่มีตัวถูกดำเนินการที่ชัดแจ้ง (หรือ RELA โดยย่อ) ในรูปแบบ ELF

เคอร์เนล Linux จะเพิ่มประสิทธิภาพขนาดหน่วยความจำบางอย่าง (เช่น การเพิ่มประสิทธิภาพการเข้าถึงแคช) เมื่อจัดสรร PLT การคอมมิตต้นทางนี้ทำให้รูปแบบการเพิ่มประสิทธิภาพมีความซับซ้อน O(N^2) โดยที่ N คือจำนวน RELA ประเภท R_AARCH64_JUMP26 หรือ R_AARCH64_CALL26 ดังนั้น การมี RELA ประเภทนี้น้อยลงจึงช่วยลดเวลาที่ใช้ในการโหลดโมดูลได้

รูปแบบการเขียนโค้ดที่พบบ่อยซึ่งเพิ่มจำนวน RELA R_AARCH64_CALL26 หรือ R_AARCH64_JUMP26 คือการบันทึกมากเกินไปในไดรเวอร์ โดยปกติแล้ว การเรียกใช้ printk() หรือรูปแบบการบันทึกอื่นๆ จะเพิ่มรายการ RELA CALL26/JUMP26 ในข้อความคอมมิตในการคอมมิตต้นทาง คอมมิต, ให้สังเกตว่าแม้จะมีการเพิ่มประสิทธิภาพแล้ว โมดูลทั้ง 6 โมดูลก็ยังใช้เวลาโหลดประมาณ 250 มิลลิวินาที ซึ่งเป็นเพราะโมดูลทั้ง 6 โมดูลนี้เป็นโมดูล 6 อันดับแรกที่มี การบันทึกมากที่สุด

การลดการบันทึกอาจช่วยลดเวลาบูตได้ประมาณ 100-300 มิลลิวินาที ทั้งนี้ขึ้นอยู่กับปริมาณการบันทึกที่มีอยู่

เปิดใช้การตรวจสอบแบบไม่พร้อมกันอย่างเลือกสรร

เมื่อโหลดโมดูล หากระบบได้ป้อนข้อมูลอุปกรณ์ที่โมดูลรองรับจาก DT (devicetree) และเพิ่มลงในไดรเวอร์หลักแล้ว การตรวจสอบอุปกรณ์จะดำเนินการในบริบทของการเรียกใช้ module_init() เมื่อดำเนินการตรวจสอบอุปกรณ์ในบริบทของ module_init() โมดูลจะโหลดไม่เสร็จจนกว่าการตรวจสอบจะเสร็จสมบูรณ์ เนื่องจากการโหลดโมดูลส่วนใหญ่เป็นแบบอนุกรม อุปกรณ์ที่ใช้เวลาตรวจสอบค่อนข้างนานจะทำให้เวลาบูตช้าลง

หากต้องการหลีกเลี่ยงเวลาบูตที่ช้าลง ให้เปิดใช้การตรวจสอบแบบไม่พร้อมกันสำหรับโมดูลที่ใช้เวลาตรวจสอบอุปกรณ์นาน การเปิดใช้การตรวจสอบแบบอะซิงโครนัสสำหรับโมดูลทั้งหมดอาจไม่เป็นประโยชน์ เนื่องจากเวลาที่ใช้ในการฟอร์กเทรดและเริ่มการตรวจสอบอาจสูงเท่ากับเวลาที่ใช้ในการตรวจสอบอุปกรณ์

อุปกรณ์ที่เชื่อมต่อผ่านบัสที่ช้า เช่น I2C, อุปกรณ์ที่โหลดเฟิร์มแวร์ในฟังก์ชันการตรวจสอบ และอุปกรณ์ที่เริ่มต้นฮาร์ดแวร์จำนวนมากอาจทำให้เกิดปัญหาด้านเวลา วิธีที่ดีที่สุดในการระบุว่าปัญหานี้เกิดขึ้นเมื่อใดคือการรวบรวมเวลาตรวจสอบสำหรับไดรเวอร์ทุกตัวและจัดเรียง

หากต้องการเปิดใช้การตรวจสอบแบบไม่พร้อมกันสำหรับโมดูล การตั้งค่าแฟล็ก PROBE_PREFER_ASYNCHRONOUS ไม่ เพียงพอ สำหรับโมดูล คุณต้องเพิ่ม module_name.async_probe=1 ในบรรทัดคำสั่งเคอร์เนล หรือส่ง async_probe=1 เป็นพารามิเตอร์โมดูลเมื่อโหลดโมดูลโดยใช้ modprobe หรือ insmod

การเปิดใช้การตรวจสอบแบบไม่พร้อมกันอาจช่วยลดเวลาบูตได้ประมาณ 100-500 มิลลิวินาที ทั้งนี้ขึ้นอยู่กับฮาร์ดแวร์/ไดรเวอร์

ตรวจสอบไดรเวอร์ CPUfreq โดยเร็วที่สุด

ไดรเวอร์ CPUfreq ตรวจสอบเร็วเท่าใด คุณก็จะปรับขนาดความถี่ CPU เป็นสูงสุด (หรือสูงสุดที่จำกัดด้วยความร้อน) ได้เร็วขึ้นเท่านั้นระหว่างการบูต CPU เร็วขึ้นเท่าใด การบูตก็จะเร็วขึ้นเท่านั้น หลักเกณฑ์นี้ใช้กับไดรเวอร์ devfreq ที่ควบคุมความถี่ DRAM, หน่วยความจำ และการเชื่อมต่อระหว่างกันด้วย

สำหรับโมดูล ลำดับการโหลดอาจขึ้นอยู่กับระดับ initcall และลำดับการคอมไพล์หรือลิงก์ของไดรเวอร์ ใช้นามแฝง MODULE_SOFTDEP() เพื่อให้แน่ใจว่าไดรเวอร์ cpufreq เป็นหนึ่งในโมดูลแรกๆ ที่โหลด

นอกจากการโหลดโมดูลก่อนแล้ว คุณยังต้องตรวจสอบว่ามีการตรวจสอบการขึ้นอยู่ทั้งหมดเพื่อตรวจสอบไดรเวอร์ CPUfreq แล้วด้วย ตัวอย่างเช่น หากคุณต้องใช้แฮนเดิลนาฬิกาหรือตัวควบคุมเพื่อควบคุมความถี่ของ CPU ให้ตรวจสอบว่ามีการตรวจสอบแฮนเดิลเหล่านั้นก่อน หรือคุณอาจต้องโหลดไดรเวอร์ความร้อนก่อนไดรเวอร์ CPUfreq หาก CPU อาจร้อนเกินไประหว่างการบูต ดังนั้น ให้ทำทุกวิถีทางเพื่อให้แน่ใจว่าไดรเวอร์ CPUfreq และไดรเวอร์ devfreq ที่เกี่ยวข้องจะตรวจสอบโดยเร็วที่สุด

การประหยัดเวลาจากการตรวจสอบไดรเวอร์ CPUfreq ก่อนอาจมีขนาดเล็กมากไปจนถึงใหญ่มาก ทั้งนี้ขึ้นอยู่กับว่าคุณจะตรวจสอบไดรเวอร์เหล่านี้ได้เร็วเพียงใด และ Bootloader จะตั้งค่าความถี่ของ CPU ไว้ที่เท่าใด

ย้ายโมดูลไปยังการเริ่มต้นระยะที่ 2, พาร์ติชันของผู้ให้บริการหรือ `vendor_dlkm`

เนื่องจากกระบวนการเริ่มต้นระยะที่ 1 เป็นแบบอนุกรม จึงมีโอกาสไม่มากนักที่จะขนานกระบวนการบูต หากไม่จำเป็นต้องใช้โมดูลสำหรับการเริ่มต้นระยะที่ 1 ให้เสร็จสิ้น ให้ย้ายโมดูลไปยังการเริ่มต้นระยะที่ 2 โดยวางไว้ในพาร์ติชันของผู้ให้บริการหรือ vendor_dlkm

การเริ่มต้นระยะที่ 1 ไม่จำเป็นต้องตรวจสอบอุปกรณ์หลายเครื่องเพื่อไปยังการเริ่มต้นระยะที่ 2 การบูตตามปกติจะต้องใช้ความสามารถของคอนโซลและพื้นที่เก็บข้อมูลแฟลชเท่านั้น

โหลดไดรเวอร์ที่จำเป็นต่อไปนี้

  • watchdog
  • reset
  • cpufreq

สำหรับการกู้คืนและโหมด fastbootd ในพื้นที่ผู้ใช้ การเริ่มต้นระยะที่ 1 ต้องตรวจสอบอุปกรณ์เพิ่มเติม (เช่น USB) และจอแสดงผล เก็บสำเนาโมดูลเหล่านี้ไว้ใน ramdisk ระยะที่ 1 และในพาร์ติชันของผู้ให้บริการหรือ vendor_dlkm ซึ่งจะช่วยให้โหลดโมดูลเหล่านี้ในการเริ่มต้นระยะที่ 1 สำหรับการกู้คืนหรือโฟลว์การบูต fastbootd ได้ อย่างไรก็ตาม อย่าโหลดโมดูลโหมดการกู้คืนในการเริ่มต้นระยะที่ 1 ระหว่างโฟลว์การบูตตามปกติ คุณสามารถเลื่อนโมดูลโหมดการกู้คืน [Recovery mode] ไปยังการเริ่มต้นระยะที่ 2 เพื่อลดเวลาบูตได้ และย้ายโมดูลอื่นๆ ทั้งหมดที่ไม่จำเป็นในการเริ่มต้นระยะที่ 1 ไปยังพาร์ติชันของผู้ให้บริการหรือ vendor_dlkm

สคริปต์ dev needs.sh จะค้นหาไดรเวอร์ อุปกรณ์ และโมดูลทั้งหมดที่จำเป็นสำหรับการขึ้นอยู่หรือ ซัพพลายเออร์ (เช่น นาฬิกา ตัวควบคุม หรือ gpio) เพื่อตรวจสอบ โดยพิจารณาจากรายการอุปกรณ์ปลายทาง (เช่น UFS หรือ Serial)

การย้ายโมดูลไปยังการเริ่มต้นระยะที่ 2 จะช่วยลดเวลาบูตด้วยวิธีต่อไปนี้

  • การลดขนาด ramdisk
    • ซึ่งจะช่วยให้การอ่านแฟลชเร็วขึ้นเมื่อ Bootloader โหลด ramdisk (ขั้นตอนการบูตแบบอนุกรม)
    • ซึ่งจะช่วยให้ความเร็วในการคลายการบีบอัดเร็วขึ้นเมื่อเคอร์เนลคลายการบีบอัด ramdisk (ขั้นตอนการบูตแบบอนุกรม)
  • การเริ่มต้นระยะที่ 2 ทำงานแบบขนาน ซึ่งจะซ่อนเวลาในการโหลดโมดูลด้วยงานที่ทำในการเริ่มต้นระยะที่ 2

การย้ายโมดูลไปยังระยะที่ 2 อาจช่วยลดเวลาบูตได้ 500-1,000 มิลลิวินาที ทั้งนี้ขึ้นอยู่กับจำนวนโมดูลที่คุณย้ายไปยังการเริ่มต้นระยะที่ 2 ได้

โลจิสติกส์การโหลดโมดูล

การสร้าง Android เวอร์ชันล่าสุดมีการกำหนดค่าบอร์ดที่ควบคุมโมดูลที่จะคัดลอกไปยังแต่ละระยะ และโมดูลที่จะโหลด ส่วนนี้จะเน้นที่ชุดย่อยต่อไปนี้

  • BOARD_VENDOR_RAMDISK_KERNEL_MODULESรายการโมดูลที่จะคัดลอกลงใน ramdisk
  • BOARD_VENDOR_RAMDISK_KERNEL_MODULES_LOADรายการโมดูลที่จะโหลดในการเริ่มต้นระยะที่ 1
  • BOARD_VENDOR_RAMDISK_RECOVERY_KERNEL_MODULES_LOADรายการโมดูลที่จะโหลดเมื่อเลือกการกู้คืนหรือ fastbootd จาก ramdisk
  • BOARD_VENDOR_KERNEL_MODULES รายการโมดูลที่จะคัดลอกลงในพาร์ติชันของผู้ให้บริการหรือ vendor_dlkm ในไดเรกทอรี /vendor/lib/modules/
  • BOARD_VENDOR_KERNEL_MODULES_LOADรายการโมดูลที่จะโหลดในการเริ่มต้นระยะที่ 2

นอกจากนี้ คุณต้องคัดลอกโมดูลการบูตและการกู้คืนใน ramdisk ไปยังพาร์ติชันของผู้ให้บริการหรือ vendor_dlkm ที่ /vendor/lib/modules ด้วย การคัดลอกโมดูลเหล่านี้ไปยังพาร์ติชันของผู้ให้บริการจะช่วยให้มั่นใจได้ว่าโมดูลจะไม่มองไม่เห็นระหว่างการเริ่มต้นระยะที่ 2 ซึ่งจะเป็นประโยชน์สำหรับการแก้ไขข้อบกพร่องและการรวบรวม modinfo สำหรับรายงานข้อบกพร่อง

การทำซ้ำควรใช้พื้นที่น้อยที่สุดในพาร์ติชันของผู้ให้บริการหรือ vendor_dlkm ตราบใดที่ชุดโมดูลการบูตมีขนาดเล็กที่สุด ตรวจสอบว่าไฟล์ modules.list ของผู้ให้บริการมีรายการโมดูลที่กรองแล้วใน /vendor/lib/modules รายการที่กรองแล้วจะช่วยให้มั่นใจได้ว่าเวลาบูตจะไม่ได้รับผลกระทบจากการโหลดโมดูลอีกครั้ง (ซึ่งเป็นกระบวนการที่ใช้ทรัพยากรมาก)

ตรวจสอบว่าโมดูลโหมดการกู้คืนโหลดเป็นกลุ่ม คุณสามารถโหลดโมดูลโหมดการกู้คืนได้ทั้งในโหมดการกู้คืนหรือที่จุดเริ่มต้นของการเริ่มต้นระยะที่ 2 ในโฟลว์การบูตแต่ละรายการ

คุณสามารถใช้ไฟล์ 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 ที่จัดการได้ง่ายขึ้น ซึ่งจะระบุไว้ในไฟล์การกำหนดค่าบอร์ดในเครื่อง สคริปต์ก่อนหน้าจะค้นหาและเติมโมดูลชุดย่อยแต่ละโมดูลจากโมดูลเคอร์เนลที่มีอยู่ซึ่งเลือกไว้ โดยจะเหลือโมดูลที่เหลือไว้สำหรับการเริ่มต้นระยะที่ 2

สำหรับการเริ่มต้นระยะที่ 2 เราขอแนะนำให้เรียกใช้การโหลดโมดูลเป็นบริการเพื่อไม่ให้บล็อกโฟลว์การบูต ใช้สคริปต์เชลล์เพื่อจัดการการโหลดโมดูล เพื่อให้ระบบรายงาน (หรือละเว้น) โลจิสติกส์อื่นๆ เช่น การจัดการและการลดข้อผิดพลาด หรือการโหลดโมดูลเสร็จสมบูรณ์ได้หากจำเป็น

คุณสามารถละเว้นความล้มเหลวในการโหลดโมดูลการแก้ไขข้อบกพร่องที่ไม่มีในการสร้างของผู้ใช้ หากต้องการละเว้นความล้มเหลวนี้ ให้ตั้งค่าพร็อพเพอร์ตี้ 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

คุณสามารถทำการเพิ่มประสิทธิภาพเพิ่มเติมได้หลังจากที่โมดูลย้ายจากระยะที่ 1 ไปยังระยะที่ 2 คุณสามารถใช้ฟีเจอร์บล็อกลิสต์ modprobe เพื่อแยกโฟลว์การบูตระยะที่ 2 ออกเป็นส่วนๆ เพื่อรวมการโหลดโมดูลแบบเลื่อนออกของโมดูลที่ไม่จำเป็น คุณสามารถเลื่อนการโหลดโมดูลที่ใช้โดย HAL เฉพาะออกไปเพื่อโหลดโมดูลเมื่อ HAL เริ่มทำงานแล้วเท่านั้น

หากต้องการปรับปรุงเวลาบูตที่ปรากฏ คุณสามารถเลือกโมดูลในบริการโหลดโมดูลที่เหมาะกับการโหลดหลังจากหน้าจอเปิดตัวได้โดยเฉพาะ ตัวอย่างเช่น คุณสามารถโหลดโมดูลสำหรับตัวถอดรหัสวิดีโอหรือ Wi-Fi แบบเลื่อนออกได้โดยชัดแจ้งหลังจากที่โฟลว์การบูต init เสร็จสิ้นแล้ว (เช่น สัญญาณพร็อพเพอร์ตี้ sys.boot_complete ของ Android) ตรวจสอบว่า HAL สำหรับโมดูลการโหลดแบบเลื่อนออกบล็อกนานพอเมื่อไม่มีไดรเวอร์เคอร์เนล

หรือคุณสามารถใช้คำสั่ง wait<file>[<timeout>] ของ init ในสคริปต์ rc ของโฟลว์การบูต เพื่อรอให้รายการ sysfs ที่เลือกแสดงว่าโมดูลไดรเวอร์ ดำเนินการตรวจสอบเสร็จสมบูรณ์แล้ว ตัวอย่างเช่น การรอให้ไดรเวอร์จอแสดงผลโหลดเสร็จสมบูรณ์ในเบื้องหลังของการกู้คืนหรือ fastbootd ก่อนที่จะแสดงกราฟิกเมนู

เริ่มต้นความถี่ CPU เป็นค่าที่เหมาะสมใน Bootloader

SoC/ผลิตภัณฑ์บางอย่างอาจบูต CPU ที่ความถี่สูงสุดไม่ได้เนื่องจากปัญหาด้านความร้อนหรือพลังงานระหว่างการทดสอบการบูตวนซ้ำ อย่างไรก็ตาม ตรวจสอบว่า Bootloader ตั้งค่าความถี่ของ CPU ทั้งหมดที่ออนไลน์ไว้สูงที่สุดเท่าที่จะเป็นไปได้สำหรับ SoC หรือผลิตภัณฑ์ ซึ่งเป็นสิ่งสำคัญมากเนื่องจากเคอร์เนลแบบแยกโมดูลทั้งหมดจะคลายการบีบอัด init ramdisk ก่อนที่จะโหลดไดรเวอร์ CPUfreq ได้ ดังนั้น หาก Bootloader ตั้งค่าความถี่ของ CPU ไว้ที่ระดับต่ำสุด เวลาในการคลายการบีบอัด ramdisk อาจใช้เวลานานกว่าเคอร์เนลที่คอมไพล์แบบคงที่ (หลังจากปรับความแตกต่างของขนาด ramdisk แล้ว) เนื่องจากความถี่ CPU จะต่ำมากเมื่อทำงานที่ใช้ CPU มาก (การคลายการบีบอัด) หลักการเดียวกันนี้ใช้กับความถี่ของหน่วยความจำและการเชื่อมต่อระหว่างกัน

เริ่มต้นความถี่ CPU ของ CPU ขนาดใหญ่ใน Bootloader

ก่อนที่จะโหลดไดรเวอร์ CPUfreq เคอร์เนลจะไม่ทราบความถี่ CPU และจะไม่ปรับขนาดความจุของตัวกำหนดเวลา CPU สำหรับความถี่ปัจจุบัน เคอร์เนลอาจย้ายเธรดไปยัง CPU ขนาดใหญ่หากโหลดสูงพอใน CPU ขนาดเล็ก

ตรวจสอบว่า CPU ขนาดใหญ่มีประสิทธิภาพอย่างน้อยเท่ากับ CPU ขนาดเล็กสำหรับความถี่ที่ Bootloader ตั้งค่าไว้ ตัวอย่างเช่น หาก CPU ขนาดใหญ่มีประสิทธิภาพมากกว่า CPU ขนาดเล็ก 2 เท่าสำหรับความถี่เดียวกัน แต่ Bootloader ตั้งค่าความถี่ของ CPU ขนาดเล็กไว้ที่ 1.5 GHz และความถี่ของ CPU ขนาดใหญ่ไว้ที่ 300 MHz ประสิทธิภาพการบูตจะลดลงหากเคอร์เนลย้ายเธรดไปยัง CPU ขนาดใหญ่ ในตัวอย่างนี้ หากการบูต CPU ขนาดใหญ่ที่ 750 MHz ปลอดภัย คุณควรทำเช่นนั้นแม้ว่าคุณจะไม่ได้วางแผนที่จะใช้ CPU ขนาดใหญ่อย่างชัดแจ้งก็ตาม

ไดรเวอร์ไม่ควรโหลดเฟิร์มแวร์ในการเริ่มต้นระยะที่ 1

อาจมีบางกรณีที่หลีกเลี่ยงไม่ได้ซึ่งต้องโหลดเฟิร์มแวร์ในการเริ่มต้นระยะที่ 1 แต่โดยทั่วไปแล้ว ไดรเวอร์ไม่ควรโหลดเฟิร์มแวร์ใดๆ ในการเริ่มต้นระยะที่ 1 โดยเฉพาะในบริบทการตรวจสอบอุปกรณ์ การโหลดเฟิร์มแวร์ในการเริ่มต้นระยะที่ 1 จะทำให้กระบวนการบูตทั้งหมดหยุดชะงักหากไม่มีเฟิร์มแวร์ใน ramdisk ระยะที่ 1 และแม้ว่าจะมีเฟิร์มแวร์ใน ramdisk ระยะที่ 1 ก็ยังทำให้เกิดความล่าช้าที่ไม่จำเป็น