بسم الله الرحمن الرحيم.
السلام عليكم ورحمة الله تعالى وبركاته.
ستغطي هذه السلسلة المواضيع التالية:
- إدارة العمليات (Processes).
- إدارة الذاكرة (Memory Management).
- إدارة الملفات (File System).
- الجدولة (Scheduling).
- المقاطعات (Interrupts).
وكما اعتدنا، لن تكون السلسلة مملة ونظرية فحسب؛ بل ستجري فيها أمثلة عملية بلغة C ورسومات لتوضيح الفهم أكثر. أحببت أن أذكر ما ستأخذه من هذه السلسلة حتى يعرف القارئ ما في انتظاره. وأسأل الله التوفيق والسداد.
ويُفضل قبل البدء بهذه السلسلة الاطلاع على سلسلة معمارية وتنظيم الحاسوب في المدونة.
فضاء النواة وفضاء المستخدم (Kernel Space vs User Space)
قبل البدء لا بد أن نشرح النقاط المهمة الواجب المعرفة بها:
في البداية يجب أن نعرف أن نظام التشغيل يقسم الذاكرة (Memory) إلى جزأين أساسيين هما: الـ Kernel Space والـ User Space. وكما يظهر من الاسم: الـ Kernel Space مخصص لتحميل وتشغيل النواة Kernel، بينما الـ User Space مخصص لتحميل وتشغيل أي شيء آخر مثل البرامج التي يستخدمها المستخدم.
طيب، جيد — ما الفرق بينهما؟
يستطيع الـ Kernel التحكم في أي جزء من الذاكرة بما في ذلك الـ User Space، أما العكس غير مسموح به: فلا يستطيع أي برنامج من الـ User Space التحكم بأي شيء داخل الـ Kernel Space.
ولننظر إلى كيفية تقسيم الذاكرة:
شكل (1): تقسيم الذاكرة
كما هو واضح، الذاكرة مقسمة إلى Kernel Space وUser Space، وقد تحدثنا سابقاً عن الـ User Space في درس الذاكرة الافتراضية ضمن ورشة لغة C، وهو المسؤول عن البرامج التي يستخدمها المستخدم.
طيب، لماذا هذا التقسيم؟
هذا العزل أو التقسيم لحماية نظام التشغيل من أي شيء يتم تشغيله بواسطة المستخدم. تخيل ماذا سيحدث لو تركنا الأمر للمستخدم بالتحكم في الكود الخاص بنظام التشغيل الموجود داخل النواة؛ ستكون النتائج كارثية، وسيحدث انهيار (Crash) لنظام التشغيل مراراً وتكراراً.
نداءات النظام (System Calls)
طيب، ماذا يحدث إذا أراد برنامج يعمل في الـ User Space التواصل مع الـ Kernel Space وطلب بعض المهام منه؟
يتم ذلك عن طريق ما يسمى الـ System Calls: وهي الواجهة أو نقطة الوصل بين الـ User Space والـ Kernel Space. فلا يوجد سبيل لأي شيء موجود داخل الـ User Space للتواصل مع الـ Kernel Space إلا عن طريق الـ System Calls:
شكل (2): مسار الطلب من المستخدم إلى النواة
مثال يوضح الصورة
عندما نقوم بكتابة كود بلغة C يطبع Hello World مثلاً:
printf("Hello World");
ماذا يحدث عند التشغيل؟
عند تشغيل هذا البرنامج سيتم تحميله داخل الذاكرة في الـ User Space، لكن البرنامج يتضمن عملية طباعة وهي مهمة مسؤول عنها نظام التشغيل — أو بالأدق النواة Kernel. عندها سيستخدم البرنامج الـ Syscall (في حالة Linux) ليطلب من النواة تنفيذ عملية الطباعة، وستنفذ النواة المهمة ثم تعود إلى البرنامج في الـ User Space وتخبره بالنتيجة.
قد تسأل نفسك: هل كل هذا يحدث لمجرد استخدام printf؟ أجابت هي: نعم، ما شرحناه سابقاً هو ما يحدث داخلياً فعلاً. فعند استخدامك printf يتم استدعاء الـ Syscall الخاص بها الذي يسمى write()، وهو الذي ينفذ عملية الطباعة بالحقيقة.
وماذا عن الـ Syscall في ويندوز؟
في حالة Windows لدينا ما يسمى Windows API بدلاً من الـ System Calls، وهي الطريقة التي نستخدمها إذا أردنا من نظام التشغيل تنفيذ إحدى المهام المسؤول عنها — كالطباعة في المثال السابق.
الخلاصة
المهام المسؤول عنها نظام التشغيل (OS) عديدة، ولاستخدام أي منها لا بد من المرور عبر الـ Syscalls في حالة Linux أو الـ Windows API في حالة Windows.
وهذا جدول يوضح مجموعة من أهم Linux System Calls وما يقابلها من Windows APIs:
شكل (3): مقارنة بين نداءات النظام في لينكس وواجهة ويندوز
اذكرونا من صالح الدعاء.