From e5434498369d5ec241837c325a967dd5bfa2eb22 Mon Sep 17 00:00:00 2001 From: Jiajie Chen Date: Sat, 2 Mar 2019 20:15:55 +0800 Subject: [PATCH 1/2] 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) +} From 687caf804da4d827c056f48e126a7576f12cfb38 Mon Sep 17 00:00:00 2001 From: Jiajie Chen Date: Sat, 2 Mar 2019 20:25:30 +0800 Subject: [PATCH 2/2] Implement sys_getcwd --- kernel/src/process/structs.rs | 8 ++++---- kernel/src/syscall/fs.rs | 15 +++++++++++++++ kernel/src/syscall/mod.rs | 2 +- 3 files changed, 20 insertions(+), 5 deletions(-) diff --git a/kernel/src/process/structs.rs b/kernel/src/process/structs.rs index ae64823..230469e 100644 --- a/kernel/src/process/structs.rs +++ b/kernel/src/process/structs.rs @@ -51,7 +51,7 @@ impl Thread { proc: Arc::new(Mutex::new(Process { memory_set: MemorySet::new(), files: BTreeMap::default(), - cwd: String::new(), + cwd: String::from("/"), sockets: SocketSet::new(vec![]) })), }) @@ -67,7 +67,7 @@ impl Thread { proc: Arc::new(Mutex::new(Process { memory_set, files: BTreeMap::default(), - cwd: String::new(), + cwd: String::from("/"), sockets: SocketSet::new(vec![]) })), }) @@ -146,7 +146,7 @@ impl Thread { proc: Arc::new(Mutex::new(Process { memory_set, files, - cwd: String::new(), + cwd: String::from("/"), sockets: SocketSet::new(vec![]) })), }) @@ -178,7 +178,7 @@ impl Thread { proc: Arc::new(Mutex::new(Process { memory_set, files: self.proc.lock().files.clone(), - cwd: String::new(), + cwd: self.proc.lock().cwd.clone(), // TODO: duplicate sockets for child process sockets: SocketSet::new(vec![]) })), diff --git a/kernel/src/syscall/fs.rs b/kernel/src/syscall/fs.rs index 4e38c13..27d0552 100644 --- a/kernel/src/syscall/fs.rs +++ b/kernel/src/syscall/fs.rs @@ -115,6 +115,21 @@ pub fn sys_close(fd: usize) -> SysResult { } } +pub fn sys_getcwd(buf: *mut u8, len: usize) -> SysResult { + info!("getcwd: buf: {:?}, len: {:#x}", buf, len); + let mut proc = process(); + if !proc.memory_set.check_mut_array(buf, len) { + return Err(SysError::EFAULT); + } + if proc.cwd.len() + 1 > len { + return Err(SysError::ERANGE); + } + unsafe { + util::write_cstr(buf, &proc.cwd) + } + Ok(0) +} + pub fn sys_stat(path: *const u8, stat_ptr: *mut Stat) -> SysResult { warn!("stat is partial implemented as lstat"); sys_lstat(path, stat_ptr) diff --git a/kernel/src/syscall/mod.rs b/kernel/src/syscall/mod.rs index 82b6a95..5843366 100644 --- a/kernel/src/syscall/mod.rs +++ b/kernel/src/syscall/mod.rs @@ -73,7 +73,7 @@ pub fn syscall(id: usize, args: [usize; 6], tf: &mut TrapFrame) -> isize { // 074 => sys_fsync(), // 076 => sys_trunc(), // 077 => sys_ftrunc(), -// 079 => sys_getcwd(), + 079 => sys_getcwd(args[0] as *mut u8, args[1]), // 080 => sys_chdir(), // 082 => sys_rename(), // 083 => sys_mkdir(),