0. مقدّمة
انغمس في العالم البديع لأنظمة الحاسوب! إن فهم ما هو نظام الحاسوب وكيف يشغّل برامجك يمكن أن يساعدك على تصميم شيفرة تعمل بكفاءة وتستفيد استفادة مثلى من قدرة النظام الأساسي. في هذا الكتاب، نأخذك في رحلة عبر أنظمة الحاسوب. ستتعلم كيف ينفَّذ برنامجك المكتوب بلغة برمجة عالية المستوى (نستخدم لغة C) على الحاسوب. ستتعلم كيف تُترجم تعليمات البرنامج إلى ثنائي وكيف تنفّذ الدوائر ترميزها الثنائي. ستتعلم كيف يدير نظام التشغيل البرامج التي تعمل على النظام. ستتعلم كيف تكتب برامج تستفيد من الحواسيب متعددة الأنوية. وطوال ذلك، ستتعلم كيف تقيّم التكاليف النظامية (systems costs) المرتبطة بشيفرة البرنامج وكيف تصمّم برامج تعمل بكفاءة.
ما هو نظام الحاسوب؟
يجمع نظام الحاسوب (computer system) بين عتاد الحاسوب وبرمجيات النظام الخاصة التي تجعل الحاسوب صالحاً للاستخدام من قِبل المستخدمين والبرامج معاً. وتحديداً، يتكوّن نظام الحاسوب من المكوّنات التالية (انظر الشكل 1):
- منافذ الإدخال/الإخراج (I/O) تتيح للحاسوب أخذ المعلومات من بيئته وعرضها مجدداً للمستخدم بطريقة ذات معنى.
- تتشغّل وحدة المعالجة المركزية (CPU) التعليمات وتحسب البيانات وعناوين الذاكرة.
- تحفظ ذاكرة الوصول العشوائي (RAM) بيانات البرامج قيد التشغيل وتعليماتها. وعادةً ما تُفقد البيانات والتعليمات الموجودة في RAM عند انقطاع الطاقة عن نظام الحاسوب.
- تحفظ أجهزة التخزين الثانوية مثل الأقراص الصلبة البرامج والبيانات حتى عندما لا تُزوَّد الطاقة للحاسوب بشكل فعّال.
- تقع طبقة برمجية هي نظام التشغيل (OS) بين عتاد الحاسوب والبرمجيات التي يشغّلها المستخدم على الحاسوب. ويوفّر نظام التشغيل تجريدات (abstractions) وواجهات تُمكّن المستخدمين من تشغيل البرامج والتفاعل معها بسهولة على النظام. كما يدير موارد العتاد الأساسية ويتحكم في كيفية وموعد تنفيذ البرامج. وينفّذ نظام التشغيل تجريدات وسياسات وآليات تضمن إمكانية تشغيل برامج متعددة في الوقت نفسه على النظام بكفاءة وبحماية وبسلاسة.
وتعرّف البنود الأربعة الأولى عتاد الحاسوب (computer hardware) في نظام الحاسوب. ويمثّل البند الأخير (نظام التشغيل) الجزء البرمجي الرئيسي في نظام الحاسوب. وقد توجد طبقات برمجية إضافية فوق نظام التشغيل توفّر واجهات أخرى لمستخدمي النظام (مثل المكتبات). غير أن نظام التشغيل هو برمجية النظام الجوهرية التي نركّز عليها في هذا الكتاب.
الشكل 1. المكوّنات الطبقية لنظام الحاسوب
نركّز تحديداً على أنظمة الحاسوب التي تتّصف بالخصائص التالية:
- أنها عامة الغرض (general purpose)، أي أن وظيفتها ليست مصمّمة لتطبيق بعينه.
- أنها قابلة لإعادة البرمجة (reprogrammable)، أي أنها تدعم تشغيل برنامج مختلف دون تعديل عتاد الحاسوب أو برمجيات النظام.
ولهذا الغرض، فإن كثيراً من الأجهزة التي قد «تحسب» بشكل ما لا تندرج في فئة نظام الحاسوب. فالآلات الحاسبة مثلاً تمتلك عادةً معالجاً وكميات محدودة من الذاكرة وقدرة على الإدخال/الإخراج. ومع ذلك، لا تمتلك الآلات الحاسبة عادةً نظام تشغيل (والآلات الحاسبة البيانية المتقدمة مثل TI-89 استثناء ملحوظ من هذه القاعدة)، ولا تمتلك تخزيناً ثانوياً، وليست عامة الغرض.
ومن الأمثلة الأخرى الجديرة بالذكر المتحكّم الدقيق (microcontroller)، وهو نوع من الدوائر المتكاملة يمتلك كثيراً من القدرات نفسها التي يمتلكها الحاسوب. وغالباً ما تُدمج المتحكّمات الدقيقة في أجهزة أخرى (مثل الألعاب والأجهزة الطبية والسيارات والأجهزة المنزلية)، حيث تتحكم في وظيفة تلقائية محددة. ورغم أن المتحكّمات الدقيقة عامة الغرض وقابلة لإعادة البرمجة وتحتوي على معالج وذاكرة داخلية وتخزين ثانوي وقادرة على الإدخال/الإخراج، فإنها تفتقر إلى نظام تشغيل. فالمتحكّم الدقيق مصمّم ليقلع ويشغّل برنامجاً واحداً محدداً حتى انقطاع الطاقة عنه. ولهذا السبب، لا يندرج المتحكّم الدقيق في تعريفنا لنظام الحاسوب.
كيف تبدو أنظمة الحاسوب الحديثة؟
بعد أن رسّخنا ما هو نظام الحاسوب (وما ليس هو)، لنتحدث عن الشكل المعتاد لأنظمة الحاسوب. يوضّح الشكل 2 نوعين من أنظمة عتاد الحاسوب (باستثناء الأجهزة الطرفية): حاسوب مكتبي (يسار) وحاسوب محمول (يمين). ووجود قطعة ربع دولار أمريكي على كل جهاز يمنح القارئ فكرة عن حجم كل وحدة.
الشكل 2. نظامان شائعان للحاسوب: حاسوب مكتبي (يسار) وحاسوب محمول (يمين)
لاحظ أن كليهما يحتوي على مكوّنات العتاد نفسها، وإن كان بعض المكوّنات أصغر حجماً أو أكثر إحكاماً. وقد نُقلت فتحة أقراص DVD/CD في الحاسوب المكتبي إلى الجانب لإظهار القرص الصلب تحتها — فالوحدتان مكدّستان إحداهما فوق الأخرى. ويساعد مزوّد الطاقة المخصّص في تزويد الحاسوب المكتبي بالطاقة.
في المقابل، يكون الحاسوب المحمول أكثر تسطّحاً وإحكاماً (لاحظ أن قطعة الربع في هذه الصورة تبدو أكبر قليلاً). وللحاسوب المحمول بطارية وتميل مكوّناته إلى أن تكون أصغر. وفي كل من الحاسوب المكتبي والمحمول، يحجب مروحة معالج ثقيلة الوزن رؤية المعالج، وتساعد هذه المروحة في إبقاء المعالج عند درجة حرارة تشغيل معقولة. وإذا ارتفعت حرارة المكوّنات زيادةً مفرطة، فقد تتلف تلفاً دائماً. ولكلتا الوحدتين وحدات ذاكرة مزدوجة الصف (DIMM) لوحدات RAM. لاحظ أن وحدات ذاكرة الحاسوب المحمول أصغر بكثير من وحدات الحاسوب المكتبي.
ومن حيث الوزن واستهلاك الطاقة، تستهلك الحواسيب المكتبية عادةً من 100 إلى 400 واط من الطاقة وتزن عادةً ما بين 5 و20 رطلاً. أما الحاسوب المحمول فيستهلك عادةً من 50 إلى 100 واط ويستخدم شاحناً خارجياً لتعويض البطارية عند الحاجة.
يتجه تصميم عتاد الحاسوب نحو أجهزة أصغر وأكثر إحكاماً. ويعرض الشكل 3 حاسوباً أحادي اللوحة من نوع Raspberry Pi. والحاسوب أحادي اللوحة (SBC) جهاز تُطبع فيه كامل مكوّنات الحاسوب على لوحة دوائر واحدة.
الشكل 3. حاسوب أحادي اللوحة Raspberry Pi
يحتوي حاسوب Raspberry Pi أحادي اللوحة على معالج نظام على شريحة (SoC) بذاكرة RAM ومعالج مدمجين، ويشمل ذلك كثيراً من عتاد الحاسوب المحمول والمكتبي المعروض في الشكل 2. وخلافاً لأنظمة الحاسوب المحمول والمكتبي، فإن Raspberry Pi بحجم بطاقة ائتمان تقريباً، ويزن 1.5 أونصة (نحو شريحة من الخبز)، ويستهلك نحو 5 واط من الطاقة. وتوجد تقنية SoC الموجودة في Raspberry Pi شائعةً أيضاً في الهواتف الذكية. بل إن الهاتف الذكي مثال آخر على نظام الحاسوب!
وأخيراً، فإن جميع أنظمة الحاسوب المذكورة آنفاً (بما فيها Raspberry Pi والهواتف الذكية) تحتوي على معالجات متعددة الأنوية (multicore). وبعبارة أخرى، تستطيع معالجاتها تنفيذ برامج متعددة في الوقت نفسه. ونشير إلى هذا التنفيذ المتزامن باسم التنفيذ المتوازي (parallel execution). وستُغطّى أساسيات البرمجة متعددة الأنوية في الفصل 14 من هذا الكتاب.
ويمكن لجميع هذه الأنواع المختلفة من أنظمة عتاد الحاسوب تشغيل نظام تشغيل واحد أو أكثر من الأنظمة عامة الغرض، مثل macOS أو Windows أو Unix. ويدير نظام التشغيل عام الغرض عتاد الحاسوب الأساسي ويوفّر واجهة للمستخدمين لتشغيل أي برنامج على الحاسوب. ومجتمعةً، تشكّل هذه الأنواع المختلفة من عتاد الحاسوب التي تشغّل أنظمة تشغيل عامة الغرض نظامَ حاسوب.
ما الذي ستتعلمه في هذا الكتاب
بحلول نهاية هذا الكتاب، ستعرف ما يلي:
كيف يشغّل الحاسوب برنامجاً: ستكون قادراً على وصف، بالتفصيل، كيف ينفّذ عتاد الحاسوب منخفض المستوى برنامجاً مكتوباً بلغة برمجة عالية المستوى. وتحديداً، ستعرف:
- كيف تُرمَّز بيانات البرنامج إلى ثنائي وكيف ينفّذ العتاد العمليات الحسابية عليها
- كيف يترجم المصرّف (compiler) برامج C إلى لغة التجميع (assembly) وشيفرة آلة ثنائية (ولغة التجميع هي الصورة المقروءة بشرياً من شيفرة الآلة الثنائية)
- كيف ينفّذ المعالج (CPU) تعليمات ثنائية على بيانات برنامج ثنائية، بدءاً من البوابات المنطقية الأساسية وصولاً إلى الدوائر المعقّدة التي تخزّن القيم وتنفّذ العمليات الحسابية وتتحكم في تنفيذ البرنامج
- كيف ينفّذ نظام التشغيل الواجهة التي تتيح للمستخدمين تشغيل البرامج على النظام وكيف يتحكم في تنفيذ البرامج على النظام أثناء إدارته لموارد النظام.
كيفية تقييم التكاليف النظامية (systems costs) المرتبطة بأداء البرنامج: يعمل البرنامج ببطء لأسباب عديدة. فقد يكون اختيار الخوارزمية سيئاً أو مجرد خيارات سيئة في كيفية استخدام برنامجك لموارد النظام. ستفهم التسلسل الهرمي للذاكرة (Memory Hierarchy) وآثاره على أداء البرنامج، والتكاليف النظامية المرتبطة بأداء البرنامج في نظام التشغيل. وستتعلم أيضاً بعض النصائح القيّمة لتحسين الشيفرة. وفي النهاية، ستكون قادراً على تصميم برامج تستخدم موارد النظام بكفاءة، وستعرف كيف تقيّم التكاليف النظامية المرتبطة بتنفيذ البرنامج.
كيف تستفيد من قوة الحواسيب المتوازية عبر البرمجة المتوازية: تكتسب الاستفادة من الحوسبة المتوازية أهمية في عالم اليوم متعدد الأنوية. وستتعلم كيفية استغلال الأنوية المتعددة في معالجك لجعل برنامجك يعمل أسرع. وستعرف أساسيات العتاد متعدد الأنوية، وتجريد الخيوط (thread) في نظام التشغيل، والقضايا المتعلقة بتنفيذ البرامج المتوازية متعددة الخيوط. وستكتسب خبرة في تصميم البرامج المتوازية وكتابة برامج متوازية متعددة الخيوط باستخدام مكتبة الخيوط POSIX (Pthreads). وسيكون لديك أيضاً مقدمة إلى أنواع أخرى من الأنظمة المتوازية ونماذج البرمجة المتوازية.
وعلى طول الطريق، ستتعلم أيضاً تفاصيل مهمة كثيرة أخرى عن أنظمة الحاسوب، بما في ذلك كيفية تصميمها وكيفية عملها. وستتعلم موضوعات مهمة في تصميم الأنظمة وتقنيات لتقييم أداء الأنظمة والبرامج. كما ستتقن مهارات مهمة، منها البرمجة بلغة C ولغة التجميع والتنقيح (debugging).
الشروع في هذا الكتاب
بضع ملاحظات عن اللغات وترميز الكتاب وتوصيات للبدء بقراءة هذا الكتاب:
لينكس ولغة C ومصرّف GNU
نستخدم لغة البرمجة C في الأمثلة عبر الكتاب. وC لغة برمجة عالية المستوى مثل Java وPython، لكنها أقل تجريداً من نظام الحاسوب الأساسي من كثير من اللغات عالية المستوى الأخرى. ونتيجةً لذلك، فإن C هي اللغة المفضّلة للبرمجين الذين يريدون تحكّماً أكبر في كيفية تنفيذ برنامجهم على نظام الحاسوب.
تُصرَّف الشيفرة والأمثلة في هذا الكتاب باستخدام مصرّف GNU للغة C (GCC) وتُشغَّل على نظام تشغيل Linux. ورغم أنه ليس نظام التشغيل السائد الأكثر شيوعاً، فإن Linux هو نظام التشغيل المهيمن على أنظمة الحوسبة الفائقة، ويمكن القول إنه نظام التشغيل الأكثر استخداماً لدى علماء الحاسوب.
كما أن Linux مجاني ومفتوح المصدر، وهو ما يسهم في استخدامه الشائع في هذه البيئات. وتمثّل المعرفة العملية بـ Linux ميزةً لكل دارسي الحوسبة. وبالمثل، يمكن القول إن GCC هو أكثر مصرّف C شيوعاً قيد الاستخدام اليوم. ونتيجةً لذلك، نستخدم Linux وGCC في أمثلتنا. ومع ذلك، فإن أنظمة Unix والمصرّفات الأخرى لها واجهات ووظائف مشابهة.
في هذا الكتاب، نشجعك على كتابة الأمثلة المذكورة بنفسك أثناء متابعتها. تظهر أوامر Linux في كتل كهذه:
$
يرمز $ إلى موجّه الأوامر. وإذا رأيت صندوقاً كهذا
$ uname -a
فهذا إشارة إلى أن تكتب uname -a في سطر الأوامر. احرص على ألا تكتب علامة $!
عادةً ما يظهر ناتج الأمر مباشرة بعد الأمر في قائمة سطر الأوامر. وكمثال، جرّب كتابة uname -a. ويختلف ناتج هذا الأمر من نظام لآخر. ويظهر أدناه ناتج نموذجي لنظام 64 بت.
$ uname -a
Linux Fawkes 4.4.0-171-generic #200-Ubuntu SMP Tue Dec 3 11:04:55 UTC 2019
x86_64 x86_64 x86_64 GNU/Linux
يطبع الأمر uname معلومات عن نظام بعينه. وتطبع العلامة -a كل المعلومات المهمة المرتبطة بالنظام بالترتيب التالي:
- اسم نواة النظام (في هذه الحالة Linux)
- اسم المضيف (hostname) للجهاز (مثل Fawkes)
- إصدار النواة (kernel release) (مثل 4.4.0-171-generic)
- نسخة النواة (kernel version) (مثل #200-Ubuntu SMP Tue Dec 3 11:04:55 UTC 2019)
- عتاد الآلة (مثل x86_64)
- نوع المعالج (مثل x86_64)
- النظام الأساسي للعتاد (مثل x86_64)
- اسم نظام التشغيل (مثل GNU/Linux)
يمكنك معرفة المزيد عن الأمر uname أو أي أمر Linux آخر بوضع man قبل الأمر، كما هو موضح هنا:
$ man uname
يعرض هذا الأمر صفحة الدليل المرتبطة بالأمر uname. وللخروج من هذه الواجهة، اضغط على المفتاح q.
وبينما تقع التغطية التفصيلية لـ Linux خارج نطاق هذا الكتاب، يمكن للقرّاء الحصول على مقدمة جيدة في الملحق 2 - استخدام UNIX على الإنترنت. وهناك أيضاً عدة موارد إلكترونية تمنح القرّاء نظرة عامة جيدة. ومن التوصيات كتاب «The Linux Command Line»1.
أنواع أخرى من الترميز والتنبيهات
إلى جانب سطر الأوامر ومقتطفات الشيفرة، نستخدم عدة أنواع أخرى من «التنبيهات» (callouts) لعرض المحتوى في هذا الكتاب.
النوع الأول هو الهامش (aside). والهوامش مخصّصة لتوفير سياق إضافي للنص، غالباً سياق تاريخي. وفيما يلي هامش نموذجي:
أصول Linux وGNU وحركة البرمجيات الحرة والمفتوحة المصدر (FOSS)
في عام 1969، طوّرت مختبرات AT&T Bell نظام تشغيل UNIX للاستخدام الداخلي. ورغم أنه كُتب في البداية بلغة التجميع، فقد أُعيدت كتابته بلغة C في عام 1973. وبسبب قضية مكافحة الاحتكار التي منعت مختبرات AT&T Bell من دخول صناعة الحوسبة، رخّصت المختبرات نظام تشغيل UNIX للجامعات مجاناً، مما أدى إلى اعتماده على نطاق واسع. وبحلول عام 1984، فصلت AT&T نفسها عن Bell Labs، وبدأت (بعد تحرّرها من قيودها السابقة) ببيع UNIX كمنتج تجاري، مما أثار غضب واستياء عدة أفراد في الأوساط الأكاديمية.
ورداً مباشراً على ذلك، طوّر ريتشارد ستالمان (وكان آنذاك طالباً في MIT) مشروع GNU («GNU ليس UNIX») في عام 1984، بهدف إنشاء نظام شبيه بـ UNIX مكوّن بالكامل من برمجيات حرة. وقد أنتج مشروع GNU عدة منتجات برمجية حرة ناجحة، منها مصرّف GNU للغة C (GCC)، ومحرّر GNU Emacs (بيئة تطوير شائعة)، ورخصة GNU العامة (GPL، أصل مبدأ «حقوق النسخ التشاركية» copyleft).
وفي عام 1992، أصدر لينوس تورفالدس، وكان آنذاك طالباً في جامعة هلسنكي، نظام تشغيل شبيه بـ UNIX كتبه بموجب رخصة GPL. وقد طُوّر نظام تشغيل Linux (وتُلفظ «Lin-nux» أو «Lee-nux» لأن الاسم الأول لينوس تورفالدس يُلفظ «Lee-nus») باستخدام أدوات GNU. واليوم، تُحزَّم أدوات GNU عادةً مع توزيعات Linux. وتعويذة نظام تشغيل Linux هي Tux، وهو بطريق. ويبدو أن تورفالدس تعرّض لعضة بطريق أثناء زيارته حديقة حيوان، فاختار البطريق تعويذةً لنظامه بعد أن تعلّق بهذه المخلوقات، ووصف إصابته بأنها «التهاب البطاريق» (penguinitis).
النوع الثاني من التنبيهات المستخدمة في هذا النص هو الملاحظة (note). وتُستخدم الملاحظات لإبراز معلومات مهمة، مثل استخدام أنواع معينة من الترميز أو اقتراحات حول كيفية استيعاب معلومات معينة. وتظهر ملاحظة نموذجية أدناه:
ملاحظة — كيف تُنجز القراءات في هذا الكتاب
بصفتك طالباً، من المهم أن تُنجز قراءات الكتاب المقرّر. لاحظ أننا نقول «أنجز» القراءات، لا مجرد «اقرأ» القراءات. فـ«قراءة» نص تعني عادةً استقبال الكلمات من الصفحة بشكل سلبي. ونشجع الطلاب على اتباع نهج أكثر نشاطاً. إذا رأيت مثالاً برمجياً، فجرّب كتابته! لا بأس إن كتبت شيئاً خاطئاً أو واجهت أخطاء؛ فتلك أفضل طريقة للتعلّم! في الحوسبة، الأخطاء ليست إخفاقات — إنها مجرد خبرة.
النوع الأخير من التنبيهات التي ينبغي للطلاب إيلاءه اهتماماً خاصاً هو التحذير (warning). ويستخدم المؤلفون التحذيرات لإبراز أمور تُعدّ «مزالق» شائعة أو سبباً شائعاً للانزعاج لدى طلابنا أنفسهم. ورغم أن التحذيرات قد لا تكون جميعها بالقيمة نفسها لجميع الطلاب، فإننا نوصي بمراجعتها لتجنّب المزالق الشائعة كلما أمكن. ويظهر تحذير نموذجي هنا:
تحذير — هذا الكتاب يحتوي على تلاعب لفظي
يحب المؤلفون (وخصوصاً المؤلف الأول) التلاعب اللفظي والمحاكاة الساخرة الموسيقية المتعلقة بالحوسبة (وليست بالضرورة جيدة). وقد تشمل ردود الفعل السلبية تجاه حس الدعابة لدى المؤلفين (دون حصر) تدوير العينين والتنهدات المكبوتة وضرب الجبهة.
إذا كنت مستعداً للبدء، فتابع إلى الفصل الأول حيث نغوص في عالم C الرائع. وإذا كنت تعرف بعض البرمجة بلغة C بالفعل، فقد ترغب في البدء بالفصل 4 عن التمثيل الثنائي، أو المتابعة بالبرمجة المتقدمة بلغة C في الفصل 2.
نأمل أن تستمتع برحلتك معنا!
المراجع
- ويليام شوتس. «The Linux Command Line»، LinuxCommand.org، https://linuxcommand.org/