লোডেবল কার্নেল মডিউল

Android 8.0-এ চালু করা মডিউল কার্নেল সংক্রান্ত প্রয়োজনীয়তা অনুযায়ী, সব সিস্টেম-অন-চিপ (SoC) কার্নেলকে লোড করা যায় এমন কার্নেল মডিউলকে সাপোর্ট করতে হবে।

কার্নেল কনফিগারেশন সংক্রান্ত বিকল্প

লোড করা যায় এমন কার্নেল মডিউলকে সাপোর্ট করতে, সব সাধারণ কার্নেলে android-base.config-এ নিম্নলিখিত কার্নেল-কনফিগারেশন বিকল্প (অথবা তাদের কার্নেল-ভার্সনের সমতুল্য) অন্তর্ভুক্ত থাকে:

CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y
CONFIG_MODVERSIONS=y

সব ডিভাইস কার্নেলে এই বিকল্পগুলি চালু থাকতে হবে। এছাড়াও, কার্নেল মডিউলকে যখনই সম্ভব আনলোড ও রিলোড করার সুবিধা থাকতে হবে।

মডিউল সাইনিং

GKI ভেন্ডর মডিউলের জন্য মডিউল-সাইনিং কাজ করে না। যেসব ডিভাইসে যাচাই করা বুট সাপোর্ট করতে হয়, সেগুলিতে Android-এর প্রয়োজন হয় যে কার্নেল মডিউলগুলি যেন এমন পার্টিশনে থাকে যেখানে dm-verity চালু করা আছে। এর ফলে, প্রতিটি মডিউলের সত্যতা যাচাই করার জন্য সেগুলিতে আলাদা করে স্বাক্ষর করার প্রয়োজন হয় না। Android 13-এ GKI মডিউলের ধারণা চালু করা হয়েছে। GKI মডিউল, রান-টাইমে GKI ও অন্যান্য মডিউলের মধ্যে পার্থক্য করতে, কার্নেলের বিল্ড টাইম স্বাক্ষর পরিকাঠামো ব্যবহার করে। স্বাক্ষর না করা মডিউল লোড করার অনুমতি দেওয়া হয়, যতক্ষণ না সেগুলি শুধুমাত্র সাদা তালিকায় দেখানো চিহ্ন ব্যবহার করে অথবা অন্য কোনও স্বাক্ষর না করা মডিউল দ্বারা প্রদান করা হয়। GKI বিল্ডের সময় কার্নেলের বিল্ড টাইম কী পেয়ার ব্যবহার করে GKI মডিউল সাইন করার সুবিধা দিতে, GKI কার্নেল কনফিগে CONFIG_MODULE_SIG_ALL=y চালু করা হয়েছে। ডিভাইস কার্নেল বিল্ড করার সময় নন-GKI মডিউল সাইন করা এড়াতে, আপনার কার্নেল কনফিগারেশন ফ্র্যাগমেন্টের অংশ হিসেবে আপনাকে অবশ্যই # CONFIG_MODULE_SIG_ALL is not set যোগ করতে হবে।

ফাইলের লোকেশন

Android 7.x ও তার আগের যেকোনও ভার্সনে কার্নেল মডিউল ব্যবহার করা বাধ্যতামূলক না হলেও (এবং insmod ও rmmod-এর জন্য সাপোর্ট অন্তর্ভুক্ত থাকলেও), Android 8.x ও তার পরবর্তী যেকোনও ভার্সনে ইকোসিস্টেমে কার্নেল মডিউল ব্যবহার করার সাজেশন দেওয়া হয়। নিচের টেবিলে তিনটি Android বুট মোড জুড়ে প্রয়োজনীয় সম্ভাব্য বোর্ড-নির্দিষ্ট পেরিফেরাল সহায়তা দেখানো হয়েছে।

বুট মোড স্টোরেজ ডিসপ্লে কীপ্যাড ব্যাটারি PMIC টাচস্ক্রিন NFC, ওয়াই-ফাই,
ব্লুটুথ
সেন্সর ক্যামেরা
রিকভারি
চার্জার
Android

Android বুট মোডে উপলভ্যতা ছাড়াও, কার্নেল মডিউলগুলি কে মালিক (SoC ভেন্ডর বা ODM) তার ভিত্তিতেও শ্রেণীবদ্ধ করা হতে পারে। কার্নেল মডিউল ব্যবহার করা হলে, ফাইল সিস্টেমে সেগুলির প্লেসমেন্ট সংক্রান্ত প্রয়োজনীয়তা নিম্নলিখিত:

  • সব কার্নেলে বুটিং ও মাউন্টিং পার্টিশনের জন্য বিল্ট-ইন সহায়তা থাকতে হবে।
  • কার্নেল মডিউল অবশ্যই শুধু-পঠনযোগ্য পার্টিশন থেকে লোড করতে হবে।
  • যেসব ডিভাইসে যাচাই করা বুট প্রয়োজন, সেগুলির ক্ষেত্রে যাচাই করা পার্টিশন থেকে কার্নেল মডিউল লোড করতে হবে।
  • কার্নেল মডিউল /system-এ থাকলে চলবে না।
  • ডিভাইসের জন্য প্রয়োজনীয় GKI মডিউল /system/lib/modules থেকে লোড করতে হবে যা /system_dlkm/lib/modules-এর সিম্বলিক লিঙ্ক।
  • সম্পূর্ণ Android বা চার্জার মোডের জন্য প্রয়োজনীয় SoC ভেন্ডরের কার্নেল মডিউল /vendor/lib/modules-এ থাকতে হবে।
  • ODM পার্টিশন থাকলে, সম্পূর্ণ Android বা চার্জার মোডের জন্য প্রয়োজনীয় ODM থেকে কার্নেল মডিউল /odm/lib/modules-এ অবস্থিত হতে হবে। অন্যথায়, এইসব মডিউলকে /vendor/lib/modules-এ থাকতে হবে।
  • SoC ভেন্ডর ও ODM-এর থেকে পাওয়া কার্নেল মডিউল যা রিকভারি মোডের জন্য প্রয়োজন, তা রিকভারি ramfs-এ /lib/modules থাকতে হবে।
  • রিকভারি মোড এবং সম্পূর্ণ Android বা চার্জার মোড, দুটির জন্যই প্রয়োজনীয় কার্নেল মডিউল, রিকভারি rootfs এবং /vendor বা /odm পার্টিশন (উপরে যেমন বর্ণনা করা হয়েছে), উভয় জায়গাতেই থাকতে হবে।
  • রিকভারি মোডে ব্যবহৃত কার্নেল মডিউলগুলি শুধুমাত্র /vendor বা /odm-এ অবস্থিত মডিউলের উপর নির্ভর করলে চলবে না, কারণ রিকভারি মোডে সেইসব পার্টিশন মাউন্ট করা হয় না।
  • SoC ভেন্ডর কার্নেল মডিউল ODM কার্নেল মডিউলের উপর নির্ভর করা উচিত নয়।

Android 7.x ও এর আগের যেকোনও ভার্সনে, /vendor ও /odm পার্টিশন আগে মাউন্ট করা হয় না। Android 8.x ও তার পরবর্তী ভার্সনে, এইসব পার্টিশন থেকে মডিউল লোড করার সুবিধা দিতে, নন-A/B ও A/B ডিভাইস, দুটির ক্ষেত্রেই পার্টিশন আগে মাউন্ট করার ব্যবস্থা করা হয়েছে। এছাড়াও, এটি নিশ্চিত করে যে Android এবং চার্জার মোড, দুটি ক্ষেত্রেই পার্টিশন মাউন্ট করা আছে।

Android বিল্ড সিস্টেম সাপোর্ট

BoardConfig.mk-এ, Android বিল্ড একটি BOARD_VENDOR_KERNEL_MODULES ভেরিয়েবলকে সংজ্ঞায়িত করে যা ভেন্ডর ইমেজের জন্য উদ্দিষ্ট কার্নেল মডিউলের সম্পূর্ণ তালিকা প্রদান করে। এই ভেরিয়েবলে তালিকাভুক্ত মডিউলগুলি /lib/modules/-এ ভেন্ডর ইমেজে কপি করা হয়, এবং Android-এ মাউন্ট করার পরে, /vendor/lib/modules-এ দেখা যায় (উপরের প্রয়োজনীয়তা অনুযায়ী)। ভেন্ডর কার্নেল মডিউলের কনফিগারেশনের উদাহরণ:

vendor_lkm_dir := device/$(vendor)/lkm-4.x
BOARD_VENDOR_KERNEL_MODULES := \
  $(vendor_lkm_dir)/vendor_module_a.ko \
  $(vendor_lkm_dir)/vendor_module_b.ko \
  $(vendor_lkm_dir)/vendor_module_c.ko

এই উদাহরণে, উপরে তালিকাভুক্ত লোকেশনে Android বিল্ডে একটি ভেন্ডর কার্নেল মডিউল প্রি-বিল্ট রিপোজিটরি ম্যাপ করা হয়েছে।

রিকভারি ইমেজে ভেন্ডর মডিউলের সাবসেট থাকতে পারে। Android বিল্ড এইসব মডিউলের জন্য BOARD_RECOVERY_KERNEL_MODULES ভেরিয়েবেল নির্দিষ্ট করে। উদাহরণ:

vendor_lkm_dir := device/$(vendor)/lkm-4.x
BOARD_RECOVERY_KERNEL_MODULES := \
  $(vendor_lkm_dir)/vendor_module_a.ko \
  $(vendor_lkm_dir)/vendor_module_b.ko

Android বিল্ড depmod চালানোর দায়িত্ব নেয় যাতে /vendor/lib/modules এবং /lib/modules (recovery ramfs)-এ প্রয়োজনীয় modules.dep ফাইল তৈরি করা যায়।

মডিউল লোড করা ও ভার্সন করা

init.rc* থেকে একবারে সব কার্নেল মডিউল লোড করুন modprobe -a ইনভোক করে। এটি modprobe বাইনারির জন্য C রানটাইম এনভায়রনমেন্ট বারবার ইনিশিয়ালাইজ করার ওভারহেড এড়িয়ে যায়। early-init ইভেন্টটি পরিবর্তন করে modprobe চালু করা যেতে পারে:

on early-init
    exec u:r:vendor_modprobe:s0 -- /vendor/bin/modprobe -a -d \
        /vendor/lib/modules module_a module_b module_c ...

সাধারণত, কার্নেল মডিউলকে অবশ্যই কার্নেলের সাথে কম্পাইল করতে হবে, যে কার্নেলের সাথে মডিউলটি ব্যবহার করা হবে (অন্যথায় কার্নেল মডিউল লোড করতে অস্বীকার করে)। CONFIG_MODVERSIONS অ্যাপ্লিকেশন বাইনারি ইন্টারফেসে (ABI) ত্রুটি শনাক্ত করে একটি সমাধান প্রদান করে। এই ফিচারটি কার্নেলে এক্সপোর্ট করা প্রতিটি প্রতীকের প্রোটোটাইপের জন্য একটি সাইক্লিক রিডান্ডেন্সি চেক (CRC) ভ্যালু গণনা করে এবং কার্নেলের অংশ হিসেবে ভ্যালুগুলি স্টোর করে; কার্নেল মডিউল দ্বারা ব্যবহৃত প্রতীকের জন্য, ভ্যালুগুলি কার্নেল মডিউলেও স্টোর করা হয়। যখন মডিউল লোড করা হয়, তখন মডিউলের ব্যবহার করা চিহ্নের ভ্যালু কার্নেলের চিহ্নের ভ্যালুর সাথে তুলনা করা হয়। ভ্যালু মিলে গেলে, মডিউল লোড করা হয়; অন্যথায় লোড করা যায় না।

ভেন্ডর ইমেজ থেকে আলাদা করে কার্নেল ইমেজ আপডেট করার সুবিধা চালু করতে, CONFIG_MODVERSIONS চালু করুন। এটি করলে, ভেন্ডর ইমেজে আগে থেকে থাকা কার্নেল মডিউলের সাথে মানানসই রেখে কার্নেলে ছোটখাটো আপডেট (যেমন, LTS থেকে বাগ ফিক্স) করা যায়। তবে, CONFIG_MODVERSIONS নিজে থেকে ABI ব্রেকিং ঠিক করে না। কার্নেলে এক্সপোর্ট করা কোনও প্রতীকের প্রোটোটাইপ পরিবর্তন হলে, তা সোর্সে পরিবর্তন বা কার্নেল কনফিগারেশন পরিবর্তন হওয়ার কারণে হতে পারে। এর ফলে সেই প্রতীক ব্যবহার করা কার্নেল মডিউলের সাথে কম্প্যাটিবিলিটি ভেঙে যায়। এইসব ক্ষেত্রে, কার্নেল মডিউল আবার কম্পাইল করতে হবে।

যেমন, কার্নেলের task_struct স্ট্রাকচারে (যা include/linux/sched.h-এ সংজ্ঞায়িত করা হয়েছে) অনেক ফিল্ড থাকে যা কার্নেল কনফিগারেশনের উপর নির্ভর করে শর্তসাপেক্ষে অন্তর্ভুক্ত করা হয়। sched_info ফিল্ডটি শুধুমাত্র CONFIG_SCHED_INFO চালু করা থাকলে তবেই থাকে (যা CONFIG_SCHEDSTATS বা CONFIG_TASK_DELAY_ACCT চালু করা থাকলে তবেই হয়)। এইসব কনফিগারেশন বিকল্পের স্টেট পরিবর্তন হলে, task_struct স্ট্রাকচারের লেআউট পরিবর্তন হয় এবং কার্নেল থেকে এক্সপোর্ট করা যেসব ইন্টারফেস task_struct ব্যবহার করে সেগুলি পরিবর্তিত হয় (যেমন, set_cpus_allowed_ptr in kernel/sched/core.c)। এইসব ইন্টারফেস ব্যবহার করে আগে কম্পাইল করা কার্নেল মডিউলের সাথে সামঞ্জস্য ভেঙে যায়, যার ফলে নতুন কার্নেল কনফিগারেশন দিয়ে সেইসব মডিউল আবার তৈরি করতে হয়।

CONFIG_MODVERSIONS সম্পর্কে আরও বিবরণের জন্য, kernel tree-তে Documentation/kbuild/modules.rst-এ থাকা ডকুমেন্টেশন দেখুন।