जेनेरिक कर्नेल इमेज (जीकेआई), अपस्ट्रीम Linux कर्नेल के साथ मिलकर काम करती है. इससे कर्नेल फ़्रैगमेंटेशन कम होता है. हालांकि, कुछ पैच को अपस्ट्रीम में स्वीकार न किए जाने की सही वजहें हैं. साथ ही, प्रॉडक्ट के शेड्यूल को पूरा करना ज़रूरी है. इसलिए, कुछ पैच को Android Common Kernel (ACK) सोर्स में बनाए रखा जाता है. जीकेआई, ACK सोर्स से ही बनाया जाता है.
डेवलपर को कोड में किए गए बदलाव, Linux Kernel Mailing List (LKML) का इस्तेमाल करके अपस्ट्रीम में सबमिट करने चाहिए. कोड में किए गए बदलाव, ACK की android-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 कर्नेल कोडिंग के मानकों और
योगदान के दिशा-निर्देशों के मुताबिक होने चाहिए.
आपको कमिट मैसेज में, Change-Id
टैग शामिल करना होगा. अगर पैच को एक से ज़्यादा ब्रांच में सबमिट किया जाता है (उदाहरण के लिए, android-mainline और android12-5.4), तो पैच के सभी इंस्टेंस के लिए, एक ही
Change-Id का इस्तेमाल करना होगा.
अपस्ट्रीम की समीक्षा के लिए, पैच को सबसे पहले LKML में सबमिट करें. अगर पैच:
- अपस्ट्रीम में स्वीकार किया जाता है, तो यह
android-mainlineमें अपने-आप मर्ज हो जाता है. - अपस्ट्रीम में स्वीकार नहीं किया जाता है, तो इसे
android-mainlineमें सबमिट करें. साथ ही, अपस्ट्रीम में सबमिट किए गए पैच का रेफ़रंस दें या यह बताएं कि इसे LKML में क्यों सबमिट नहीं किया गया.
अपस्ट्रीम या android-mainline में पैच स्वीकार किए जाने के बाद, इसे एलटीएस पर आधारित ACK (जैसे, Android-specific कोड को ठीक करने वाले पैच के लिए android12-5.4 और android11-5.4) में बैकपोर्ट किया जा सकता है. android-mainline में सबमिट करने से, नए अपस्ट्रीम रिलीज़ कैंडिडेट के साथ टेस्टिंग की जा सकती है. साथ ही, यह पक्का किया जा सकता है कि पैच, एलटीएस पर आधारित अगले ACK में शामिल हो. हालांकि, कुछ मामलों में अपस्ट्रीम पैच को android12-5.4 में बैकपोर्ट किया जाता है. ऐसा इसलिए किया जाता है, क्योंकि पैच के android-mainline में पहले से मौजूद होने की संभावना होती है.
अपस्ट्रीम पैच
UPSTREAM:- 'android-mainline` से चुने गए पैच को ACK में स्वीकार किए जाने की संभावना होती है. हालांकि, इसके लिए कोई सही वजह होनी चाहिए.BACKPORT:- अपस्ट्रीम से चुने गए पैच को भी ACK में स्वीकार किए जाने की संभावना होती है. हालांकि, इसके लिए कोई सही वजह होनी चाहिए. साथ ही, इन पैच में बदलाव करने की ज़रूरत होती है.FROMGIT:- Linux मेनलाइन में सबमिट करने की तैयारी में, मेंटेनर ब्रांच से चुने गए पैच को स्वीकार किया जा सकता है. हालांकि, इसके लिए कोई आने वाली समयसीमा होनी चाहिए. इन पैच के लिए, कॉन्टेंट और शेड्यूल, दोनों के लिए सही वजह होनी चाहिए.FROMLIST:- LKML में सबमिट किए गए पैच को स्वीकार किए जाने की संभावना कम होती है. ऐसा तब तक होता है, जब तक उन्हें मेंटेनर ब्रांच में स्वीकार नहीं किया जाता. हालांकि, अगर पैच को स्वीकार करने की कोई सही वजह है, तो उसे अपस्ट्रीम Linux में स्वीकार किया जा सकता है. हमारा मानना है कि ऐसा नहीं होगा.FROMLISTपैच से जुड़ी कोई समस्या होनी चाहिए, ताकि Android कर्नेल टीम के साथ चर्चा की जा सके.
Android-specific पैच
अगर ज़रूरी बदलावों को अपस्ट्रीम में सबमिट नहीं किया जा सकता, तो ACK में सीधे तौर पर आउट-ऑफ़-ट्री पैच सबमिट किए जा सकते हैं. आउट-ऑफ़-ट्री पैच सबमिट करने के लिए, आपको आईटी में एक समस्या क्रिएट करनी होगी. इसमें पैच और उस वजह का हवाला देना होगा कि पैच को अपस्ट्रीम में क्यों सबमिट नहीं किया जा सकता. उदाहरण के लिए, पिछली सूची देखें.
हालांकि, कुछ मामलों में कोड को अपस्ट्रीम में सबमिट नहीं किया जा सकता. इन
मामलों के बारे में यहां बताया गया है. साथ ही, Android-specific पैच के लिए, योगदान
के दिशा-निर्देशों
का पालन करना ज़रूरी है. इसके अलावा, विषय में ANDROID: प्रीफ़िक्स टैग करना ज़रूरी है.
gki_defconfig में किए गए बदलाव
gki_defconfig में किए गए सभी CONFIG बदलाव, arm64 और x86, दोनों वर्शन पर लागू होने चाहिए. हालांकि, अगर CONFIG, आर्किटेक्चर के हिसाब से अलग-अलग है, तो ऐसा नहीं है. CONFIG सेटिंग में बदलाव का अनुरोध करने के लिए, बदलाव पर चर्चा करने के लिए आईटी में एक समस्या क्रिएट करें. फ़्रीज़ होने के बाद, कर्नेल मॉड्यूल इंटरफ़ेस (केएमआई) पर असर डालने वाले किसी भी CONFIG बदलाव को अस्वीकार कर दिया जाता है. अगर पार्टनर, एक ही कॉन्फ़िगरेशन के लिए अलग-अलग सेटिंग का अनुरोध करते हैं, तो हम संबंधित बग पर चर्चा करके विवादों को सुलझाते हैं.
अपस्ट्रीम में मौजूद न होने वाला कोड
Android-specific कोड में किए गए बदलावों को अपस्ट्रीम में नहीं भेजा जा सकता. उदाहरण के लिए, भले ही बाइंडर ड्राइवर को अपस्ट्रीम में बनाए रखा जाता हो, लेकिन बाइंडर ड्राइवर की प्राथमिकता इनहेरिटेंस सुविधाओं में किए गए बदलावों को अपस्ट्रीम में नहीं भेजा जा सकता, क्योंकि ये Android-specific हैं. बग और पैच में साफ़ तौर पर बताएं कि कोड को अपस्ट्रीम में क्यों नहीं भेजा जा सकता. अगर हो सके, तो पैच को उन हिस्सों में बांटें जिन्हें अपस्ट्रीम में सबमिट किया जा सकता है. साथ ही, Android-specific हिस्सों को अपस्ट्रीम में सबमिट नहीं किया जा सकता. इससे, ACK में बनाए रखे गए आउट-ऑफ़-ट्री कोड की मात्रा कम हो जाएगी.
इस कैटगरी में अन्य बदलाव, केएमआई की जानकारी देने वाली फ़ाइलों, केएमआई सिंबल की सूचियों, gki_defconfig, बिल्ड स्क्रिप्ट या कॉन्फ़िगरेशन या अपस्ट्रीम में मौजूद न होने वाली अन्य स्क्रिप्ट के अपडेट हैं.
आउट-ऑफ़-ट्री मॉड्यूल
अपस्ट्रीम Linux, आउट-ऑफ़-ट्री मॉड्यूल बनाने की सुविधा को हतोत्साहित करता है. यह एक सही वजह है, क्योंकि Linux मेंटेनर, इन-कर्नेल सोर्स या बाइनरी कंपैटिबिलिटी की गारंटी नहीं देते. साथ ही, वे ऐसे कोड को सपोर्ट नहीं करना चाहते जो ट्री में मौजूद नहीं है. हालांकि, जीकेआई, वेंडर मॉड्यूल के लिए ABI की गारंटी देता है. इससे यह पक्का होता है कि केएमआई इंटरफ़ेस, कर्नेल के सपोर्ट किए गए लाइफ़टाइम के लिए स्थिर हों. इसलिए, वेंडर मॉड्यूल को सपोर्ट करने के लिए, बदलावों की एक क्लास है. इन्हें ACK के लिए स्वीकार किया जा सकता है, लेकिन अपस्ट्रीम के लिए नहीं.
उदाहरण के लिए, ऐसे पैच पर विचार करें जो EXPORT_SYMBOL_GPL() मैक्रो जोड़ता है. इसमें, एक्सपोर्ट का इस्तेमाल करने वाले मॉड्यूल, सोर्स ट्री में मौजूद नहीं हैं. आपको EXPORT_SYMBOL_GPL() के लिए अपस्ट्रीम में अनुरोध करना होगा. साथ ही, ऐसा मॉड्यूल उपलब्ध कराना होगा जो नए एक्सपोर्ट किए गए सिंबल का इस्तेमाल करता है. हालांकि, अगर मॉड्यूल को अपस्ट्रीम में सबमिट न करने की कोई सही वजह है, तो इसके बजाय ACK में पैच सबमिट किया जा सकता है. आपको समस्या में, मॉड्यूल को अपस्ट्रीम में सबमिट न करने की वजह शामिल करनी होगी. (जीपीएल के अलावा, EXPORT_SYMBOL() का अनुरोध न करें.)
छिपे हुए कॉन्फ़िगरेशन
कुछ इन-ट्री मॉड्यूल, छिपे हुए कॉन्फ़िगरेशन को अपने-आप चुन लेते हैं. इन्हें gki_defconfig में तय नहीं किया जा सकता. उदाहरण के लिए, CONFIG_SND_SOC_SOF=y कॉन्फ़िगर करने पर, CONFIG_SND_SOC_TOPOLOGY अपने-आप चुन लिया जाता है. आउट-ऑफ़-ट्री मॉड्यूल बनाने के लिए, जीकेआई में छिपे हुए कॉन्फ़िगरेशन को चालू करने का एक तरीका शामिल है.
छिपे हुए कॉन्फ़िगरेशन को चालू करने के लिए, init/Kconfig.gki में select स्टेटमेंट जोड़ें. इससे, CONFIG_GKI_HACKS_TO_FIX कर्नेल कॉन्फ़िगरेशन के आधार पर, यह अपने-आप चुन लिया जाता है. यह कॉन्फ़िगरेशन, gki_defconfig में चालू होता है. इस तरीके का इस्तेमाल सिर्फ़ छिपे हुए कॉन्फ़िगरेशन के लिए करें. अगर कॉन्फ़िगरेशन छिपा हुआ नहीं है, तो इसे gki_defconfig में साफ़ तौर पर या डिपेंडेंसी के तौर पर तय करना होगा.
लोड किए जा सकने वाले गवर्नर
कर्नेल फ़्रेमवर्क (जैसे, cpufreq) के लिए, लोड किए जा सकने वाले गवर्नर का इस्तेमाल किया जा सकता है. इनमें डिफ़ॉल्ट गवर्नर (जैसे, cpufreq का schedutil गवर्नर) को बदला जा सकता है. ऐसे
फ़्रेमवर्क (जैसे, थर्मल फ़्रेमवर्क) के लिए, लोड किए जा सकने वाले गवर्नर
या ड्राइवर का इस्तेमाल नहीं किया जा सकता. हालांकि, इनमें वेंडर-specific लागू करने की ज़रूरत होती है. इसके लिए, आईटी में एक समस्या क्रिएट करें
और Android कर्नेल टीमसे सलाह लें.
ज़रूरी सहायता जोड़ने के लिए, हम आपके और अपस्ट्रीम मेंटेनर के साथ मिलकर काम करेंगे.
वेंडर हुक
पिछले रिलीज़ में, वेंडर-specific बदलावों को सीधे कोर कर्नेल में जोड़ा जा सकता था. जीकेआई 2.0 के साथ ऐसा नहीं किया जा सकता, क्योंकि प्रॉडक्ट-specific कोड को मॉड्यूल में लागू करना होगा. इसे अपस्ट्रीम या ACK के कोर कर्नेल में स्वीकार नहीं किया जाएगा. वैल्यू-ऐडेड सुविधाओं को चालू करने के लिए, जीकेआई, वेंडर हुक को स्वीकार करता है. इनकी मदद से, मॉड्यूल को कोर कर्नेल कोड से शुरू किया जा सकता है. इन सुविधाओं पर पार्टनर भरोसा करते हैं. साथ ही, इनका कोर कर्नेल कोड पर कम से कम असर पड़ता है. इसके अलावा, इन सुविधाओं को लागू करने के लिए, वेंडर-specific डेटा को सेव करने के लिए उपलब्ध, वेंडर डेटा फ़ील्ड के साथ, मुख्य डेटा स्ट्रक्चर को पैड किया जा सकता है.
वेंडर हुक के दो वैरिएंट (सामान्य और पाबंदी वाले) होते हैं. ये वैरिएंट, ट्रेसपॉइंट (ट्रेस इवेंट नहीं) पर आधारित होते हैं. वेंडर मॉड्यूल, इनसे अटैच हो सकते हैं. उदाहरण के लिए, टास्क से बाहर निकलने पर, हिसाब रखने के लिए, वेंडर, नया sched_exit() फ़ंक्शन जोड़ने के बजाय, do_exit() में एक हुक जोड़ सकते हैं. वेंडर मॉड्यूल, प्रोसेसिंग के लिए इससे अटैच हो सकता है. लागू करने के उदाहरण में, ये वेंडर हुक शामिल हैं.
- सामान्य वेंडर हुक,
DECLARE_HOOK()का इस्तेमाल करके, ट्रेसपॉइंट फ़ंक्शन बनाते हैं. इसमेंtrace_nameनाम सेnameट्रेस के लिए यूनीक आइडेंटिफ़ायर होता है. सामान्य तौर पर, सामान्य वेंडर हुक के नामandroid_vhसे शुरू होते हैं. इसलिए,sched_exit()हुक का नामandroid_vh_sched_exitहोगा. - पाबंदी वाले वेंडर हुक की ज़रूरत, शेड्यूलर हुक जैसे मामलों में होती है. इनमें, अटैच किए गए फ़ंक्शन को तब भी कॉल करना होता है, जब सीपीयू ऑफ़लाइन हो या उसे नॉन-एटॉमिक कॉन्टेक्स्ट की ज़रूरत हो. पाबंदी वाले वेंडर हुक को डिटैच नहीं किया जा सकता. इसलिए, पाबंदी वाले हुक से अटैच होने वाले मॉड्यूल कभी अनलोड नहीं हो सकते. पाबंदी वाले वेंडर हुक के नाम
android_rvhसे शुरू होते हैं.
वेंडर हुक जोड़ने के लिए, आईटी में एक समस्या दर्ज करें और पैच सबमिट करें. Android-specific सभी पैच के लिए, एक समस्या मौजूद होनी चाहिए. साथ ही, आपको सही वजह बतानी होगी. वेंडर हुक की सुविधा सिर्फ़ 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 की स्थिरता की गारंटी देने के लिए, हुक एलान में इस्तेमाल किए गए डेटा स्ट्रक्चर को
पूरी तरह से तय करना ज़रूरी है. ऐसा न करने पर, अपारदर्शी पॉइंटर को डीरेफ़रंस करना या साइज़ वाले कॉन्टेक्स्ट में स्ट्रक्चर का इस्तेमाल करना सुरक्षित नहीं है. ऐसे डेटा स्ट्रक्चर की पूरी जानकारी देने वाला, शामिल किया गया कोड, 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-specific बदलाव के तौर पर जोड़ना होगा. बातचीत शुरू करने के लिए, समस्या ट्रैक करने वाले टूल (आईटी) में एक समस्या क्रिएट करें.
यूज़र ऐप्लिकेशन प्रोग्रामिंग इंटरफ़ेस (यूएपीआई)
- यूएपीआई हेडर फ़ाइलें. यूएपीआई हेडर फ़ाइलों में किए गए बदलाव, अपस्ट्रीम में होने चाहिए. हालांकि, अगर बदलाव, Android-specific इंटरफ़ेस में किए गए हैं, तो ऐसा नहीं है. वेंडर मॉड्यूल और वेंडर यूज़रस्पेस कोड के बीच इंटरफ़ेस तय करने के लिए, वेंडर-specific हेडर फ़ाइलों का इस्तेमाल करें.
- sysfs नोड. जीकेआई कर्नेल में नए sysfs नोड न जोड़ें. इस तरह के नोड सिर्फ़ वेंडर मॉड्यूल में जोड़े जा सकते हैं. SoC और डिवाइस-agnostic लाइब्रेरी और Android फ़्रेमवर्क बनाने वाले Java कोड में इस्तेमाल किए गए sysfs नोड में सिर्फ़ कंपैटिबल तरीके से बदलाव किया जा सकता है. अगर ये Android-specific sysfs नोड नहीं हैं, तो इनमें अपस्ट्रीम में बदलाव करना ज़रूरी है. वेंडर यूज़रस्पेस में इस्तेमाल किए जाने वाले, वेंडर-specific sysfs नोड बनाए जा सकते हैं. डिफ़ॉल्ट तौर पर, SELinux का इस्तेमाल करके, यूज़रस्पेस को sysfs नोड ऐक्सेस करने की अनुमति नहीं दी जाती. वेंडर को, SELinux के सही लेबल जोड़ने होंगे, ताकि मंज़ूरी वाले वेंडर सॉफ़्टवेयर को ऐक्सेस करने की अनुमति दी जा सके.
- DebugFS नोड. वेंडर मॉड्यूल, सिर्फ़ डीबग करने के लिए,
debugfsमें नोड तय कर सकते हैं. ऐसा इसलिए, क्योंकि डिवाइस के सामान्य ऑपरेशन के दौरान,debugfsमाउंट नहीं होता.