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

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

מיקום המודול

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

  • מודולים של ליבה (kernel) של ספק init בשלב ראשון, שנמצאים ב-/lib/modules/.
  • קובצי תצורה של modprobe שנמצאים ב-/lib/modules/: modules.dep, modules.softdep, modules.alias, modules.options.
  • קובץ modules.load שמציין אילו מודולים צריך לטעון במהלך ההפעלה הראשונית של השלב הראשון, ובאיזה סדר, ב-/lib/modules/.
  • מודולים של ליבה (kernel) לשחזור של ספק, למכשירי A/B ומכשירי A/B וירטואליים, ב-/lib/modules/
  • modules.load.recovery שמציין את המודולים לטעינה, ואת הסדר שלהם במכשירי A/B ו-Virtual 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 במקרה של שחזור) ומנסה לטעון כל אחד מהמודולים האלה לפי הסדר, בהתאם לתצורה שצוינה בקובצים שהועלו קודם. ייתכן שההזמנה המבוקשת תחרוג מכדי לספק יחסי תלות כבדים או רכים.

בניית תמיכה, שלב ראשון

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

ה-build יוצר גם קובץ modules.load ומאחסן אותו ב-cpio של הספק ramdisk. כברירת מחדל, הוא מכיל את כל המודולים שמפורטים ב-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

בניית תמיכה, Android מלא

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

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

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

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