توسعه کد هسته برای GKI

«تصویر هسته عمومی» (GKI) با هم‌راستا شدن دقیق با هسته لینوکس بالادستی، تکه‌تکه‌سازی هسته را کاهش می‌دهد. بااین‌حال، دلایل معتبری وجود دارد که چرا برخی وصله‌ها نمی‌توانند در بالادست پذیرفته شوند، و برنامه‌های زمانی محصولی وجود دارد که باید رعایت شوند، بنابراین برخی وصله‌ها در منابع «هسته مشترک Android» (ACK) که GKI از آن‌ها ساخته می‌شود، نگهداری می‌شوند.

توسعه‌دهندگان باید تغییرات کد را بااستفاده از «فهرست پستی هسته Linux» (LKML) به‌عنوان اولین انتخاب به بالادست ارسال کنند و تغییرات کد را فقط زمانی به شاخه ACK android-mainline ارسال کنند که دلیل محکمی وجود داشته باشد که چرا بالادست امکان‌پذیر نیست. نمونه‌هایی از دلایل معتبر و نحوه رسیدگی به آن‌ها در زیر فهرست شده است.

  • وصله به LKML ارسال شد، اما به‌موقع برای انتشار محصول پذیرفته نشد. برای مدیریت این وصله:

    • شواهدی ارائه دهید که وصله به LKML ارسال شده است و نظراتی برای وصله دریافت شده است، یا زمان تخمینی که وصله به بالادست ارسال می‌شود.
    • درباره روشی برای قرار دادن وصله در ACK، تأیید آن در بالادست، و سپس خارج کردن آن از ACK پس‌از ادغام نسخه بالادست نهایی در ACK تصمیم بگیرید.
  • وصله EXPORT_SYMBOLS_GPL() را برای واحد فروشنده تعریف می‌کند، اما نمی‌تواند به منبع اصلی ارسال شود زیرا هیچ واحد درون‌درختی‌ای وجود ندارد که از آن نماد استفاده کند. برای رسیدگی به این وصله، جزئیاتی درباره اینکه چرا واحد شما نمی‌تواند به بالادست ارسال شود و جایگزین‌هایی که قبل‌از ارائه این درخواست درنظر گرفته‌اید ارائه دهید.

  • وصله به‌اندازه کافی برای بالادست عمومی نیست و زمان کافی برای بازسازی کد آن قبل‌از انتشار محصول وجود ندارد. برای مدیریت این وصله، زمان تخمینی‌ای ارائه دهید که براساس آن وصله بازسازی‌شده به بالادست ارسال می‌شود (بدون طرحی برای ارسال وصله بازسازی‌شده به بالادست برای بررسی، وصله در ACK پذیرفته نخواهد شد).

  • وصله نمی‌تواند توسط بالادست پذیرفته شود زیرا... <دلیل را در اینجا وارد کنید>. برای مدیریت این وصله، با تیم هسته Android تماس بگیرید و درباره گزینه‌های بازسازی وصله با ما همکاری کنید تا بتوانید آن را برای مرور ارسال کنید و در بالادست پذیرفته شود.

توجیهات بالقوه بسیار دیگری وجود دارد. وقتی اشکال یا وصله‌تان را ارسال می‌کنید، توجیه معتبری ارائه دهید و انتظار داشته باشید که چند بار تکرار و بحث شود. می‌دانیم که ACK برخی وصله‌ها را حمل می‌کند، به‌ویژه در مراحل اولیه GKI که همه درحال یادگیری نحوه کار با بالادست هستند اما نمی‌توانند برنامه‌های زمانی محصول را برای انجام این کار کاهش دهند. انتظار داشته باشید که الزامات بالادست با گذشت زمان سخت‌تر شود.

الزامات وصله

وصله‌ها باید با استانداردهای کدنویسی هسته 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 ادغام می‌شود.
  • در بالادست پذیرفته نشده است، آن را با ارجاع به ارسال بالادست یا توضیحی درباره اینکه چرا به LKML ارسال نشده است به android-mainline ارسال کنید.

پس‌از پذیرفته شدن وصله در بالادست یا در android-mainline، می‌توان آن را به ACK مناسب مبتنی بر LTS (مانند android12-5.4 و android11-5.4 برای وصله‌هایی که کد مختص Android را اصلاح می‌کنند) منتقل کرد. ارسال به android-mainline امکان آزمایش با نامزدهای انتشار بالادستی جدید را فراهم می‌کند و تضمین می‌کند که وصله در ACK بعدی مبتنی بر LTS قرار دارد. موارد استثنا شامل مواردی است که وصله بالادستی به android12-5.4 منتقل می‌شود (زیرا وصله احتمالاً ازقبل در android-mainline وجود دارد).

وصله‌های بالادستی

همان‌طور که در دستورالعمل‌های همیاری مشخص شده است، وصله‌های بالادستی که برای هسته‌های ACK درنظر گرفته شده‌اند در گروه‌های زیر قرار می‌گیرند (به‌ترتیب احتمال پذیرفته شدن فهرست شده‌اند).

  • UPSTREAM: - وصله‌های دست‌چین‌شده از «android-mainline» احتمالاً در ACK پذیرفته می‌شوند، به‌شرطی که مورد استفاده منطقی وجود داشته باشد.
  • BACKPORT: - وصله‌هایی از بالادست که به‌طور تمیز انتخاب نمی‌شوند و نیاز به اصلاح دارند نیز درصورتی‌که مورد استفاده معقولی داشته باشند، احتمالاً پذیرفته می‌شوند.
  • FROMGIT: - وصله‌هایی که از شاخه نگه‌دارنده برای آماده‌سازی انتخاب شده‌اند برای ارسال به شاخه اصلی Linux ممکن است درصورت وجود مهلت آتی پذیرفته شوند. این موارد باید هم برای محتوا و هم برای زمان‌بندی توجیه شوند.
  • FROMLIST: - وصله‌هایی که به LKML ارسال شده‌اند اما هنوز در شاخه نگهدارنده پذیرفته نشده‌اند، احتمالاً پذیرفته نخواهند شد، مگر اینکه توجیه آنقدر قانع‌کننده باشد که وصله صرف‌نظر از اینکه در Linux بالادستی قرار می‌گیرد یا نه پذیرفته شود (فرض می‌کنیم که پذیرفته نخواهد شد). برای تسهیل بحث با تیم هسته Android، باید مشکلی مرتبط با FROMLIST وصله وجود داشته باشد.

وصله‌های ویژه Android

اگر نمی‌توانید تغییرات موردنیاز را در بالادست اعمال کنید، می‌توانید تلاش کنید وصله‌های خارج از درخت را مستقیماً به ACK ارسال کنید. برای ارسال وصله‌های خارج از درخت، باید مشکلی در IT ایجاد کنید که وصله و دلیل اینکه چرا وصله نمی‌تواند در بالادست ارسال شود را ذکر کند (برای مثال، فهرست قبلی را ببینید). بااین‌حال، چند مورد وجود دارد که کد نمی‌تواند به بالادست ارسال شود. این موارد به شرح زیر پوشش داده می‌شوند و باید از دستورالعمل‌های همیاری برای وصله‌های مختص Android پیروی کنند و با پیشوند ANDROID: در موضوع برچسب‌گذاری شوند.

تغییرات در gki_defconfig

همه CONFIG تغییر در gki_defconfig باید هم روی نسخه arm64 و هم روی نسخه x86 اعمال شود، مگر اینکه CONFIG مختص معماری باشد. برای درخواست تغییر در تنظیمات CONFIG، در IT مسئله‌ای ایجاد کنید تا درباره تغییر بحث شود. هرگونه CONFIG تغییری که پس‌از ثابت شدن «میانای واحد هسته» (KMI) بر آن تأثیر بگذارد رد می‌شود. در مواردی که شرکا تنظیمات متناقضی را برای یک پیکربندی درخواست می‌کنند، ما تداخل‌ها را ازطریق بحث درباره اشکال‌های مربوطه حل می‌کنیم.

کدی که در بالادست وجود ندارد

اصلاحات کد که ازقبل مختص Android است نمی‌تواند به بالادست ارسال شود. برای مثال، اگرچه درایور binder در بالادست نگهداری می‌شود، اصلاحات ویژگی‌های وراثت اولویت درایور binder را نمی‌توان به بالادست ارسال کرد چون مختص Android هستند. در اشکال و وصله خود به‌صراحت توضیح دهید که چرا کد نمی‌تواند به بالادست ارسال شود. درصورت امکان، وصله‌ها را به قطعاتی تقسیم کنید که می‌توانند به بالادست ارسال شوند و قطعات مختص Android که نمی‌توانند به بالادست ارسال شوند تا مقدار کد خارج از درخت نگهداری‌شده در ACK به حداقل برسد.

سایر تغییرات در این دسته شامل به‌روزرسانی فایل‌های نمایش KMI، فهرست نمادهای KMI،‏ gki_defconfig، پیکربندی یا دستورگان‌های ساخت، یا دستورگان‌های دیگری است که در بالادست وجود ندارند.

پیمانه‌های خارج از درخت

‫Upstream Linux به‌طور فعال از پشتیبانی برای ساختن پیمانه‌های خارج از درخت جلوگیری می‌کند. این موضع منطقی است زیرا نگهبانان Linux درباره سازگاری منبع یا باینری درون هسته تضمینی نمی‌دهند و نمی‌خواهند از کدی که در درخت نیست پشتیبانی کنند. بااین‌حال، GKI برای واحدهای فروشنده ضمانت‌های ABI ارائه می‌دهد و تضمین می‌کند که میاناهای KMI در طول عمر پشتیبانی‌شده هسته پایدار هستند. بنابراین، دسته‌ای از تغییرات برای پشتیبانی از ماژول‌های فروشنده وجود دارد که برای ACK قابل‌قبول است اما برای بالادست قابل‌قبول نیست.

برای مثال، وصله‌ای را درنظر بگیرید که EXPORT_SYMBOL_GPL() کلان‌دستور اضافه می‌کند و در آن واحدهایی که از برون‌برد استفاده می‌کنند در درخت منبع نیستند. اگرچه باید تلاش کنید EXPORT_SYMBOL_GPL() بالادستی را درخواست کنید و واحدی را که از نماد جدیداً صادرشده استفاده می‌کند تأمین کنید، اما اگر دلیل موجهی وجود داشته باشد که چرا واحد به بالادست ارسال نمی‌شود، می‌توانید وصله را به‌جای آن به ACK ارسال کنید. باید توجیهی برای اینکه چرا ماژول نمی‌تواند در مسئله بالادستی شود ارائه دهید. (متغیر غیر GPL را درخواست نکنید، EXPORT_SYMBOL().)

پیکربندی‌های پنهان

برخی‌از واحدهای درون‌درختی به‌طور خودکار پیکربندی‌های پنهانی را انتخاب می‌کنند که نمی‌توانند در gki_defconfig مشخص شوند. برای مثال، وقتی CONFIG_SND_SOC_SOF=y پیکربندی شود، CONFIG_SND_SOC_TOPOLOGY به‌طور خودکار انتخاب می‌شود. برای جای دادن ساخت پیمانه خارج از درخت، GKI سازوکاری برای فعال کردن پیکربندی‌های پنهان دارد.

برای فعال کردن پیکربندی پنهان، عبارت select را در init/Kconfig.gki اضافه کنید تا به‌طور خودکار براساس پیکربندی هسته CONFIG_GKI_HACKS_TO_FIX انتخاب شود، که در gki_defconfig فعال شده است. از این سازوکار فقط برای پیکربندی‌های پنهان استفاده کنید؛ اگر پیکربندی پنهان نیست، باید در gki_defconfig به‌صورت صریح یا به‌عنوان وابستگی مشخص شود.

فرمانداران بارشدنی

برای چارچوب‌های هسته (مانند cpufreq) که از فرمانداران قابل‌بارگیری پشتیبانی می‌کنند، می‌توانید فرماندار پیش‌فرض (مانند فرماندار schedutil در cpufreq) را لغو کنید. برای چارچوب‌هایی (مثل چارچوب حرارتی) که از کنترل‌کننده‌ها یا درایورهای بارشدنی پشتیبانی نمی‌کنند اما همچنان به پیاده‌سازی خاص فروشنده نیاز دارند، در IT مشکل ایجاد کنید و با تیم هسته Android مشورت کنید.

با شما و نگهداران بالادستی همکاری خواهیم کرد تا پشتیبانی لازم را اضافه کنیم.

قلاب‌های فروشنده

در نسخه‌های قبلی، می‌توانستید تغییرات مختص فروشنده را مستقیماً به هسته اصلی اضافه کنید. این کار با GKI 2.0 امکان‌پذیر نیست زیرا کد مختص محصول باید در ماژول‌ها پیاده‌سازی شود و در هسته‌های اصلی بالادستی یا در ACK پذیرفته نخواهد شد. برای فعال کردن ویژگی‌های ارزش‌افزوده که شرکا با کمترین تأثیر بر کد هسته اصلی به آن‌ها تکیه می‌کنند، GKI قلاب‌های فروشنده را می‌پذیرد که به واحدها اجازه می‌دهد از کد هسته اصلی فراخوانی شوند. علاوه‌براین، ساختارهای داده کلیدی را می‌توان با فیلدهای داده فروشنده که برای ذخیره داده‌های مختص فروشنده برای پیاده‌سازی این ویژگی‌ها دردسترس هستند، تکمیل کرد.

قلاب‌های فروشنده در دو نوع (عادی و محدودشده) ارائه می‌شوند که براساس نقاط ردیابی (نه رویدادهای ردیابی) هستند که ماژول‌های فروشنده می‌توانند به آن‌ها متصل شوند. برای مثال، به‌جای افزودن تابع sched_exit() جدید برای انجام حسابداری در تکلیف خروج، عرضه‌کنندگان می‌توانند قلابی در do_exit() اضافه کنند که واحد عرضه‌کننده بتواند برای پردازش به آن متصل شود. یک نمونه پیاده‌سازی شامل قلاب‌های فروشنده زیر است.

  • قلاب‌های عادی فروشنده از DECLARE_HOOK() برای ایجاد تابع نقطه ردیابی با نام trace_name استفاده می‌کنند که در آن name شناسه متمایز برای ردیابی است. طبق قرارداد، نام‌های قلاب فروشنده عادی با android_vh شروع می‌شود، بنابراین نام قلاب sched_exit()، android_vh_sched_exit خواهد بود.
  • قلاب‌های فروشنده محدودشده برای مواردی مانند قلاب‌های زمان‌بندی لازم است که در آن‌ها تابع پیوست‌شده باید فراخوانی شود، حتی اگر CPU آفلاین باشد یا به بافت غیراتمی نیاز داشته باشد. قلاب‌های فروشنده محدودشده نمی‌توانند جدا شوند، بنابراین واحدهایی که به قلاب محدودشده متصل می‌شوند هرگز نمی‌توانند بارگیری شوند. نام‌های قلاب فروشنده محدودشده با android_rvh شروع می‌شود.

برای افزودن قلاب فروشنده، در IT مشکل ثبت کنید و وصله‌ها را ارسال کنید (مانند همه وصله‌های مختص 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() ثبت کند، تابع ثبت‌شده فراخوانده می‌شود. کارپرداز باید از بافت مربوط به قفل‌های نگه‌داشته‌شده، وضعیت «سرویس‌های ارتباطی غنی»، و عوامل دیگر آگاه باشد. قلاب باید در فایل سرصفحه در 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 تضمین شود. درغیراین‌صورت، ارجاع‌زدایی از اشاره‌گرهای مبهم یا استفاده از ساختار در زمینه‌های اندازه‌دار ایمن نیست. The include which provides the full definition of such data structures should go inside the #ifndef __GENKSYMS__ section of drivers/android/vendor_hooks.c. فایل‌های سرصفحه در include/trace/hooks نباید شامل فایل سرصفحه هسته با تعریف‌های نوع باشد تا از تغییرات 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.

برای رفع این نوع خطای ساخت، اصلاح معادل را در فایل سرصفحه قلاب فروشنده که اضافه می‌کنید اعمال کنید. برای اطلاعات بیشتر، به 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 اضافه نکنید (این افزوده‌ها فقط در واحدهای فروشنده معتبر هستند). گره‌های sysfs که توسط کتابخانه‌های مستقل از SoC و دستگاه و کد جاوا که چارچوب Android را تشکیل می‌دهد استفاده می‌شوند، فقط به روش‌های سازگار قابل تغییر هستند و اگر گره‌های sysfs مختص Android نباشند، باید در بالادست تغییر کنند. می‌توانید گره‌های sysfs مختص فروشنده ایجاد کنید تا توسط فضای کاربر فروشنده استفاده شود. به‌طور پیش‌فرض، دسترسی به گره‌های sysfs توسط فضای کاربر بااستفاده از SELinux رد می‌شود. افزودن برچسب‌های SELinux مناسب برای اجازه دادن به دسترسی نرم‌افزار فروشنده مجاز برعهده فروشنده است.
  • گره‌های DebugFS. مدول‌های فروشنده می‌توانند گره‌ها را در debugfs فقط برای اشکال‌زدایی تعریف کنند (چون debugfs درطول عملکرد عادی دستگاه سوار نمی‌شود).