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

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

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

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

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

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

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

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

דרישות לגבי תיקון

תיקוני האבטחה צריכים להיות תואמים לתקני הקידוד של ליבת לינוקס שמתוארים בעץ המקור של לינוקס, בין אם הם נשלחים ל-upstream או ל-ACK. הסקריפט scripts/checkpatch.pl מופעל כחלק מבדיקת טרום-התחייבות ב-Gerrit, לכן צריך להפעיל אותו מראש כדי לוודא שהוא עובר. כדי להריץ את הסקריפט checkpatch עם אותה הגדרה כמו בבדיקות לפני שליחת הקוד, משתמשים ב-//build/kernel/static_analysis:checkpatch_presubmit. פרטים נוספים זמינים בכתובת build/kernel/kleaf/docs/checkpatch.md.

תיקוני ACK

תיקונים שנשלחים ל-ACK צריכים לעמוד בסטנדרטים של קידוד ליבת לינוקס ובהנחיות לשליחת תרומות. צריך לכלול תג 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 מאפשרת בדיקה באמצעות מועמדים חדשים לפרסום במעלה הזרם ומבטיחה שהתיקון יהיה ב-ACK הבא שמבוסס על LTS. החריגים כוללים מקרים שבהם תיקון במעלה הזרם מועבר חזרה אל android12-5.4 (כי סביר להניח שהתיקון כבר נמצא ב-android-mainline).

תיקונים ב-Upstream

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

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

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

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

שינויים ב-gki_defconfig

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

קוד שלא קיים במעלה הזרם

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

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

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

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

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

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

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

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

Loadable governors

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

נעבוד איתך ועם המפתחים של upstream כדי להוסיף את התמיכה הנדרשת.

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

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

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

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

כדי להוסיף ווֹקְסֶט של ספק, צריך לפתוח כרטיס תמיכה ב-IT ולשלוח תיקונים (כמו בכל התיקונים שספציפיים ל-Android, צריך לפתוח כרטיס תמיכה ולספק הצדקה). התמיכה ב-vendor hooks קיימת רק ב-ACK, ולכן אין לשלוח את התיקונים האלה ל-upstream 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() בודקת בהתחלה רק אם משהו מצורף. עם זאת, אם מודול של ספק רושם handler באמצעות register_trace_android_vh_sched_exit(), הפונקציה הרשומה נקראת. ה-handler צריך להיות מודע להקשר בנוגע לנעילות שמוחזקות, למצב 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>

כדי ליצור מופע של הממשקים שנדרשים ל-vendor 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);

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

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

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

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

תכונות ליבה

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

ממשק תכנות יישומים (API) למשתמש (UAPI)

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