From 6a5c32fa6ae8ec34e3e5b44d7e5a78ded8fe729b Mon Sep 17 00:00:00 2001 From: salmonik Date: Fri, 31 Jul 2026 02:58:31 +0200 Subject: restructure: rsnix kernel + shell crate + rsdos entry point MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Architecture: rs-dos/ (workspace root, was raisernics/) ├── rsnix/ — kernel lib crate (uefi, serial, gop, ps2, interrupts, memory) ├── shell/ — shell lib crate (prompt, commands, line input) ├── rsdos/ — binary crate (efi_main, init, panic handler) └── rsboot/ — future git submodule No functional changes — boots to shell prompt identically. Version auto-pulled from Cargo.toml via env!("CARGO_PKG_VERSION"). --- src/memory.rs | 196 ---------------------------------------------------------- 1 file changed, 196 deletions(-) delete mode 100644 src/memory.rs (limited to 'src/memory.rs') diff --git a/src/memory.rs b/src/memory.rs deleted file mode 100644 index d223f69..0000000 --- a/src/memory.rs +++ /dev/null @@ -1,196 +0,0 @@ -use crate::uefi::*; -use core::alloc::{GlobalAlloc, Layout}; -use core::mem; -use core::ptr; - -const MAX_MAP_ENTRIES: usize = 512; - -static mut MEMORY_MAP: [MemoryDescriptor; MAX_MAP_ENTRIES] = unsafe { mem::zeroed() }; -static mut MAP_ENTRIES: usize = 0; - -/// The map key returned by GetMemoryMap, needed for ExitBootServices. -static mut MAP_KEY: usize = 0; - -/// Static working buffer for GetMemoryMap (64 KB, way more than enough). -/// Lives in .bss; no pool allocation, so no map-key staleness. -static mut MAP_WORK_BUF: [u8; 65536] = [0u8; 65536]; - -// --------------------------------------------------------------------------- -// Bump allocator — no deallocation, just pointer advancement. -// Used as Rust's #[global_allocator] once the heap region is set up. -// --------------------------------------------------------------------------- -struct BumpAllocator; - -unsafe impl Sync for BumpAllocator {} - -unsafe impl GlobalAlloc for BumpAllocator { - unsafe fn alloc(&self, layout: Layout) -> *mut u8 { - let align = layout.align().max(16); - let size = layout.size(); - unsafe { - let a = (HEAP_CURSOR + align - 1) & !(align - 1); - let e = a + size; - if e > HEAP_END || e < a { - return ptr::null_mut(); - } - HEAP_CURSOR = e; - a as *mut u8 - } - } - - unsafe fn dealloc(&self, _ptr: *mut u8, _layout: Layout) { - // Bump allocator — cannot free individual allocations. - // Memory is reclaimed on reboot. Good enough for now. - unsafe { - core::ptr::read_volatile(&_ptr); - } - let _ = _layout; - } -} - -#[global_allocator] -static ALLOCATOR: BumpAllocator = BumpAllocator; - -/// Heap bump allocator bounds (`static mut` accessed only inside -/// `GlobalAlloc` impl, which is already `unsafe`). -static mut HEAP_START: usize = 0; -static mut HEAP_END: usize = 0; -static mut HEAP_CURSOR: usize = 0; - -/// Capture the UEFI memory map into the static buffer. Uses a pre-allocated -/// .bss working buffer so no pool allocation (and thus no memory-map change) -/// occurs between GetMemoryMap and ExitBootServices. -pub fn capture_memory_map(bs: &BootServices) -> Result { - let mut map_key: usize = 0; - let mut desc_size: usize = 0; - let mut desc_ver: u32 = 0; - - // Probe with null to get required size + descriptor size - let mut buf_size: usize = 0; - let status = unsafe { - (bs.get_memory_map)( - &mut buf_size, - ptr::null_mut(), - &mut map_key, - &mut desc_size, - &mut desc_ver, - ) - }; - if status != EFI_BUFFER_TOO_SMALL { - // Fallback: allocate a sensible size - buf_size = 64 * 1024; - } - if desc_size == 0 { - desc_size = mem::size_of::(); - } - - // Round up to desc_size alignment - let buf_size = (buf_size + desc_size - 1) / desc_size * desc_size; - - // If our static buffer is too small, fall back to pool (rare) - if buf_size > unsafe { MAP_WORK_BUF.len() } { - return Err(EFI_BUFFER_TOO_SMALL); - } - - let mut actual_size = buf_size; - let status = unsafe { - (bs.get_memory_map)( - &mut actual_size, - &raw mut MAP_WORK_BUF[0] as *mut MemoryDescriptor, - &mut map_key, - &mut desc_size, - &mut desc_ver, - ) - }; - - if status == EFI_BUFFER_TOO_SMALL { - // The map grew between the probe and the real call. Try a larger - // static buffer (can't grow here without pool, so return error to - // let the caller retry if they can allocate pool). - // For our 64 KB buffer this should never happen on OVMF. - return Err(EFI_BUFFER_TOO_SMALL); - } - if status != EFI_SUCCESS { - return Err(status); - } - - // Copy descriptors into our indexed array - let count = actual_size / desc_size; - let count = count.min(MAX_MAP_ENTRIES); - unsafe { - for i in 0..count { - let p = (&raw const MAP_WORK_BUF[..]) as *const u8; - let off = i * desc_size; - let src = p.add(off) as *const MemoryDescriptor; - MEMORY_MAP[i] = ptr::read(src); - } - MAP_ENTRIES = count; - MAP_KEY = map_key; - } - - // Do NOT free anything — the static buffer stays. Map key is still - // valid because no pool allocation/free happened after GetMemoryMap. - - init_bump_allocator(); - Ok(map_key) -} - -/// Retry ExitBootServices with a fresh memory map. -pub fn refresh_and_exit(bs: &BootServices, image_handle: Handle) -> Result { - let key = capture_memory_map(bs)?; - let status = unsafe { (bs.exit_boot_services)(image_handle, key) }; - if status == EFI_SUCCESS { - Ok(key) - } else { - Err(status) - } -} - -fn init_bump_allocator() { - unsafe { - let mut best_start = 0usize; - let mut best_size = 0usize; - for i in 0..MAP_ENTRIES { - let d = &MEMORY_MAP[i]; - if d.kind == MEMORY_TYPE_CONVENTIONAL { - let sz = d.number_of_pages as usize * 4096; - if sz > best_size { - best_start = d.physical_start as usize; - best_size = sz; - } - } - } - if best_size > 2 * 1024 * 1024 { - let s = best_start + 2 * 1024 * 1024; - let e = best_start + best_size; - if s < e { - HEAP_START = s; - HEAP_END = e; - HEAP_CURSOR = s; - } - } - } -} - -#[allow(dead_code)] -pub fn allocate(size: usize) -> *mut u8 { - unsafe { - let a = (HEAP_CURSOR + 15) & !15; - let e = a + size; - if e > HEAP_END || e < a { - return ptr::null_mut(); - } - HEAP_CURSOR = e; - a as *mut u8 - } -} - -#[allow(dead_code)] -pub fn get_map() -> (&'static [MemoryDescriptor], usize) { - unsafe { - ( - core::slice::from_raw_parts(&MEMORY_MAP[0], MAP_ENTRIES), - MAP_KEY, - ) - } -} -- cgit v1.2.3