Implement basic version of sys_munmap and sys_time

master
Jiajie Chen 6 years ago
parent 472dac5d09
commit e543449836

@ -224,7 +224,7 @@ impl<T: InactivePageTable> MemorySet<T> {
// try each area's end address as the start
core::iter::once(addr_hint)
.chain(self.areas.iter().map(|area| area.end_addr))
.map(|addr| addr + PAGE_SIZE) // move up a page
.map(|addr| (addr + PAGE_SIZE) & ! PAGE_SIZE) // round up a page
.find(|&addr| self.test_free_area(addr, addr + len))
.expect("failed to find free area ???")
}
@ -245,6 +245,24 @@ impl<T: InactivePageTable> MemorySet<T> {
self.page_table.edit(|pt| area.map(pt));
self.areas.push(area);
}
/*
** @brief remove the memory area to the memory set
** @param area: MemoryArea the memory area to remove
** @retval none
*/
pub fn pop(&mut self, start_addr: VirtAddr, end_addr: VirtAddr) {
assert!(start_addr <= end_addr, "invalid memory area");
for i in 0..self.areas.len() {
if self.areas[i].start_addr == start_addr && self.areas[i].end_addr == end_addr {
let area = self.areas.remove(i);
self.page_table.edit(|pt| area.unmap(pt));
return;
}
}
panic!("no memory area found");
}
/*
** @brief get iterator of the memory area
** @retval impl Iterator<Item=&MemoryArea>

@ -21,7 +21,7 @@ pub enum DeviceType {
Block
}
pub trait Driver : Send + AsAny {
pub trait Driver : Send {
// if interrupt belongs to this driver, handle it and return true
// return false otherwise
fn try_handle_interrupt(&mut self) -> bool;
@ -40,14 +40,6 @@ pub trait NetDriver : Send {
fn poll(&mut self, socket: &mut SocketSet) -> Option<bool>;
}
// little hack, see https://users.rust-lang.org/t/how-to-downcast-from-a-trait-any-to-a-struct/11219/3
pub trait AsAny {
fn as_any(&self) -> &Any;
}
impl<T: Any> AsAny for T {
fn as_any(&self) -> &Any { self }
}
lazy_static! {
pub static ref DRIVERS: SpinNoIrqLock<Vec<Box<Driver>>> = SpinNoIrqLock::new(Vec::new());

@ -25,7 +25,10 @@ pub fn sys_mmap(mut addr: usize, len: usize, prot: usize, flags: usize, fd: i32,
}
pub fn sys_munmap(addr: usize, len: usize) -> SysResult {
unimplemented!()
info!("munmap addr={:#x}, size={:#x}", addr, len);
let mut proc = process();
proc.memory_set.pop(addr, addr + len);
Ok(0)
}
bitflags! {

@ -84,9 +84,11 @@ pub fn syscall(id: usize, args: [usize; 6], tf: &mut TrapFrame) -> isize {
// 098 => sys_getrusage(),
// 133 => sys_mknod(),
141 => sys_set_priority(args[0]),
158 => sys_arch_prctl(args[0] as i32, args[1], tf),
// 160 => sys_setrlimit(),
// 162 => sys_sync(),
// 169 => sys_reboot(),
201 => sys_time(args[0] as *mut u64),
217 => sys_getdents64(args[0], args[1] as *mut LinuxDirent64, args[2]),
// 293 => sys_pipe(),
@ -135,7 +137,6 @@ pub fn syscall(id: usize, args: [usize; 6], tf: &mut TrapFrame) -> isize {
warn!("sys_sigaltstack is unimplemented");
Ok(0)
}
158 => sys_arch_prctl(args[0] as i32, args[1], tf),
218 => {
warn!("sys_set_tid_address is unimplemented");
Ok(thread::current().id() as isize)

@ -5,3 +5,17 @@ use super::*;
pub fn sys_get_time() -> SysResult {
unsafe { Ok(crate::trap::TICK as isize) }
}
pub fn sys_time(time: *mut u64) -> SysResult {
let t = unsafe { crate::trap::TICK };
if time as usize != 0 {
let mut proc = process();
if !proc.memory_set.check_mut_ptr(time) {
return Err(SysError::EFAULT);
}
unsafe {
time.write(t as u64);
}
}
Ok(t as isize)
}

Loading…
Cancel
Save