מהי שיחת מערכת לינוקס?

What Is Linux System Call



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

ליבת לינוקס היא תוכנית מיוחדת שמתחילה ופועלת ברמה הנמוכה ביותר הזמינה בחומרה שלך. מוטלת עליו המשימה לתזמן את כל מה שפועל במחשב, כולל טיפול במקלדת, בדיסק ובאירועי רשת למתן פרוסות זמן לביצוע מספר תוכניות במקביל.







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



עיקול המכשול עם שיחות מערכת לינוקס

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



כדי להקל על האינטראקציה, הגרעין מייעד שער תוכנה המאפשר לתוכנית הפועלת לבקש שהגרעין יפעל בשמו. ממשק זה מכונה קריאת מערכת.





מכיוון שלינוקס עוקבת אחר פילוסופיית UNIX של הכל הוא קובץ, ניתן לבצע פונקציות רבות על ידי פתיחה וקריאה או כתיבה לקובץ, שיכול להיות מכשיר. ב- Windows, למשל, תוכל להשתמש בפונקציה בשם CryptGenRandom כדי לגשת לבייטים אקראיים. אך ב- Linux, ניתן לעשות זאת על ידי פתיחת הקובץ/dev/urandom וקריאת בתים מתוכו באמצעות שיחות מערכת קלט/פלט של קבצים סטנדרטיים. הבדל מכריע זה מאפשר ממשק שיחות מערכת פשוט יותר.

ופל-דק עטיפה

ברוב היישומים, שיחות מערכת אינן מתבצעות ישירות לגרעין. כמעט כל התוכניות מקשרות בספריית C הסטנדרטית, המספקת מעטפת דקה אך חשובה סביב שיחות מערכת לינוקס. הספרייה מוודאת שהארגומנטים של הפונקציה מועתקים לרשומות המעבד הנכונות ואז מוציאה את שיחת מערכת Linux המתאימה. כאשר מתקבלים נתונים מהשיחה, העטיפה מפרשת את התוצאות ומחזירה אותם לתוכנית בצורה עקבית.



מאחורי הקלעים

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

בָּטֵלרָאשִׁי() {
}

זו כנראה התוכנית C הטריוויאלית ביותר שתראו. היא פשוט משיגה שליטה דרך נקודת הכניסה הראשית ואז יוצאת. הוא אפילו לא מחזיר ערך מכיוון שהעיקרי מוגדר כבטל. שמור את הקובץ כ ctest.c ובוא נאסוף אותו:

gcc ctest.ג -הבדיקה

לאחר הידור, אנו יכולים לראות את גודל הקובץ כ- 8664 בתים. המערכת עשויה להשתנות מעט במערכת שלך, אך היא אמורה להיות סביב 8k. זה הרבה קוד רק להיכנס ולצאת! הסיבה שזה 8k היא שזמן הריצה של libc נכלל. גם אם אנו מפשיטים את הסמלים, זה עדיין טיפה יותר מ -6 אלף.

בדוגמה פשוטה עוד יותר, אנו יכולים לגרום למערכת לינוקס לקרוא ליציאה ולא בהתאם לזמן הריצה C כדי לעשות זאת עבורנו.

בָּטֵל_הַתחָלָה() {
asm('movl $ 1,%eax;'
'xorl %ebx, %ebx;'
'int $ 0x80');
}

כאן אנו עוברים 1 לרשום EAX, מנקים את פנקס ה- EBX (שאחרת היה מכיל את ערך ההחזרה) ואז קוראים לשיחת מערכת הפעלת מערכת לינוקס 0x80 (או 128 עשרונית). הפרעה זו מפעילה את הגרעין לעבד את השיחה שלנו.

אם נאסוף את הדוגמה החדשה שלנו, שנקראת asmtest.c, ונפשט את הסמלים ולא יכלול את הספרייה הסטנדרטית:

gcc-ש-nostdlib asmtest.ג -o מבחן

אנו מייצרים בינארי פחות מ- 1k (במערכת שלי, הוא מניב 984 בתים). רוב הקוד הזה הוא כותרות הפעלה. כעת אנו קוראים לשיחת מערכת לינוקס הישירה.

לכל מטרה מעשית

כמעט בכל המקרים, לעולם לא תצטרך לבצע שיחות מערכת ישירות בתוכניות C שלך. עם זאת, אם אתה משתמש בשפת הרכבה, הצורך עשוי להתעורר. עם זאת, באופטימיזציה, עדיף לתת לפונקציות ספריית C לבצע את שיחות המערכת ולכלול רק את קוד הביקורת לביצועים שלך בהוראות ההרכבה.

כיצד לתכנת שיעורי שיחות מערכת

רשימת כל שיחות המערכת

אם ברצונך לראות רשימה של כל שיחות המערכת הזמינות עבור Linux תוכל לבדוק את דפי ההפניה הבאים: רשימה מלאה של שיחות מערכת ב- LinuxHint.com, filippo.io/linux-syscall-table/ ו או syscalls.kernelgrok.com