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

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

מפתחים צריכים לשלוח שינויים בקוד ל-upstream באמצעות רשימת התפוצה של ליבת לינוקס (LKML) כאפשרות הראשונה, ולשלוח שינויים בקוד לענף ACK android-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 יהפכו מחמירות יותר עם הזמן.

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

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

תיקונים ב-Upstream

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

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

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

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

שינויים ב-gki_defconfig

כל השינויים ב-CONFIG צריכים להיות מיושמים גם בגרסאות arm64 וגם בגרסאות x86, אלא אם CONFIG ספציפי לארכיטקטורה מסוימת.gki_defconfig כדי לבקש שינוי בהגדרה של CONFIG, יוצרים בעיה ב-IT כדי לדון בשינוי. כל שינוי שמשפיע על ממשק מודול הליבה (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 מקבלת ווים של ספקים שמאפשרים להפעיל מודולים מקוד ליבת הליבה. בנוסף, אפשר להוסיף לשדות של מבני נתונים מרכזיים שדות של נתוני ספקים שזמינים לאחסון נתונים ספציפיים לספקים, כדי להטמיע את התכונות האלה.

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

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

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

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