এই পাতায় বুট টাইম উন্নত করার কিছু পরামর্শ দেওয়া হয়েছে।
মডিউল থেকে ডিবাগ প্রতীকগুলি সরান
প্রোডাকশন ডিভাইসে কার্নেল থেকে যেভাবে ডিবাগ সিম্বলগুলো স্ট্রিপ করা হয়, ঠিক একইভাবে মডিউলগুলো থেকেও ডিবাগ সিম্বলগুলো স্ট্রিপ করা নিশ্চিত করুন। মডিউল থেকে ডিবাগ সিম্বল স্ট্রিপ করলে নিম্নলিখিত বিষয়গুলো হ্রাস পাওয়ার মাধ্যমে বুট টাইম উন্নত হয়:
- ফ্ল্যাশ থেকে বাইনারিগুলো পড়তে যে সময় লাগে।
- র্যামডিস্ক ডিকম্প্রেস করতে যে সময় লাগে।
- মডিউলগুলো লোড হতে যে সময় লাগে।
মডিউল থেকে ডিবাগ সিম্বল সরিয়ে দিলে বুট করার সময় কয়েক সেকেন্ড সাশ্রয় হতে পারে।
অ্যান্ড্রয়েড প্ল্যাটফর্ম বিল্ডে সিম্বল স্ট্রিপিং ডিফল্টরূপে সক্রিয় থাকে, কিন্তু এটিকে স্পষ্টভাবে সক্রিয় করতে, আপনার ডিভাইস-নির্দিষ্ট কনফিগের device/ vendor / device ফোল্ডারে BOARD_DO_NOT_STRIP_VENDOR_RAMDISK_MODULES সেট করুন।
কার্নেল এবং র্যামডিস্কের জন্য LZ4 কম্প্রেশন ব্যবহার করুন।
LZ4-এর তুলনায় Gzip একটি ছোট সংকুচিত আউটপুট তৈরি করে, কিন্তু LZ4, Gzip-এর চেয়ে দ্রুত ডিকম্প্রেস হয়। কার্নেল এবং মডিউলগুলোর ক্ষেত্রে, LZ4-এর ডিকম্প্রেশন সময়ের সুবিধার তুলনায় Gzip ব্যবহারের ফলে স্টোরেজের মোট আকার হ্রাস ততটা উল্লেখযোগ্য নয়।
BOARD_RAMDISK_USE_LZ4 এর মাধ্যমে অ্যান্ড্রয়েড প্ল্যাটফর্ম বিল্ডে LZ4 র্যামডিস্ক কম্প্রেশনের সাপোর্ট যোগ করা হয়েছে। আপনি আপনার ডিভাইস-নির্দিষ্ট কনফিগে এই অপশনটি সেট করতে পারেন। কার্নেল কম্প্রেশন কার্নেল ডেফকনফিগ-এর মাধ্যমে সেট করা যায়।
LZ4-এ পরিবর্তন করলে বুট টাইম ৫০০ থেকে ১০০০ মিলিসেকেন্ড দ্রুততর হওয়া উচিত।
আপনার ড্রাইভারগুলিতে অতিরিক্ত লগিং এড়িয়ে চলুন।
ARM64 এবং ARM32-এ, কল সাইট থেকে একটি নির্দিষ্ট দূরত্বের চেয়ে বেশি দূরে থাকা ফাংশন কলগুলোর সম্পূর্ণ জাম্প অ্যাড্রেস এনকোড করার জন্য একটি জাম্প টেবিলের (যাকে প্রসিডিউর লিঙ্কিং টেবিল বা PLT বলা হয়) প্রয়োজন হয়। যেহেতু মডিউলগুলো ডাইনামিকভাবে লোড করা হয়, তাই মডিউল লোডের সময় এই জাম্প টেবিলগুলোকে নির্দিষ্ট করে দেওয়ার প্রয়োজন হয়। যে কলগুলোর রিলোকেশনের প্রয়োজন হয়, সেগুলোকে ELF ফরম্যাটে এক্সপ্লিসিট অ্যাডেন্ডসহ রিলোকেশন এন্ট্রি (সংক্ষেপে RELA) বলা হয়।
লিনাক্স কার্নেল PLT বরাদ্দ করার সময় কিছু মেমরি সাইজ অপ্টিমাইজেশন (যেমন ক্যাশে হিট অপ্টিমাইজেশন) করে থাকে। এই আপস্ট্রিম কমিটের মাধ্যমে, অপ্টিমাইজেশন স্কিমটির কমপ্লেক্সিটি O(N^2) , যেখানে N হলো R_AARCH64_JUMP26 বা R_AARCH64_CALL26 টাইপের RELA-এর সংখ্যা। সুতরাং, এই ধরনের RELA-এর সংখ্যা কম থাকলে মডিউল লোড হওয়ার সময় কমাতে সুবিধা হয়।
একটি সাধারণ কোডিং প্যাটার্ন যা R_AARCH64_CALL26 বা R_AARCH64_JUMP26 RELA-এর সংখ্যা বাড়িয়ে দেয়, তা হলো ড্রাইভারে অতিরিক্ত লগিং। printk() বা অন্য কোনো লগিং স্কিমের প্রতিটি কল সাধারণত একটি CALL26 / JUMP26 RELA এন্ট্রি যোগ করে। আপস্ট্রিম কমিটের কমিট টেক্সটে লক্ষ্য করুন যে, অপটিমাইজেশন সত্ত্বেও, ছয়টি মডিউল লোড হতে প্রায় ২৫০ms সময় নেয়—এর কারণ হলো, ওই ছয়টি মডিউলই ছিল সর্বাধিক লগিং সম্পন্ন শীর্ষ ছয়টি মডিউল।
বিদ্যমান লগিং কতটা অতিরিক্ত তার উপর নির্ভর করে, লগিং কমালে বুট টাইমে প্রায় ১০০ - ৩০০ মিলিসেকেন্ড সাশ্রয় হতে পারে।
অ্যাসিঙ্ক্রোনাস প্রোবিং নির্বাচনমূলকভাবে সক্ষম করুন
যখন একটি মডিউল লোড করা হয়, যদি মডিউলটি যে ডিভাইসটিকে সাপোর্ট করে সেটি ইতিমধ্যেই ডিটি (ডিভাইসট্রি) থেকে যুক্ত হয়ে ড্রাইভার কোরে যোগ করা হয়ে থাকে, তাহলে ডিভাইস প্রোবটি module_init() কলের প্রেক্ষাপটে সম্পন্ন করা হয়। যখন module_init() এর প্রেক্ষাপটে একটি ডিভাইস প্রোব করা হয়, তখন প্রোবটি সম্পূর্ণ না হওয়া পর্যন্ত মডিউলটির লোডিং শেষ হতে পারে না। যেহেতু মডিউল লোডিং মূলত সিরিয়ালাইজড, তাই যে ডিভাইসটি প্রোব হতে তুলনামূলকভাবে বেশি সময় নেয়, সেটি বুট টাইমকে ধীর করে দেয়।
ধীরগতির বুট টাইম এড়াতে, যে মডিউলগুলো তাদের ডিভাইস প্রোব করতে সময় নেয়, সেগুলোর জন্য অ্যাসিঙ্ক্রোনাস প্রোবিং সক্ষম করুন। সমস্ত মডিউলের জন্য অ্যাসিঙ্ক্রোনাস প্রোবিং সক্ষম করা সুবিধাজনক নাও হতে পারে, কারণ একটি থ্রেড ফোর্ক করে প্রোব শুরু করতে যে সময় লাগে, তা ডিভাইসটি প্রোব করার সময়ের সমান হতে পারে।
I2C-এর মতো ধীরগতির বাসের মাধ্যমে সংযুক্ত ডিভাইস, যে ডিভাইসগুলো তাদের প্রোব ফাংশনে ফার্মওয়্যার লোড করে, এবং যে ডিভাইসগুলো প্রচুর পরিমাণে হার্ডওয়্যার ইনিশিয়ালাইজেশন করে, সেগুলোর কারণে টাইমিং সমস্যা হতে পারে। কখন এটি ঘটে তা শনাক্ত করার সর্বোত্তম উপায় হলো প্রতিটি ড্রাইভারের প্রোব টাইম সংগ্রহ করে সেগুলোকে সাজানো।
কোনো মডিউলের জন্য অ্যাসিঙ্ক্রোনাস প্রোবিং চালু করতে, ড্রাইভার কোডে শুধু PROBE_PREFER_ASYNCHRONOUS ফ্ল্যাগটি সেট করাই যথেষ্ট নয় । মডিউলগুলোর জন্য, আপনাকে কার্নেল কমান্ড লাইনে module_name .async_probe=1 যোগ করতে হবে অথবা modprobe বা insmod ব্যবহার করে মডিউলটি লোড করার সময় মডিউল প্যারামিটার হিসেবে async_probe=1 পাস করতে হবে।
আপনার হার্ডওয়্যার/ড্রাইভারের উপর নির্ভর করে, অ্যাসিঙ্ক্রোনাস প্রোবিং চালু করলে বুট টাইমে প্রায় ১০০ - ৫০০ মিলিসেকেন্ড সাশ্রয় হতে পারে।
যত তাড়াতাড়ি সম্ভব আপনার CPUfreq ড্রাইভারটি পরীক্ষা করুন।
আপনার CPUfreq ড্রাইভার যত আগে প্রোব করবে, বুট করার সময় আপনি তত তাড়াতাড়ি সিপিইউ ফ্রিকোয়েন্সিকে সর্বোচ্চ (বা তাপীয়ভাবে সীমিত কোনো সর্বোচ্চ) পর্যায়ে নিয়ে যেতে পারবেন। সিপিইউ যত দ্রুত হবে, বুটও তত দ্রুত হবে। এই নির্দেশিকাটি devfreq ড্রাইভারের ক্ষেত্রেও প্রযোজ্য, যা DRAM, মেমরি এবং ইন্টারকানেক্ট ফ্রিকোয়েন্সি নিয়ন্ত্রণ করে।
মডিউলের ক্ষেত্রে, লোড হওয়ার ক্রম ড্রাইভারগুলোর initcall লেভেল এবং কম্পাইল বা লিঙ্ক অর্ডারের উপর নির্ভর করতে পারে। cpufreq ড্রাইভারটি যেন লোড হওয়া প্রথম কয়েকটি মডিউলের মধ্যে থাকে, তা নিশ্চিত করতে MODULE_SOFTDEP() অ্যালিয়াসটি ব্যবহার করুন।
মডিউলটি আগেভাগে লোড করা ছাড়াও, আপনাকে এটাও নিশ্চিত করতে হবে যে CPUfreq ড্রাইভারকে প্রোব করার জন্য প্রয়োজনীয় সমস্ত ডিপেন্ডেন্সিও যেন প্রোব হয়ে যায়। উদাহরণস্বরূপ, আপনার সিপিইউ-এর ফ্রিকোয়েন্সি নিয়ন্ত্রণের জন্য যদি কোনো ক্লক বা রেগুলেটর হ্যান্ডেলের প্রয়োজন হয়, তবে নিশ্চিত করুন যে সেগুলো প্রথমে প্রোব করা হয়েছে। অথবা, বুট আপের সময় আপনার সিপিইউ অতিরিক্ত গরম হয়ে যাওয়ার সম্ভাবনা থাকলে, CPUfreq ড্রাইভারের আগে থার্মাল ড্রাইভার লোড করার প্রয়োজন হতে পারে। তাই, CPUfreq এবং প্রাসঙ্গিক devfreq ড্রাইভারগুলো যাতে যত তাড়াতাড়ি সম্ভব প্রোব হয়, তা নিশ্চিত করতে আপনার সাধ্যমতো সবকিছু করুন।
আপনার CPUfreq ড্রাইভারটি আগেভাগে প্রোব করার মাধ্যমে যে সাশ্রয় হয়, তা খুব কম থেকে খুব বেশি হতে পারে। এটি নির্ভর করে আপনি কত আগে এই প্রোবটি করাতে পারছেন এবং বুটলোডার সিপিইউগুলোকে কোন ফ্রিকোয়েন্সিতে রাখছে, তার উপর।
মডিউলগুলিকে দ্বিতীয় পর্যায়ের ইনিট, ভেন্ডর বা ভেন্ডর_ডিএলকেএম পার্টিশনে সরান
যেহেতু প্রথম ধাপের ইনিট প্রক্রিয়াটি ক্রমিক, তাই বুট প্রক্রিয়াকে সমান্তরাল করার সুযোগ খুব বেশি থাকে না। যদি প্রথম ধাপের ইনিট শেষ হওয়ার জন্য কোনো মডিউলের প্রয়োজন না হয়, তবে মডিউলটিকে vendor বা vendor_dlkm পার্টিশনে রেখে দ্বিতীয় ধাপের ইনিটে সরিয়ে দিন।
প্রথম পর্যায়ের ইনিটের জন্য দ্বিতীয় পর্যায়ের ইনিটে যেতে একাধিক ডিভাইস প্রোব করার প্রয়োজন হয় না। একটি স্বাভাবিক বুট ফ্লো-এর জন্য শুধুমাত্র কনসোল এবং ফ্ল্যাশ স্টোরেজের সক্ষমতাই যথেষ্ট।
নিম্নলিখিত অপরিহার্য ড্রাইভারগুলি লোড করুন:
-
watchdog -
reset -
cpufreq
রিকভারি এবং ইউজার স্পেস fastbootd মোডের জন্য, প্রথম পর্যায়ের ইনিট-এর প্রোব (যেমন ইউএসবি) এবং ডিসপ্লে করার জন্য আরও ডিভাইসের প্রয়োজন হয়। এই মডিউলগুলোর একটি কপি প্রথম পর্যায়ের র্যামডিস্কে এবং ভেন্ডর বা vendor_dlkm পার্টিশনে রাখুন। এর ফলে রিকভারি বা fastbootd বুট ফ্লো-এর জন্য প্রথম পর্যায়ের ইনিট-এ এগুলো লোড করা যায়। তবে, সাধারণ বুট ফ্লো চলাকালীন প্রথম পর্যায়ের ইনিট-এ রিকভারি মোড মডিউলগুলো লোড করবেন না। বুট টাইম কমানোর জন্য রিকভারি মোড মডিউলগুলোকে দ্বিতীয় পর্যায়ের ইনিট-এর জন্য স্থগিত রাখা যেতে পারে। প্রথম পর্যায়ের ইনিট-এ প্রয়োজন নেই এমন অন্য সমস্ত মডিউল ভেন্ডর বা vendor_dlkm পার্টিশনে সরিয়ে নেওয়া উচিত।
লিফ ডিভাইসগুলির (যেমন, UFS বা সিরিয়াল) একটি তালিকা দেওয়া হলে, dev needs.sh স্ক্রিপ্টটি প্রোব করার জন্য প্রয়োজনীয় ডিপেন্ডেন্সি বা সাপ্লায়ারদের (যেমন, ক্লক, রেগুলেটর বা gpio ) সমস্ত ড্রাইভার, ডিভাইস এবং মডিউল খুঁজে বের করে।
মডিউলগুলিকে দ্বিতীয় পর্যায়ের ইনিট-এ স্থানান্তর করলে বুট টাইম নিম্নলিখিত উপায়ে হ্রাস পায়:
- র্যামডিস্কের আকার হ্রাস।
- এর ফলে বুটলোডার যখন র্যামডিস্ক লোড করে (সিরিয়ালাইজড বুট স্টেপ), তখন ফ্ল্যাশ রিড আরও দ্রুত হয়।
- এর ফলে কার্নেল যখন র্যামডিস্ক ডিকম্প্রেস করে (সিরিয়ালাইজড বুট স্টেপ), তখন ডিকম্প্রেশনের গতি বৃদ্ধি পায়।
- দ্বিতীয় পর্যায়ের ইনিট সমান্তরালভাবে কাজ করে, যার ফলে এই কাজের আড়ালে মডিউল লোড হওয়ার সময়টি ঢাকা পড়ে যায়।
মডিউলগুলোকে দ্বিতীয় পর্যায়ে স্থানান্তর করলে বুট টাইমে ৫০০ থেকে ১০০০ মিলিসেকেন্ড পর্যন্ত সাশ্রয় হতে পারে, যা নির্ভর করে আপনি কতগুলো মডিউলকে দ্বিতীয় পর্যায়ের ইনিট-এ স্থানান্তর করতে পারছেন তার উপর।
মডিউল লোডিং লজিস্টিকস
সর্বশেষ অ্যান্ড্রয়েড বিল্ডে বোর্ড কনফিগারেশন রয়েছে, যা নিয়ন্ত্রণ করে কোন মডিউলগুলো প্রতিটি স্টেজে কপি হবে এবং কোন মডিউলগুলো লোড হবে। এই বিভাগে নিম্নলিখিত উপসেটটির উপর আলোকপাত করা হয়েছে:
-
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 বাvendor_dlkmপার্টিশনে কপি করা হবে। -
BOARD_VENDOR_KERNEL_MODULES_LOAD. এটি হলো দ্বিতীয় পর্যায়ের ইনিট-এ লোড করা মডিউলগুলোর তালিকা।
র্যামডিস্কে থাকা বুট এবং রিকভারি মডিউলগুলোকেও অবশ্যই /vendor/lib/modules এ অবস্থিত ভেন্ডর বা vendor_dlkm পার্টিশনে কপি করতে হবে। এই মডিউলগুলোকে ভেন্ডর পার্টিশনে কপি করার ফলে দ্বিতীয় পর্যায়ের ইনিট (init)-এর সময় মডিউলগুলো অদৃশ্য থাকে না, যা ডিবাগিং এবং বাগরিপোর্টের জন্য modinfo সংগ্রহ করার ক্ষেত্রে সহায়ক।
যতক্ষণ বুট মডিউল সেটটি মিনিমাইজ করা থাকবে, ততক্ষণ ডুপ্লিকেশনটি ভেন্ডর বা vendor_dlkm পার্টিশনে ন্যূনতম জায়গা নেবে। নিশ্চিত করুন যে /vendor/lib/modules এ থাকা ভেন্ডরের modules.list ফাইলে মডিউলগুলোর একটি ফিল্টার করা তালিকা রয়েছে। এই ফিল্টার করা তালিকাটি নিশ্চিত করে যে মডিউলগুলো পুনরায় লোড হওয়ার কারণে (যা একটি ব্যয়বহুল প্রক্রিয়া) বুট টাইম প্রভাবিত না হয়।
নিশ্চিত করুন যে রিকভারি মোড মডিউলগুলো একটি গ্রুপ হিসেবে লোড হয়। রিকভারি মোড মডিউলগুলো রিকভারি মোডে, অথবা প্রতিটি বুট ফ্লো-এর দ্বিতীয় পর্যায়ের ইনিট (init)-এর শুরুতে লোড করা যেতে পারে।
নিম্নলিখিত উদাহরণে যেমন দেখা যাচ্ছে, আপনি ডিভাইস 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 blocklist ফিচারটি ব্যবহার করে দ্বিতীয় পর্যায়ের বুট ফ্লোকে বিভক্ত করতে পারেন, যার মধ্যে অনাবশ্যক মডিউলগুলোর বিলম্বিত লোডিং অন্তর্ভুক্ত থাকবে। কোনো নির্দিষ্ট HAL দ্বারা একচেটিয়াভাবে ব্যবহৃত মডিউলগুলোর লোডিং বিলম্বিত করা যেতে পারে, যাতে মডিউলগুলো কেবল HAL চালু হওয়ার সময়ই লোড হয়।
দৃশ্যমান বুট টাইম উন্নত করতে, আপনি মডিউল লোডিং সার্ভিসে নির্দিষ্টভাবে এমন মডিউল বেছে নিতে পারেন যা লঞ্চ স্ক্রিনের পরে লোড হওয়ার জন্য বেশি উপযোগী। উদাহরণস্বরূপ, ইনিট বুট ফ্লো ক্লিয়ার হয়ে যাওয়ার পরে আপনি ভিডিও ডিকোডার বা ওয়াই-ফাই-এর মডিউলগুলো স্পষ্টভাবে লেট লোড করতে পারেন (যেমন, অ্যান্ড্রয়েড প্রপার্টি সিগন্যাল sys.boot_complete ব্যবহার করে)। নিশ্চিত করুন যে কার্নেল ড্রাইভারগুলো উপস্থিত না থাকলে লেট লোডিং মডিউলগুলোর জন্য HAL-গুলো যথেষ্ট দীর্ঘ সময় ধরে ব্লক থাকে।
বিকল্পভাবে, ড্রাইভার মডিউলগুলো প্রোব অপারেশন সম্পন্ন করেছে তা দেখানোর জন্য, আপনি বুট ফ্লো আরসি স্ক্রিপ্টিং-এ init-এর wait<file>[<timeout>] কমান্ড ব্যবহার করে নির্দিষ্ট sysfs এন্ট্রিগুলোর জন্য অপেক্ষা করতে পারেন। এর একটি উদাহরণ হলো, মেনু গ্রাফিক্স দেখানোর আগে রিকভারি বা fastbootd এর ব্যাকগ্রাউন্ডে ডিসপ্লে ড্রাইভারের লোডিং সম্পন্ন হওয়ার জন্য অপেক্ষা করা।
বুটলোডারে সিপিইউ ফ্রিকোয়েন্সি একটি যুক্তিসঙ্গত মানে সেট করুন।
বুট লুপ টেস্টের সময় থার্মাল বা পাওয়ার সংক্রান্ত উদ্বেগের কারণে সব SoC/প্রোডাক্ট হয়তো সিপিইউকে সর্বোচ্চ ফ্রিকোয়েন্সিতে বুট করতে সক্ষম নাও হতে পারে। তবে, নিশ্চিত করুন যে বুটলোডার একটি SoC বা প্রোডাক্টের জন্য সমস্ত অনলাইন সিপিইউ-এর ফ্রিকোয়েন্সি যতটা সম্ভব নিরাপদে সেট করে। এটি খুবই গুরুত্বপূর্ণ কারণ, একটি সম্পূর্ণ মডিউলার কার্নেলের ক্ষেত্রে, সিপিইউফ্রিক ড্রাইভার লোড হওয়ার আগেই ইনিট র্যামডিস্ক ডিকম্প্রেশন সম্পন্ন হয়। তাই, যদি বুটলোডার সিপিইউকে তার ফ্রিকোয়েন্সির নিম্ন প্রান্তে রেখে দেয়, তাহলে র্যামডিস্ক ডিকম্প্রেশনের সময় একটি স্ট্যাটিক্যালি কম্পাইল করা কার্নেলের চেয়ে বেশি লাগতে পারে (র্যামডিস্কের আকারের পার্থক্য সমন্বয় করার পর), কারণ সিপিইউ-ইনটেনসিভ কাজ (ডিকম্প্রেশন) করার সময় সিপিইউ ফ্রিকোয়েন্সি খুব কম থাকবে। একই কথা মেমরি এবং ইন্টারকানেক্ট ফ্রিকোয়েন্সির ক্ষেত্রেও প্রযোজ্য।
বুটলোডারে বড় সিপিইউগুলোর ফ্রিকোয়েন্সি নির্ধারণ করুন
CPUfreq ড্রাইভার লোড হওয়ার আগে, কার্নেল সিপিইউ ফ্রিকোয়েন্সিগুলো সম্পর্কে অবগত থাকে না এবং সেগুলোর বর্তমান ফ্রিকোয়েন্সি অনুযায়ী সিপিইউ শিডিউল ক্ষমতা সমন্বয় করে না। ছোট সিপিইউ-তে লোড যথেষ্ট বেশি হলে কার্নেল থ্রেডগুলোকে বড় সিপিইউ-তে স্থানান্তর করতে পারে।
নিশ্চিত করুন যে, বুটলোডার যে ফ্রিকোয়েন্সিতে বড় সিপিইউগুলোকে রাখে, সেই ফ্রিকোয়েন্সিতে সেগুলোর পারফরম্যান্স যেন ছোট সিপিইউগুলোর চেয়ে অন্তত সমান বা তার চেয়ে ভালো হয়। উদাহরণস্বরূপ, যদি একই ফ্রিকোয়েন্সিতে বড় সিপিইউটি ছোট সিপিইউটির চেয়ে ২ গুণ বেশি পারফর্ম্যান্ট হয়, কিন্তু বুটলোডার ছোট সিপিইউটির ফ্রিকোয়েন্সি ১.৫ গিগাহার্টজ এবং বড় সিপিইউটির ফ্রিকোয়েন্সি ৩০০ মেগাহার্টজ নির্ধারণ করে দেয়, তাহলে কার্নেল যদি কোনো থ্রেডকে বড় সিপিইউতে স্থানান্তর করে, তবে বুট পারফরম্যান্স কমে যাবে। এই উদাহরণে, যদি বড় সিপিইউটিকে ৭৫০ মেগাহার্টজে বুট করা নিরাপদ হয়, তবে আপনি এটিকে স্পষ্টভাবে ব্যবহার করার পরিকল্পনা না করলেও তাই করা উচিত।
ড্রাইভারদের প্রথম পর্যায়ের ইনিটে ফার্মওয়্যার লোড করা উচিত নয়।
কিছু অনিবার্য ক্ষেত্রে প্রথম পর্যায়ের ইনিট-এ ফার্মওয়্যার লোড করার প্রয়োজন হতে পারে। কিন্তু সাধারণত, ড্রাইভারদের প্রথম পর্যায়ের ইনিট-এ কোনো ফার্মওয়্যার লোড করা উচিত নয়, বিশেষ করে ডিভাইস প্রোব কনটেক্সটে। যদি ফার্মওয়্যারটি প্রথম পর্যায়ের র্যামডিস্কে উপলব্ধ না থাকে, তবে প্রথম পর্যায়ের ইনিট-এ ফার্মওয়্যার লোড করার ফলে সম্পূর্ণ বুট প্রক্রিয়াটি আটকে যায়। আর ফার্মওয়্যারটি প্রথম পর্যায়ের র্যামডিস্কে উপস্থিত থাকলেও, এটি একটি অপ্রয়োজনীয় বিলম্ব ঘটায়।