From e5434498369d5ec241837c325a967dd5bfa2eb22 Mon Sep 17 00:00:00 2001 From: Jiajie Chen Date: Sat, 2 Mar 2019 20:15:55 +0800 Subject: [PATCH] Implement basic version of sys_munmap and sys_time --- crate/memory/src/memory_set/mod.rs | 20 +++++++++++++++++++- kernel/src/drivers/mod.rs | 10 +--------- kernel/src/syscall/mem.rs | 5 ++++- kernel/src/syscall/mod.rs | 3 ++- kernel/src/syscall/time.rs | 16 +++++++++++++++- 5 files changed, 41 insertions(+), 13 deletions(-) diff --git a/crate/memory/src/memory_set/mod.rs b/crate/memory/src/memory_set/mod.rs index 10da7cd..35bf2bc 100644 --- a/crate/memory/src/memory_set/mod.rs +++ b/crate/memory/src/memory_set/mod.rs @@ -224,7 +224,7 @@ impl MemorySet { // 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 MemorySet { 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 diff --git a/kernel/src/drivers/mod.rs b/kernel/src/drivers/mod.rs index ff0500b..4e48c6f 100644 --- a/kernel/src/drivers/mod.rs +++ b/kernel/src/drivers/mod.rs @@ -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; } -// 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 AsAny for T { - fn as_any(&self) -> &Any { self } -} lazy_static! { pub static ref DRIVERS: SpinNoIrqLock>> = SpinNoIrqLock::new(Vec::new()); diff --git a/kernel/src/syscall/mem.rs b/kernel/src/syscall/mem.rs index bdc021e..2f05578 100644 --- a/kernel/src/syscall/mem.rs +++ b/kernel/src/syscall/mem.rs @@ -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! { diff --git a/kernel/src/syscall/mod.rs b/kernel/src/syscall/mod.rs index 5c31dc2..82b6a95 100644 --- a/kernel/src/syscall/mod.rs +++ b/kernel/src/syscall/mod.rs @@ -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) diff --git a/kernel/src/syscall/time.rs b/kernel/src/syscall/time.rs index 53cb490..dd91554 100644 --- a/kernel/src/syscall/time.rs +++ b/kernel/src/syscall/time.rs @@ -4,4 +4,18 @@ use super::*; pub fn sys_get_time() -> SysResult { unsafe { Ok(crate::trap::TICK as isize) } -} \ No newline at end of file +} + +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) +}