feat: major memory managment & PMactor

This commit is contained in:
Faynot
2026-06-26 14:33:29 +03:00
parent ceedd21aee
commit 3f87a93d52
14 changed files with 2347 additions and 162 deletions

View File

@@ -0,0 +1,113 @@
use core::arch::global_asm;
use core::arch::asm;
use crate::mem::vmm::KERNEL_SPACE; // Оставили только один импорт
use crate::mem::address::VirtAddr;
// Глобальная статическая таблица дескрипторов прерываний (IDT)
pub static mut IDT: crate::cpu::idt::InterruptDescriptorTable = crate::cpu::idt::InterruptDescriptorTable::new();
// Низкоуровневый ассемблерный трамплин (Context Save & Restore)
global_asm!(
".global page_fault_stub",
"page_fault_stub:",
"push rax",
"push rcx",
"push rdx",
"push rbx",
"push rbp",
"push rsi",
"push rdi",
"push r8",
"push r9",
"push r10",
"push r11",
"push r12",
"push r13",
"push r14",
"push r15",
"mov rdi, [rsp + 15*8]",
"call rust_page_fault_handler",
"pop r15",
"pop r14",
"pop r13",
"pop r12",
"pop r11",
"pop r10",
"pop r9",
"pop r8",
"pop rdi",
"pop rsi",
"pop rbp",
"pop rbx",
"pop rdx",
"pop rcx",
"pop rax",
"add rsp, 8",
"iretq"
);
unsafe extern "C" {
fn page_fault_stub();
}
pub fn init_idt() {
unsafe {
let idt_mut_ptr = core::ptr::addr_of_mut!(IDT);
(*idt_mut_ptr).set_handler(14, page_fault_stub as u64);
let idt_static_ref: &'static crate::cpu::idt::InterruptDescriptorTable = &*core::ptr::addr_of!(IDT);
idt_static_ref.load();
}
}
pub fn process_deferred_mmu_events() {
let mut vmm_guard = KERNEL_SPACE.lock();
if let Some(space) = vmm_guard.as_mut() {
space.process_pending_revocations();
}
}
#[unsafe(no_mangle)]
pub extern "C" fn rust_page_fault_handler(error_code: u64) {
let fault_addr: u64;
unsafe {
asm!("mov {}, cr2", out(reg) fault_addr, options(nomem, nostack, preserves_flags));
}
let write = (error_code & 0x2) != 0;
let present = (error_code & 0x1) != 0;
let virt_addr = VirtAddr(fault_addr);
// 1. Сначала применяем все отложенные отзывы прав из других Actor'ов (чтобы избежать Deadlock)
process_deferred_mmu_events();
// 2. Теперь захватываем VMM для обработки текущего сбоя
let mut vmm_guard = KERNEL_SPACE.lock();
if let Some(space) = vmm_guard.as_mut() {
match space.handle_fault(virt_addr, write) {
Ok(_) => return,
Err(e) => {
panic!(
"KERNEL PANIC: Необработанный сбой виртуальной памяти (Page Fault)!\n\
Адрес: {:#X}\n\
Режим: {}\n\
Присутствие: {}\n\
Причина VMM: {:?}",
fault_addr,
if write { "WRITE" } else { "READ" },
if present { "YES (Protection Violation)" } else { "NO (Not Present)" },
e
);
}
}
} else {
panic!(
"KERNEL PANIC: Критический Page Fault до аллокации глобального KERNEL_SPACE!\n\
Адрес сбоя: {:#X}",
fault_addr
);
}
}