जेनेरिक कर्नेल इमेज (जीकेआई), अपस्ट्रीम Linux कर्नेल के साथ मिलकर काम करती है. इससे कर्नेल फ़्रैगमेंटेशन कम होता है. हालांकि, कुछ पैच को अपस्ट्रीम में स्वीकार नहीं किया जा सकता. इसके अलावा, प्रॉडक्ट के कुछ शेड्यूल होते हैं जिन्हें पूरा करना ज़रूरी होता है. इसलिए, कुछ पैच को Android Common Kernel (ACK) के सोर्स में बनाए रखा जाता है. GKI को इन्हीं सोर्स से बनाया जाता है.
डेवलपर को कोड में किए गए बदलावों को अपस्ट्रीम में सबमिट करना होगा. इसके लिए, Linux Kernel Mailing List (LKML) का इस्तेमाल करना होगा. कोड में किए गए बदलावों को ACK android-mainline
ब्रांच में सिर्फ़ तब सबमिट करना होगा, जब अपस्ट्रीम में सबमिट न करने की कोई ठोस वजह हो. मान्य वजहों के उदाहरण और उन्हें ठीक करने का तरीका यहां दिया गया है.
पैच को LKML में सबमिट किया गया था, लेकिन प्रॉडक्ट रिलीज़ के लिए इसे समय पर स्वीकार नहीं किया गया. इस पैच को मैनेज करने के लिए:
- इस बात का सबूत दें कि पैच को LKML में सबमिट किया गया था और पैच के लिए टिप्पणियां मिली थीं. इसके अलावा, यह भी बताएं कि पैच को अपस्ट्रीम में कब तक सबमिट किया जाएगा.
- ACK में पैच को शामिल करने के लिए, कार्रवाई का तरीका तय करें. इसे अपस्ट्रीम से मंज़ूरी दिलाएं. इसके बाद, जब अपस्ट्रीम का फ़ाइनल वर्शन ACK में मर्ज हो जाए, तब इसे ACK से हटा दें.
इस पैच में, वेंडर मॉड्यूल के लिए
EXPORT_SYMBOLS_GPL()
तय किया गया है. हालांकि, इसे अपस्ट्रीम में सबमिट नहीं किया जा सका, क्योंकि ऐसे कोई इन-ट्री मॉड्यूल नहीं हैं जो इस सिंबल का इस्तेमाल करते हों. इस पैच को मैनेज करने के लिए, इस बारे में जानकारी दें कि आपका मॉड्यूल अपस्ट्रीम क्यों सबमिट नहीं किया जा सकता. साथ ही, इस अनुरोध को करने से पहले आपने किन विकल्पों पर विचार किया.अपस्ट्रीम के लिए पैच सामान्य नहीं है और प्रॉडक्ट रिलीज़ होने से पहले, इसे फिर से बनाने का समय नहीं है. इस पैच को मैनेज करने के लिए, अनुमानित समय बताएं. इस समय तक, रिफ़ैक्टर किया गया पैच अपस्ट्रीम में सबमिट कर दिया जाएगा. रिफ़ैक्टर किए गए पैच को समीक्षा के लिए अपस्ट्रीम में सबमिट करने की योजना के बिना, पैच को ACK में स्वीकार नहीं किया जाएगा.
अपस्ट्रीम में पैच स्वीकार नहीं किया जा सकता, क्योंकि... <insert reason here>. इस पैच को ठीक करने के लिए, Android कर्नल टीम से संपर्क करें. साथ ही, पैच को फिर से बनाने के विकल्पों पर हमारे साथ काम करें, ताकि इसे समीक्षा के लिए सबमिट किया जा सके और अपस्ट्रीम में स्वीकार किया जा सके.
इसके अलावा, कई और वजहें भी हो सकती हैं. बग या पैच सबमिट करते समय, उसके बारे में सही जानकारी दें. साथ ही, कुछ बदलाव और चर्चा के लिए तैयार रहें. हम जानते हैं कि ACK में कुछ पैच होते हैं. खास तौर पर, GKI के शुरुआती चरणों में. ऐसा इसलिए होता है, क्योंकि सभी लोग अपस्ट्रीम पर काम करने का तरीका सीख रहे होते हैं. हालांकि, वे ऐसा करने के लिए, प्रॉडक्ट के शेड्यूल में बदलाव नहीं कर सकते. समय के साथ, अपस्ट्रीमिंग से जुड़ी ज़रूरी शर्तों के और ज़्यादा सख्त होने की उम्मीद करें.
पैच से जुड़ी ज़रूरी शर्तें
पैच, Linux सोर्स ट्री में बताए गए Linux कर्नेल कोडिंग स्टैंडर्ड के मुताबिक होने चाहिए. भले ही, उन्हें अपस्ट्रीम या ACK को सबमिट किया गया हो. scripts/checkpatch.pl
स्क्रिप्ट को Gerrit की प्रीसबमिट टेस्टिंग के हिस्से के तौर पर चलाया जाता है. इसलिए, इसे पहले से चलाएं, ताकि यह पक्का किया जा सके कि यह पास हो गई है. अगर आपको checkpatch स्क्रिप्ट को उसी कॉन्फ़िगरेशन के साथ चलाना है जिसका इस्तेमाल presubmit टेस्टिंग के लिए किया गया था, तो //build/kernel/static_analysis:checkpatch_presubmit
का इस्तेमाल करें.
ज़्यादा जानकारी के लिए, build/kernel/kleaf/docs/checkpatch.md पर जाएं.
ACK पैच
ACK को सबमिट किए गए पैच, Linux कर्नल कोडिंग के मानकों और योगदान से जुड़े दिशा-निर्देशों के मुताबिक होने चाहिए.
आपको कमिट मैसेज में Change-Id
टैग शामिल करना होगा. अगर आपको पैच को एक से ज़्यादा ब्रांच (उदाहरण के लिए, android-mainline
और android12-5.4
) में सबमिट करना है, तो आपको पैच के सभी इंस्टेंस के लिए एक ही Change-Id
टैग का इस्तेमाल करना होगा.
अपस्ट्रीम समीक्षा के लिए, पैच को सबसे पहले LKML पर सबमिट करें. अगर पैच:
- अपस्ट्रीम में स्वीकार किए जाने के बाद, इसे
android-mainline
में अपने-आप मर्ज कर दिया जाता है. - इसे अपस्ट्रीम में स्वीकार नहीं किया गया है. इसे
android-mainline
पर सबमिट करें. साथ ही, अपस्ट्रीम सबमिशन का रेफ़रंस दें या यह बताएं कि इसे LKML पर क्यों सबमिट नहीं किया गया.
अपस्ट्रीम या android-mainline
में पैच स्वीकार किए जाने के बाद, इसे एलटीएस पर आधारित सही ACK (जैसे, Android के लिए खास कोड ठीक करने वाले पैच के लिए android12-5.4
और android11-5.4
) में बैकपोर्ट किया जा सकता है. android-mainline
को सबमिट करने से, अपस्ट्रीम रिलीज़ कैंडिडेट के नए वर्शन के साथ टेस्टिंग की जा सकती है. साथ ही, यह पक्का किया जा सकता है कि पैच, अगले एलटीएस पर आधारित ACK में शामिल हो. अपवाद के तौर पर, ऐसे मामले शामिल हैं जिनमें अपस्ट्रीम पैच को android12-5.4
में बैकपोर्ट किया जाता है. ऐसा इसलिए किया जाता है, क्योंकि पैच पहले से ही android12-5.4
में मौजूद होता है.android-mainline
अपस्ट्रीम पैच
योगदान से जुड़े दिशा-निर्देशों में बताया गया है कि ACK कर्नल के लिए तैयार किए गए अपस्ट्रीम पैच, इन ग्रुप में शामिल होते हैं. इन्हें स्वीकार किए जाने की संभावना के क्रम में यहां दिया गया है.
UPSTREAM:
- अगर इस्तेमाल का कोई सही उदाहरण मौजूद है, तो 'android-mainline` से चुने गए पैच को ACK में स्वीकार किया जा सकता है.BACKPORT:
- अगर अपस्ट्रीम से लिए गए पैच में कोई समस्या है और उसमें बदलाव करने की ज़रूरत है, तो उसे भी स्वीकार किया जा सकता है. हालांकि, ऐसा तब होगा, जब उसे इस्तेमाल करने की कोई वजह हो.FROMGIT:
- अगर कोई डेडलाइन आने वाली है, तो मेंटेनर ब्रांच से चुनी गई पैच को स्वीकार किया जा सकता है. ये पैच, Linux मेनलाइन में सबमिट करने के लिए तैयार किए जाते हैं. कॉन्टेंट और शेड्यूल, दोनों के लिए इन बदलावों की वजह बताना ज़रूरी है.FROMLIST:
- LKML को सबमिट किए गए ऐसे पैच स्वीकार नहीं किए जाएंगे जिन्हें अब तक मेंटेनर ब्रांच में स्वीकार नहीं किया गया है. हालांकि, अगर पैच को स्वीकार करने की वजह इतनी मज़बूत है कि उसे अपस्ट्रीम Linux में शामिल किया जाए या न किया जाए, तो उसे स्वीकार किया जा सकता है. हम यह मानकर चल रहे हैं कि इसे अपस्ट्रीम Linux में शामिल नहीं किया जाएगा. Android कर्नल टीम से बातचीत करने के लिए,FROMLIST
पैच से जुड़ी कोई समस्या होनी चाहिए.
Android के लिए खास तौर पर बनाए गए पैच
अगर आपको अपस्ट्रीम में ज़रूरी बदलाव करने में समस्या आ रही है, तो ACK को सीधे तौर पर आउट-ऑफ़-ट्री पैच सबमिट करने की कोशिश करें. आउट-ऑफ़-ट्री पैच सबमिट करने के लिए, आपको आईटी में एक समस्या बनानी होगी. इसमें पैच और इस बात की वजह बतानी होगी कि पैच को अपस्ट्रीम में क्यों सबमिट नहीं किया जा सकता. उदाहरण के लिए, पिछली सूची देखें.
हालांकि, कुछ मामलों में कोड को अपस्ट्रीम में सबमिट नहीं किया जा सकता. इन मामलों को इस तरह से कवर किया जाता है. साथ ही, इनमें Android के लिए खास तौर पर बनाए गए पैच के लिए, योगदान से जुड़े दिशा-निर्देशों का पालन करना ज़रूरी है. इसके अलावा, इन्हें विषय में ANDROID:
प्रीफ़िक्स के साथ टैग किया जाना चाहिए.
gki_defconfig में बदलाव
gki_defconfig
में किए गए सभी CONFIG
बदलाव, arm64 और x86, दोनों वर्शन पर लागू होने चाहिए. हालांकि, अगर CONFIG
आर्किटेक्चर के हिसाब से अलग-अलग है, तो ऐसा करना ज़रूरी नहीं है. CONFIG
सेटिंग में बदलाव का अनुरोध करने के लिए, आईटी टीम के साथ एक समस्या शेयर करें, ताकि बदलाव के बारे में चर्चा की जा सके. केएमआई (कर्नेल मॉड्यूल इंटरफ़ेस) फ़्रीज़ होने के बाद, उसमें किए गए किसी भी CONFIG
बदलाव को अस्वीकार कर दिया जाता है. अगर पार्टनर किसी एक कॉन्फ़िगरेशन के लिए अलग-अलग सेटिंग का अनुरोध करते हैं, तो हम संबंधित गड़बड़ियों पर चर्चा करके विवादों को हल करते हैं.
ऐसा कोड जो अपस्ट्रीम में मौजूद नहीं है
Android के लिए पहले से मौजूद कोड में किए गए बदलावों को अपस्ट्रीम नहीं किया जा सकता. उदाहरण के लिए, भले ही बाइंडर ड्राइवर को अपस्ट्रीम मेंटेन किया जाता हो, लेकिन बाइंडर ड्राइवर की प्राथमिकता इनहेरिटेंस सुविधाओं में किए गए बदलावों को अपस्ट्रीम में नहीं भेजा जा सकता, क्योंकि वे Android के लिए खास तौर पर बनाए गए हैं. बग और पैच के बारे में साफ़ तौर पर बताएं. साथ ही, यह भी बताएं कि कोड को अपस्ट्रीम क्यों नहीं भेजा जा सकता. अगर हो सके, तो पैच को ऐसे हिस्सों में बांटें जिन्हें अपस्ट्रीम किया जा सकता है. साथ ही, Android के लिए खास तौर पर बनाए गए ऐसे हिस्सों में बांटें जिन्हें अपस्ट्रीम नहीं किया जा सकता. इससे ACK मेंटेन किए गए आउट-ऑफ़-ट्री कोड की संख्या कम हो जाएगी.
इस कैटगरी में अन्य बदलावों में, केएमआई प्रज़ेंटेशन फ़ाइलों, केएमआई सिंबल की सूचियों, gki_defconfig
, बिल्ड स्क्रिप्ट या कॉन्फ़िगरेशन या ऐसी अन्य स्क्रिप्ट के अपडेट शामिल हैं जो अपस्ट्रीम में मौजूद नहीं हैं.
आउट-ऑफ़-ट्री मॉड्यूल
अपस्ट्रीम Linux, आउट-ऑफ़-ट्री मॉड्यूल बनाने की सुविधा को बढ़ावा नहीं देता. यह एक सही फ़ैसला है, क्योंकि Linux के रखरखाव करने वाले लोग, कर्नल में मौजूद सोर्स या बाइनरी के साथ काम करने की गारंटी नहीं देते. साथ ही, वे ऐसे कोड को सपोर्ट नहीं करना चाहते जो ट्री में मौजूद नहीं है. हालांकि, जीकेआई, वेंडर मॉड्यूल के लिए एबीआई की गारंटी देता है. इससे यह पक्का होता है कि केएमआई इंटरफ़ेस, कर्नेल के लिए तय की गई अवधि तक स्थिर रहते हैं. इसलिए, वेंडर मॉड्यूल के साथ काम करने वाले बदलावों की एक क्लास है. ये बदलाव, ACK के लिए स्वीकार किए जा सकते हैं, लेकिन अपस्ट्रीम के लिए स्वीकार नहीं किए जा सकते.
उदाहरण के लिए, ऐसे पैच पर विचार करें जो EXPORT_SYMBOL_GPL()
मैक्रो जोड़ता है. इसमें एक्सपोर्ट का इस्तेमाल करने वाले मॉड्यूल, सोर्स ट्री में नहीं होते. आपको EXPORT_SYMBOL_GPL()
से अपस्ट्रीम में अनुरोध करना होगा और एक ऐसा मॉड्यूल उपलब्ध कराना होगा जो हाल ही में एक्सपोर्ट किए गए सिंबल का इस्तेमाल करता हो. हालांकि, अगर मॉड्यूल को अपस्ट्रीम में सबमिट न करने की कोई मान्य वजह है, तो ACK को पैच सबमिट किया जा सकता है. आपको समस्या में यह जानकारी देनी होगी कि मॉड्यूल को अपस्ट्रीम क्यों नहीं किया जा सकता. (GPL के अलावा किसी अन्य वैरिएंट का अनुरोध न करें, EXPORT_SYMBOL()
.)
छिपे हुए कॉन्फ़िगरेशन
कुछ इन-ट्री मॉड्यूल, छिपे हुए कॉन्फ़िगरेशन को अपने-आप चुनते हैं. इन्हें gki_defconfig
में नहीं बताया जा सकता. उदाहरण के लिए, CONFIG_SND_SOC_SOF=y
को कॉन्फ़िगर करने पर, CONFIG_SND_SOC_TOPOLOGY
अपने-आप चुना जाता है. आउट-ऑफ़-ट्री मॉड्यूल बनाने के लिए, GKI में छिपे हुए कॉन्फ़िगरेशन चालू करने का एक तरीका शामिल है.
छुपे हुए कॉन्फ़िगरेशन को चालू करने के लिए, init/Kconfig.gki
में select
स्टेटमेंट जोड़ें, ताकि CONFIG_GKI_HACKS_TO_FIX
कर्नल कॉन्फ़िगरेशन के आधार पर यह अपने-आप चुना जा सके. यह gki_defconfig
में चालू होता है. इस तरीके का इस्तेमाल सिर्फ़ छिपे हुए कॉन्फ़िगरेशन के लिए करें. अगर कॉन्फ़िगरेशन छिपा हुआ नहीं है, तो इसे 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
फ़ील्ड जोड़कर, वेंडर के डेटा को मुख्य डेटा स्ट्रक्चर से जोड़ा जा सकता है. उदाहरण के लिए, वैल्यू-ऐडेड सुविधाओं को सपोर्ट करने के लिए, स्ट्रक्चर में फ़ील्ड जोड़ें. इसके लिए, यहां दिए गए कोड सैंपल में दिखाया गया तरीका अपनाएं.
वेंडर और ओईएम के लिए ज़रूरी फ़ील्ड के बीच संभावित टकराव से बचने के लिए, ओईएम को ANDROID_VENDOR_DATA()
मैक्रो का इस्तेमाल करके घोषित किए गए फ़ील्ड का इस्तेमाल कभी नहीं करना चाहिए. इसके बजाय, ओईएम को 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()
का इस्तेमाल करके, वेंडर हुक को कर्नल कोड में ट्रेसपॉइंट के तौर पर जोड़ें. इसके बाद, उन्हें कोड में ट्रेसपॉइंट के तौर पर जोड़ें. उदाहरण के लिए, मौजूदा do_exit()
कर्नल फ़ंक्शन में trace_android_vh_sched_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);
ध्यान दें: हुक के एलान में इस्तेमाल किए गए डेटा स्ट्रक्चर को पूरी तरह से तय किया जाना चाहिए, ताकि यह पक्का किया जा सके कि ABI स्टेबल है. इसके अलावा, ओपेक पॉइंटर को डीरेफ़रंस करना या साइज़ वाले कॉन्टेक्स्ट में स्ट्रक्चर का इस्तेमाल करना सुरक्षित नहीं है. ऐसे डेटा स्ट्रक्चर की पूरी जानकारी देने वाले 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
को अनडिफ़ाइन कर दिया जाए.
कर्नेल की मुख्य सुविधाएं
अगर ऊपर बताई गई किसी भी तकनीक से, आपको किसी मॉड्यूल की सुविधा लागू करने में मदद नहीं मिलती है, तो आपको सुविधा को Android के हिसाब से, मुख्य कर्नल में बदलाव के तौर पर जोड़ना होगा. बातचीत शुरू करने के लिए, समस्या ट्रैकर (आईटी) में कोई समस्या बनाएं.
यूज़र ऐप्लिकेशन प्रोग्रामिंग इंटरफ़ेस (यूएपीआई)
- यूएपीआई हेडर फ़ाइलें. UAPI हेडर फ़ाइलों में किए गए बदलाव, अपस्ट्रीम में होने चाहिए. हालांकि, अगर बदलाव Android के लिए खास तौर पर बनाए गए इंटरफ़ेस में किए जा रहे हैं, तो ऐसा करना ज़रूरी नहीं है. वेंडर के हिसाब से हेडर फ़ाइलों का इस्तेमाल करके, वेंडर मॉड्यूल और वेंडर यूज़रस्पेस कोड के बीच इंटरफ़ेस तय करें.
- sysfs नोड. GKI कर्नल में नए sysfs नोड न जोड़ें. इस तरह के नोड सिर्फ़ वेंडर मॉड्यूल में जोड़े जा सकते हैं. एसओसी और डिवाइस के हिसाब से काम करने वाली लाइब्रेरी और Android फ़्रेमवर्क में शामिल Java कोड के लिए इस्तेमाल किए जाने वाले sysfs नोड में सिर्फ़ ऐसे बदलाव किए जा सकते हैं जो इनके साथ काम करते हों. अगर ये Android के हिसाब से काम करने वाले sysfs नोड नहीं हैं, तो इनमें अपस्ट्रीम में बदलाव किया जाना चाहिए. वेंडर के उपयोगकर्ता स्पेस के लिए, वेंडर के हिसाब से sysfs नोड बनाए जा सकते हैं. डिफ़ॉल्ट रूप से, SELinux का इस्तेमाल करके, उपयोगकर्ताओं को sysfs नोड ऐक्सेस करने से रोका जाता है. वेंडर को सही SELinux लेबल जोड़ने होते हैं, ताकि वेंडर के सॉफ़्टवेयर को ऐक्सेस करने की अनुमति दी जा सके.
- DebugFS नोड. वेंडर मॉड्यूल, सिर्फ़ डीबग करने के लिए
debugfs
में नोड तय कर सकते हैं. ऐसा इसलिए, क्योंकि डिवाइस के सामान्य ऑपरेशन के दौरानdebugfs
माउंट नहीं होता है.