تطوير رمز النواة (kernel) لـ GKI

تعمل صورة النواة العامة (GKI) على الحدّ من تجزئة النواة من خلال التوافق بشكل وثيق مع نواة Linux الرئيسية. ومع ذلك، هناك أسباب وجيهة لتعذُّر قبول بعض رموز التصحيح، وهناك جداول زمنية للمنتجات يجب الوفاء بها، لذلك يتم الاحتفاظ ببعض رموز التصحيح في مصادر Android Common Kernel (ACK) التي تم إنشاء GKI منها.

على المطوّرين إرسال تغييرات الرموز البرمجية من البداية باستخدام 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، يمكن إعادته إلى الإصدار الثابت المتوافق مع الإصدارات الطويلة المدى (مثل android12-5.4 و android11-5.4 للتصحيحات التي تعالج الرمز البرمجي المخصّص لنظام Android). يتيح الإرسال إلى android-mainline إجراء الاختبار باستخدام الإصدارات المرشحة الجديدة من الإصدارات الرئيسية، ويضمن أنّ الإصلاح متوفّر في الإصدار التالي من ACK المستنِد إلى الإصدار الثابت طويل الأمد. تشمل الاستثناءات الحالات التي يتم فيها نقل تصحيح من الإصدار الأحدث إلى الإصدار android12-5.4 (لأنّ التصحيح هو من المرجّح أن يكون متوفّرًا في الإصدار android-mainline).

تصحيحات المصدر

كما هو موضّح في إرشادات المساهمة، تندرج التصحيحات المرسَلة إلى الإصدارات العلنية والمخصّصة لنظام تشغيل ACK ضمن المجموعات التالية (المُدرَجة حسب ترتيب احتمالية قبولها).

  • UPSTREAM: - من المرجّح أن يتم قبول التصحيحات التي تم اختيارها من "android-mainline" في ACK إذا كانت هناك حالة استخدام معقولة.
  • BACKPORT: - من المحتمل أيضًا قبول التصحيحات من المصدر التي لا يتم اختيارها بعناية وتحتاج إلى تعديل إذا كان هناك حالة استخدام معقولة.
  • FROMGIT: - قد يتم قبول الإصلاحات التي تم اختيارها من فرع المشرف في إطار التحضير لإرسالها إلى الإصدار الرئيسي لنظام التشغيل Linux إذا كان هناك مهلة قادمة. ويجب أن يكون هناك سبب وجيه لكل من المحتوى والجدول الزمني.
  • FROMLIST: - من غير المرجّح قبول رموز التصحيح التي تم إرسالها إلى LKML ولكن لم يتم قبولها لدى فرع الصيانة حتى الآن، ما لم يكن المبرر مقنعًا بما يكفي لقبول رمز التصحيح سواء تم إصداره في إصدار نظام التشغيل Linux أم لا (نفترض أنّه لن يتم قبوله) يجب أن يكون هناك مشكلة مرتبطة بإصلاحات FROMLIST لتسهيل المناقشة مع فريق نواة Android.

التصحيحات الخاصة بنظام التشغيل Android

إذا لم تتمكّن من طرح التغييرات المطلوبة في الإصدار العلني، يمكنك محاولة إرسال تصحيحات خارج الشجرة إلى ACK مباشرةً. يتطلّب إرسال الرموز البرمجية الإضافية التي لا تتبع المسار المعتاد إنشاء مشكلة في تكنولوجيا المعلومات تشير إلى التصحيح والسبب الذي يتعذّر معه إرسال التصحيح إلى المسار المعتاد (اطّلِع على القائمة السابقة للحصول على أمثلة). ومع ذلك، هناك بعض الحالات التي لا يمكن فيها إرسال الرمز البرمجي إلى المصدر. يتم التعامل مع هذه الحالات على النحو التالي ويجب أن تلتزم بإرشادات المساهمة للتصحيحات الخاصة بنظام Android وأن يتم وضع البادئة ANDROID: في عنوان الرسالة.

التغييرات في gki_defconfig

يجب تطبيق جميع التغييرات في CONFIG على gki_defconfig على كل من الإصدارَين arm64 و x86 ما لم تكن CONFIG خاصة بالبنية. لطلب إجراء تغيير في إعدادات CONFIG، أنشئ مشكلة في قسم تكنولوجيا المعلومات لمناقشة التغيير. يتم رفض أي CONFIG تغيير يؤثر في واجهة وحدة المعالجة الأساسية (KMI) بعد تجميدها. في الحالات التي يطلب فيها الشركاء إعدادات متناقضة لإعدادات واحدة، نحلّ التعارضات من خلال مناقشة الأخطاء ذات الصلة.

رمز غير متوفّر في المصدر

لا يمكن إرسال تعديلات على الرموز البرمجية الخاصة بنظام التشغيل Android قبل إطلاقها. على سبيل المثال، على الرغم من أنّ برنامج تشغيل أداة الربط يتم الاحتفاظ به في المصدر، لا يمكن إرسال التعديلات على ميزات اكتساب الأولوية في برنامج تشغيل أداة الربط إلى المصدر لأنّها خاصة بنظام Android. كن واضحًا في الخطأ وصحح سبب عدم إمكانية إرسال التعليمات البرمجية قبل التنفيذ. إذا أمكن، يمكنك تقسيم الرقع إلى أجزاء يمكن إرسالها إلى الإصدار العلني وأجزاء خاصة بنظام التشغيل Android لا يمكن إرسالها إلى الإصدار العلني لتقليل كمية الرموز البرمجية التي لا تندرج ضمن البنية الأساسية والتي يتم الاحتفاظ بها في ACK.

تشمل التغييرات الأخرى في هذه الفئة تعديلات على ملفات تمثيل KMI أو قوائم رموز KMI أو gki_defconfig أو نصوص برمجية لإنشاء الإصدارات أو الضبط أو نصوص برمجية أخرى غير متوفّرة في المصدر.

الوحدات خارج الشجرة

لا ينصح فريق Linux Upstream بدعم إنشاء وحدات خارج الشجرة. وهذا موقف معقول نظرًا لأنّ مشرفي Linux لا يقدّمون ضمانات بشأن التوافق مع المصدر أو الثنائي في النواة ولا يريدون إتاحة الرمز المبرمَج الذي لا يتبع الشجرة. ومع ذلك، يقدّم GKI ضمانات ABI ل وحدات المورّدين، ما يضمن ثبات واجهات KMI خلال مدة استخدام النواة المتوافقة. لذلك، هناك فئة من التغييرات لتوفير وحدات المورّدين المقبولة في ACK ولكنّها غير مقبولة في المصدر.

على سبيل المثال، نأخذ تصحيحًا يضيف وحدات ماكرو EXPORT_SYMBOL_GPL() حيث تكون الوحدات التي تستخدِم التصدير غير متوفّرة في شجرة المصدر. على الرغم من أنّه عليك محاولة طلب EXPORT_SYMBOL_GPL() من المصدر وتقديم وحدة تستخدم الرمز الذي تم تصديره حديثًا، إذا كان هناك سبب وجيه لعدم إرسال الوحدة إلى المصدر، يمكنك إرسال التعديل إلى ACK بدلاً من ذلك. عليك تضمين سبب عدم إمكانية نقل بيانات الوحدة إلى الإصدار العلني في المشكلة. (لا تطلب صيغة غير متوافقة مع "قائمة المورّدين العالميين"، EXPORT_SYMBOL()).

الإعدادات المخفية

تختار بعض الوحدات النمطية تلقائيًا الإعدادات المخفية التي لا يمكن تحديدها في gki_defconfig. على سبيل المثال، يتم اختيار CONFIG_SND_SOC_TOPOLOGY تلقائيًا عند ضبط CONFIG_SND_SOC_SOF=y. لاستيعاب إنشاء الوحدات خارج الشجرة، يشمل GKI آلية لتفعيل الإعدادات المخفية.

لتفعيل إعدادات مخفية، أضِف عبارة select في init/Kconfig.gki حتى تتم اختيارها تلقائيًا استنادًا إلى إعدادات CONFIG_GKI_HACKS_TO_FIX kernel، التي تم تفعيلها في gki_defconfig. لا تستخدِم هذه الآلية إلا للإعدادات المخفية، وإذا لم تكن الإعدادات مخفية، يجب تحديدها في gki_defconfig إما بشكل صريح أو كعنصر تابع.

عناصر التحكّم القابلة للتحميل

بالنسبة إلى إطارات عمل النواة (مثل cpufreq) التي تتيح استخدام أدوات التحكّم القابلة للتحميل، يمكنك تجاوز أداة التحكّم التلقائية (مثل أداة التحكّم schedutil في cpufreq). بالنسبة إلى الإطارات الأساسية (مثل إطار العمل الحراري) التي لا تتوافق مع أدوات التحكّم في الطاقة أو برامج التشغيل القابلة للتحميل، ولكنّها لا تزال تتطلّب تنفيذًا خاصًا بالمورّد، يمكنك إنشاء مشكلة في تكنولوجيا المعلومات والتشاور مع فريق نواة Android.

سنتعاون معك ومع مشرفي الإصدارات السابقة لإضافة الدعم اللازم.

عناصر الربط الخاصة بالمورّدين

في الإصدارات السابقة، يمكنك إضافة تعديلات خاصة بالبائعين مباشرةً في النواة الأساسية. لا يمكن إجراء ذلك باستخدام GKI 2.0 لأنّه يجب تنفيذ الرمز المخصّص للمنتج في الوحدات ولن يتم قبوله في النوى الأساسية في المصدر أو في ACK. لتفعيل الميزات ذات القيمة المضافة التي يعتمد عليها الشركاء بأقل تأثير على رمز النواة الأساسية، يقبل GKI عناصر التحكّم في واجهة المستخدم (GKI) التي تتيح إمكانية استدعاء الوحدات من رمز النواة الأساسية. بالإضافة إلى ذلك، يمكن ملء هياكل البيانات الرئيسية باستخدام حقول بيانات المورّدين المتاحة لتخزين البيانات الخاصة بالمورّدين من أجل تنفيذ هذه الميزات.

تتوفّر عناصر الجذب للمورّدين في صيغتين (عادي ومحظور) تستند إلى نقاط التتبّع (وليس أحداث التتبُّع) التي يمكن لوحدات المورّدين إرفاقها. على سبيل المثال، بدلاً من إضافة دالة sched_exit() جديدة لإجراء محاسبة عند معالجة مهمة، يمكن للمورّدين إضافة عنصر ربط في do_exit() يمكن أن ترتبط به وحدة مورّد لمعالجتها. يتضمن مثال التنفيذ نقاط الربط التالية الخاصة بالمورّد.

  • تستخدم عناصر الجذب العادية للمورّدين DECLARE_HOOK() لإنشاء دالة نقطة تتبُّع تحمل الاسم trace_name، حيث يكون name هو المعرّف الفريد للتتبُّع. وفقًا للعرف، تبدأ أسماء أدوات الربط العادية الخاصة بالمورّدين بـ android_vh، لذلك سيكون اسم أداة الربط sched_exit() هو android_vh_sched_exit.
  • هناك حاجة إلى عناصر الجذب المشروطة من المورِّدين في حالات مثل عناصر الجدولة التي يجب فيها استدعاء الوظيفة المرفقة حتى إذا كانت وحدة المعالجة المركزية (CPU) غير متصلة بالإنترنت أو تتطلّب سياقًا غير ذري. لا يمكن فصل عناصر الجذب المفروض عليها قيود، وبالتالي لا يمكن أبدًا إلغاء تحميل الوحدات التي يتم ربطها بعنصر جذب مشروط. تبدأ أسماء المكوّنات المخصّصة لموفّري الخدمات المحظورة بـ 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() ثم إضافتها إلى الرمز كنقاط تتبُّع. على سبيل المثال، لإضافة 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()، يتمّ استدعاء الدالة المسجّلة. يجب أن يكون المعالج على دراية بالسياق في ما يتعلق بالقفلات المعلّقة وحالة RCS وغيرها من العوامل. يجب تحديد العنصر المشغِّل في ملف عنوان في دليل include/trace/hooks.

على سبيل المثال، يقدّم الرمز التالي بيانًا محتملاً بشأن trace_android_vh_sched_exit() في الملف include/trace/hooks/exit.h.

/* 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 الذي يقدّم التعريف الكامل لهياكل البيانات هذه داخل القسم #ifndef __GENKSYMS__ من drivers/android/vendor_hooks.c. يجب ألا تتضمّن ملفّات العنوان في include/trace/hooks ملفّ عنوان kernel مع تعريفات الأنواع لتجنُّب تغييرات CRC التي تؤدي إلى إيقاف KMI. بدلاً من ذلك، يمكنك إعادة توجيه الأنواع.

إرفاقها بعناصر الربط الخاصة بالمورّد

لاستخدام أدوات الربط الخاصة بالمورّدين، يجب أن تسجِّل وحدة المورّد معالِجًا للإجراء المرتبط بالربط (يحدث ذلك عادةً أثناء بدء تشغيل الوحدة). على سبيل المثال، تعرِض التعليمة البرمجية التالية معالج الوحدة foo.ko لـ trace_android_vh_sched_exit().

#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.

لإصلاح هذا النوع من أخطاء الإنشاء، طبِّق الإصلاح المكافئ على ملف header الذي يتضمّن رمز الربط الخاص بالمورّد. لمزيد من المعلومات، يُرجى الرجوع إلى 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 إلى ملف التمهيد الأساسي. أنشئ مشكلة في أداة تتبُّع المشاكل (IT) لبدء المحادثة.

واجهة برمجة تطبيقات المستخدم (UAPI)

  • ملفات عناوين UAPI: يجب أن تحدث التغييرات التي يتم إجراؤها على ملفات عناوين UAPI أولاً ما لم تكن التغييرات على الواجهات الخاصة بنظام Android. استخدِم ملفات الرأس الخاصة بالمورّد لتحديد الواجهات بين وحدات المورّد ورمز مساحة المستخدم الخاصة بالمورّد.
  • عُقد sysfs لا تُضِف عقد sysfs جديدة إلى نواة GKI (لا تكون هذه الإضافات válida إلا في وحدات المورّدين). لا يمكن تغيير عقد sysfs التي تستخدمها المكتبات التي لا تعتمد على وحدة المعالجة المركزية والأجهزة ورمز Java الذي يشكّل إطار عمل Android إلا بطرق متوافقة، ويجب تغييرها في المصدر إذا كانت ليست عقد sysfs خاصة بنظام Android. يمكنك إنشاء عقد sysfs خاصة بالمورّد لاستخدامها في مساحة المستخدم الخاصة بالمورّد. بشكل تلقائي، يتم رفض الوصول إلى عُقد sysfs من خلال مساحة المستخدم باستخدام SELinux. على العميل إضافة تصنيفات SELinux المناسبة للسماح بالوصول من خلال برامج العميل المعتمَدة.
  • عقد DebugFS: يمكن أن تحدِّد وحدات المورّدين العقد في debugfs ل debugging فقط (لأنّ debugfs لا يتم تثبيته أثناء التشغيل العادي ل الجهاز).