Clear memory on demand
This commit is contained in:
parent
9796d21906
commit
aa2915001e
|
@ -1,3 +1,4 @@
|
||||||
|
use arch::externs::memset;
|
||||||
use arch::paging::{ActivePageTable, Page, PageIter, VirtualAddress};
|
use arch::paging::{ActivePageTable, Page, PageIter, VirtualAddress};
|
||||||
use arch::paging::entry::EntryFlags;
|
use arch::paging::entry::EntryFlags;
|
||||||
|
|
||||||
|
@ -9,14 +10,14 @@ pub struct Memory {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl 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 {
|
let mut memory = Memory {
|
||||||
start: start,
|
start: start,
|
||||||
size: size,
|
size: size,
|
||||||
flags: flags
|
flags: flags
|
||||||
};
|
};
|
||||||
|
|
||||||
memory.map(true);
|
memory.map(flush, clear);
|
||||||
|
|
||||||
memory
|
memory
|
||||||
}
|
}
|
||||||
|
@ -35,7 +36,7 @@ impl Memory {
|
||||||
Page::range_inclusive(start_page, end_page)
|
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() };
|
let mut active_table = unsafe { ActivePageTable::new() };
|
||||||
|
|
||||||
//TODO: Clear pages?
|
//TODO: Clear pages?
|
||||||
|
@ -45,6 +46,11 @@ impl Memory {
|
||||||
active_table.flush(page);
|
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) {
|
pub fn unmap(&mut self, flush: bool) {
|
||||||
|
@ -71,39 +77,35 @@ impl Memory {
|
||||||
self.flags = new_flags;
|
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() };
|
let mut active_table = unsafe { ActivePageTable::new() };
|
||||||
|
|
||||||
//TODO: Clear pages?
|
|
||||||
//TODO: Calculate page changes to minimize operations
|
//TODO: Calculate page changes to minimize operations
|
||||||
if new_size > self.size {
|
if new_size > self.size {
|
||||||
let start_page = Page::containing_address(VirtualAddress::new(self.start.get() + 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));
|
let end_page = Page::containing_address(VirtualAddress::new(self.start.get() + new_size - 1));
|
||||||
for page in Page::range_inclusive(start_page, end_page) {
|
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() {
|
if active_table.translate_page(page).is_none() {
|
||||||
//println!("Not found - mapping");
|
|
||||||
active_table.map(page, self.flags);
|
active_table.map(page, self.flags);
|
||||||
if flush {
|
if flush {
|
||||||
active_table.flush(page);
|
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 {
|
} else if new_size < self.size {
|
||||||
let start_page = Page::containing_address(VirtualAddress::new(self.start.get() + new_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));
|
let end_page = Page::containing_address(VirtualAddress::new(self.start.get() + self.size - 1));
|
||||||
for page in Page::range_inclusive(start_page, end_page) {
|
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() {
|
if active_table.translate_page(page).is_some() {
|
||||||
//println!("Found - unmapping");
|
|
||||||
active_table.unmap(page);
|
active_table.unmap(page);
|
||||||
if flush {
|
if flush {
|
||||||
active_table.flush(page);
|
active_table.flush(page);
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
//println!("Not found - skipping {:X}", page.start_address().get());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,7 @@ use goblin::elf32::{header, program_header};
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
use goblin::elf64::{header, program_header};
|
use goblin::elf64::{header, program_header};
|
||||||
|
|
||||||
use arch::externs::{memcpy, memset};
|
use arch::externs::memcpy;
|
||||||
use arch::paging::{entry, VirtualAddress};
|
use arch::paging::{entry, VirtualAddress};
|
||||||
use arch::start::usermode;
|
use arch::start::usermode;
|
||||||
use context;
|
use context;
|
||||||
|
@ -70,7 +70,9 @@ impl<'a> Elf<'a> {
|
||||||
let mut memory = context::memory::Memory::new(
|
let mut memory = context::memory::Memory::new(
|
||||||
VirtualAddress::new(segment.p_vaddr as usize),
|
VirtualAddress::new(segment.p_vaddr as usize),
|
||||||
segment.p_memsz as usize,
|
segment.p_memsz as usize,
|
||||||
entry::NO_EXECUTE | entry::WRITABLE
|
entry::NO_EXECUTE | entry::WRITABLE,
|
||||||
|
true,
|
||||||
|
true
|
||||||
);
|
);
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
|
@ -78,10 +80,6 @@ impl<'a> Elf<'a> {
|
||||||
memcpy(segment.p_vaddr as *mut u8,
|
memcpy(segment.p_vaddr as *mut u8,
|
||||||
(self.data.as_ptr() as usize + segment.p_offset as usize) as *const u8,
|
(self.data.as_ptr() as usize + segment.p_offset as usize) as *const u8,
|
||||||
segment.p_filesz as usize);
|
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;
|
let mut flags = entry::NO_EXECUTE | entry::USER_ACCESSIBLE;
|
||||||
|
@ -107,11 +105,10 @@ impl<'a> Elf<'a> {
|
||||||
context.stack = Some(context::memory::Memory::new(
|
context.stack = Some(context::memory::Memory::new(
|
||||||
VirtualAddress::new(stack_addr),
|
VirtualAddress::new(stack_addr),
|
||||||
stack_size,
|
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
|
// Go to usermode
|
||||||
|
|
|
@ -24,14 +24,16 @@ pub fn brk(address: usize) -> Result<usize> {
|
||||||
} else if address >= arch::USER_HEAP_OFFSET {
|
} else if address >= arch::USER_HEAP_OFFSET {
|
||||||
//TODO: out of memory errors
|
//TODO: out of memory errors
|
||||||
if let Some(ref mut heap) = context.heap {
|
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);
|
return Ok(address);
|
||||||
}
|
}
|
||||||
|
|
||||||
context.heap = Some(context::memory::Memory::new(
|
context.heap = Some(context::memory::Memory::new(
|
||||||
VirtualAddress::new(arch::USER_HEAP_OFFSET),
|
VirtualAddress::new(arch::USER_HEAP_OFFSET),
|
||||||
address - 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)
|
Ok(address)
|
||||||
|
|
Loading…
Reference in a new issue