feat: major memory managment & PMactor
This commit is contained in:
113
kernel/src/cpu/interrupts.rs
Normal file
113
kernel/src/cpu/interrupts.rs
Normal 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
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user