GKI के लिए कर्नेल कोड डेवलप करना

सामान्य कर्नेल इमेज (जीकेआई), अपस्ट्रीम Linux कर्नेल के साथ मिलकर काम करके, कर्नेल के फ़्रैगमेंटेशन को कम करती है. हालांकि, इसके पीछे मान्य वजहें होती हैं कुछ पैच अपस्ट्रीम में स्वीकार नहीं किए जा सकते हैं और कुछ प्रॉडक्ट शेड्यूल हैं पूरा होना चाहिए, ताकि कुछ पैच Android Common कर्नेल (ACK) में मैनेज किए जाते हों सोर्स हैं जिनसे जीकेआई बनाया गया है.

डेवलपर को कोड में किए गए बदलावों को अपस्ट्रीम सबमिट करना चाहिए. इसके लिए, उन्हें Linux Kernel Mailing List (LKML) का इस्तेमाल करना चाहिए. यह पहला विकल्प होना चाहिए. साथ ही, ACKandroid-mainline शाखा में कोड में किए गए बदलावों को सिर्फ़ तब सबमिट करना चाहिए, जब अपस्ट्रीम में बदलाव करना संभव न हो. यहां कुछ मान्य वजहों के उदाहरण दिए गए हैं. साथ ही, उन्हें ठीक करने का तरीका भी बताया गया है.

  • पैच को LKML को सबमिट किया गया था, लेकिन प्रॉडक्ट रिलीज़ करने के लिए, उसे समय पर स्वीकार नहीं किया गया. इस पैच को मैनेज करने के लिए:

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

  • पैच, अपस्ट्रीम के लिए ज़रूरत के मुताबिक नहीं है. साथ ही, प्रॉडक्ट रिलीज़ होने से पहले, इसे फिर से बनाने का समय नहीं है. इस पैच को मैनेज करने के लिए, वह अनुमानित समय जब तक रिफ़ैक्टर किया गया पैच अपस्ट्रीम सबमिट किया जाता है ( पैच को ACK में स्वीकार नहीं किया जाएगा. ऐसा तब तक नहीं किया जाएगा, जब तक कि रीफ़ैक्टर सबमिट करने का प्लान न हो समीक्षा के लिए पैच अपस्ट्रीम करें).

  • अपस्ट्रीम पैच स्वीकार नहीं किया जा सकता, क्योंकि... <वजह डालें यहां> क्लिक करें. इस पैच को मैनेज करने के लिए, Android कर्नेल टीम से संपर्क करें और पैच के डेटा को फिर से तैयार करने के लिए, हमारे साथ मिलकर काम करें, ताकि इसे सबमिट किया जा सके समीक्षा के लिए भेजा है और अपस्ट्रीम स्वीकार किए हैं.

इसके अलावा, कई और वजहें हो सकती हैं. गड़बड़ी या पैच सबमिट करते समय, सही वजह बताएं. साथ ही, कुछ बदलाव और चर्चा की उम्मीद करें. हम मानते हैं कि ACK में कुछ पैच होते हैं, विशेष रूप से के चरण पूरे करने के बाद, सभी लोग अपस्ट्रीम काम करना सीख रहे हैं, लेकिन आराम नहीं कर पा रहे प्रॉडक्ट शेड्यूल करने का विकल्प भी दिया गया है. लाइव स्ट्रीम करने से जुड़ी ज़रूरी शर्तें ज़्यादा होंगी समय के साथ और सख्त हो गई हैं.

पैच की ज़रूरी शर्तें

पैच, Linux कर्नेल कोडिंग स्टैंडर्ड के मुताबिक होने चाहिए Linux सोर्स ट्री, भले ही, उन्हें अपस्ट्रीम या ACK पर सबमिट किया गया हो. scripts/checkpatch.pl स्क्रिप्ट, Gerrit प्री-सबमिट टेस्टिंग के हिस्से के तौर पर चलती है, इसलिए इसे पहले से चलाकर देखें ठीक हो जाता है. सबमिट करने से पहले की जाने वाली जांच के उसी कॉन्फ़िगरेशन के साथ checkpatch स्क्रिप्ट को चलाने के लिए, //build/kernel/static_analysis:checkpatch_presubmit का इस्तेमाल करें. जानकारी के लिए, यह देखें build/kernel/kleaf/docs/checkpatch.md पर जाएं.

ACK पैच

ACK को सबमिट किए गए पैच, Linux kernel कोडिंग स्टैंडर्ड और योगदान से जुड़े दिशा-निर्देशों के मुताबिक होने चाहिए. आपको कमिट मैसेज में Change-Id टैग शामिल करना होगा. अगर पैच को एक से ज़्यादा शाखाओं (उदाहरण के लिए, android-mainline और android12-5.4) में सबमिट किया जाता है, तो आपको पैच के सभी इंस्टेंस के लिए एक ही Change-Id का इस्तेमाल करना होगा.

अपस्ट्रीम समीक्षा के लिए, पहले LKML को पैच सबमिट करें. अगर पैच:

  • अपस्ट्रीम स्वीकार की गई, यह अपने-आप android-mainline में मर्ज हो गई है.
  • अपस्ट्रीम में स्वीकार नहीं किया गया. इसे android-mainline पर सबमिट करें. साथ ही, अपस्ट्रीम सबमिशन का रेफ़रंस दें या यह बताएं कि इसे LKML पर क्यों सबमिट नहीं किया गया.

जब किसी पैच को अपस्ट्रीम या android-mainline में स्वीकार कर लिया जाता है, तो उसे LTS पर आधारित सही ACK में बैकपोर्ट किया जा सकता है. जैसे, Android के लिए बने कोड को ठीक करने वाले पैच के लिए android12-5.4 और android11-5.4. android-mainline पर सबमिट करने से, अपस्ट्रीम रिलीज़ के नए उम्मीदवारों के साथ टेस्टिंग की सुविधा मिलती है. साथ ही, यह भी पक्का होता है कि पैच, LTS पर आधारित अगले ACK में शामिल है. अपवाद में केस शामिल हैं जहां अपस्ट्रीम पैच को android12-5.4 में बैकपोर्ट किया जाता है (क्योंकि पैच android-mainline में हो सकती है).

अपस्ट्रीम पैच

जैसा कि योगदान देने वाले पेज पर बताया गया है दिशा-निर्देश, ACK कर्नेल के लिए तय किए गए अपस्ट्रीम पैच इन ग्रुप में आते हैं इन्हें स्वीकार किए जाने की संभावना के क्रम में किया जाता है).

  • UPSTREAM: - 'android-mainline` से चुने गए पैच के को ACK में स्वीकार किया जाता है.
  • BACKPORT: - अपस्ट्रीम से मिलने वाले ऐसे पैच भी स्वीकार किए जा सकते हैं जिनमें सिर्फ़ कुछ बदलाव किए गए हों और जिनमें बदलाव की ज़रूरत हो. हालांकि, इसके लिए ज़रूरी है कि उनका इस्तेमाल सही तरीके से किया जा रहा हो.
  • FROMGIT: - ऐसे पैच जिन्हें तैयार करने के लिए, मैनेजर टहनी से चुना गया है को सबमिट करने के लिए: Linux मेनलाइन को सबमिट करने पर आखिरी तारीख. कॉन्टेंट और शेड्यूल, दोनों के हिसाब से यह जानकारी सही होनी चाहिए.
  • FROMLIST: - LKML को सबमिट किए गए पैच, अगर अब तक मैनेजर की शाखा में स्वीकार नहीं किए गए हैं, तो उन्हें स्वीकार किए जाने की संभावना कम है. हालांकि, अगर पैच को अपस्ट्रीम Linux में शामिल किया जाता है, तो उसे स्वीकार किया जाएगा. हालांकि, हमारा मानना है कि ऐसा नहीं होगा. Android kernel टीम के साथ चर्चा करने के लिए, FROMLIST पैच से जुड़ी कोई समस्या होनी चाहिए.

Android के लिए खास पैच

अगर आपको अपस्ट्रीम में ज़रूरी बदलाव नहीं मिल पा रहे हैं, तो सीधे ACK में आउट-ऑफ़-ट्री पैच सबमिट किए जा सकते हैं. ट्री से बाहर के पैच सबमिट करने के लिए, आपको आईटी में एक समस्या बनानी होगी. इसमें पैच के बारे में जानकारी दी जानी चाहिए. साथ ही, यह भी बताया जाना चाहिए कि पैच को अपस्ट्रीम क्यों सबमिट नहीं किया जा सकता. उदाहरण के लिए, पिछली सूची देखें. हालांकि, कुछ मामलों में कोड अपस्ट्रीम सबमिट नहीं किया जा सकता. ये मामले नीचे दिए गए हैं और उन्हें योगदान के लिए दिशा-निर्देश Android-विशिष्ट पैच के लिए और ANDROID: प्रीफ़िक्स के साथ टैग किए गए होने चाहिए विषय.

gki_defconfig में बदलाव

gki_defconfig में किए गए सभी CONFIG बदलावों को arm64 और x86, दोनों वर्शन पर लागू करना ज़रूरी है. ऐसा तब तक करना होगा, जब तक कि CONFIG किसी खास आर्किटेक्चर के लिए न हो. CONFIG सेटिंग में बदलाव का अनुरोध करने के लिए, बदलाव के बारे में चर्चा करने के लिए आईटी में कोई समस्या बनाएं. CONFIG ऐसा कोई भी बदलाव अस्वीकार कर दिया जाता है जिससे फ़्रीज़ होने के बाद, Kernel Module Interface (KMI) पर असर पड़ता है. अगर पार्टनर किसी एक कॉन्फ़िगरेशन के लिए, एक-दूसरे से मेल न खाने वाली सेटिंग का अनुरोध करते हैं, तो हम उनसे जुड़ी गड़बड़ियों पर चर्चा करके, विवादों को सुलझाते हैं.

ऐसा कोड जो अपस्ट्रीम में मौजूद नहीं है

पहले से ही Android के लिए बने कोड में किए गए बदलावों को अपस्ट्रीम नहीं भेजा जा सकता. उदाहरण के लिए, भले ही बाइंडर ड्राइवर को अपस्ट्रीम मैनेज किया जाता है, लेकिन उसमें बदलाव कर दिए जाते हैं बाइंडर ड्राइवर की प्राथमिकता वाली इनहेरिटेंस की सुविधाओं को अपस्ट्रीम नहीं भेजा जा सकता क्योंकि ये सिस्टम खास तौर से Android के लिए बने हैं. बग और पैच में साफ़ तौर पर बताएं कि कोड को अपस्ट्रीम क्यों नहीं भेजा जा सकता. अगर हो सके, तो पैच को ऐसे हिस्सों में बांटें जिन्हें अपस्ट्रीम सबमिट किया जा सकता है और Android के हिसाब से ऐसे हिस्सों में बांटें जिन्हें अपस्ट्रीम सबमिट नहीं किया जा सकता. इससे ACK में, ट्री से बाहर के कोड की संख्या कम हो जाएगी.

इस कैटगरी में अन्य बदलावों में, केएमआई रेप्रज़ेंटेशन फ़ाइलों, केएमआई के सिंबल की सूचियों, gki_defconfig, बिल्ड स्क्रिप्ट या कॉन्फ़िगरेशन या ऐसी अन्य स्क्रिप्ट के अपडेट शामिल हैं जो अपस्ट्रीम में मौजूद नहीं हैं.

पेड़-पौधों से उगने वाले मॉड्यूल

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

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

छिपे हुए कॉन्फ़िगरेशन

कुछ इन-ट्री मॉड्यूल, छिपे हुए कॉन्फ़िगरेशन अपने-आप चुन लेते हैं जिन्हें बताया नहीं जा सकता gki_defconfig में. उदाहरण के लिए, CONFIG_SND_SOC_SOF=y कॉन्फ़िगर होने पर, CONFIG_SND_SOC_TOPOLOGY अपने-आप चुना जाता है. जगह पाने के लिए जीकेआई में छिपे हुए कॉन्फ़िगरेशन को चालू करने का एक तरीका शामिल है.

छिपे हुए कॉन्फ़िगरेशन को चालू करने के लिए, init/Kconfig.gki में select स्टेटमेंट जोड़ें, ताकि वह gki_defconfig में चालू किए गए CONFIG_GKI_HACKS_TO_FIX कर्नेल कॉन्फ़िगरेशन के आधार पर अपने-आप चुना जाए. इस तरीके का इस्तेमाल सिर्फ़ छिपे हुए कॉन्फ़िगरेशन के लिए करें. अगर कॉन्फ़िगरेशन छिपा नहीं है, तो उसे gki_defconfig में साफ़ तौर पर या डिपेंडेंसी के तौर पर बताना होगा.

लोड किए जा सकने वाले गवर्नर

cpufreq जैसे ऐसे कर्नेल फ़्रेमवर्क के लिए जो लोड किए जा सकने वाले गवर्नर के साथ काम करते हैं, डिफ़ॉल्ट गवर्नर (जैसे, cpufreq का schedutil गवर्नर) को बदला जा सकता है. ऐसे फ़्रेमवर्क (जैसे, थर्मल फ़्रेमवर्क) के लिए, जो लोड किए जा सकने वाले गवर्नर या ड्राइवर के साथ काम नहीं करते, लेकिन फिर भी वेंडर के हिसाब से लागू करने की ज़रूरत होती है, आईटी में समस्या दर्ज करें और Android कर्नेल टीम से सलाह लें.

ज़रूरी सहायता जोड़ने के लिए, हम आपके और अपस्ट्रीम डेवलपर के साथ मिलकर काम करेंगे.

वेंडर हुक

पिछली रिलीज़ में, सीधे कोर कर्नेल में वेंडर के हिसाब से बदलाव किए जा सकते थे. GKI 2.0 के साथ ऐसा नहीं किया जा सकता, क्योंकि प्रॉडक्ट के हिसाब से कोड को मॉड्यूल में लागू करना ज़रूरी है. इसे अपस्ट्रीम कोर कर्नेल या ACK में स्वीकार नहीं किया जाएगा. आसानी से इस्तेमाल की जा सकने वाली अतिरिक्त सुविधाओं को चालू करने के लिए, पार्टनर जिन पर भरोसा करते हैं कोर कर्नेल कोड पर, GKI, वेंडर हुक को स्वीकार करता है. इससे, मॉड्यूल को शुरू करने में मदद मिलती है कोर कर्नेल कोड से. इसके अलावा, मुख्य डेटा स्ट्रक्चर को वेंडर डेटा फ़ील्ड जिन्हें लागू करने के लिए, वेंडर के खास डेटा को स्टोर किया जा सकता है इन सुविधाओं के बारे में ज़्यादा जानें.

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

  • सामान्य वेंडर हुक, DECLARE_HOOK() का इस्तेमाल करके trace_name नाम वाला ट्रैसपॉइंट फ़ंक्शन बनाते हैं. यहां name, ट्रैस के लिए यूनीक आइडेंटिफ़ायर होता है. नियम के मुताबिक, सामान्य वेंडर हुक के नाम android_vh से शुरू होते हैं. इसलिए sched_exit() हुक का नाम android_vh_sched_exit होगा.
  • शेड्यूलर हुक जैसे मामलों में प्रतिबंधित वेंडर हुक की ज़रूरत होती है अटैच किए गए फ़ंक्शन को कॉल किया जाना चाहिए, भले ही सीपीयू ऑफ़लाइन हो या इसकी ज़रूरत हो विषय से अलग है. पाबंदी वाले वेंडर हुक को अलग नहीं किया जा सकता. इसलिए, पाबंदी वाले हुक से जुड़े मॉड्यूल कभी भी अनलोड नहीं हो सकते. पाबंदी वाले वेंडर हुक के नाम android_rvh से शुरू होते हैं.

वेंडर हुक जोड़ने के लिए, आईटी में कोई समस्या दर्ज करें और पैच सबमिट करें. Android के लिए बने सभी पैच की तरह, यह ज़रूरी है कि कोई समस्या मौजूद हो और आपको उसका जवाब देना होगा. वेंडर हुक के साथ सिर्फ़ ACK पर काम करते हैं, इसलिए इन्हें न भेजें अपस्ट्रीम Linux के लिए पैच करेंगे.

स्ट्रक्चर में वेंडर फ़ील्ड जोड़ना

ANDROID_VENDOR_DATA() मैक्रो का इस्तेमाल करके android_vendor_data फ़ील्ड जोड़कर, वेंडर डेटा को मुख्य डेटा स्ट्रक्चर से जोड़ा जा सकता है. उदाहरण के लिए, वैल्यू-ऐडेड सुविधाओं के साथ काम करने के लिए, नीचे दिए गए कोड सैंपल में दिखाए गए तरीके के मुताबिक, स्ट्रक्चर में फ़ील्ड जोड़ें.

वेंडर के लिए ज़रूरी फ़ील्ड और OEM के लिए ज़रूरी फ़ील्ड के बीच संभावित विरोध से बचने के लिए, OEM को कभी भी ANDROID_VENDOR_DATA() मैक्रो का इस्तेमाल करके एलान किए गए फ़ील्ड का इस्तेमाल नहीं करना चाहिए. इसके बजाय, OEM को ANDROID_OEM_DATA() का इस्तेमाल करना चाहिए android_oem_data फ़ील्ड के बारे में बताने के लिए.

#include <linux/android_vendor.h>
...
struct important_kernel_data {
  [all the standard fields];
  /* Create vendor data for use by hook implementations. The
   * size of vendor data is based on vendor input. Vendor data
   * can be defined as single u64 fields like the following that
   * declares a single u64 field named "android_vendor_data1" :
   */
  ANDROID_VENDOR_DATA(1);

  /*
   * ...or an array can be declared. The following is equivalent to
   * u64 android_vendor_data2[20]:
   */
  ANDROID_VENDOR_DATA_ARRAY(2, 20);

  /*
   * SoC vendors must not use fields declared for OEMs and
   * OEMs must not use fields declared for SoC vendors.
   */
  ANDROID_OEM_DATA(1);

  /* no further fields */
}

वेंडर हुक तय करना

कर्नेल कोड में, वेंडर हुक को ट्रेसपॉइंट के तौर पर जोड़ें. ऐसा करने के लिए, DECLARE_HOOK() या DECLARE_RESTRICTED_HOOK(). इसके बाद, उन्हें इस खाते से कोड में जोड़ें: ट्रेसपॉइंट बदल जाता है. उदाहरण के लिए, trace_android_vh_sched_exit() को मौजूदा do_exit() कर्नेल फ़ंक्शन:

#include <trace/hooks/exit.h>
void do_exit(long code)
{
    struct task_struct *tsk = current;
    ...
    trace_android_vh_sched_exit(tsk);
    ...
}

trace_android_vh_sched_exit() फ़ंक्शन शुरू में सिर्फ़ यह जांचता है कि कोई फ़ाइल अटैच है या नहीं. हालांकि, अगर कोई वेंडर मॉड्यूल, register_trace_android_vh_sched_exit() का इस्तेमाल करके हैंडलर रजिस्टर करता है, तो रजिस्टर किए गए फ़ंक्शन को कॉल किया जाता है. कॉन्टेंट बनाने हैंडलर को होल्ड किए गए लॉक, आरसीएस की स्थिति, और अन्य फ़ैक्टर. हुक को include/trace/hooks डायरेक्ट्री में मौजूद हेडर फ़ाइल में तय किया जाना चाहिए.

उदाहरण के लिए, नीचे दिया गया कोड, include/trace/hooks/exit.h फ़ाइल में trace_android_vh_sched_exit() के लिए एक संभावित एलान देता है.

/* SPDX-License-Identifier: GPL-2.0 */
#undef TRACE_SYSTEM
#define TRACE_SYSTEM sched
#define TRACE_INCLUDE_PATH trace/hooks

#if !defined(_TRACE_HOOK_SCHED_H) || defined(TRACE_HEADER_MULTI_READ)
#define _TRACE_HOOK_SCHED_H
#include <trace/hooks/vendor_hooks.h>
/*
 * Following tracepoints are not exported in tracefs and provide a
 * mechanism for vendor modules to hook and extend functionality
 */

struct task_struct;

DECLARE_HOOK(android_vh_sched_exit,
             TP_PROTO(struct task_struct *p),
             TP_ARGS(p));

#endif /* _TRACE_HOOK_SCHED_H */

/* This part must be outside protection */
#include <trace/define_trace.h>

वेंडर हुक के लिए ज़रूरी इंटरफ़ेस इंस्टैंशिएट करने के लिए, drivers/android/vendor_hooks.c में हुक के एलान के साथ हेडर फ़ाइल जोड़ें और सिंबल एक्सपोर्ट करें. उदाहरण के लिए, यहां दिया गया कोड, android_vh_sched_exit() हुक के एलान को पूरा करता है.

#ifndef __GENKSYMS__
/* struct task_struct */
#include <linux/sched.h>
#endif

#define CREATE_TRACE_POINTS
#include <trace/hooks/vendor_hooks.h>
#include <trace/hooks/exit.h>
/*
 * Export tracepoints that act as a bare tracehook (i.e. have no trace
 * event associated with them) to allow external modules to probe
 * them.
 */
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_sched_exit);

ध्यान दें: हुक डिक्लेरेशन में इस्तेमाल किए जाने वाले डेटा स्ट्रक्चर को पूरी तरह से परिभाषित किया गया है, ताकि एबीआई की स्थिरता की गारंटी दी जा सके. अगर ऐसा नहीं किया जाता है, तो ओपेक पॉइंटर को रेफ़रंस न करें या साइज़ वाले कॉन्टेक्स्ट में स्ट्रक्चर का इस्तेमाल करें. ऐसे डेटा स्ट्रक्चर की पूरी जानकारी देने वाले include को drivers/android/vendor_hooks.c के #ifndef __GENKSYMS__ सेक्शन में शामिल किया जाना चाहिए. include/trace/hooks में मौजूद हेडर फ़ाइलों में, टाइप की परिभाषाओं के साथ कर्नेल हेडर फ़ाइल शामिल नहीं होनी चाहिए. इससे सीआरसी में होने वाले ऐसे बदलावों से बचा जा सकता है जो केएमआई को नुकसान पहुंचाते हैं. इसके बजाय, टाइप के बारे में जानकारी दें.

वेंडर हुक के साथ अटैच करें

वेंडर हुक का इस्तेमाल करने के लिए, वेंडर मॉड्यूल को हुक के लिए हैंडलर रजिस्टर करना होगा (आम तौर पर, मॉड्यूल शुरू करने के दौरान किया जाता है). उदाहरण के लिए, यह कोड trace_android_vh_sched_exit() के लिए मॉड्यूल foo.ko हैंडलर दिखाता है.

#include <trace/hooks/sched.h>
...
static void foo_sched_exit_handler(void *data, struct task_struct *p)
{
    foo_do_exit_accounting(p);
}
...
static int foo_probe(..)
{
    ...
    rc = register_trace_android_vh_sched_exit(foo_sched_exit_handler, NULL);
    ...
}

हेडर फ़ाइलों से वेंडर हुक का इस्तेमाल करना

हेडर फ़ाइलों से वेंडर हुक का इस्तेमाल करने के लिए, आपको वेंडर हुक हेडर फ़ाइल को अपडेट करना पड़ सकता है, ताकि TRACE_INCLUDE_PATH को अनडिफ़ाइन किया जा सके. इससे, ट्रैक पॉइंट हेडर फ़ाइल न मिलने की जानकारी देने वाली बिल्ड गड़बड़ियों से बचा जा सकता है. उदाहरण के लिए,

In file included from .../common/init/main.c:111:
In file included from .../common/include/trace/events/initcall.h:74:
.../common/include/trace/define_trace.h:95:10: fatal error: 'trace/hooks/initcall.h' file not found
   95 | #include TRACE_INCLUDE(TRACE_INCLUDE_FILE)
      |          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.../common/include/trace/define_trace.h:90:32: note: expanded from macro 'TRACE_INCLUDE'
   90 | # define TRACE_INCLUDE(system) __TRACE_INCLUDE(system)
      |                                ^~~~~~~~~~~~~~~~~~~~~~~
.../common/include/trace/define_trace.h:87:34: note: expanded from macro '__TRACE_INCLUDE'
   87 | # define __TRACE_INCLUDE(system) __stringify(TRACE_INCLUDE_PATH/system.h)
      |                                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.../common/include/linux/stringify.h:10:27: note: expanded from macro '__stringify'
   10 | #define __stringify(x...)       __stringify_1(x)
      |                                 ^~~~~~~~~~~~~~~~
.../common/include/linux/stringify.h:9:29: note: expanded from macro '__stringify_1'
    9 | #define __stringify_1(x...)     #x
      |                                 ^~
<scratch space>:14:1: note: expanded from here
   14 | "trace/hooks/initcall.h"
      | ^~~~~~~~~~~~~~~~~~~~~~~~
1 error generated.

बिल्ड की इस तरह की गड़बड़ी को ठीक करने के लिए, वेंडर हुक पर उसी तरह का सुधार लागू करें हेडर फ़ाइल है जिसे आप शामिल कर रहे हैं. ज़्यादा जानकारी के लिए, https://r.android.com/3066703 पर जाएं.

diff --git a/include/trace/hooks/mm.h b/include/trace/hooks/mm.h
index bc6de7e53d66..039926f7701d 100644
--- a/include/trace/hooks/mm.h
+++ b/include/trace/hooks/mm.h
@@ -2,7 +2,10 @@
 #undef TRACE_SYSTEM
 #define TRACE_SYSTEM mm

+#ifdef CREATE_TRACE_POINTS
 #define TRACE_INCLUDE_PATH trace/hooks
+#define UNDEF_TRACE_INCLUDE_PATH
+#endif

UNDEF_TRACE_INCLUDE_PATH तय करने पर, include/trace/define_trace.h को ट्रेस पॉइंट बनाने के बाद, TRACE_INCLUDE_PATH को अनफ़ाइन करने के लिए कहा जाता है.

Kernel की मुख्य सुविधाएं

अगर पिछली कोई भी तकनीक आपको मॉड्यूल से सुविधा लागू करने में मदद नहीं करती है, तो तो आपको इस सुविधा को मूल रूप से Android के हिसाब से किए जाने वाले बदलाव के तौर पर जोड़ना होगा कर्नेल. बातचीत शुरू करने के लिए, समस्या ट्रैकर (आईटी) में कोई समस्या बनाएं.

यूज़र ऐप्लिकेशन प्रोग्रामिंग इंटरफ़ेस (यूएपीआई)

  • UAPI हेडर फ़ाइलें. UAPI हेडर फ़ाइलों में बदलाव, अपस्ट्रीम में होने चाहिए. ऐसा तब तक करना होगा, जब तक कि बदलाव Android के इंटरफ़ेस के लिए न हों. इंटरफ़ेस तय करने के लिए, वेंडर के हिसाब से बनी हेडर फ़ाइलों का इस्तेमाल करना और वेंडर मॉड्यूल और वेंडर यूज़रस्पेस कोड के बीच स्विच कर सकता है.
  • sysfs नोड. जीकेआई कर्नेल में नए sysfs नोड न जोड़ें (इस तरह के जोड़ सिर्फ़ वेंडर मॉड्यूल में मान्य हैं). SoC- और डिवाइस-एग्नोस्टिक लाइब्रेरी और Java कोड, जिनमें Android फ़्रेमवर्क शामिल होता है को सिर्फ़ साथ काम करने वाले तरीकों से बदला जा सकता है. साथ ही, अपस्ट्रीम को भी बदलना होगा, अगर ये Android के लिए खास तौर पर कॉन्फ़िगर किए गए sysfs नोड नहीं हैं. आप बना सकते हैं वेंडर यूज़रस्पेस से इस्तेमाल किए जाने वाले वेंडर के लिए खास sysfs नोड. डिफ़ॉल्ट रूप से, SELinux का इस्तेमाल करके, userspace से sysfs नोड को ऐक्सेस करने की अनुमति नहीं दी जाती. यह तय करना कि वेंडर को सही SELinux लेबल जोड़ने की अनुमति देनी होगी, ताकि वेंडर सॉफ़्टवेयर.
  • DebugFS नोड. वेंडर मॉड्यूल, सिर्फ़ डीबग करने के लिए debugfs में नोड तय कर सकते हैं. ऐसा इसलिए, क्योंकि डिवाइस के सामान्य कामकाज के दौरान debugfs माउंट नहीं होता.