diff --git a/kernel/context/memory.rs b/kernel/context/memory.rs index f235e7c..c0b885b 100644 --- a/kernel/context/memory.rs +++ b/kernel/context/memory.rs @@ -1,3 +1,4 @@ +use arch::externs::memset; use arch::paging::{ActivePageTable, Page, PageIter, VirtualAddress}; use arch::paging::entry::EntryFlags; @@ -9,14 +10,14 @@ pub struct Memory { } impl Memory { - pub fn new(start: VirtualAddress, size: usize, flags: EntryFlags) -> Self { + pub fn new(start: VirtualAddress, size: usize, flags: EntryFlags, flush: bool, clear: bool) -> Self { let mut memory = Memory { start: start, size: size, flags: flags }; - memory.map(true); + memory.map(flush, clear); memory } @@ -35,7 +36,7 @@ impl Memory { Page::range_inclusive(start_page, end_page) } - pub fn map(&mut self, flush: bool) { + pub fn map(&mut self, flush: bool, clear: bool) { let mut active_table = unsafe { ActivePageTable::new() }; //TODO: Clear pages? @@ -45,6 +46,11 @@ impl Memory { active_table.flush(page); } } + + if clear { + assert!(flush); + unsafe { memset(self.start_address().get() as *mut u8, 0, self.size); } + } } pub fn unmap(&mut self, flush: bool) { @@ -71,39 +77,35 @@ impl Memory { self.flags = new_flags; } - pub fn resize(&mut self, new_size: usize, flush: bool) { + pub fn resize(&mut self, new_size: usize, flush: bool, clear: bool) { let mut active_table = unsafe { ActivePageTable::new() }; - //TODO: Clear pages? //TODO: Calculate page changes to minimize operations if new_size > self.size { let start_page = Page::containing_address(VirtualAddress::new(self.start.get() + self.size)); let end_page = Page::containing_address(VirtualAddress::new(self.start.get() + new_size - 1)); for page in Page::range_inclusive(start_page, end_page) { - //println!("Map {:X}", page.start_address().get()); if active_table.translate_page(page).is_none() { - //println!("Not found - mapping"); active_table.map(page, self.flags); if flush { active_table.flush(page); } - } else { - //println!("Found - skipping {:X}", page.start_address().get()); } } + + if clear { + assert!(flush); + unsafe { memset((self.start.get() + self.size) as *mut u8, 0, new_size - self.size); } + } } else if new_size < self.size { let start_page = Page::containing_address(VirtualAddress::new(self.start.get() + new_size)); let end_page = Page::containing_address(VirtualAddress::new(self.start.get() + self.size - 1)); for page in Page::range_inclusive(start_page, end_page) { - //println!("Unmap {:X}", page.start_address().get()); if active_table.translate_page(page).is_some() { - //println!("Found - unmapping"); active_table.unmap(page); if flush { active_table.flush(page); } - } else { - //println!("Not found - skipping {:X}", page.start_address().get()); } } } diff --git a/kernel/elf.rs b/kernel/elf.rs index 7f96914..d8200ad 100644 --- a/kernel/elf.rs +++ b/kernel/elf.rs @@ -10,7 +10,7 @@ use goblin::elf32::{header, program_header}; #[cfg(target_arch = "x86_64")] use goblin::elf64::{header, program_header}; -use arch::externs::{memcpy, memset}; +use arch::externs::memcpy; use arch::paging::{entry, VirtualAddress}; use arch::start::usermode; use context; @@ -70,7 +70,9 @@ impl<'a> Elf<'a> { let mut memory = context::memory::Memory::new( VirtualAddress::new(segment.p_vaddr as usize), segment.p_memsz as usize, - entry::NO_EXECUTE | entry::WRITABLE + entry::NO_EXECUTE | entry::WRITABLE, + true, + true ); unsafe { @@ -78,10 +80,6 @@ impl<'a> Elf<'a> { memcpy(segment.p_vaddr as *mut u8, (self.data.as_ptr() as usize + segment.p_offset as usize) as *const u8, segment.p_filesz as usize); - // Set BSS - memset((segment.p_vaddr + segment.p_filesz) as *mut u8, - 0, - (segment.p_memsz - segment.p_filesz) as usize); } let mut flags = entry::NO_EXECUTE | entry::USER_ACCESSIBLE; @@ -107,11 +105,10 @@ impl<'a> Elf<'a> { context.stack = Some(context::memory::Memory::new( VirtualAddress::new(stack_addr), stack_size, - entry::NO_EXECUTE | entry::WRITABLE | entry::USER_ACCESSIBLE + entry::NO_EXECUTE | entry::WRITABLE | entry::USER_ACCESSIBLE, + true, + true )); - - // Clear stack - unsafe { memset(stack_addr as *mut u8, 0, stack_size); } } // Go to usermode diff --git a/kernel/syscall/process.rs b/kernel/syscall/process.rs index 1abc61c..2307f1c 100644 --- a/kernel/syscall/process.rs +++ b/kernel/syscall/process.rs @@ -24,14 +24,16 @@ pub fn brk(address: usize) -> Result { } else if address >= arch::USER_HEAP_OFFSET { //TODO: out of memory errors if let Some(ref mut heap) = context.heap { - heap.resize(address - arch::USER_HEAP_OFFSET, true); + heap.resize(address - arch::USER_HEAP_OFFSET, true, true); return Ok(address); } context.heap = Some(context::memory::Memory::new( VirtualAddress::new(arch::USER_HEAP_OFFSET), address - arch::USER_HEAP_OFFSET, - entry::WRITABLE | entry::NO_EXECUTE | entry::USER_ACCESSIBLE + entry::WRITABLE | entry::NO_EXECUTE | entry::USER_ACCESSIBLE, + true, + true )); Ok(address)