מודולי ליבה ניתנים לטעינה

כחלק מדרישות ליבת המודול שהוצגו באנדרואיד 8.0, כל ליבות המערכת-על-שבב (SoC) חייבות לתמוך במודולי ליבה הניתנים לטעינה.

אפשרויות תצורת ליבה

כדי לתמוך במודולי ליבה הניתנים לטעינה, android-base.config בכל הליבות הנפוצות כולל את האפשרויות הבאות של kernel-config (או שווה ערך לגרסת הקרנל שלהם):

CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y
CONFIG_MODVERSIONS=y

כל ליבות המכשיר חייבות להפעיל את האפשרויות הללו. מודולי ליבה צריכים גם לתמוך בפריקה וטעינה מחדש במידת האפשר.

חתימת מודול

חתימת מודולים אינה נתמכת עבור מודולים של ספקי GKI. במכשירים הנדרשים לתמיכה באתחול מאומת, אנדרואיד דורשת שמודולי ליבה יהיו במחיצות ש-dm-verity מופעלת בהן. זה מסיר את הצורך בחתימה על מודולים בודדים על האותנטיות שלהם. אנדרואיד 13 הציגה את הרעיון של מודולי GKI. מודולי GKI משתמשים בתשתית חתימת זמן הבנייה של הליבה כדי להבדיל בין GKI למודולים אחרים בזמן הריצה. מודולים לא חתומים רשאים להיטען כל עוד הם משתמשים רק בסמלים המופיעים ברשימת ההיתרים או מסופקים על ידי מודולים לא חתומים אחרים. כדי להקל על חתימת מודולי GKI במהלך בניית GKI באמצעות צמד מפתחות זמן הבנייה של הליבה, תצורת ליבת GKI הפעילה את CONFIG_MODULE_SIG_ALL=y . כדי להימנע מחתימה על מודולים שאינם GKI במהלך בניית ליבת מכשיר, עליך להוסיף # CONFIG_MODULE_SIG_ALL is not set כחלק מקטעי תצורת הליבה שלך.

מיקומי קבצים

בעוד ש-Android 7.x ומטה אינם מחייבים נגד מודולי ליבה (וכוללים תמיכה ב- insmod ו- rmmod ), אנדרואיד 8.x ומעלה ממליצה להשתמש במודולי ליבה במערכת האקולוגית. הטבלה הבאה מציגה תמיכה היקפית פוטנציאלית ספציפית ללוח הנדרשת בשלושה מצבי אתחול של אנדרואיד.

מצב אתחול אִחסוּן לְהַצִיג לוח מקשים סוֹלְלָה PMIC מסך מגע NFC, Wi-Fi,
בלוטות
חיישנים מַצלֵמָה
התאוששות
מַטעֵן
דְמוּי אָדָם

בנוסף לזמינות במצבי אתחול של אנדרואיד, מודולי ליבה עשויים להיות מסווגים גם לפי מי שבבעלותם (ספק ה-SoC או ה-ODM). אם נעשה שימוש במודולי ליבה, הדרישות למיקומם במערכת הקבצים הן כדלקמן:

  • כל הגרעינים צריכים להיות בעלי תמיכה מובנית עבור אתחול והרכבת מחיצות.
  • יש לטעון מודולי ליבה ממחיצה לקריאה בלבד.
  • עבור התקנים הנדרשים לאתחול מאומת, יש לטעון מודולי ליבה ממחיצות מאומתות.
  • מודולי ליבה לא צריכים להיות ממוקמים ב- /system .
  • יש לטעון את מודולי ה-GKI הנדרשים למכשיר מ- /system/lib/modules שהוא קישור סמלי אל /system_dlkm/lib/modules .
  • מודולי ליבה של ספק ה-SoC הנדרשים עבור מצבי Android או Charger מלאים צריכים להיות ממוקמים ב- /vendor/lib/modules .
  • אם קיימת מחיצת ODM, מודולי ליבה מה-ODM הנדרשים עבור מצבי Android או Charger מלאים צריכים להיות ממוקמים ב- /odm/lib/modules . אחרת, מודולים אלה צריכים להיות ממוקמים ב- /vendor/lib/modules .
  • מודולי ליבה של ספק ה-SoC וה-ODM הנדרשים עבור מצב שחזור צריכים להיות ממוקמים ramfs השחזור ב- /lib/modules .
  • מודולי ליבה הנדרשים הן עבור מצב שחזור והן עבור מצבי אנדרואיד או מטען מלא צריכים להתקיים הן ב- rootfs של השחזור והן במחיצות /vendor או /odm (כמתואר לעיל).
  • מודולי ליבה המשמשים במצב שחזור אינם אמורים להיות תלויים במודולים הממוקמים רק ב- /vendor או /odm , מכיוון שהמחיצות הללו אינן מותקן במצב שחזור.
  • מודולי ליבת ספקי SoC לא צריכים להיות תלויים במודולי ליבת ODM.

ב-Android 7.x ומטה, מחיצות /vendor ו- /odm אינן נטענות מוקדם. ב-Android 8.x ומעלה, כדי לאפשר טעינת מודול ממחיצות אלו, בוצעו הוראות להרכבת מחיצות מוקדם עבור מכשירי A/B ו-A/B כאחד . זה גם מבטיח שהמחיצות מותקנות הן במצב אנדרואיד והן במצב מטען.

תמיכה במערכת בניית אנדרואיד

ב- BoardConfig.mk , ה-build של Android מגדיר משתנה BOARD_VENDOR_KERNEL_MODULES המספק רשימה מלאה של מודולי הליבה המיועדים לתמונת הספק. המודולים הרשומים במשתנה זה מועתקים לתמונת הספק ב- /lib/modules/ , ולאחר הרכבה באנדרואיד, מופיעים ב- /vendor/lib/modules (בהתאם לדרישות לעיל). תצורה לדוגמה של מודולי ליבת הספק:

vendor_lkm_dir := device/$(vendor)/lkm-4.x
BOARD_VENDOR_KERNEL_MODULES := \
  $(vendor_lkm_dir)/vendor_module_a.ko \
  $(vendor_lkm_dir)/vendor_module_b.ko \
  $(vendor_lkm_dir)/vendor_module_c.ko

בדוגמה זו, מאגר בנוי מראש של מודול ליבת הספק ממופה ל-Android build במיקום המפורט למעלה.

תמונת השחזור עשויה להכיל תת-קבוצה של מודולי הספק. מבנה האנדרואיד מגדיר את המשתנה BOARD_RECOVERY_KERNEL_MODULES עבור מודולים אלה. דוגמא:

vendor_lkm_dir := device/$(vendor)/lkm-4.x
BOARD_RECOVERY_KERNEL_MODULES := \
  $(vendor_lkm_dir)/vendor_module_a.ko \
  $(vendor_lkm_dir)/vendor_module_b.ko

ה-Android build דואג להפעיל depmod כדי ליצור את קבצי modules.dep הנדרשים ב- /vendor/lib/modules ו- /lib/modules ( recovery ramfs ).

טעינת מודול וניהול גרסאות

טען את כל מודולי הליבה במעבר אחד מ- init.rc* על ידי הפעלת modprobe -a . זה ימנע את התקורה של אתחול שוב ושוב של סביבת זמן הריצה C עבור הבינארי modprobe . ניתן לשנות את האירוע early-init כדי להפעיל modprobe :

on early-init
    exec u:r:vendor_modprobe:s0 -- /vendor/bin/modprobe -a -d \
        /vendor/lib/modules module_a module_b module_c ...

בדרך כלל, יש להרכיב מודול ליבה עם הקרנל שאיתו מודול אמור לשמש (אחרת הקרנל מסרב לטעון את המודול). CONFIG_MODVERSIONS מספק פתרון עוקף על ידי זיהוי שברים בממשק הבינארי של היישום (ABI). תכונה זו מחשבת ערך בדיקת יתירות מחזורית (CRC) עבור אב הטיפוס של כל סמל מיוצא בליבה ומאחסנת את הערכים כחלק מהקרנל; עבור סמלים המשמשים מודול ליבה, הערכים מאוחסנים גם במודול הקרנל. כאשר המודול נטען, הערכים של הסמלים המשמשים את המודול מושווים לאלה שבקרנל. אם הערכים תואמים, המודול נטען; אחרת העומס נכשל.

כדי לאפשר את העדכון של תמונת הליבה בנפרד מתמונת הספק, הפעל את CONFIG_MODVERSIONS . פעולה זו מאפשרת לבצע עדכונים קטנים לקרנל (כגון תיקוני באגים מ-LTS) תוך שמירה על תאימות עם מודולי ליבה קיימים בתמונת הספק. עם זאת, CONFIG_MODVERSIONS אינו מתקן שבירה של ABI בעצמו. אם אב הטיפוס של סמל מיוצא בקרנל משתנה, בין אם עקב שינוי במקור או בגלל שתצורת הליבה השתנתה, הדבר שובר את התאימות עם מודולי ליבה המשתמשים בסמל זה. במקרים כאלה, יש לבצע קומפילציה מחדש של מודול הליבה.

לדוגמה, מבנה task_struct בקרנל (מוגדר ב- include/linux/sched.h ) מכיל שדות רבים הכלולים באופן מותנה בהתאם לתצורת הליבה. השדה sched_info קיים רק אם CONFIG_SCHED_INFO מופעל (מה שמתרחש כאשר CONFIG_SCHEDSTATS או CONFIG_TASK_DELAY_ACCT מופעלים). אם אפשרויות התצורה הללו משתנות מצב, הפריסה של מבנה task_struct משתנה וכל הממשקים המיוצאים מהקרנל המשתמשים task_struct ישתנו (לדוגמה, set_cpus_allowed_ptr ב- kernel/sched/core.c ). תאימות עם מודולי ליבה שהורכבו בעבר המשתמשים בממשקים אלה נשברת, מה שמחייב לבנות מחדש את המודולים האלה עם תצורת הקרנל החדשה.

לפרטים נוספים על CONFIG_MODVERSIONS , עיין בתיעוד בעץ הליבה בכתובת Documentation/kbuild/modules.rst .