تقدّم هذه الصفحة نصائح لتحسين وقت بدء التشغيل.
إزالة رموز تصحيح الأخطاء من الوحدات
على غرار طريقة إزالة رموز تصحيح الأخطاء من النواة على جهاز الإصدار العلني، تأكَّد أيضًا من إزالة رموز تصحيح الأخطاء من الوحدات. إزالة تصحيح الأخطاء تساعد الرموز من الوحدات في وقت التشغيل عن طريق تقليل ما يلي:
- الوقت الذي يستغرقه قراءة الملفات الثنائية من ذاكرة الفلاش
- الوقت المستغرق لفك ضغط قرص ذاكرة التخزين المؤقت.
- الوقت المستغرق لتحميل الوحدات.
قد يؤدي إزالة رمز تصحيح الأخطاء من الوحدات إلى توفير عدة ثوانٍ أثناء عملية التشغيل.
يكون خيار إزالة الرموز مفعَّلاً تلقائيًا في إصدار نظام التشغيل Android، ولكن
لتفعيله صراحةً، اضبط
BOARD_DO_NOT_STRIP_VENDOR_RAMDISK_MODULES
في الإعدادات الخاصة بالجهاز
ضمن device/vendor/device.
استخدام ضغط LZ4 للنواة وذاكرة التخزين المؤقت
يُنشئ Gzip إخراجًا مضغوطًا أصغر حجمًا مقارنةً بـ LZ4، ولكن LZ4 وفك ضغطها أسرع من Gzip. بالنسبة للنواة والوحدات، تكون مساحة التخزين المطلقة كما أن تقليل الحجم من استخدام Gzip ليس كبيرًا مقارنة مزايا وقت فك الضغط لـ LZ4.
تمت إضافة ميزة ضغط LZ4 لشريحة ذاكرة الوصول العشوائي (RAM) إلى نظام Android
الإصدار BOARD_RAMDISK_USE_LZ4
والإصدارات الأحدث. يمكنك ضبط هذا الخيار في
الإعدادات الخاصة بالجهاز. يمكن ضبط ضغط النواة من خلال kernel defconfig.
من المفترض أن يؤدي التبديل إلى LZ4 إلى تقليل وقت التشغيل بمقدار 500 إلى 1,000 ملي ثانية.
تجنَّب التسجيل المفرط في برامج التشغيل
في ARM64 وARM32، تحتاج استدعاءات الدوال التي تزيد مسافتها عن مسافة محدّدة عن موقع الاستدعاء إلى جدول قفزة (يُعرف باسم جدول ربط الإجراءات أو PLT) ليكون بإمكانها ترميز عنوان القفزة الكامل. وبما أنّه يتم تحميل الوحدات ديناميكيًا، يجب إصلاح جداول القفزة هذه أثناء تحميل الوحدة. تُعرف المكالمات التي تحتاج إلى إعادة التعيين باسم إدخالات إعادة التعيين التي تحتوي على ملحقَين واضحَين (أو RELA اختصارًا) في تنسيق ELF.
يُجري نواة Linux بعض تحسينات حجم الذاكرة (مثل تحسين عمليات الاستفادة من ذاكرة التخزين المؤقت) عند تخصيص جدول البحث. باستخدام هذا الالتزام بالبيانات في المصدر
،
يكون مخطط التحسين معقدًا بدرجة O(N^2)
، حيث يكون N
هو عدد
RELAs من النوع R_AARCH64_JUMP26
أو R_AARCH64_CALL26
. لذلك، من المفيد تقليل عدد RELAs
من هذه الأنواع لتقليل وقت تحميل الوحدة.
من أنماط الترميز الشائعة التي تزيد من عدد RELAs
R_AARCH64_CALL26
أو R_AARCH64_JUMP26
هو التسجيل المفرط في
driver. يضيف عادةً كل استدعاء إلى printk()
أو أي مخطط تسجيل آخر
الإدخال CALL26
من JUMP26
في RELA في نص الالتزام في بداية الصفحة
الالتزام،
،لاحظ أنه حتى مع التحسين، تستغرق الوحدات الست حوالي 250 ملّي ثانية
ينبغي تحميلها - وذلك لأن تلك الوحدات الست كانت أعلى ست وحدات ذات
أكبر قدر من التسجيل.
يمكن أن يؤدي تقليل التسجيل إلى توفير حوالي 100 إلى 300 مللي ثانية في أوقات التشغيل بناءً على على مدى المبالغة في التسجيل الحالي.
تفعيل الاستقصاء غير المتزامن، بشكل انتقائي
عند تحميل وحدة، إذا كان الجهاز المتوافق معها قد سبق وتم تحميله
تتم تعبئته من خلال DT (devicetree) وإضافتها إلى نواة برنامج التشغيل، ثم إلى
يتم إجراء التحقق في سياق استدعاء module_init()
. عند إكمال عملية فحص الجهاز
في سياق module_init()
، لا يمكن للوحدة إكمال تحميلها إلا بعد اكتمال عملية الفحص. بما أنّ تحميل الوحدات يكون متسلسلًا في الغالب، فإنّ الجهاز الذي يحتاج إلى وقت طويل نسبيًا لفحصه يبطئ وقت التشغيل.
لتجنُّب زيادة وقت التشغيل، فعِّل الاستكشاف غير المتزامن للوحدات التي تستغرق وقتًا في فحص أجهزتها. تفعيل اختبارات غير متزامنة لجميع الوحدات قد لا يكون مفيدًا نظرًا للوقت الذي يستغرقه إنشاء سلسلة محادثات وبدء المسبار كمقدار الوقت الذي يستغرقه استقصاء الجهاز.
يمكن أن تؤدي الأجهزة المتصلة من خلال ناقل بطيء مثل I2C والأجهزة التي تُجري عملية تحميل الثابت في وظيفة التحقيق والأجهزة التي تُجري الكثير من عمليات بدء تشغيل الأجهزة إلى حدوث مشكلة في التوقيت. وأفضل طريقة لتحديد الحالات التي يحدث فيها ذلك هي جمع وقت الاستكشاف لكل سائق وترتيبه.
لتفعيل الاستكشاف غير المتزامن لوحدة، لا يكفي فقط
ضبط العلامة PROBE_PREFER_ASYNCHRONOUS
في رمز برنامج التشغيل. بالنسبة إلى الوحدات، تحتاج أيضًا إلى إضافة
module_name.async_probe=1
في سطر أوامر النواة (kernel)
أو ضبط async_probe=1
كمعلمة الوحدة عند تحميل الوحدة باستخدام
modprobe
أو insmod
.
يمكن أن يؤدي تفعيل الاستكشاف غير المتزامن إلى توفير 100 إلى 500 ملي ثانية في أوقات التشغيل حسب الأجهزة أو برامج التشغيل.
افحص برامج تشغيل CPUfreq في أقرب وقت ممكن
كلما كان فحص برنامج تشغيل CPUfreq مبكرًا، كان بإمكانك زيادة تردد CPU
إلى أقصى حد (أو الحد الأقصى المسموح به من حيث الحرارة) أثناء عملية التمهيد. تشير رسالة الأشكال البيانية
كلما زادت سرعة وحدة المعالجة المركزية، زادت سرعة التشغيل. ينطبق هذا الإرشاد أيضًا على devfreq
برامج التشغيل التي تتحكّم في ذاكرة الوصول العشوائي (DRAM) والذاكرة ومعدّل تكرار الربط.
وعند استخدام الوحدات، قد يعتمد ترتيب التحميل على مستوى السمة initcall
تجميع أو ترتيب برامج التشغيل. استخدم الاسم المستعار MODULE_SOFTDEP()
لإجراء
تأكَّد من أنّ برنامج التشغيل cpufreq
من بين الوحدات القليلة التي سيتم تحميلها.
بالإضافة إلى تحميل الوحدة في وقت مبكر، عليك أيضًا التأكّد من فحص جميع التبعيات لفحص برنامج تشغيل CPUfreq. على سبيل المثال، إذا تحتاج إلى ساعة أو مقبض تنظيم للتحكم في معدل تكرار وحدة المعالجة المركزية لديك، فتأكد من يتم التحقق منها أولاً. أو قد تحتاج إلى تحميل برامج تشغيل حرارية قبل برنامج تشغيل CPUfreq إذا كان من الممكن أن تصبح وحدات المعالجة المركزية (CPU) ساخنة جدًا أثناء عملية التمهيد. لذا، افعل ما بوسعك للتأكد من أن وحدة المعالجة المركزية (CPUfreq) مناسبة يجب التحقق من برامج تشغيل devfreq في أقرب وقت ممكن.
قد تكون المبالغ التي وفّرتها فحص برنامج تشغيل CPUfreq مبكرًا قليلاً جدًا اعتمادًا على مدى مبكر يمكنك استقصاءه وإلى أي وتيرة فإن برنامج الإقلاع يترك وحدات المعالجة المركزية فيها.
نقل الوحدات إلى المرحلة الثانية init أو المورّد أو Seller_dlkm
نظرًا لأن المرحلة الأولى من عملية البدء متسلسلة، فليس هناك العديد من
الفرص لموازاة عملية التمهيد. إذا لم تكن هناك حاجة إلى وحدة
تهيئة المرحلة الأولى حتى النهاية، انقل الوحدة إلى بداية المرحلة الثانية من خلال وضعها
في قسم المورّد أو vendor_dlkm
لا تحتاج عملية الإعداد في المرحلة الأولى إلى فحص عدة أجهزة للوصول إلى المرحلة الثانية بدء. لا يلزم سوى إمكانات وحدة التحكّم والتخزين الفلاشي لبدء عملية التمهيد بشكلٍ طبيعي.
حمِّل برامج التشغيل الأساسية التالية:
watchdog
reset
cpufreq
بالنسبة إلى وضع الاسترداد ومساحة المستخدم fastbootd
، تتطلب عملية الإعداد من المرحلة الأولى المزيد
والأجهزة المطلوب فحصها (مثل USB) والعرض. احتفِظ بنسخة من هذه الوحدات في
قرص RAM المرحلة الأولى وفي قسم المورِّد أو vendor_dlkm
. وهذا يتيح لهم
أن يتم تحميله في إعداد المرحلة الأولى من عملية الاسترداد أو مسار تشغيل fastbootd
. ومع ذلك،
لا تحمِّل وحدات وضع الاسترداد في المرحلة الأولى أثناء التشغيل العادي
التدفق. يمكن تأجيل وحدات وضع الاسترداد إلى المرحلة الثانية من الإعداد لتقليل
وقت التشغيل. يجب نقل جميع الوحدات الأخرى غير المطلوبة في مرحلة الإعداد الأولى
إلى قسم المورِّد أو vendor_dlkm
.
استنادًا إلى قائمة بالأجهزة الطرفية (مثل UFS أو الجهاز التسلسلي)، يعثر dev needs.sh
النص البرمجي على جميع برامج التشغيل والأجهزة والوحدات اللازمة للعناصر المُستندة إليها أو
المزوّدين (مثل الساعات أو المنظمات أو gpio
) للفحص.
يؤدي نقل الوحدات إلى مرحلة التشغيل الثانية إلى تقليل أوقات التشغيل بالطُرق التالية:
- تقليل حجم ذاكرة التخزين المؤقت في ذاكرة الوصول العشوائي
- يؤدي ذلك إلى قراءة ذاكرة فلاش بشكل أسرع عندما يحمِّل مشغِّل التحميل ملف ramdisk (خطوة التمهيد التسلسلي).
- ويؤدي ذلك إلى سرعات فك ضغط أسرع عندما تفكّ النواة ضغط ملف ramdisk (خطوة التمهيد التسلسلي).
- تعمل مرحلة الإعداد الثانية بشكل موازٍ، ما يخفي وقت تحميل الوحدة مع العمل الذي يتم تنفيذه في مرحلة الإعداد الثانية.
يمكن أن يؤدي نقل الوحدات إلى المرحلة الثانية إلى توفير من 500 إلى 1000 ملي ثانية في أوقات التشغيل استنادًا إلى عدد الوحدات التي يمكنك نقلها إلى مرحلة الإعداد الثانية.
الخدمات اللوجستية لتحميل الوحدات
يعرض أحدث إصدار من 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_dlkm
في الدليل/vendor/lib/modules/
.BOARD_VENDOR_KERNEL_MODULES_LOAD
. هذه قائمة بالوحدات التي سيتم تحميلها في مرحلة الإعداد الثانية.
يجب أيضًا نسخ وحدتي التشغيل والاسترداد في RAMD إلى المورد أو
قسم 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
لتحديدها محليًا فيملفّات ملفّات برمجة اللوحة
. يعثر النص البرمجي السابق على كل وحدة من وحدات المجموعة الفرعية من
وحدات kernel المتاحة المحدّدة ويملؤها، ويترك الوحدات المتبقية لبدء الخطوة
الثانية.
بالنسبة لبدء المرحلة الثانية، نوصي بتشغيل تحميل الوحدة كخدمة حتى فإنه لا يحظر تدفق التمهيد. استخدِم نصًا برمجيًا لنظام التشغيل لإدارة تحميل الوحدات كي تتمكّن من تسجيل (أو تجاهل) العمليات اللوجستية الأخرى، مثل معالجة الأخطاء والحدّ منها أو اكتمال تحميل الوحدات إذا لزم الأمر.
يمكنك تجاهل تعذُّر تحميل وحدة تصحيح الأخطاء غير متوفِّر في بُنى المستخدم.
لتجاهل هذا الخطأ، اضبط السمة 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.
لتحسين أوقات التشغيل الواضحة، يمكنك اختيار وحدات من
هي خدمة تحميل الوحدات التي تكون أكثر ملاءمة للتحميل بعد الإطلاق
الشاشة. على سبيل المثال، يمكنك تحميل وحدات فك ترميز الفيديو أو Wi-Fi بعد محو عملية التمهيد المبدئي
(sys.boot_complete
إشارة موقع Android، على سبيل المثال). التأكُّد من HALs للتحميل المتأخر
يحجبها الوحدات لمدة كافية في حال عدم توفّر برامج تشغيل النواة.
بدلاً من ذلك، يمكنك استخدام الأمر wait<file>[<timeout>]
init في عملية التشغيل
تدفق rc Scripting لانتظار إدخالات sysfs
محددة لإظهار وحدات برنامج التشغيل
عمليات الفحص بنجاح. مثال على ذلك هو انتظار
عرض برنامج التشغيل لإكمال التحميل في خلفية الاسترداد أو fastbootd
،
قبل تقديم رسومات القائمة.
بدء وتيرة وحدة المعالجة المركزية (CPU) بقيمة معقولة في برنامج الإقلاع
قد لا تتمكن بعض تقنيات المنظومة على رقاقة (SoC)/المنتجات من تشغيل وحدة المعالجة المركزية (CPU) بأعلى معدّل تكرار. بسبب مشاكل في الحرارة أو الطاقة أثناء اختبارات حلقة التمهيد. ومع ذلك، تأكَّد من أنّ بوتloader يضبط تردد جميع وحدات المعالجة المركزية (CPU) المتصلّة على أعلى معدّل ممكن بأمان لوحدة المعالجة المركزية (SoC) أو المنتج. هذا مهم جدًا لأنّه باستخدام نواة متكاملة بالكامل، يتم فك ضغط ملف init ramdisk قبل تحميل ملف التحكم في سرعة وحدة المعالجة المركزية. ولذلك، إذا تركت وحدة المعالجة المركزية عند الحد الأدنى لترددها، من خلال برنامج الإقلاع، قد يستغرق فك ضغط ذاكرة الوصول العشوائي (RAM) وقتًا أطول من نواة مجمّعة بشكل ثابت (بعد ضبط فرق حجم RAMD) لأنّ معدّل تكرار وحدة المعالجة المركزية (CPU) سيكون منخفضًا جدًا عند أداء العمل الذي يتطلب مهامًا مكثّفة (فك الضغط). وينطبق هذا أيضًا على تردد الذاكرة والاتصال.
تهيئة تردد وحدة المعالجة المركزية لوحدات المعالجة المركزية الكبيرة في برنامج الإقلاع
قبل تحميل برنامج التشغيل CPUfreq
، لا تكون النواة على دراية
ترددات وحدة المعالجة المركزية (CPU) ولا تقيس السعة المجدولة لوحدة المعالجة المركزية (CPU) بما يتناسب مع الأجهزة الحالية
والتردد. قد تنقل النواة سلاسل المهام إلى وحدة المعالجة المركزية الكبيرة إذا كان الحمل
مرتفعًا بما يكفي على وحدة المعالجة المركزية الصغيرة.
تأكد من أن أداء وحدات المعالجة المركزية الكبيرة لا يقل عن أداء وحدات المعالجة المركزية الصغيرة التردد الذي يتركه برنامج الإقلاع. على سبيل المثال، إذا كانت وحدة المعالجة المركزية الكبيرة أعلى بمرتين من أداء وحدة المعالجة المركزية الصغيرة بنفس معدل التكرار، ولكن برنامج الإقلاع يضبط تردد وحدة المعالجة المركزية الصغيرة على 1.5 غيغاهرتز وتضبط وحدة المعالجة المركزية الكبيرة إلى 300 ميغاهرتز، فإن أداء التشغيل سينخفض إذا كانت النواة أي سلسلة تعليمات إلى وحدة المعالجة المركزية الكبيرة. في هذا المثال، إذا كان من الآمن بدء تشغيل يجب استخدام وحدة معالجة مركزية بسرعة 750 ميغاهرتز حتى إذا لم تكن تنوي استخدامها بشكل صريح.
يجب ألا تحمِّل برامج التشغيل البرامج الثابتة في الخطوة الأولى.
قد تكون هناك بعض الحالات الحتمية التي تحتاج إلى تحميل البرامج الثابتة أولاً بداية المسرح. ولكن بشكل عام، يجب ألا تحمِّل برامج التشغيل أيّ برنامج ثابت في المرحلة الأولى init، خاصةً في سياق فحص الجهاز. يؤدي تحميل البرامج الثابتة في مرحلة الإعداد الأولى إلى توقُّف عملية التمهيد بالكامل إذا لم تكن البرامج الثابتة متاحة في أداة ramdisk الخاصة بالمرحلة الأولى. وحتى إذا كان البرنامج الثابت متوفّرًا في المرحلة الأولى ramdisk، سيظلّ يتسبب في تأخير غير ضروري.