From 41eaae9fbe638292efb192f89c3bb4df6fbaba4f Mon Sep 17 00:00:00 2001 From: Vincent Ollivier Date: Mon, 11 Apr 2022 19:06:16 +0200 Subject: [PATCH] Fix issues with process alloc (#327) * Fix off by one errors * Simplify phys_addr * Add offset to frame allocator * Change code_addr * Remove unknown commands * Use allocated frames counter * Remove debug code --- src/sys/allocator.rs | 9 ++++----- src/sys/mem.rs | 16 +++++++++------- src/sys/process.rs | 5 +++-- src/usr/shell.rs | 6 +++--- 4 files changed, 19 insertions(+), 17 deletions(-) diff --git a/src/sys/allocator.rs b/src/sys/allocator.rs index 127e96369..095e945ff 100644 --- a/src/sys/allocator.rs +++ b/src/sys/allocator.rs @@ -49,7 +49,7 @@ pub fn alloc_pages(addr: u64, size: u64) { let flags = PageTableFlags::PRESENT | PageTableFlags::WRITABLE | PageTableFlags::USER_ACCESSIBLE; let pages = { let start_page = Page::containing_address(VirtAddr::new(addr)); - let end_page = Page::containing_address(VirtAddr::new(addr + size)); + let end_page = Page::containing_address(VirtAddr::new(addr + size - 1)); Page::range_inclusive(start_page, end_page) }; for page in pages { @@ -71,7 +71,7 @@ pub fn free_pages(addr: u64, size: u64) { let mut mapper = unsafe { sys::mem::mapper(VirtAddr::new(sys::mem::PHYS_MEM_OFFSET)) }; let pages: PageRangeInclusive = { let start_page = Page::containing_address(VirtAddr::new(addr)); - let end_page = Page::containing_address(VirtAddr::new(addr + size)); + let end_page = Page::containing_address(VirtAddr::new(addr + size - 1)); Page::range_inclusive(start_page, end_page) }; for page in pages { @@ -109,9 +109,8 @@ impl PhysBuf { } } -fn phys_addr(ptr: &u8) -> u64 { - let rx_ptr = ptr as *const u8; - let virt_addr = VirtAddr::new(rx_ptr as u64); +pub fn phys_addr(ptr: *const u8) -> u64 { + let virt_addr = VirtAddr::new(ptr as u64); let phys_addr = sys::mem::virt_to_phys(virt_addr).unwrap(); phys_addr.as_u64() } diff --git a/src/sys/mem.rs b/src/sys/mem.rs index b1a8da905..b04f57f21 100644 --- a/src/sys/mem.rs +++ b/src/sys/mem.rs @@ -1,6 +1,6 @@ use crate::sys; use bootloader::bootinfo::{BootInfo, MemoryMap, MemoryRegionType}; -use core::sync::atomic::{AtomicU64, Ordering}; +use core::sync::atomic::{AtomicU64, AtomicUsize, Ordering}; use x86_64::instructions::interrupts; use x86_64::structures::paging::{FrameAllocator, OffsetPageTable, PageTable, PhysFrame, Size4KiB, Translate}; use x86_64::{PhysAddr, VirtAddr}; @@ -10,6 +10,8 @@ pub static mut PHYS_MEM_OFFSET: u64 = 0; pub static mut MEMORY_MAP: Option<&MemoryMap> = None; pub static MEMORY_SIZE: AtomicU64 = AtomicU64::new(0); +static ALLOCATED_FRAMES: AtomicUsize = AtomicUsize::new(0); + pub fn init(boot_info: &'static BootInfo) { interrupts::without_interrupts(|| { let mut memory_size = 0; @@ -17,7 +19,7 @@ pub fn init(boot_info: &'static BootInfo) { let start_addr = region.range.start_addr(); let end_addr = region.range.end_addr(); memory_size += end_addr - start_addr; - log!("MEM [{:#016X}-{:#016X}] {:?}\n", start_addr, end_addr, region.region_type); + log!("MEM [{:#016X}-{:#016X}] {:?}\n", start_addr, end_addr - 1, region.region_type); } log!("MEM {} KB\n", memory_size >> 10); MEMORY_SIZE.store(memory_size, Ordering::Relaxed); @@ -63,13 +65,12 @@ unsafe fn active_level_4_table(physical_memory_offset: VirtAddr) -> &'static mut } pub struct BootInfoFrameAllocator { - memory_map: &'static MemoryMap, - next: usize, + memory_map: &'static MemoryMap } impl BootInfoFrameAllocator { pub unsafe fn init(memory_map: &'static MemoryMap) -> Self { - BootInfoFrameAllocator { memory_map, next: 0 } + BootInfoFrameAllocator { memory_map } } fn usable_frames(&self) -> impl Iterator { @@ -83,10 +84,11 @@ impl BootInfoFrameAllocator { unsafe impl FrameAllocator for BootInfoFrameAllocator { fn allocate_frame(&mut self) -> Option { + let next = ALLOCATED_FRAMES.fetch_add(1, Ordering::SeqCst); + // FIXME: creating an iterator for each allocation is very slow if // the heap is larger than a few megabytes. - let frame = self.usable_frames().nth(self.next); - self.next += 1; + let frame = self.usable_frames().nth(next); frame } } diff --git a/src/sys/process.rs b/src/sys/process.rs index 53d78a724..ea9e3972e 100644 --- a/src/sys/process.rs +++ b/src/sys/process.rs @@ -192,7 +192,7 @@ use crate::sys::gdt::GDT; use core::sync::atomic::AtomicU64; use x86_64::VirtAddr; -static CODE_ADDR: AtomicU64 = AtomicU64::new((sys::allocator::HEAP_START as u64) + (16 << 20)); // 16 MB +static CODE_ADDR: AtomicU64 = AtomicU64::new((sys::allocator::HEAP_START as u64) + (16 << 20)); const PAGE_SIZE: u64 = 4 * 1024; #[repr(align(8), C)] @@ -253,8 +253,9 @@ impl Process { } fn create(bin: &[u8]) -> Result { - let code_size = 1024 * PAGE_SIZE; + let code_size = 1 * PAGE_SIZE; let code_addr = CODE_ADDR.fetch_add(code_size, Ordering::SeqCst); + sys::allocator::alloc_pages(code_addr, code_size); let mut entry_point = 0; diff --git a/src/usr/shell.rs b/src/usr/shell.rs index 4567c63f2..dc29c0348 100644 --- a/src/usr/shell.rs +++ b/src/usr/shell.rs @@ -213,7 +213,7 @@ pub fn exec(cmd: &str) -> ExitCode { let res = match args[0] { "" => ExitCode::CommandSuccessful, - "a" | "alias" => ExitCode::CommandUnknown, + "a" => ExitCode::CommandUnknown, "b" => ExitCode::CommandUnknown, "c" | "copy" => usr::copy::main(&args), "d" | "del" | "delete" => usr::delete::main(&args), @@ -222,8 +222,8 @@ pub fn exec(cmd: &str) -> ExitCode { "g" | "go" | "goto" => change_dir(&args), "h" | "help" => usr::help::main(&args), "i" => ExitCode::CommandUnknown, - "j" | "jump" => ExitCode::CommandUnknown, - "k" | "kill" => ExitCode::CommandUnknown, + "j" => ExitCode::CommandUnknown, + "k" => ExitCode::CommandUnknown, "l" | "list" => usr::list::main(&args), "m" | "move" => usr::r#move::main(&args), "n" => ExitCode::CommandUnknown,