🛡️ حارس البوابة: تشريح arch/gdt.rs
مرحباً بك في المنطقة العسكرية للنظام! جدول الواصفات العام (Global Descriptor Table - GDT) هو السور الفاصل بين النواة (Ring 0) وبرامج المستخدم (Ring 3). بدون هذا الملف، يمكن لأي برنامج بسيط أن يحذف النواة ويدمر الجهاز.
1. الهيكل الأساسي (كيف نقسم العالم؟)
الذاكرة لا تُعطى للبرامج بشكل عشوائي، بل تقسم إلى "مقاطع" (Segments):
lazy_static! {
static ref GDT: (GlobalDescriptorTable, Selectors) = {
let mut gdt = GlobalDescriptorTable::new();
// مقاطع النواة (Ring 0)
let kernel_code = gdt.add_entry(Descriptor::kernel_code_segment());
let kernel_data = gdt.add_entry(Descriptor::kernel_data_segment());
// مقاطع المستخدم (Ring 3)
let user_data = gdt.add_entry(Descriptor::user_data_segment());
let user_code = gdt.add_entry(Descriptor::user_code_segment());
// ...
};
}- Ring 0 (النواة): لها مقطع كود وبيانات بصلاحيات مطلقة.
- Ring 3 (المستخدم): لها مقطع كود وبيانات بصلاحيات مقيدة. المعالج يمنع هذه المقاطع من تنفيذ تعليمات خطيرة مثل
hltأوin/out.
2. اللغز الرياضي لتعليمة Sysret (سر مهم جداً!)
هل تلاحظ كيف رتبنا مقاطع المستخدم؟ وضعنا user_data قبل user_code! لماذا لم نضع الكود ثم البيانات مثل النواة؟
- الجواب (السر الهندسي): تعليمة العودة السريعة من النواة
sysretمصممة عتادياً من شركة AMD بطريقة غريبة جداً! فهي تفترض رياضياً أن مقطع (بيانات المستخدم) موجود تماماً قبل مقطع (كود المستخدم) في جدول الـ GDT. إذا قمت بعكس الترتيب، ستنهار النواة فوراً عند أول محاولة لبرنامج للخروج من النواة (General Protection Fault)!
3. مقطع الـ TSS (شبكة الأمان للقفز)
عندما يكون المعالج في وضع المستخدم (Ring 3) وتحدث مقاطعة (Interrupt)، كيف سيعرف المعالج أين مكدس النواة (Kernel Stack) لكي يقفز إليه دون أن تتداخل البيانات؟
let mut tss = TaskStateSegment::new();
tss.privilege_stack_table[0] = {
const STACK_SIZE: usize = 4096 * 5;
static mut STACK: [u8; STACK_SIZE] = [0; STACK_SIZE];
let stack_start = VirtAddr::from_ptr(unsafe { &STACK });
stack_start + STACK_SIZE // قمة المكدس (ينمو للأسفل)
};الـ TSS (Task State Segment) هو بمثابة "مظلة النجاة". نخبر المعالج هنا: "إذا قفزت من Ring 3 إلى Ring 0، أرجوك اترك مكدس المستخدم فوراً، واستخدم هذا المكدس الآمن الخاص بالنواة حصرياً".
🎯 الخلاصة
ملف gdt.rs ليس مجرد كود للذاكرة، بل هو الدستور الأمني الذي يفرضه المعالج، ونحن هنا نقوم بصياغته بدقة متناهية لتفادي أخطاء الـ Hardware القاتلة.