diff --git a/rust-toolchain.toml b/rust-toolchain.toml index 777a661f..c4ed95ba 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,3 +1,3 @@ [toolchain] -channel = "nightly-2024-09-01" +channel = "nightly-2024-12-01" components = ["rust-src", "llvm-tools-preview"] diff --git a/src/sys/idt.rs b/src/sys/idt.rs index 2509413e..949a5136 100644 --- a/src/sys/idt.rs +++ b/src/sys/idt.rs @@ -1,8 +1,9 @@ +use crate::sys::mem::phys_mem_offset; use crate::api::process::ExitCode; use crate::sys::process::Registers; use crate::{api, hlt_loop, sys}; -use core::arch::asm; +use core::arch::naked_asm; use lazy_static::lazy_static; use spin::Mutex; use x86_64::instructions::interrupts; @@ -132,9 +133,8 @@ extern "x86-interrupt" fn page_fault_handler( //debug!("EXCEPTION: PAGE FAULT ({:?}) at {:#X}", error_code, addr); let page_table = unsafe { sys::process::page_table() }; - let phys_mem_offset = unsafe { sys::mem::PHYS_MEM_OFFSET.unwrap() }; let mut mapper = unsafe { - OffsetPageTable::new(page_table, VirtAddr::new(phys_mem_offset)) + OffsetPageTable::new(page_table, VirtAddr::new(phys_mem_offset())) }; if error_code.contains(PageFaultErrorCode::CAUSED_BY_WRITE) { @@ -213,7 +213,7 @@ macro_rules! wrap { ($fn: ident => $w:ident) => { #[naked] pub unsafe extern "sysv64" fn $w() { - asm!( + naked_asm!( "push rax", "push rcx", "push rdx", @@ -237,8 +237,7 @@ macro_rules! wrap { "pop rcx", "pop rax", "iretq", - sym $fn, - options(noreturn) + sym $fn ); } }; diff --git a/src/sys/mem/mod.rs b/src/sys/mem/mod.rs index df753c5e..2ce964c5 100644 --- a/src/sys/mem/mod.rs +++ b/src/sys/mem/mod.rs @@ -8,14 +8,17 @@ pub use phys::{phys_addr, PhysBuf}; use crate::sys; use bootloader::bootinfo::{BootInfo, MemoryMap, MemoryRegionType}; use core::sync::atomic::{AtomicUsize, Ordering}; +use spin::Once; use x86_64::structures::paging::{ FrameAllocator, OffsetPageTable, PhysFrame, Size4KiB, Translate, }; use x86_64::{PhysAddr, VirtAddr}; -pub static mut PHYS_MEM_OFFSET: Option = None; -static mut MEMORY_MAP: Option<&MemoryMap> = None; -static mut MAPPER: Option> = None; +#[allow(static_mut_refs)] +static mut MAPPER: Once> = Once::new(); + +static PHYS_MEM_OFFSET: Once = Once::new(); +static MEMORY_MAP: Once<&MemoryMap> = Once::new(); static MEMORY_SIZE: AtomicUsize = AtomicUsize::new(0); static ALLOCATED_FRAMES: AtomicUsize = AtomicUsize::new(0); @@ -56,24 +59,29 @@ pub fn init(boot_info: &'static BootInfo) { log!("RAM {} MB", memory_size >> 20); MEMORY_SIZE.store(memory_size as usize, Ordering::Relaxed); - let phys_mem_offset = boot_info.physical_memory_offset; - - unsafe { PHYS_MEM_OFFSET.replace(phys_mem_offset) }; - unsafe { MEMORY_MAP.replace(&boot_info.memory_map) }; + #[allow(static_mut_refs)] unsafe { - MAPPER.replace(OffsetPageTable::new( + MAPPER.call_once(|| OffsetPageTable::new( paging::active_page_table(), - VirtAddr::new(phys_mem_offset), + VirtAddr::new(boot_info.physical_memory_offset), )) }; + PHYS_MEM_OFFSET.call_once(|| boot_info.physical_memory_offset); + MEMORY_MAP.call_once(|| &boot_info.memory_map); + heap::init_heap().expect("heap initialization failed"); sys::idt::clear_irq_mask(1); } +pub fn phys_mem_offset() -> u64 { + unsafe { *PHYS_MEM_OFFSET.get_unchecked() } +} + pub fn mapper() -> &'static mut OffsetPageTable<'static> { - unsafe { MAPPER.as_mut().unwrap() } + #[allow(static_mut_refs)] + unsafe { MAPPER.get_mut_unchecked() } } pub fn memory_size() -> usize { @@ -89,10 +97,7 @@ pub fn memory_free() -> usize { } pub fn phys_to_virt(addr: PhysAddr) -> VirtAddr { - let phys_mem_offset = unsafe { - PHYS_MEM_OFFSET.unwrap() - }; - VirtAddr::new(addr.as_u64() + phys_mem_offset) + VirtAddr::new(addr.as_u64() + phys_mem_offset()) } pub fn virt_to_phys(addr: VirtAddr) -> Option { @@ -135,5 +140,5 @@ unsafe impl FrameAllocator for BootInfoFrameAllocator { } pub fn frame_allocator() -> BootInfoFrameAllocator { - unsafe { BootInfoFrameAllocator::init(MEMORY_MAP.unwrap()) } + unsafe { BootInfoFrameAllocator::init(MEMORY_MAP.get_unchecked()) } } diff --git a/src/sys/process.rs b/src/sys/process.rs index 8fba4be1..8723523e 100644 --- a/src/sys/process.rs +++ b/src/sys/process.rs @@ -3,6 +3,7 @@ use crate::sys::console::Console; use crate::sys::fs::{Device, Resource}; use crate::sys; use crate::sys::gdt::GDT; +use crate::sys::mem::phys_mem_offset; use alloc::boxed::Box; use alloc::collections::btree_map::BTreeMap; @@ -348,9 +349,8 @@ impl Process { *user_page = kernel_page.clone(); } - let phys_mem_offset = unsafe { sys::mem::PHYS_MEM_OFFSET.unwrap() }; let mut mapper = unsafe { - OffsetPageTable::new(page_table, VirtAddr::new(phys_mem_offset)) + OffsetPageTable::new(page_table, VirtAddr::new(phys_mem_offset())) }; let proc_size = MAX_PROC_SIZE as u64; @@ -424,9 +424,8 @@ impl Process { // Switch to user mode and execute the program fn exec(&self, args_ptr: usize, args_len: usize) { let page_table = unsafe { sys::process::page_table() }; - let phys_mem_offset = unsafe { sys::mem::PHYS_MEM_OFFSET.unwrap() }; let mut mapper = unsafe { - OffsetPageTable::new(page_table, VirtAddr::new(phys_mem_offset)) + OffsetPageTable::new(page_table, VirtAddr::new(phys_mem_offset())) }; // Copy args to user memory @@ -496,11 +495,8 @@ impl Process { let page_table = unsafe { sys::mem::create_page_table(self.page_table_frame) }; - let phys_mem_offset = unsafe { - sys::mem::PHYS_MEM_OFFSET.unwrap() - }; unsafe { - OffsetPageTable::new(page_table, VirtAddr::new(phys_mem_offset)) + OffsetPageTable::new(page_table, VirtAddr::new(phys_mem_offset())) } }