מודול ליבה נטען

במחשבים, מודול ליבה נטען (או בפשטות מודול ליבה) הוא קובץ המכיל קוד להרחבת פעולת הליבה, או מה שנקרא ליבת הבסיס, של מערכת הפעלה. מודול ליבה נטען משמש בדרך כלל כדי להוסיף תמיכה בחומרה או מערכת קבצים, או להוספת קריאות מערכת. כאשר אין עוד צורך בפונקציונליות הניתנת על ידי המודול, ניתן לפרוק אותו כדי לפנות זיכרון ומשאבים אחרים. רוב מערכות ההפעלה המבוססות על יוניקס, וכן חלונות, תומכות במודולי ליבה נטענים, למרות שהן עשויות להשתמש במונחים שונים. כך לדוגמה הם נקראים בחלונות (החל מחלונות NT ואילך) בשם "Kernel-mode drivers", במק בשם "Kernel Extentions" ("הרחבות ליבה") וב-FreeBSD בשםkernel loadable modules (בקיצור kld). ללא מודולי ליבה הניתנים לטעינה, מערכת הפעלה תצטרך להכיל בתוכה מראש את כל התכונות שהיא עשויה להצטרך להן, מורכבות ישירות בליבת הבסיס. הרבה מהתכונות הללו תשבנה בזיכרון מבלי שייעשה בהן שימוש - בזבוז זיכרון שלא יהיה זמין לשימושים אחרים, ובנוסף משתמשים יצטרכו לבנות מחדש את ליבת הבסיס בכל פעם שהם זקוקים לפונקציונליות חדשה. אחת הבעיות העלולות להיווצר בליבה שכזו, לעומת ליבה "סטטית", היא בעיית הקיטוע (Fragmentation). ליבת הבסיס נטענת אל תוך קטע זיכרון רציף בזמן האתחול. כאשר המערכת נכנסת למצב בו ניתן לטעון אליה מודולים, לדוגמה: לאחר טעינת מערכת הקבצים המכילה את המודולים, סביר להניח שטעינת המודולים לאחר מכן תגרום לקיטוע בזיכרון, דבר העשוי לגרור פגיעה מינורית בביצועים בגלל שימוש במספר רב של חוצצי זיכרון לתרגום כתובות (TLB, Translation lookaside buffer). בלינוקס, טעינת המודולים מהזיכרון והסרתם מתבצעת באמצעות הפקודה modprobe, שנועדה להחליף את פקודות insmod ו-rmmod הוותיקות יותר. המודולים ממוקמים בתיקיית /lib/modules ומאז גרסת הליבה 2.6, מקבלים את הסיומת .ko (גרסאות קודמות הצמידו למודולי ליבה את הסיומת .o). באמצעות הפקודה lsmod המשתמש יכול לסקור את רשימת המודולים הטעונים במערכת. במקרי חירום (לדוגמה, מערכת שמסרבת להיטען בשל מודול פגום), המשתמש יכול לערוך את רשימת המודולים הנטענים על ידי שימוש במנהל האתחול של מערכת ההפעלה. מנקודת מבטם של מתחזקי ליבת לינוקס, מודולי הליבה הם יצירה נגזרת של הליבה עצמה. בעוד שהם מוכנים לקבל גם מודלים קנייניים, הם מאפשרים ייצוא של Symbols (פונקציות "חיצוניות" של המודול, שאינן עוסקות באתחולו או בסיום פעולתו) כך שייפעלו רק במודולים חופשיים (תחת הרישיון הציבורי הכללי של גנו, בקיצור GPL). טעינה של מודול קנייני, או של מודול שיצא ברישיון שאינו GPL, תגרום לקרנל להיות במצב taint. המשמעות של tainted kernel היא שבאגים שייוצרו במהלך ריצתו לא ייבדקו היטב על ידי המתחזקים. מודולי ליבה עבור FreeBSD עשויים להישמר או בתיקיית /boot/kernel/, במקרה של מודולים שהגיעו עם מערכת ההפעלה, או בתיקיית /boot/modules/ במקרה של מודולים שהגיעו ממקורות חיצוניים, למשל כאלו שהגיעו ממנהל החבילות או שהותקנו ידנית, או מודולים קנייניים. בדומה ללינוקס, גם כאן הם נשמרים תחת הסיומת .ko. ניתן לטעון מודולים על ידי הפקודה kldload, להסירם מהזיכרון על ידי הפקודה kldunload, ולצפות ברשימת המודולים הפועלים כעת על ידי הפקודה kldstat. ניתן גם לטעון מודולי ליבה עוד לפני טעינת הליבה עצמה, הן על ידי שימוש במנהל האתחול או ידנית. במערכת ההפעלה macOS, מודולי ליבה, הנקראים "הרחבות ליבה" נטענים אוטומטית או ידנית על ידי שימוש בפקודות kextload. גם כאן ניתן לצפות ברשימת ההרחבות הטעונות, על ידי שימוש בפקודה kextstat. המערכת תומכת גם ב"אריזת" מספר הרחבות לקובץ אחד (bundle) בסיומת .kext. הרחבות שהגיעו עם מערכת ההפעלה נשמרות בתיקיית /System/Library/Extensions, בעוד שהרחבות שהגיעו ממקורות צד שלישי (מנהלי התקן חיצוניים למשל) נשמרות בתיקיות המתאימות להם (תלוי במקור ממנו הגיעו). בסולאריס ניתן לשנות את הנתיב אליו מגיעים המודולים. כברירת מחדל, המודולים פזורים בין 3 תיקיות שונות: /kernel, או /platform/`uname -i`/kernel, או /usr/kernel . בעוד שהתיקיות מכילות את כל המודולים (כולל מודולים מצד שלישי) הנחוצים עבור מערכת מלאה ומתפקדת, התיקייה הראשונה מכילה רק את המודולים הדואגים לכך שהמערכת תיטען כיאות. כאשר מריצים את הליבה במצב DEBUG, היא תנסה להסיר "בכוח" מודולים לא נחוצים. רוב מערכות ההפעלה המודרניות, ובכללן חלונות, macOS ו-FreeBSD מספקות API ו-ABI (אנ') מסודרים. לדוגמה, מודול שנכתב עבור גרסה 6 של ליבת FreeBSD יפעל ללא בעיות על כל גרסת ליבה שמספרה הראשי 6 (גם על 6.4), אבל, במידה ונרצה לטעון את המודול על גרסה חדשה יותר של הליבה (לדוגמה, טעינת מודול לגרסה 6.4 לליבה בגרסה 7), המערכת לא תאפשר זאת, ותחייב להדר מחדש את המודול לגרסה החדשה. בלינוקס המצב שונה - ללינוקס אין API מסודר עבור מודולי ליבה. המשמעות היא שעשויות להיווצר בעיות תאימות כאשר עובדים עם גרסאות שונות של אותה הליבה, למשל כאשר כותבים מודול עבור גרסת ליבה מסוימת ומנסים לטעון אותו לגרסה אחרת של הליבה. כדי להתמודד עם בעיה זו, ניתן להשוות את הגרסאות בעזרת modinfo. במידה ומספרי הגרסאות אינם תואמים זה לזה, המודול לא ייטען. Tainted kernels — The Linux Kernel documentation, www.kernel.org Tainted kernel | Support | SUSE, www.suse.com Kernel Overview - Device Driver Tutorial, docs.oracle.com