المرحلة الثالثة: الذاكرة الافتراضية ومخصص الكومة
هذه المرحلة تُمثّل نقطة تحول جوهرية في تطوير النواة. قبلها، كنا محدودين بالمتغيرات الثابتة (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): المخصص محمي بطبقتين:
spin::Mutexلمنع التزامن بين الخيوط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 ميغابايت.