פיתוח קוד ליבה ל-GKI

Generic Kernel Image‏ (GKI) מפחית את הפיצול של הליבה על ידי התאמה הדוקה לליבה של Linux ב-upstream. עם זאת, יש סיבות לגיטימיות לכך שחלק מהתיקונים לא יכולים להתקבל ב-upstream, ויש לוחות זמנים למוצרים שצריך לעמוד בהם. לכן, חלק מהתיקונים נשמרים במקורות של Android Common Kernel‏ (ACK) שמהם נוצר GKI.

מפתחים צריכים לשלוח שינויים בקוד למקור (upstream) באמצעות רשימת התפוצה של Linux Kernel (LKML) כאפשרות הראשונה, ולשלוח שינויים בקוד להסתעפות ACKandroid-mainline רק אם יש סיבה טובה לכך שהאפשרות של שליחה למקור לא מתאימה. בהמשך מפורטות דוגמאות לסיבות חוקיות ודרכים לטיפול בהן.

  • התיקון נשלח ל-LKML, אבל לא אושר בזמן כדי שיתאפשר להשיק את המוצר. כדי לטפל בתיקון הזה:

    • צריך לספק הוכחה לכך שהתיקון נשלח ל-LKML ולתגובות שהתקבלו בשביל התיקון, או מהו הזמן המשוער שבו התיקון נשלח ב-upstream.
    • להחליט על דרך פעולה להטמעת התיקון ב-ACK, לקבל אישור למעלה בזרם (upstream) ואז להסיר אותו מ-ACK כשהגרסה הסופית של upstream תשולב ב-ACK.
  • התיקון מגדיר את EXPORT_SYMBOLS_GPL() למודול של ספק, אבל לא ניתן היה לשלוח אותו ל-upstream כי אין מודולים בעץ שמשתמשים בסמל הזה. כדי לטפל בתיקון הזה, עליך לספק פרטים על הסיבה לכך שלא ניתן לשלוח את המודול ל-upstream, ועל האפשרויות החלופיות שבדקת לפני שליחת הבקשה.

  • התיקון לא מספיק כללי כדי להשתמש בו ב-upstream, ואין זמן לבצע בו refactoring לפני השקת המוצר. כדי לטפל בתיקון הזה, תצטרכו לציין מועד משוער שבו יישלח תיקון שעבר ארגון מחדש ב-upstream (התיקון לא יתקבל ב-ACK ללא תוכנית לשליחת upstream של תיקון שעבר ארגון מחדש לבדיקה).

  • אי אפשר לקבל את התיקון ב-upstream כי… <insert reason here>. כדי לטפל בתיקון הזה, צריך לפנות לצוות הליבה של Android ולעבוד איתנו על אפשרויות לשינוי מבנה התיקון כדי שניתן יהיה לשלוח אותו לבדיקה ולאשר אותו ב-upstream.

יש עוד הרבה סיבות אפשריות. כששולחים את הבאג או התיקון, צריך לכלול הצדקה תקפה ולצפות לסבב של שיפורים ודיונים. אנחנו מבינים שה-ACK כולל תיקונים מסוימים, במיוחד בשלבים המוקדמים של GKI, כשכולם לומדים איך לעבוד ב-upstream אבל לא יכולים לשנות את לוחות הזמנים של המוצרים כדי לעשות זאת. עם הזמן, הדרישות להעלאה ל-upstream יהיו מחמירות יותר.

דרישות לגבי תיקונים

התיקונים חייבים לעמוד בתקני הקוד של ליבה של Linux שמתוארים בעץ המקור של Linux, בין שהם נשלחים ל-upstream ובין שהם נשלחים ל-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 לבדיקה ב-upstream. אם התיקון הוא:

  • אחרי שהקוד מאושר ב-upstream, הוא ימוזג באופן אוטומטי ל-android-mainline.
  • לא התקבלה ב-upstream, שולחים אותה אל android-mainline עם הפניה לשליחה ל-upstream או הסבר למה היא לא נשלחה ל-LKML.

אחרי שתיקון מתקבל ב-upstream או ב-android-mainline, אפשר להעביר אותו לאחור אל ה-ACK המתאים מבוסס LTS (כמו android12-5.4 ו-android11-5.4 לתיקונים שמתקנים קוד ספציפי ל-Android). שליחת בקשה ל-android-mainline מאפשרת בדיקה עם גרסאות מועמדות חדשות ל-upstream, ומבטיחה שהתיקון יהיה ב-ACK הבא שמבוסס על LTS. החרגות כוללות מקרים שבהם תיקון מ-upstream מועבר ל-android12-5.4 (כי סביר להניח שהתיקון כבר נמצא ב-android-mainline).

תיקונים ב-upstream

כפי שמפורט בהנחיות לשליחת תיקונים, תיקונים ב-upstream שמיועדים לליבת ACK נכללים בקבוצות הבאות (הרשימה מפורטת לפי הסבירות לקבלה).

  • UPSTREAM: – סביר להניח שתיקונים שנבחרו מ-'android-mainline' יאושרו ב-ACK אם יש תרחיש לדוגמה סביר.
  • BACKPORT: – תיקונים מ-upstream שלא מבצעים בחירה מדויקת של שינויים ודורשים שינוי, צפויים להתקבל גם אם יש מקרה שימוש סביר.
  • FROMGIT: – תיקונים שנבחרו בקפידה מענף של מנהל תוכנה לקראת שליחה ל-Linux mainline עשויים להתקבל אם יש מועד הגשה קרוב. צריך להצדיק את הקביעה הזו גם מבחינת התוכן וגם מבחינת לוח הזמנים.
  • FROMLIST: – תיקונים שנשלחו ל-LKML אבל עדיין לא אושרו להוספה להסתעפות של המנהל, לא צפויים להתקבל, אלא אם ההצדקה מספיק משכנעת כדי שהתיקון יתקבל גם אם הוא לא ייכלל ב-Linux למקור (אנחנו מניחים שהוא לא ייכלל). כדי לאפשר דיון עם צוות הליבה של Android, צריכה להיות בעיה שקשורה לתיקוני FROMLIST.

תיקונים ספציפיים ל-Android

אם אי אפשר להעביר את השינויים הנדרשים ב-upstream, אתם יכולים לנסות לשלוח תיקונים שאינם מעץ ישירות ל-ACK. כדי לשלוח תיקונים 'מחוץ לעץ' צריך ליצור בעיה ב-IT, שמציינת את התיקון ואת הנימוקים לכך שאי אפשר לשלוח את התיקון ב-upstream (ראו דוגמאות ברשימה הקודמת). עם זאת, יש מקרים מסוימים שבהם לא ניתן לשלוח את הקוד ב-upstream. המקרים האלה מכוסים לפי הסעיפים הבאים, ועליהם לעמוד בהנחיות לתרומה לתיקונים ספציפיים ל-Android, וצריך לתייג אותם עם הקידומת ANDROID: בנושא.

שינויים ב-gki_defconfig

צריך להחיל את כל השינויים ב-CONFIG ב-gki_defconfig גם בגרסה ל-arm64 וגם בגרסה ל-x86, אלא אם ה-CONFIG הוא ספציפי לארכיטקטורה. כדי לבקש לשנות את ההגדרה של CONFIG, צריך ליצור בעיה ב-IT כדי לדון בשינוי. כל שינוי ב-CONFIG שמשפיע על ממשק מודול הליבה (KMI) אחרי שהוא קפוא נדחה. במקרים שבהם שותפים מבקשים הגדרות סותרות בתצורה אחת, אנחנו פותרים את הבעיות באמצעות דיון בבאגים הרלוונטיים.

קוד שלא קיים ב-upstream

לא ניתן לשלוח שינויים בקוד שהוא כבר ספציפי ל-Android ב-upstream. לדוגמה, למרות שמנהל התקן של הקלסר נשמר ב-upstream, אי אפשר לשלוח שינויים בתכונות הירושה בעדיפות של מנהל התקן של הקישור ב-upstream כי הם ספציפיים ל-Android. יש לציין במדויק בבאג ובתיקון למה אי אפשר לשלוח את הקוד ל-upstream. אם אפשר, כדאי לפצל את התיקונים לחלקים שאפשר לשלוח למקור (upstream) ולחלקים ספציפיים ל-Android שאי אפשר לשלוח למקור, כדי לצמצם את כמות הקוד מחוץ לעץ שמנוהל ב-ACK.

שינויים אחרים בקטגוריה הזו הם עדכונים בקובצי ייצוג של KMI, ברשימות סמלים של KMI, ב-gki_defconfig, בסקריפטים ל-build או בתצורה, או בסקריפטים אחרים שלא קיימים ב-upstream.

מודולים מחוץ לעץ

ב-Upstream Linux לא מעודדים תמיכה ביצירת מודולים מחוץ לעץ. זו עמדה סבירה, מכיוון שמנהלי Linux לא מבטיחים תאימות למקורות או לקבצים הבינאריים בליבה, והם לא רוצים לתמוך בקוד שלא נמצא בעץ. עם זאת, GKI כן מבטיח ABI למודול של הספק, כדי לוודא שממשקי KMI יהיו יציבים במשך כל תוחלת החיים הנתמכת של הליבה. לכן, יש סוג של שינויים לתמיכה במודולים של ספקים שמתאימים ל-ACK אבל לא מתאימים למקור.

לדוגמה, נניח תיקון שמוסיף פקודות מאקרו EXPORT_SYMBOL_GPL() כאשר המודולים שמשתמשים בייצוא לא נמצאים בעץ המקור. אתם צריכים לנסות לבקש את EXPORT_SYMBOL_GPL() ב-upstream ולספק מודול שמשתמש בסמל שיוצאו לאחרונה. עם זאת, אם יש הצדקה תקפה לכך שהמודול לא נשלח ל-upstream, תוכלו לשלוח את התיקון ל-ACK במקום זאת. עליכם לכלול את ההצדקה לכך שאי אפשר להעביר את המודול לטיפול ברמה גבוהה יותר. (לא מבקשים את הווריאנט שאינו GPL, EXPORT_SYMBOL()).

הגדרות מוסתרות

חלק מהמודולים שבתוך העץ בוחרים באופן אוטומטי הגדרות מוסתרות שלא ניתן לציין ב-gki_defconfig. לדוגמה, CONFIG_SND_SOC_TOPOLOGY נבחר באופן אוטומטי כשCONFIG_SND_SOC_SOF=y מוגדר. כדי להתאים לבניית מודולים מחוץ לעץ, GKI כולל מנגנון להפעלת הגדרות נסתרות.

כדי להפעיל הגדרה מוסתרת, צריך להוסיף הצהרת select ב-init/Kconfig.gki כדי שהיא תיבחר באופן אוטומטי בהתאם להגדרת הליבה (kernel) של CONFIG_GKI_HACKS_TO_FIX, שמופעלת ב-gki_defconfig. יש להשתמש במנגנון הזה רק להגדרות מוסתרות. אם ההגדרה לא מוסתרת, צריך לציין אותה ב-gki_defconfig באופן מפורש או כיחסי תלות.

מושלים שניתן לטעון

במסגרות ליבה (כמו cpufreq) שתומכות בפקדי בקרה ניתנים לטעינה, אפשר לשנות את ברירת המחדל של הפקדים (כמו הפקדים schedutil ו-schedutil של cpufreq). למסגרות (כמו framework תרמי) שלא תומכות במנהלים או במנהלי התקנים שניתנים לטעינה אבל עדיין דורשים הטמעה ספציפית לספק, צריך ליצור בעיה ב-IT ולהתייעץ עם צוות הליבה של Android.

אנחנו נעזור לכם להוסיף את התמיכה הנדרשת, בשיתוף עם המטפלים בקוד המקור.

קטעי הוּק (hooks) של ספקים

בגרסאות קודמות, אפשר היה להוסיף שינויים ספציפיים לספק ישירות בליבה (kernel) של הליבה. אי אפשר לעשות זאת ב-GKI 2.0 כי קוד ספציפי למוצר צריך להיות מוטמע במודולים, ולא יתקבל בליבה של הליבה או ב-ACK. כדי להפעיל תכונות עם ערך מוסף ששותפים מסתמכים עליהן עם השפעה מינימלית על קוד ליבה (kernel), GKI מקבל הוקים (hooks) של ספקים שמאפשרים להפעיל מודולים מקוד ליבה (kernel). בנוסף, אפשר להוסיף למבנים של נתוני מפתח שדות של נתוני ספקים שזמינים לאחסון נתונים ספציפיים לספק כדי להטמיע את התכונות האלה.

קטעי הוק (hooks) של ספקים מגיעים בשתי וריאנטים (רגילים ומוגבלים) המבוססים על נקודות מעקב (ולא אירועי מעקב) שאפשר לחבר אליהם מודולים של ספקים. לדוגמה, במקום להוסיף פונקציית sched_exit() חדשה לצורך ניהול חשבונות בסיום המשימה, ספקים יכולים להוסיף הוק ב-do_exit() שאליו מודול של ספק יכול להתחבר לצורך עיבוד. דוגמה להטמעה כוללת את ה-hooks הבאים של הספק.

  • קטעי הוק רגילים של ספק משתמשים ב-DECLARE_HOOK() כדי ליצור פונקציית מעקב אחרי השם trace_name, כש-name הוא המזהה הייחודי של המעקב. לפי המוסכמה, שמות ה-hook הרגילים של הספקים מתחילים ב-android_vh, כך שהשם של ההוק (hook) sched_exit() יהיה android_vh_sched_exit.
  • צריך להשתמש ב-hooks מוגבלים של ספקים במקרים כמו ווקים של מתזמן, שבהם צריך להפעיל את הפונקציה המצורפת גם אם המעבד (CPU) במצב אופליין או אם נדרש הקשר לא אטומי. אי אפשר לנתק קטעי הוק (hooks) של ספקים מוגבלים, ולכן אי אפשר להסיר את הטעינה של מודולים שמתחברים להוק מוגבל. שמות של ווקים מוגבלים של ספקים מתחילים ב-android_rvh.

כדי להוסיף וו של ספק, צריך לדווח על בעיה ב-IT ולשלוח תיקונים (כמו בכל התיקונים הספציפיים ל-Android, צריכה להיות בעיה וצריך לספק הצדקה). התמיכה בהולים של ספקים זמינה רק ב-ACK, ולכן לא כדאי לשלוח את התיקונים האלה ל-upstream ב-Linux.

הוספת שדות של ספקים למבנים

כדי לשייך נתוני ספקים למבנים של נתוני מפתח, מוסיפים שדות android_vendor_data באמצעות המאקרו ANDROID_VENDOR_DATA(). לדוגמה, כדי לתמוך בתכונות עם ערך מוסף, מוסיפים שדות למבנים כפי שמתואר בדוגמת הקוד הבאה.

כדי למנוע התנגשויות פוטנציאליות בין שדות שנדרשים לספקים לבין שדות שנדרשים ליצרני ציוד מקורי (OEM), יצרני ציוד מקורי (OEM) לעולם לא יכולים להשתמש בשדות שהוגדרו באמצעות מאקרו 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 */
}

הגדרת קטעי הוק (hooks) של ספקים

כדי להוסיף ווקים של ספקים לקוד הליבה בתור נקודות מעקב, מכריזים עליהם באמצעות 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 וגורמים אחרים. צריך להגדיר את ה-hook בקובץ כותרת בספרייה 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>

כדי ליצור את הממשקים הנדרשים ל-hook של הספק, מוסיפים את קובץ הכותרת עם הצהרת ה-hook אל drivers/android/vendor_hooks.c ומיצאים את הסמלים. לדוגמה, הקוד הבא משלים את ההצהרה על ה-hook של 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);

הערה: צריך להגדיר באופן מלא את מבני הנתונים שבהם נעשה שימוש בהצהרת ה-hook כדי להבטיח יציבות של ABI. אחרת, לא בטוח לבצע הסרה של הפניה (dereference) של ההפניות האטומות או להשתמש ב-struct בהקשרים עם גודל. הקטע include שמספק את ההגדרה המלאה של מבני הנתונים האלה צריך להופיע בקטע #ifndef __GENKSYMS__ של drivers/android/vendor_hooks.c. קובצי הכותרות ב-include/trace/hooks לא צריכים לכלול את קובץ הכותרת של הליבה עם הגדרות הטיפוסים, כדי למנוע שינויים ב-CRC שגורמים לשיבושים ב-KMI. במקום זאת, צריך להצהיר על הסוגים.

צירוף ל-hooks של ספקים

כדי להשתמש ב-hooks של ספקים, מודול הספק צריך לרשום טיפול ב-hook (בדרך כלל במהלך האינטוליזציה של המודול). לדוגמה, הקוד הבא מציג את הטיפול במודול 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);
    ...
}

שימוש ב-hooks של ספקים מקובצי כותרות

כדי להשתמש בהיטים של ספק מקובצי הכותרת, יכול להיות שתצטרכו לעדכן את קובץ כותרת ה-hook של הספק כדי לבטל את ההגדרה של TRACE_INCLUDE_PATH, על מנת למנוע שגיאות build שמציינות שלא ניתן היה למצוא קובץ כותרת של נקודת מעקב. לדוגמה,

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.

כדי לתקן שגיאת build מהסוג הזה, צריך להחיל את התיקון המקביל על קובץ כותרת ה-hook של הספק שמוסיפים. מידע נוסף זמין בכתובת 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. כדי להתחיל את השיחה, צריך ליצור בעיה בכלי למעקב אחרי בעיות (IT).

ממשק תכנות של משתמש באפליקציה (UAPI)

  • קובצי כותרות של UAPI שינויים בקובצי הכותרות של UAPI חייבים להתבצע בחלק העליון של זרם הנתונים, אלא אם מדובר בשינויים בממשקים ספציפיים ל-Android. שימוש בקובצי כותרת ספציפיים לספק כדי להגדיר ממשקים בין מודולים של ספקים לבין קוד של שטח משתמש של ספקים.
  • צומתי sysfs אסור להוסיף צמתים חדשים של sysfs לליבה של GKI (תוספות כאלה תקפות רק במודולים של ספקים). אפשר לשנות צמתים של sysfs שמשמשים את הספריות והקוד ב-Java שמרכיבים את מסגרת Android, שהם לא תלויים ב-SoC ובמכשיר, רק בדרכים תואמות, וצריך לשנות אותם ב-upstream אם הם לא צמתים ספציפיים ל-Android. אפשר ליצור צמתים sysfs ספציפיים לספק לשימוש במרחב המשתמש של הספק. כברירת מחדל, הגישה לצמתים של sysfs על ידי מרחב המשתמש נדחית באמצעות SELinux. הספק צריך להוסיף את תוויות ה-SELinux המתאימות כדי לאפשר גישה לתוכנות של ספק מורשה.
  • צמתים של DebugFS במודולים של ספקים אפשר להגדיר צמתים ב-debugfs לניפוי באגים בלבד (כי debugfs לא נטען במהלך פעולה רגילה של המכשיר).