תמיכה במודולים של ליבה

יכול להיות שתמונת ליבה גנרית (GKI) לא תכלול את תמיכת הדרייבר הנדרשת כדי לאפשר למכשיר לטעון מחיצות. כדי לאפשר למכשיר לטעון את המחיצות ולהמשיך את האתחול, השלב הראשון של init משופר כדי לטעון את מודולי הליבה שנמצאים ב-ramdisk. דיסק ה-RAM מחולק לדיסק RAM כללי ולדיסק RAM של ספק. מודולי הליבה של הספק מאוחסנים ב-ramdisk של הספק. אפשר להגדיר את הסדר שבו מודולי הליבה נטענים.

מיקום המודול

דיסק ה-RAM הוא מערכת הקבצים של init, בשלב הראשון ושל קובץ האימג' של recovery/fastbootd במכשירי A/B ובמכשירים וירטואליים של A/B. זהו קובץ initramfs שמורכב משני ארכיונים מסוג cpio שמקושרים על ידי תוכנת האתחול. הארכיון הראשון של cpio, שנשמר כ-ramdisk של הספק במחיצה vendor-boot, מכיל את הרכיבים הבאים:

  • מודולים של ליבה של ספקי init בשלב ראשון, שנמצאים ב-/lib/modules/.
  • קובצי תצורה של modprobe, שנמצאים ב-/lib/modules/: modules.dep, modules.softdep, modules.alias, modules.options.
  • קובץ modules.load שמציין אילו מודולים צריך לטעון במהלך ההפעלה הראשונית של השלב הראשון, ובאיזה סדר, ב-/lib/modules/.
  • מודולים של ליבה לשחזור של ספקים, למכשירי A/B ולמכשירי A/B וירטואליים, ב-/lib/modules/
  • modules.load.recovery, שמציין את המודולים שצריך לטעון, ובאיזה סדר, למכשירי A/B ולמכשירי A/B וירטואליים, ב-/lib/modules.

הארכיון השני של cpio, שסופק עם GKI בתור דיסק ה-RAM של boot.img ויושם מעל הראשון, מכיל את first_stage_init ואת הספריות שהוא תלוי בהן.

טעינה של מודולים בשלב הראשון של האתחול

בשלב הראשון, init מתחיל בקריאת קובצי התצורה של modprobe מ-/lib/modules/ ב-ramdisk. לאחר מכן, המערכת קוראת את רשימת המודולים שצוינה בקובץ /lib/modules/modules.load (או בקובץ /lib/modules/modules.load.recovery במקרה של שחזור) ומנסה לטעון כל אחד מהמודולים האלה לפי הסדר, בהתאם לתצורה שצוינה בקובצים שהועלו קודם. יכול להיות שינוי בסדר הבקשה כדי לעמוד בתנאי של יחסי תלות קשיחים או רכים.

תמיכה ב-build, שלב ראשון של init

כדי לציין מודולים של ליבה שרוצים להעתיק לקובץ ה-cpio של ה-ramdisk של הספק, צריך לציין אותם בקובץ BOARD_VENDOR_RAMDISK_KERNEL_MODULES. ה-build מפעיל את depmod במודולים האלה ומעביר את קובצי התצורה של modprobe שנוצרים ל-cpio של דיסק ה-RAM של הספק.

ב-build נוצר גם קובץ modules.load שנשמר ב-cpio של דיסק ה-RAM של הספק. כברירת מחדל, הוא מכיל את כל המודולים שמפורטים ב-BOARD_VENDOR_RAMDISK_KERNEL_MODULES. כדי לשנות את התוכן של הקובץ, משתמשים ב-BOARD_VENDOR_RAMDISK_KERNEL_MODULES_LOAD, כפי שמתואר בדוגמה הבאה:

BOARD_VENDOR_RAMDISK_KERNEL_MODULES_LOAD := \
    device/vendor/mydevice-kernel/first.ko \
    device/vendor/mydevice-kernel/second.ko \
    device/vendor/mydevice-kernel/third.ko

תמיכה ב-build, Android מלא

כמו בגרסאות Android 10 וקודמות, מודולי הליבה שמפורטים ב-BOARD_VENDOR_KERNEL_MODULES מועתקים על ידי ה-build של פלטפורמת Android למחיצה של הספק ב-/vendor/lib/modules. ה-build של הפלטפורמה מפעיל את depmod במודולים האלה ומעתיק את קובצי הפלט של depmod למחיצה של הספק באותו מיקום. המנגנון לטעינת מודולים של ליבה מ-/vendor נשאר זהה למנגנון שהיה בגרסאות קודמות של Android. אתם מחליטים איך ומתי לטעון את המודולים האלה, אם כי בדרך כלל עושים זאת באמצעות סקריפטים של init.rc.

תווים כלליים לחיפוש וגרסאות build משולבות של ליבה

ספקים שמשלבים את ה-build של ליבה של המכשיר עם ה-build של פלטפורמת Android עשויים להיתקל בבעיה בשימוש במאקרו BOARD שצוין למעלה כדי לציין את המודולים של הליבה שרוצים להעתיק למכשיר. אם הספק רוצה להימנע מהצגת רשימה של מודולי הליבה בקובצי ה-build של פלטפורמת המכשיר, הוא יכול להשתמש בתווית Wildcard‏ ($(wildcard device/vendor/mydevice/*.ko). שימו לב שהתווית הזו לא פועלת במקרה של build משולב של ליבה, כי כשמפעילים את make והמאקרוים מורחבים בקובצי make, מודולי הליבה עדיין לא נוצרו, ולכן המאקרוים ריקים.

כדי לעקוף את הבעיה הזו, יכול להיות שהיצרן יבקש שיוצר הליבה ייצור ארכיון zip שמכיל את המודולים של הליבה שצריך להעתיק לכל מחיצה. מגדירים את הנתיב של הארכיון ב-zip ב-BOARD_*_KERNEL_MODULES_ARCHIVE, כאשר * הוא שם המחיצה (למשל BOARD_VENDOR_KERNEL_MODULES_ARCHIVE). ה-build של פלטפורמת Android מחלץ את הארכיון ב-zip למיקום המתאים ומריץ את depmod על המודולים.

לארכיון ה-zip של מודול הליבה צריך להיות כלל make שמבטיח ש-build הפלטפורמה יוכל ליצור את הארכיון לפי הצורך.

שחזור

בגרסאות קודמות של Android, המודולים של הליבה שנדרשים לשחזור צוינו ב-BOARD_RECOVERY_KERNEL_MODULES. ב-Android 12, עדיין מציינים את המודולים של הליבה הנדרשים לשחזור באמצעות המאקרו הזה. עם זאת, המודולים של ליבה של התאוששות מועתקים ל-cpio של ה-ramdisk של הספק, ולא ל-cpio של ה-ramdisk הכללי. כברירת מחדל, כל המודולים של הליבה שמפורטים ב-BOARD_RECOVERY_KERNEL_MODULES נטענים בשלב הראשון init. אם רוצים לטעון רק קבוצת משנה של המודולים האלה, צריך לציין את התוכן של קבוצת המשנה הזו ב-BOARD_RECOVERY_KERNEL_MODULES_LOAD.

מידע נוסף על יצירת מחיצת אתחול של ספק (שמכילה את דיסק ה-RAM של הספק שצוין בדף הזה) זמין במאמר מחיצות אתחול.