कर्नेल मॉड्यूल से जुड़ी सहायता

हो सकता है कि GKI में, डिवाइस के पार्टिशन को माउंट करने के लिए ज़रूरी ड्राइवर की सुविधा न हो. डिवाइस के पार्टिशन को माउंट करने और बूटिंग जारी रखने के लिए, पहले चरण के init को बेहतर बनाया गया है, ताकि रैमडिस्क पर मौजूद कर्नेल मॉड्यूल लोड किए जा सकें. रैमडिस्क को, सामान्य और वेंडर रैमडिस्क में बांटा गया है. वेंडर कर्नेल मॉड्यूल, वेंडर रैमडिस्क में सेव किए जाते हैं. कर्नेल मॉड्यूल को लोड करने का क्रम कॉन्फ़िगर किया जा सकता है.

मॉड्यूल की जगह

रैमडिस्क, पहले चरण के init, के लिए फ़ाइल सिस्टम है. साथ ही, यह रिकवरी/फ़ास्टबूट इमेज के लिए भी फ़ाइल सिस्टम है. यह initramfs है, जो दो cpio आर्काइव से मिलकर बना है. इन्हें बूटलोडर जोड़ता है. पहले cpio आर्काइव को वेंडर-बूट पार्टिशन में वेंडर रैमडिस्क के तौर पर सेव किया जाता है. इसमें ये कॉम्पोनेंट शामिल होते हैं:

  • पहले चरण के init वेंडर कर्नेल मॉड्यूल, जो /lib/modules/ में मौजूद होते हैं.
  • modprobe कॉन्फ़िगरेशन फ़ाइलें, जो /lib/modules/ में मौजूद होती हैं: modules.dep, modules.softdep, modules.alias, modules.options.
  • modules.load फ़ाइल, जो /lib/modules/ में मौजूद होती है. इससे पता चलता है कि पहले चरण के init के दौरान, किन मॉड्यूल को किस क्रम में लोड करना है.
  • A/B और वर्चुअल A/B डिवाइसों के लिए, वेंडर रिकवरी-कर्नेल मॉड्यूल, जो /lib/modules/ में मौजूद होते हैं
  • modules.load.recovery , जो /lib/modules में मौजूद होती है. इससे पता चलता है कि A/B और वर्चुअल A/B डिवाइसों के लिए, किन मॉड्यूल को किस क्रम में लोड करना है.

दूसरा cpio आर्काइव, GKI के साथ boot.img के रैमडिस्क के तौर पर दिया जाता है. इसे पहले आर्काइव के ऊपर लागू किया जाता है. इसमें first_stage_init और वे लाइब्रेरी शामिल होती हैं जिन पर यह निर्भर करता है.

पहले चरण के init में मॉड्यूल लोड करना

पहले चरण का init, रैमडिस्क पर मौजूद /lib/modules/ से modprobe कॉन्फ़िगरेशन फ़ाइलें पढ़कर शुरू होता है. इसके बाद, यह /lib/modules/modules.load (या रिकवरी के मामले में, /lib/modules/modules.load.recovery) में बताए गए मॉड्यूल की सूची को पढ़ता है. साथ ही, पहले से लोड की गई फ़ाइलों में बताए गए कॉन्फ़िगरेशन के मुताबिक, उन सभी मॉड्यूल को क्रम से लोड करने की कोशिश करता है . हार्ड या सॉफ़्ट डिपेंडेंसी को पूरा करने के लिए, अनुरोध किए गए क्रम से अलग क्रम में मॉड्यूल लोड किए जा सकते हैं.

पहले चरण के init के लिए, बिल्ड की सुविधा

वेंडर रैमडिस्क cpio में कॉपी किए जाने वाले कर्नेल मॉड्यूल तय करने के लिए, उन्हें BOARD_VENDOR_RAMDISK_KERNEL_MODULES में शामिल करें. बिल्ड, इन मॉड्यूल पर depmod चलाता है. साथ ही, इससे मिलने वाली modprobe कॉन्फ़िगरेशन फ़ाइलों को वेंडर रैमडिस्क cpio में डालता है.

बिल्ड, modules.load फ़ाइल भी बनाता है और उसे वेंडर रैमडिस्क cpio में सेव करता है. डिफ़ॉल्ट रूप से, इसमें BOARD_VENDOR_RAMDISK_KERNEL_MODULES में शामिल सभी मॉड्यूल होते हैं. उस फ़ाइल के कॉन्टेंट को बदलने के लिए, BOARD_VENDOR_RAMDISK_KERNEL_MODULES_LOAD का इस्तेमाल करें. उदाहरण के लिए:

BOARD_VENDOR_RAMDISK_KERNEL_MODULES_LOAD := \
    device/vendor/mydevice-kernel/first.ko \
    device/vendor/mydevice-kernel/second.ko \
    device/vendor/mydevice-kernel/third.ko

पूरे Android के लिए, बिल्ड की सुविधा

Android 10 और इससे पहले के वर्शन की तरह, BOARD_VENDOR_KERNEL_MODULES में शामिल कर्नेल मॉड्यूल को Android प्लैटफ़ॉर्म बिल्ड, वेंडर पार्टिशन में /vendor/lib/modules पर कॉपी करता है. प्लैटफ़ॉर्म बिल्ड, इन मॉड्यूल पर depmod चलाता है. साथ ही, depmod की आउटपुट फ़ाइलों को वेंडर पार्टिशन में उसी जगह पर कॉपी करता है. /vendor से कर्नेल मॉड्यूल लोड करने का तरीका, Android के पिछले वर्शन के जैसा ही है. यह तय करना आपका काम है कि इन मॉड्यूल को कब और कैसे लोड करना है. हालांकि, आम तौर पर ऐसा init.rc स्क्रिप्ट का इस्तेमाल करके किया जाता है.

वाइल्डकार्ड और इंटिग्रेटेड कर्नेल बिल्ड

जो वेंडर, अपने डिवाइस के कर्नेल बिल्ड को Android प्लैटफ़ॉर्म बिल्ड के साथ जोड़ते हैं उन्हें डिवाइस पर कॉपी किए जाने वाले कर्नेल मॉड्यूल तय करने के लिए, ऊपर बताए गए BOARD मैक्रो का इस्तेमाल करने में समस्या आ सकती है. अगर वेंडर, डिवाइस के प्लैटफ़ॉर्म बिल्ड फ़ाइलों में कर्नेल मॉड्यूल शामिल नहीं करना चाहते, तो वे वाइल्डकार्ड ($(wildcard device/vendor/mydevice/*.ko) का इस्तेमाल कर सकते हैं. ध्यान दें कि इंटिग्रेटेड कर्नेल बिल्ड के मामले में, वाइल्डकार्ड काम नहीं करता. ऐसा इसलिए, क्योंकि जब make को कॉल किया जाता है और मैक्रो को मेकफ़ाइल में बढ़ाया जाता है, तब कर्नेल मॉड्यूल नहीं बनाए जाते. इसलिए, मैक्रो खाली होते हैं.

इस समस्या से बचने के लिए, वेंडर अपने कर्नेल बिल्ड से एक zip आर्काइव बना सकते हैं. इसमें हर पार्टिशन पर कॉपी किए जाने वाले कर्नेल मॉड्यूल शामिल होते हैं. BOARD_*_KERNEL_MODULES_ARCHIVE में उस zip आर्काइव का पाथ सेट करें. यहां * पार्टिशन का नाम है. जैसे, BOARD_VENDOR_KERNEL_MODULES_ARCHIVE. Android प्लैटफ़ॉर्म बिल्ड इस zip आर्काइव को सही जगह पर एक्सट्रैक्ट करता है और मॉड्यूल पर depmod चलाता है.

कर्नेल मॉड्यूल zip आर्काइव में एक मेक नियम होना चाहिए. इससे यह पक्का होता है कि प्लैटफ़ॉर्म बिल्ड, ज़रूरत पड़ने पर आर्काइव जनरेट कर सके.

रिकवरी

Android के पिछले वर्शन में, रिकवरी के लिए ज़रूरी कर्नेल मॉड्यूल, BOARD_RECOVERY_KERNEL_MODULES में तय किए जाते थे. Android 12 में, रिकवरी के लिए ज़रूरी कर्नेल मॉड्यूल अब भी इस मैक्रो का इस्तेमाल करके तय किए जाते हैं. हालांकि, रिकवरी कर्नेल मॉड्यूल को सामान्य रैमडिस्क cpio के बजाय, वेंडर रैमडिस्क cpio में कॉपी किया जाता है. डिफ़ॉल्ट रूप से, BOARD_RECOVERY_KERNEL_MODULES में शामिल सभी कर्नेल मॉड्यूल, पहले चरण के init के दौरान लोड किए जाते हैं. अगर आपको इनमें से सिर्फ़ कुछ मॉड्यूल लोड करने हैं, तो BOARD_RECOVERY_KERNEL_MODULES_LOAD में उन मॉड्यूल के बारे में जानकारी दें.

वेंडर बूट पार्टिशन बनाने के बारे में जानने के लिए, बूट पार्टिशन लेख पढ़ें. इस पार्टिशन में, इस पेज पर बताया गया वेंडर रैमडिस्क शामिल होता है.