Skip to content

⏳ متحف التاريخ: تشريح sched/user_init.rs ​

هذا الملف هو بمثابة قطعة أثرية من أيام "الإصدار الخامس" (Milestone 05). اليوم، نستخدم محمل الـ ELF المتطور. ولكن قديماً، كيف أثبتنا أن القفز من Ring 0 إلى Ring 3 يعمل؟

1. حقن الأسمبلي المباشر (Machine Code Injection) ​

بما أنه لم يكن لدينا قرص صلب لقراءة البرامج، قمنا بكتابة البرنامج الأول بالبايتات الخام (Hex):

rust
let code: &[u8] = &[
    0x48, 0xC7, 0xC0, 0x01, 0x00, 0x00, 0x00, // mov rax, 1 (SYS_WRITE)
    0x0F, 0x05,                               // syscall
    // ...
];
core::ptr::copy_nonoverlapping(code.as_ptr(), base, code.len()); // لصقه في الذاكرة!

2. خدعة العودة من المقاطعة (Iretq Jump) ​

الطريقة الوحيدة للانتقال للمستخدم היא إقناع المعالج أننا كنا أصلاً في وضع المستخدم وتم مقاطعتنا! نقوم بترتيب المكدس وتزوير مسجلات وضع المستخدم، ثم نطلق تعليمة iretq:

rust
unsafe fn jump_to_ring3(entry: u64, user_stack: u64) -> ! {
    core::arch::asm!(
        "push {ss}",       // مقطع البيانات للمستخدم
        "push {rsp_user}", // مكدس المستخدم
        "push {rflags}",   // أعلام المعالج
        "push {cs}",       // مقطع الكود للمستخدم
        "push {rip_user}", // عنوان بداية برنامجنا بالـ Hex
        "iretq",           // انطلق!
        // ...
    );
}

هذا الملف يوثق لحظة "الولادة" الحقيقية لفضاء المستخدم في QOS!

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