लोड किए जा सकने वाले कर्नेल मॉड्यूल

Android 8.0 में शुरू की गई मॉड्यूल कर्नेल ज़रूरी शर्तों के हिसाब से, सभी सिस्टम-ऑन-चिप (SoC) कर्नेल के साथ लोड होने वाले कर्नेल मॉड्यूल काम करने चाहिए.

Kernel कॉन्फ़िगरेशन के विकल्प

लोड किए जा सकने वाले कर्नेल मॉड्यूल के साथ काम करने के लिए, android-base.config को सभी सामान्य कर्नेल में नीचे दिए गए kernel-config विकल्पों (या उनके कर्नेल-वर्शन के बराबर) को फ़ॉलो किया जा रहा है:

CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y
CONFIG_MODVERSIONS=y

सभी डिवाइस कर्नेल के लिए ये विकल्प चालू होने चाहिए. Kernel मॉड्यूल को भी जब भी संभव हो, अनलोड और फिर से लोड करने में मदद करें.

मॉड्यूल साइनिंग

जीकेआई वेंडर मॉड्यूल के लिए, मॉड्यूल पर हस्ताक्षर करने की सुविधा काम नहीं करती. उन डिवाइस पर जिनके लिए ज़रूरी है वेरिफ़ाइड बूट की सुविधा काम करती है. Android के लिए ज़रूरी है कि पार्टिशन में कर्नेल मॉड्यूल मौजूद हों जिनमें डीएम-वेरिटी चालू हो. इससे अलग से व्यक्ति को साइन करने की ज़रूरत नहीं होती मॉड्यूल उपलब्ध हैं. Android 13 ने जीकेआई मॉड्यूल का कॉन्सेप्ट पेश किया है. जीकेआई मॉड्यूल, कर्नेल के बिल्ड टाइम का इस्तेमाल करता है साइन इन करने के इन्फ़्रास्ट्रक्चर का इस्तेमाल करता है, ताकि रन टाइम के दौरान जीकेआई और अन्य मॉड्यूल के बीच अंतर किया जा सके. साइन नहीं किए गए मॉड्यूल लोड किए जा सकते हैं. हालांकि, इसके लिए ज़रूरी है कि उनमें सिर्फ़ अनुमति वाली सूची में शामिल सिंबल का इस्तेमाल किया गया हो या ऐसे मॉड्यूल से उपलब्ध कराया जाए जिन पर हस्ताक्षर न किए गए हों. कर्नेल के बिल्ड टाइम कुंजी के जोड़े का इस्तेमाल करके, जीकेआई बिल्ड के दौरान जीकेआई मॉड्यूल पर हस्ताक्षर करने की सुविधा देने के लिए, GKI के कर्नेल कॉन्फ़िगरेशन ने CONFIG_MODULE_SIG_ALL=y को चालू किया है. डिवाइस कर्नेल बिल्ड के दौरान गैर-जीकेआई मॉड्यूल साइन करने से बचने के लिए, आपको जोड़ना होगा आपके कर्नेल कॉन्फ़िगरेशन के हिस्से के तौर पर # CONFIG_MODULE_SIG_ALL is not set फ़्रैगमेंट.

फ़ाइल की लोकेशन

वहीं, Android 7.x और उससे पहले के वर्शन के लिए कर्नेल मॉड्यूल उपलब्ध नहीं हैं (और इनके साथ insmod और rmmod के लिए सहायता दी जाती है), Android 8.x और नेटवर्क में कर्नेल मॉड्यूल के इस्तेमाल का सुझाव दिया जाता है. नीचे दिए गए इस टेबल में, टेबल में उन सहायक डिवाइसों के बारे में बताया गया है जो बोर्ड के लिए खास तौर पर बनाए गए हैं. Android बूट मोड.

बूट मोड डिवाइस का स्टोरेज डिसप्ले कीपैड बैटरी पीएमआईसी टचस्क्रीन एनएफ़सी, वाई-फ़ाई,
ब्लूटूथ
सेंसर कैमरा
रिकवरी
चार्जर
Android

Android बूट मोड में उपलब्धता के अलावा, कर्नेल मॉड्यूल भी इन्हें उनके मालिकाना हक के हिसाब से कैटगरी में बांटा जाता है, जैसे कि SoC वेंडर या ODM. अगर कर्नेल मॉड्यूल का इस्तेमाल कर रहे हों, तो फ़ाइल सिस्टम में उनके प्लेसमेंट की ज़रूरी शर्तें ये हैं: अनुसरण करता है:

  • सभी कर्नेल में, बूट करने और माउंट करने की सुविधा पहले से मौजूद होनी चाहिए विभाजन.
  • Kernel मॉड्यूल, किसी रीड-ओनली पार्टीशन से लोड किए जाने चाहिए.
  • जिन डिवाइस के लिए वेरिफ़ाइड बूट की ज़रूरत होती है, उनके लिए कर्नेल मॉड्यूल ऐसे होने चाहिए लोड किए गए सेगमेंट से लोड किया गया.
  • /system में Kernel मॉड्यूल नहीं होने चाहिए.
  • डिवाइस के लिए ज़रूरी जीकेआई मॉड्यूल यहां से लोड किए जाने चाहिए /system/lib/modules, जो इसके लिए सांकेतिक लिंक है /system_dlkm/lib/modules.
  • SoC वेंडर के ऐसे Kernel मॉड्यूल जो पूरे Android या चार्जर मोड /vendor/lib/modules में मौजूद होने चाहिए.
  • अगर ODM विभाजन मौजूद है, तो ODM के कर्नेल मॉड्यूल ज़रूरी हैं Android या चार्जर मोड के फ़ुल /odm/lib/modules. अगर ऐसा नहीं है, तो ये मॉड्यूल यहां मौजूद होने चाहिए: /vendor/lib/modules.
  • SoC वेंडर और ODM के कर्नेल मॉड्यूल, जो वापस पाने के लिए ज़रूरी हैं इस मोड में, रिकवरी ramfs में मौजूद होना चाहिए: /lib/modules.
  • रिकवरी मोड और फ़ुल Android, दोनों के लिए कर्नेल मॉड्यूल ज़रूरी हैं या रिकवरी मोड rootfs और रिकवरी, दोनों में चार्जर मोड मौजूद होने चाहिए या तो /vendor या /odm विभाजन (जैसा कि बताया गया है ऊपर).
  • रिकवरी मोड में इस्तेमाल किए जाने वाले Kernel मॉड्यूल, मौजूद मॉड्यूल पर निर्भर नहीं होने चाहिए केवल /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 में modules.dep फ़ाइलें ज़रूरी हैं और /lib/modules (recovery ramfs).

मॉड्यूल लोडिंग और वर्शनिंग

शुरू करके, init.rc* से सभी कर्नेल मॉड्यूल को एक पास में लोड करें modprobe -a. इससे बार-बार शुरू होने वाले ओवरहेड से बचा जा सकता है modprobe बाइनरी के लिए C रनटाइम एनवायरमेंट. कॉन्टेंट बनाने modprobe शुरू करने के लिए, early-init इवेंट में बदलाव किया जा सकता है:

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, गड़बड़ियों का पता लगाकर समाधान देता है ऐप्लिकेशन बाइनरी इंटरफ़ेस (एबीआई) में. यह सुविधा, साइक्लिक को कैलकुलेट करती है एक्सपोर्ट किए गए हर सिंबल के प्रोटोटाइप के लिए, रिडंडंसी चेक (CRC) वैल्यू कर्नेल में किया जाता है और वैल्यू को कर्नेल के हिस्से के तौर पर सेव किया जाता है; के चिह्नों के लिए कर्नेल मॉड्यूल में, वैल्यू भी कर्नेल मॉड्यूल में स्टोर की जाती हैं. जब मॉड्यूल लोड होता है, तो मॉड्यूल में इस्तेमाल किए गए प्रतीकों के मानों की तुलना की जाती है कर्नेल में मौजूद सभी के साथ. अगर वैल्यू मेल खाती हैं, तो मॉड्यूल लोड होता है; ऐसा नहीं करने पर लोड नहीं हो पाता.

कर्नेल इमेज को वेंडर इमेज से अलग अपडेट करने के लिए, CONFIG_MODVERSIONS चालू करें. ऐसा करने से कर्नेल (जैसे कि एलटीएस से गड़बड़ी को ठीक करना) के ज़रिए गड़बड़ी को ठीक करना चाहिए. और वेंडर इमेज में मौजूदा कर्नेल मॉड्यूल के साथ. हालांकि, CONFIG_MODVERSIONS, एबीआई की गड़बड़ी को अपने-आप ठीक नहीं करता. अगर कर्नेल में एक्सपोर्ट किए गए चिह्न का प्रोटोटाइप बदल जाता है, जिसकी वजह से स्रोत में बदलाव हो जाता है या कर्नेल कॉन्फ़िगरेशन बदल जाता है, इसलिए यह उस सिंबल का इस्तेमाल करने वाले कर्नेल मॉड्यूल के साथ काम करने की सुविधा को तोड़ता है. ऐसे मामलों में, कर्नेल मॉड्यूल को फिर से कंपाइल करना होगा.

उदाहरण के लिए, कर्नेल में task_struct स्ट्रक्चर ( include/linux/sched.h) में शर्त के हिसाब से कई फ़ील्ड शामिल हैं कर्नेल कॉन्फ़िगरेशन के आधार पर शामिल किया जाता है. sched_info फ़ील्ड तभी मौजूद होता है, जब CONFIG_SCHED_INFO चालू हो (जो तब होता है जब CONFIG_SCHEDSTATS या CONFIG_TASK_DELAY_ACCT चालू हैं). अगर ये कॉन्फ़िगरेशन विकल्पों की स्थिति बदलने की वजह से, task_struct स्ट्रक्चर का लेआउट बदल जाएगा किए गए बदलाव और इस्तेमाल किए जा रहे कर्नेल में एक्सपोर्ट किए गए इंटरफ़ेस task_struct में बदलाव किया गया हो (उदाहरण के लिए, kernel/sched/core.c में set_cpus_allowed_ptr). पहले से इकट्ठा किए गए कर्नेल मॉड्यूल के साथ काम करता है जो इनका इस्तेमाल करते हैं इंटरफ़ेस ब्रेक होता है, जिससे उन मॉड्यूल को नए कर्नेल की मदद से फिर से बनाना पड़ता है कॉन्फ़िगरेशन.

CONFIG_MODVERSIONS के बारे में ज़्यादा जानकारी के लिए, इसे देखें कर्नेल ट्री में दस्तावेज़ Documentation/kbuild/modules.rst.