Skip to content

المرحلة الثالثة: الذاكرة الافتراضية ومخصص الكومة ​

هذه المرحلة تُمثّل نقطة تحول جوهرية في تطوير النواة. قبلها، كنا محدودين بالمتغيرات الثابتة (static) والمكدس (stack) فقط. الآن، النواة تملك ذاكرة ديناميكية كاملة — تستطيع إنشاء هياكل بيانات بأحجام متغيرة في وقت التشغيل تماماً كأي برنامج Rust عادي.

ما تم إنجازه: ​

1. مدير الذاكرة الافتراضية (VMM - kernel/mm/vmm.rs) ​

  • بناء نظام إدارة 4-Level Paging من الصفر في Rust.
  • تنفيذ map_page(virt, phys, flags) التي تمشي في الجداول الأربعة (PML4 → PDP → PD → PT) وتنشئ جداولاً جديدة عند الحاجة باستخدام alloc_frame() من PMM.
  • تنفيذ unmap_page(virt) مع تحديث TLB عبر تعليمة invlpg.
  • القاعدة الذهبية: كل إطار مخصص لجدول صفحات يُصفّر فوراً (zero_frame) قبل الاستخدام لمنع بيانات عشوائية قديمة من أن تُفسّر كإدخالات صحيحة (Present=1) مما قد يسبب corruption صامت.

2. مخصص الكومة (Heap Allocator - kernel/mm/heap.rs) ​

  • الخوارزمية: Linked-List Free-List — كل كتلة حرة تحتوي حجمها ومؤشراً للكتلة التالية.
  • دمج الكتل (Coalescing): عند تحرير كتلة، يُفحص الجيران. إذا كانوا متجاورين بالذاكرة، يُدمجون لكتلة أكبر واحدة. هذا يمنع تفتت الذاكرة (fragmentation).
  • حماية المقاطعات (Interrupt Safety): المخصص محمي بطبقتين:
    1. spin::Mutex لمنع التزامن بين الخيوط
    2. cli/sti (تعطيل/تفعيل المقاطعات) لمنع إعادة الدخول (reentrancy) إذا حاول معالج مقاطعة تخصيص ذاكرة أثناء عملية تخصيص جارية.
  • منطقة الكومة: تبدأ عند 0x4444_4444_0000 بحجم 256KB (64 صفحة)، مصممة لتكون قابلة للتوسعة بدون إعادة تصميم.

3. تفعيل alloc crate ​

  • إضافة "alloc" إلى build-std في إعدادات Cargo.
  • تسجيل المخصص عبر #[global_allocator].
  • تنفيذ #[alloc_error_handler] لعرض تفاصيل الخطأ عند فشل التخصيص.

النتيجة النهائية ​

النواة تعمل بكامل قدراتها الديناميكية:

  • Vec::push(1, 2, 3) → [1, 2, 3] ✅
  • Box::new(42) → 42 ✅
  • String::from("QOS") → "QOS" ✅

الذاكرة الحرة بعد تهيئة الكومة: 123 ميغابايت (31677 إطار) من أصل 128 ميغابايت.

تم تطويره بحب بواسطة مجتمع Qtoom.