diff --git a/crate/memory/src/memory_set/mod.rs b/crate/memory/src/memory_set/mod.rs index e141f946..1f5fe0f7 100644 --- a/crate/memory/src/memory_set/mod.rs +++ b/crate/memory/src/memory_set/mod.rs @@ -269,7 +269,7 @@ impl MemorySet { } /* - ** @brief remove the memory area to the memory set + ** @brief remove the memory area from the memory set ** @param area: MemoryArea the memory area to remove ** @retval none */ @@ -285,6 +285,41 @@ impl MemorySet { panic!("no memory area found"); } + /* + ** @brief remove the memory area from the memory set and split existed ones when necessary + ** @param area: MemoryArea the memory area to remove + ** @retval none + */ + pub fn pop_with_split(&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].is_overlap_with(start_addr, end_addr) { + if self.areas[i].start_addr >= start_addr && self.areas[i].end_addr <= end_addr { + // subset + let area = self.areas.remove(i); + self.page_table.edit(|pt| area.unmap(pt)); + } else if self.areas[i].start_addr >= start_addr && self.areas[i].start_addr < end_addr { + // prefix + let area = self.areas.remove(i); + let dead_area = MemoryArea { start_addr: area.start_addr, end_addr, attr: area.attr, handler: area.handler.box_clone(), name: area.name }; + self.page_table.edit(|pt| dead_area.unmap(pt)); + let new_area = MemoryArea { start_addr: end_addr, end_addr: area.end_addr, attr: area.attr, handler: area.handler, name: area.name }; + self.areas.insert(i, new_area); + } else if self.areas[i].end_addr <= end_addr && self.areas[i].end_addr > start_addr { + // postfix + let area = self.areas.remove(i); + let dead_area = MemoryArea { start_addr: start_addr, end_addr: area.end_addr, attr: area.attr, handler: area.handler.box_clone(), name: area.name }; + self.page_table.edit(|pt| dead_area.unmap(pt)); + let new_area = MemoryArea { start_addr: area.start_addr, end_addr: start_addr, attr: area.attr, handler: area.handler, name: area.name }; + self.areas.insert(i, new_area); + } else { + unimplemented!(""); + } + return; + } + } + } + /* ** @brief get iterator of the memory area ** @retval impl Iterator diff --git a/kernel/src/syscall/mem.rs b/kernel/src/syscall/mem.rs index 3ca13866..7c131948 100644 --- a/kernel/src/syscall/mem.rs +++ b/kernel/src/syscall/mem.rs @@ -23,7 +23,7 @@ pub fn sys_mmap(mut addr: usize, mut len: usize, prot: usize, flags: usize, fd: if flags.contains(MmapFlags::FIXED) { // we have to map it to addr, so remove the old mapping first - proc.memory_set.pop(addr, addr + len); + proc.memory_set.pop_with_split(addr, addr + len); } else { addr = proc.memory_set.find_free_area(addr, len); } @@ -63,7 +63,7 @@ pub fn sys_mprotect(addr: usize, len: usize, prot: usize) -> SysResult { pub fn sys_munmap(addr: usize, len: usize) -> SysResult { info!("munmap addr={:#x}, size={:#x}", addr, len); let mut proc = process(); - proc.memory_set.pop(addr, addr + len); + proc.memory_set.pop_with_split(addr, addr + len); Ok(0) } diff --git a/kernel/src/syscall/misc.rs b/kernel/src/syscall/misc.rs index 19413b90..9a1fcefb 100644 --- a/kernel/src/syscall/misc.rs +++ b/kernel/src/syscall/misc.rs @@ -34,3 +34,31 @@ pub fn sys_sched_getaffinity(pid: usize, size: usize, mask: *mut u32) -> SysResu } Ok(0) } + +pub fn sys_sysinfo(sys_info: *mut SysInfo) -> SysResult { + let proc = process(); + proc.memory_set.check_mut_ptr(sys_info)?; + + let sysinfo = SysInfo::default(); + unsafe { + *sys_info = sysinfo + }; + Ok(0) +} + +#[repr(C)] +#[derive(Debug, Default)] +pub struct SysInfo { + uptime: u64, + loads: [u64; 3], + totalram: u64, + freeram: u64, + sharedram: u64, + bufferram: u64, + totalswap: u64, + freeswap: u64, + procs: u16, + totalhigh: u64, + freehigh: u64, + mem_unit: u32 +} \ No newline at end of file diff --git a/kernel/src/syscall/mod.rs b/kernel/src/syscall/mod.rs index 964db49c..21cfd518 100644 --- a/kernel/src/syscall/mod.rs +++ b/kernel/src/syscall/mod.rs @@ -99,6 +99,7 @@ pub fn syscall(id: usize, args: [usize; 6], tf: &mut TrapFrame) -> isize { 096 => sys_gettimeofday(args[0] as *mut TimeVal, args[1] as *const u8), // 097 => sys_getrlimit(), // 098 => sys_getrusage(), + 099 => sys_sysinfo(args[0] as *mut SysInfo), 110 => sys_getppid(), // 133 => sys_mknod(), 141 => sys_set_priority(args[0]), @@ -131,6 +132,10 @@ pub fn syscall(id: usize, args: [usize; 6], tf: &mut TrapFrame) -> isize { warn!("sys_ioctl is unimplemented"); Ok(0) } + 028 => { + warn!("sys_madvise is unimplemented"); + Ok(0) + } 037 => { warn!("sys_alarm is unimplemented"); Ok(0) @@ -139,6 +144,10 @@ pub fn syscall(id: usize, args: [usize; 6], tf: &mut TrapFrame) -> isize { warn!("sys_fcntl is unimplemented"); Ok(0) } + 089 => { + warn!("sys_readlink is unimplemented"); + Err(SysError::ENOENT) + } 092 => { warn!("sys_chown is unimplemented"); Ok(0) @@ -171,6 +180,10 @@ pub fn syscall(id: usize, args: [usize; 6], tf: &mut TrapFrame) -> isize { warn!("sys_sigaltstack is unimplemented"); Ok(0) } + 213 => { + warn!("sys_epoll_create is unimplemented"); + Err(SysError::ENOSYS) + } 218 => { warn!("sys_set_tid_address is unimplemented"); Ok(thread::current().id()) @@ -185,7 +198,7 @@ pub fn syscall(id: usize, args: [usize; 6], tf: &mut TrapFrame) -> isize { } 291 => { warn!("sys_epoll_create1 is unimplemented"); - Err(SysError::EINVAL) + Err(SysError::ENOSYS) } 302 => { warn!("sys_prlimit64 is unimplemented");