From 3e5dc6dbd98cd1648ff7c29f3ed21f7bb7872e2e Mon Sep 17 00:00:00 2001 From: plc02 <1415227972@qq.com> Date: Thu, 27 Mar 2025 19:45:05 +0800 Subject: [PATCH] mmap,munmap --- os/src/config.rs | 3 +- os/src/main.rs | 2 +- os/src/mm/memory_set.rs | 79 +++++++++++++++++--- os/src/syscall/fs.rs | 152 +++++++++++++++++++++++++++++++++++++- os/src/syscall/mod.rs | 12 ++- os/src/syscall/process.rs | 72 +++++------------- os/src/task/mod.rs | 2 +- os/src/task/task.rs | 65 +++++++++++++++- user/src/bin/brktest.rs | 2 +- user/src/bin/mmap.rs | 12 +++ user/src/bin/rwo.rs | 58 +++++++++++++++ vfs-defs/src/file.rs | 2 +- 12 files changed, 384 insertions(+), 77 deletions(-) create mode 100644 user/src/bin/mmap.rs create mode 100644 user/src/bin/rwo.rs diff --git a/os/src/config.rs b/os/src/config.rs index 5f0298f..1847b66 100644 --- a/os/src/config.rs +++ b/os/src/config.rs @@ -6,7 +6,8 @@ use crate::task::Utsname; pub const USER_STACK_SIZE: usize = 4096 * 5; pub const KERNEL_STACK_SIZE: usize = 4096 *10; pub const KERNEL_HEAP_SIZE: usize = 0x200_0000; - +pub const USER_STACK_TOP: usize = 0x8000_0000; +pub const USER_MMAP_TOP: usize = 0x6000_0000; pub const PAGE_SIZE: usize = 0x1000; #[allow(unused)] pub const USER_HEAP_SIZE: usize = 32768; diff --git a/os/src/main.rs b/os/src/main.rs index 91dceb2..11fe391 100644 --- a/os/src/main.rs +++ b/os/src/main.rs @@ -116,7 +116,7 @@ impl ArchInterface for ArchInterfaceImpl { let args = ctx.args(); // get system call return value // info!("syscall: {}", ctx[TrapFrameArgs::SYSCALL]); - let result = syscall(ctx[TrapFrameArgs::SYSCALL], [args[0], args[1], args[2],args[3],args[4]]); + let result = syscall(ctx[TrapFrameArgs::SYSCALL], [args[0], args[1], args[2],args[3],args[4],args[5]]); // cx is changed during sys_exec, so we have to call it again ctx[TrapFrameArgs::RET] = result as usize; } diff --git a/os/src/mm/memory_set.rs b/os/src/mm/memory_set.rs index 4e26ee8..94b08b0 100644 --- a/os/src/mm/memory_set.rs +++ b/os/src/mm/memory_set.rs @@ -7,7 +7,7 @@ use alloc::alloc::dealloc; use arch::pagetable::{MappingFlags, MappingSize, PageTable, PageTableWrapper}; use arch::addr::{PhysAddr, PhysPage, VirtAddr, VirtPage}; use arch::USER_VADDR_END; -use crate::config::{PAGE_SIZE, USER_STACK_SIZE}; +use crate::config::{PAGE_SIZE, USER_STACK_SIZE, USER_STACK_TOP, USER_MMAP_TOP}; use crate::sync::UPSafeCell; use alloc::collections::BTreeMap; use alloc::sync::Arc; @@ -35,7 +35,9 @@ pub struct MemorySet { /// pub areas: Vec<MapArea>, /// - pub heap_area: MapArea, + pub heap_area: Vec<MapArea>, + /// + pub mmap_area: Vec<MapArea>, } impl MemorySet { @@ -44,12 +46,8 @@ impl MemorySet { Self { page_table:Arc::new(PageTableWrapper::alloc()), areas: Vec::new(), - heap_area: MapArea::new( - VirtAddr::new(0), - VirtAddr::new(0), - crate::mm::MapType::Framed, - MapPermission::U | MapPermission::R | MapPermission::W |MapPermission::X, - ), + heap_area: Vec::new(), + mmap_area: Vec::new(), } } ///Get pagetable `root_ppn` @@ -64,6 +62,22 @@ impl MemorySet { } self.areas.push(map_area); } + /// 分é…+æ˜ å°„->heap_area + pub fn push_into_heaparea(&mut self, mut map_area: MapArea, data: Option<&[u8]>) { + map_area.map(&self.page_table); + if let Some(data) = data { + map_area.copy_data(&self.page_table, data); + } + self.heap_area.push(map_area); + } + /// 分é…+æ˜ å°„->mmap_area + pub fn push_into_mmaparea(&mut self, mut map_area: MapArea, data: Option<&[u8]>) { + map_area.map(&self.page_table); + if let Some(data) = data { + map_area.copy_data(&self.page_table, data); + } + self.mmap_area.push(map_area); + } /// Include sections in elf and trampoline and TrapContext and user stack, /// also returns user_sp and entry point. pub fn from_elf(elf_data: &[u8]) -> (Self, usize, usize, usize) { @@ -114,7 +128,7 @@ impl MemorySet { // let max_end_va: VirtAddr = max_end_vpn.into(); // guard page - let user_stack_top = 0x8000_0000; + let user_stack_top = USER_STACK_TOP; //8G let user_stack_bottom = user_stack_top - USER_STACK_SIZE; //println!("heaptop:{:x} user_stack_bottom:{:x}",heap_top,user_stack_top); memory_set.push( @@ -151,6 +165,35 @@ impl MemorySet { dst_ppn.get_buffer().copy_from_slice(src_ppn.get_buffer()) } } + // copy heap_area (å¯èƒ½å‡ºé”™) + for area in user_space.heap_area.iter() { + let new_area = MapArea::from_another(area); + memory_set.push_into_heaparea(new_area, None); + // copy data from another space + for vpn in area.vpn_range { + let src_ppn = user_space.translate(vpn).unwrap().0; + let dst_ppn = memory_set.translate(vpn).unwrap().0; + // dst_ppn + // .get_bytes_array() + // .copy_from_slice(src_ppn.get_bytes_array()); + dst_ppn.get_buffer().copy_from_slice(src_ppn.get_buffer()) + } + } + //copy mmap_area (å¯èƒ½å‡ºé”™) + for area in user_space.mmap_area.iter() { + let new_area = MapArea::from_another(area); + memory_set.push_into_mmaparea(new_area, None); + // copy data from another space + for vpn in area.vpn_range { + let src_ppn = user_space.translate(vpn).unwrap().0; + let dst_ppn = memory_set.translate(vpn).unwrap().0; + // dst_ppn + // .get_bytes_array() + // .copy_from_slice(src_ppn.get_bytes_array()); + dst_ppn.get_buffer().copy_from_slice(src_ppn.get_buffer()) + } + } + memory_set } ///Refresh TLB with `sfence.vma` @@ -168,7 +211,18 @@ impl MemorySet { //*self = Self::new_bare(); self.areas.clear(); } + /// 用于munmap + pub fn remove_map_area_by_vpn_start(&mut self, num: VirtPage) -> i32 { + if let Some(pos) = self.mmap_area.iter().position(|map_area| map_area.vpn_range.get_start() == num) { + println!("remove vpn: {}~{}",self.mmap_area[pos].vpn_range.get_start(),self.mmap_area[pos].vpn_range.get_end()); + self.mmap_area.remove(pos); + 0 // æˆåŠŸæ‰¾åˆ°å¹¶ç§»é™¤ï¼Œè¿”å›ž 0 或其他表示æˆåŠŸçš„å€¼ + } else { + -1 // 未找到,返回 -1 或其他表示失败的值 + } + } } +/* // 动æ€å † impl MemorySet { /// æ˜ å°„è™šæ‹Ÿé¡µå·åˆ°ç‰©ç†é¡µå¸§ @@ -221,7 +275,7 @@ impl MemorySet { } //frame_dealloc(ppn); //还需è¦å¯¹areaåšdata_frames.remove(&ppn); -} +}*/ /// map area structure, controls a contiguous piece of virtual memory @@ -294,8 +348,9 @@ impl MapArea { for vpn in self.vpn_range { //self.map_one(page_table, vpn); let p_tracker = frame_alloc().expect("can't allocate frame"); + //println!("vpn={},ppn={}",vpn,p_tracker.ppn); page_table.map_page(vpn, p_tracker.ppn, self.map_perm.into(), MappingSize::Page4KB); - self.data_frames.insert(p_tracker.ppn, p_tracker); + self.data_frames.insert(p_tracker.ppn, p_tracker); } } /* pub fn unmap(&mut self, page_table: &mut PageTable) { @@ -341,7 +396,7 @@ bitflags! { const R = 1 << 1; ///Writable const W = 1 << 2; - ///Excutable + ///Executable const X = 1 << 3; ///Accessible in U mode const U = 1 << 4; diff --git a/os/src/syscall/fs.rs b/os/src/syscall/fs.rs index 6be8b2b..188ece3 100644 --- a/os/src/syscall/fs.rs +++ b/os/src/syscall/fs.rs @@ -1,12 +1,15 @@ //! File and filesystem-related syscalls +use crate::config::USER_STACK_TOP; use crate::fs::{open_file,create_file}; use crate::fs::make_pipe; use crate::fs::path_to_dentry; use crate::fs::path_to_father_dentry; use crate::mm::{translated_refmut,translated_byte_buffer, translated_str}; -use crate::task::{current_task, current_user_token}; +use crate::task::{current_task, current_user_token, MapFdControl}; use alloc::string::String; +use arch::addr::{VirtAddr, VirtPage}; +use arch::PAGE_SIZE; use device::BLOCK_DEVICE; use vfs_defs::Kstat; use vfs_defs::MountFlags; @@ -21,7 +24,9 @@ use crate::mm::frame_dealloc; use crate::mm::MapType; use alloc::sync::Arc; use alloc::vec::Vec; -use core::ptr; +use core::ptr::{self, addr_of_mut, null_mut}; +use core::slice; +use alloc::vec; //const HEAP_MAX: usize = 0; pub const AT_FDCWD: isize = -100; @@ -44,12 +49,14 @@ pub fn sys_write(fd: usize, buf: *mut u8, len: usize) -> isize { // release current task TCB manually to avoid multi-borrow drop(inner); file.write(translated_byte_buffer(token, buf, len)) as isize - } else { + } + else { println!("write3"); -1 } } + pub fn sys_read(fd: usize, buf: *mut u8, len: usize) -> isize { let token = current_user_token(); let task = current_task().unwrap(); @@ -308,4 +315,143 @@ pub fn sys_fstat(fd:usize,kst:*mut Kstat)->isize{ return 0; } return -1; +} +/* +addr: +æŒ‡å®šæ˜ å°„è¢«æ”¾ç½®çš„è™šæ‹Ÿåœ°å€ï¼Œå¦‚果将addr指定为NULLï¼Œé‚£ä¹ˆå†…æ ¸ä¼šä¸ºæ˜ å°„åˆ†é…一个åˆé€‚的地å€ã€‚如果addr为一个éžNULL值, +åˆ™å†…æ ¸åœ¨é€‰æ‹©åœ°å€æ˜ å°„æ—¶ä¼šå°†è¯¥å‚æ•°å€¼ä½œä¸ºä¸€ä¸ªæç¤ºä¿¡æ¯æ¥å¤„ç†ã€‚ä¸ç®¡é‡‡ç”¨ä½•ç§æ–¹å¼ï¼Œå†…æ ¸ä¼šé€‰æ‹©ä¸€ä¸ªä¸ä¸Žä»»ä½•æ—¢æœ‰æ˜ å°„å†²çªçš„地 +å€ã€‚在处ç†è¿‡ç¨‹ä¸ï¼Œ å†…æ ¸ä¼šå°†æŒ‡å®šçš„åœ°å€èˆå…¥åˆ°æœ€è¿‘的一个分页边界处。 +length: +傿•°æŒ‡å®šäº†æ˜ å°„çš„å—节数。尽管length æ— éœ€æ˜¯ä¸€ä¸ªç³»ç»Ÿåˆ†é¡µå¤§å°çš„倿•°ï¼Œä½†å†…æ ¸ä¼šä»¥åˆ†é¡µå¤§å°ä¸ºå•使¥åˆ›å»ºæ˜ 射, +å› æ¤å®žé™…上length会被å‘上æå‡ä¸ºåˆ†é¡µå¤§å°çš„ä¸‹ä¸€ä¸ªå€æ•°ã€‚ +prot: æ˜ å°„çš„å†…å˜ä¿æŠ¤æ–¹å¼ï¼Œå¯å–:PROT_EXEC, PROT_READ, PROT_WRITE, PROT_NONE +flags: æ˜ å°„æ˜¯å¦ä¸Žå…¶ä»–è¿›ç¨‹å…±äº«çš„æ ‡å¿—ï¼Œ +fd: æ–‡ä»¶å¥æŸ„, +off: 文件åç§»é‡ =? (off,off+len) +返回值:æˆåŠŸè¿”å›žå·²æ˜ å°„åŒºåŸŸçš„æŒ‡é’ˆï¼Œå¤±è´¥è¿”å›ž-1; +void *start, size_t len, int prot, int flags, int fd, off_t off +long ret = syscall(SYS_mmap, start, len, prot, flags, fd, off); +ä¸éœ€è¦å®žé™…分é…物ç†åœ°å€ +*/ +pub fn sys_mmap( + _start: *mut usize, + len: usize, + _prot: i32, + _flags: i32, + fd: usize, + off: i32, +) -> isize { + if len==0 || off!=0 { + return -1; + } + // é•¿åº¦å¯¹é½ + let mut num = len / PAGE_SIZE;//num:é¡µæ•°é‡ + if num*PAGE_SIZE != len { + num = num + 1; + } + // èŽ·å–æ–‡ä»¶æ•°æ® + let mut buf = vec![0u8; len]; + let buf_ptr = buf.as_mut_ptr(); + + let task = current_task().unwrap(); + let inner = task.inner_exclusive_access(); + if fd >= inner.fd_table.len() { + return -1; + } + if let Some(file) = &inner.fd_table[fd] { + let file = file.clone(); + if !file.readable() { + return -1; + } + // release current task TCB manually to avoid multi-borrow + drop(inner); + file.read_at(0, &mut buf); + } else { + return -1; + } + + let mut inner = task.inner_exclusive_access(); + let mut start = inner.mapareacontrol.find_block(num);// num是需è¦çš„页数目 + let mut move_top = false; + if start == 0 { + start = inner.mapareacontrol.mmap_top; + move_top = true; + } + if len + start >= USER_STACK_TOP { + // ä¸Žæ ˆé‡å + return -1; + } + let start_va = VirtAddr::new(start); + let end_va = VirtAddr::new(start + len); + + inner.memory_set.push_into_mmaparea( + MapArea::new( + start_va, + end_va, + MapType::Framed, + MapPermission::R|MapPermission::U|MapPermission::W|MapPermission::X + ), + unsafe { + Some(slice::from_raw_parts(buf_ptr, len)) + } + ); + if move_top { + inner.mapareacontrol.mmap_top += num * PAGE_SIZE; + } + inner.mapareacontrol.mapfd.push( + MapFdControl { + fd: fd, + len: len, + start_va: start + } + ); + return start as isize; + +} +//void *start, size_t len +//int ret = syscall(SYS_munmap, start, len); +pub fn sys_munmap(start: *mut usize, _len: usize) -> isize { + if start as usize/ PAGE_SIZE *PAGE_SIZE != start as usize { + // 未对é½ï¼Œåœ°å€é”™è¯¯ + return -1; + } + let task = current_task().unwrap(); + let mut inner = task.inner_exclusive_access(); + if inner.mapareacontrol.mmap_top <= start as usize { + // 地å€è¶Šç•Œ + return -2; + } + // fd + let mut len: usize = 0; + let fd = inner.mapareacontrol.find_fd(start as usize, &mut len); + if fd < 0 { + println!("fd not found!"); + return -3; + } + if fd >= inner.fd_table.len() as isize { + println!("fd out of range!"); + return -4; + } + // read data from va + let mut buf = vec![0u8; len]; + + if let Some(file) = &inner.fd_table[fd as usize] { + let file = file.clone(); + if !file.writable() { + return -5; + } + // release current task TCB manually to avoid multi-borrow + drop(inner); + file.write_at(0, &mut buf); + } else { + return -6; + } + let mut inner = task.inner_exclusive_access(); + let res = inner.memory_set.remove_map_area_by_vpn_start(VirtAddr::new(start as usize).into()); + if res < 0 { + // 找ä¸åˆ°åœ°å€ + println!("vpn not found!"); + return -7; + } + 0 } \ No newline at end of file diff --git a/os/src/syscall/mod.rs b/os/src/syscall/mod.rs index 5eefbd8..7820d46 100644 --- a/os/src/syscall/mod.rs +++ b/os/src/syscall/mod.rs @@ -32,8 +32,10 @@ const SYSCALL_UNAME: usize = 160; const SYSCALL_GET_TIME: usize = 169; const SYSCALL_GETPID: usize = 172; const SYSCALL_BRK: usize = 214; +const SYSCALL_MUNMAP: usize = 215; const SYSCALL_FORK: usize = 220; const SYSCALL_EXEC: usize = 221; +const SYSCALL_MMAP: usize = 222; const SYSCALL_WAITPID: usize = 260; mod fs; @@ -45,7 +47,7 @@ use crate::task::{Tms, Utsname}; const MODULE_LEVEL:log::Level = log::Level::Trace; /// handle syscall exception with `syscall_id` and other arguments -pub fn syscall(syscall_id: usize, args: [usize; 5]) -> isize { +pub fn syscall(syscall_id: usize, args: [usize; 6]) -> isize { // println!("syscallid:{}",syscall_id); let mut result:isize = 0; match syscall_id { @@ -150,6 +152,14 @@ pub fn syscall(syscall_id: usize, args: [usize; 5]) -> isize { result = sys_uname(args[0] as *mut Utsname); log_debug!("syscall_uname result:{}",result); } + SYSCALL_MMAP => { + result = sys_mmap(args[0] as *mut usize, args[1], args[2] as i32, args[3] as i32, args[4],args[5] as i32); + log_debug!("syscall_mmap result:{}",result); + } + SYSCALL_MUNMAP => { + result = sys_munmap(args[0] as *mut usize, args[1]); + log_debug!("syscall_munmap result:{}",result); + } _ => panic!("Unsupported syscall_id: {}", syscall_id), } result diff --git a/os/src/syscall/process.rs b/os/src/syscall/process.rs index bf3fac4..ae1cf6d 100644 --- a/os/src/syscall/process.rs +++ b/os/src/syscall/process.rs @@ -1,5 +1,5 @@ use crate::fs::{open_file,path_to_dentry,path_to_father_dentry,create_file}; -use crate::mm::{translated_refmut, translated_str,translated_ref}; +use crate::mm::{translated_ref, translated_refmut, translated_str, MapType}; use crate::task::{ add_task, current_task, current_user_token, exit_current_and_run_next, suspend_current_and_run_next, @@ -13,7 +13,7 @@ use crate::drivers::BLOCK_DEVICE; use vfs_defs::{DiskInodeType,OpenFlags,Dentry}; use crate::config::{PAGE_SIZE, UNAME}; use arch::addr::{PhysPage, VirtAddr, VirtPage}; -use crate::mm::MapPermission; +use crate::mm::{MapPermission, MapArea}; use arch::pagetable::MappingSize; use crate::task::{Tms, Utsname}; @@ -203,67 +203,31 @@ pub fn sys_brk(new_brk: usize) -> isize { task_inner.heap_top = new_brk; return 0; } - - let mut need_align: bool = false; - // new_brk->align to 4K - let num = new_brk / PAGE_SIZE; - if num*PAGE_SIZE < new_brk { - //align_brk = (num + 1)*PAGE_SIZE; - need_align = true; - } if new_brk > cur_brk { let user_stack_bottom = task_inner.stack_bottom; - if new_brk >= user_stack_bottom { + if new_brk >= user_stack_bottom -PAGE_SIZE { return -1; } - // 确认新增虚拟页å·èŒƒå›´ - //let cur_page = (cur_brk + PAGE_SIZE - 1) / PAGE_SIZE; - //let new_page = (new_brk + PAGE_SIZE - 1) / PAGE_SIZE; - let cur_page = task_inner.max_data_addr / PAGE_SIZE; - let mut new_page = num; - if need_align { - new_page += 1; - } - let page_count = new_page - cur_page; - //println!("{} - {}", new_page, cur_page); - let mut all_vpn = Vec::<VirtPage>::new(); - let mut all_ppn = Vec::<PhysPage>::new(); - if page_count > 0 { - // 申请ç‰é‡çš„物ç†é¡µå¸§ - /*let frames = frame_alloc_more(page_count); - if frames.is_none() { - return -1; // 物ç†å†…å˜ä¸è¶³ - } - let frames = frames.unwrap();*/ - - // 在 memory_set 䏿˜ 射新增的虚拟页å·åˆ°ç‰©ç†é¡µå¸§,如(31,32)->(31,30.9->31) 实际申请一页 - //let _start_va: VirtAddr = (cur_brk).into(); - //let _end_va: VirtAddr = (new_brk - PAGE_SIZE -1).into(); - - for i in 0..page_count { - let vpn = VirtPage::from(cur_page + i); - //let ppn = frames[i].ppn; - let mp = MapPermission::R | MapPermission::W | MapPermission::U; - let ppn = task_inner.memory_set.map_page(vpn, mp, MappingSize::Page4KB); - all_vpn.push(vpn); - all_ppn.push(ppn); - //println!("vpn:{} ppn:{}",vpn,ppn); - /*task_inner.memory_set.map_page( - vpn, - ppn, - MapPermission::R | MapPermission::W | MapPermission::U, - MappingSize::Page4KB, - );*/ - } - } + let cur_addr = VirtAddr::new(task_inner.max_data_addr).floor(); + let new_addr = VirtAddr::new(new_brk).ceil(); + + let page_count = (new_addr.addr() - cur_addr.addr()) / PAGE_SIZE; + let alloc_start_addr = task_inner.max_data_addr; + task_inner.memory_set.push_into_heaparea( + MapArea::new( + VirtAddr::new(alloc_start_addr), //å‘下 + VirtAddr::new(new_brk), //å‘上 + MapType::Framed, + MapPermission::R|MapPermission::U|MapPermission::W|MapPermission::X + ), + None + ); task_inner.max_data_addr += PAGE_SIZE*page_count; //println!("max_data_addr = {}", task_inner.max_data_addr); task_inner.heap_top = new_brk; - /*for (vpn, ppn) in all_vpn.iter().zip(all_ppn.iter()) { - println!("VPN: {:?}, PPN: {:?}", vpn, ppn); - }*/ + 0 } else if new_brk == cur_brk { diff --git a/os/src/task/mod.rs b/os/src/task/mod.rs index 44737bb..afa020e 100644 --- a/os/src/task/mod.rs +++ b/os/src/task/mod.rs @@ -30,7 +30,7 @@ use arch::KContext; use arch::TrapFrameArgs; use lazy_static::*; pub use manager::{fetch_task, TaskManager,wakeup_task}; -pub use task::{TaskControlBlock, TaskStatus, Tms, Utsname}; +pub use task::{TaskControlBlock, TaskStatus, Tms, Utsname, MapFdControl}; use vfs_defs::OpenFlags; pub use manager::add_task; pub use pid::{pid_alloc, PidAllocator, PidHandle}; diff --git a/os/src/task/task.rs b/os/src/task/task.rs index bc6a56e..791de5c 100644 --- a/os/src/task/task.rs +++ b/os/src/task/task.rs @@ -1,7 +1,7 @@ //!Implementation of [`TaskControlBlock`] use super::current_task; use super::{pid_alloc, PidHandle}; -use crate::config::{KERNEL_STACK_SIZE, USER_STACK_SIZE}; +use crate::config::{KERNEL_STACK_SIZE, USER_MMAP_TOP, USER_STACK_SIZE}; use crate::fs::{Stdin, Stdout}; use crate::mm::{translated_refmut, MapArea, MapPermission, MapType, MemorySet}; use arch::addr::VirtAddr; @@ -127,7 +127,61 @@ pub struct TaskControlBlock { // mutable inner: Mutex<TaskControlBlockInner>, } - +#[derive(Clone)] +pub struct MapAreaControl { + pub mmap_top: usize, + pub mapfd: Vec<MapFdControl>, + mapfreeblock: Vec<MapFreeControl>, +} +impl MapAreaControl { + pub fn new() -> Self { + Self { + mmap_top: USER_MMAP_TOP, + mapfd: Vec::new(), + mapfreeblock: Vec::new() + } + } + // 找到第一个åˆé€‚çš„å— + pub fn find_block(&mut self, num: usize) -> usize { + for (i, block) in self.mapfreeblock.iter_mut().enumerate() { + if block.num >= num { + block.num -= num; + if block.num == 0 { + // 移除当å‰å—并返回起始dizhi + return self.mapfreeblock.swap_remove(i).start_va; + } else { + return block.start_va; + } + } + } + 0 + } + // 找fd + pub fn find_fd(&mut self, start: usize, len: &mut usize) -> isize { + for (i, block) in self.mapfd.iter_mut().enumerate() { + if start == block.start_va { + *len = self.mapfd[i].len; + return self.mapfd.swap_remove(i).fd as isize; + } + } + return -1; + } +} +/// +#[derive(Clone)] +pub struct MapFdControl { + /// + pub fd: usize, + /// + pub len: usize, + /// + pub start_va: usize, +} +#[derive(Clone)] +pub struct MapFreeControl { + pub start_va: usize, + pub num: usize, +} pub struct TaskControlBlockInner { pub trap_cx: TrapFrame, #[allow(unused)] @@ -146,6 +200,8 @@ pub struct TaskControlBlockInner { pub stack_bottom: usize, pub max_data_addr: usize, pub tms: Tms, + pub mapareacontrol: MapAreaControl, + //pub mmap_top: usize, } fn task_entry() { let task = current_task() @@ -232,6 +288,8 @@ impl TaskControlBlock { stack_bottom: user_sp - USER_STACK_SIZE, max_data_addr: heap_top, tms: Tms::new(), + mapareacontrol: MapAreaControl::new(), + //mmap_top: USER_MMAP_TOP, } ), }; @@ -259,6 +317,7 @@ impl TaskControlBlock { self.inner_exclusive_access().stack_bottom =user_sp - USER_STACK_SIZE; self.inner_exclusive_access().max_data_addr = heap_top; self.inner_exclusive_access().tms= Tms::new(); + self.inner_exclusive_access().mapareacontrol = MapAreaControl::new(); memory_set.activate(); // push arguments on user stack user_sp -= (args.len() + 1) * core::mem::size_of::<usize>(); @@ -340,6 +399,8 @@ impl TaskControlBlock { stack_bottom: parent_inner.stack_bottom, max_data_addr: parent_inner.max_data_addr, tms: Tms::from_other_task(&parent_inner.tms), + mapareacontrol: parent_inner.mapareacontrol.clone(), + //mmap_top: parent_inner.mmap_top, }) , }); diff --git a/user/src/bin/brktest.rs b/user/src/bin/brktest.rs index 9db0639..bea8da9 100644 --- a/user/src/bin/brktest.rs +++ b/user/src/bin/brktest.rs @@ -33,7 +33,7 @@ const PAGE_SIZE: isize= 4096; #[no_mangle] pub fn main() -> i32 { let init_brk = brk(0); - let size: isize = 6000; + let size: isize = 2000; for i in 1..5 { println!("第{}轮扩充({}):", i, size/PAGE_SIZE + 1); diff --git a/user/src/bin/mmap.rs b/user/src/bin/mmap.rs new file mode 100644 index 0000000..1434c51 --- /dev/null +++ b/user/src/bin/mmap.rs @@ -0,0 +1,12 @@ +#![no_std] +#![no_main] + +#[macro_use] +extern crate user_lib; +//use user_lib::{exit, fork, wait, waitpid, yield_}; + +#[no_mangle] +pub fn main() -> i32 { + + 0 +} \ No newline at end of file diff --git a/user/src/bin/rwo.rs b/user/src/bin/rwo.rs new file mode 100644 index 0000000..79dde37 --- /dev/null +++ b/user/src/bin/rwo.rs @@ -0,0 +1,58 @@ +#![no_std] +#![no_main] + +#[macro_use] +extern crate user_lib; +extern crate alloc; +use alloc::vec; +use core::{convert::TryInto, str}; +use user_lib::{open,write,read,OpenFlags,close}; + + +#[no_mangle] +pub fn main() -> i32 {// 测试 open, write, read 功能 + const FILE_NAME: &str = "./testfile.txt"; + const CONTENT: &str = "Hello, Rust userland!"; + + // 打开或创建文件(O_CREATE | O_WRONLY | O_TRUNC) + let flags = OpenFlags::CREATE | OpenFlags::WRONLY | OpenFlags::TRUNC; + let fd = open(FILE_NAME, flags); + if fd < 0 { + println!("Failed to open file: {}", fd); + return -1; + } + println!("File opened successfully, fd: {}", fd); + + // 写入文件 + let content_bytes = CONTENT.as_bytes(); + let bytes_written = write(fd.try_into().unwrap(), content_bytes); + if bytes_written < 0 { + println!("Failed to write to file: {}", bytes_written); + close(fd.try_into().unwrap()); + return -1; + } + println!("Written {} bytes to file", bytes_written); + + // è¯»å–æ–‡ä»¶å†…容 + let mut buffer = vec![0u8; 128]; // å‡è®¾ç¼“冲区足够大 + let bytes_read = read(fd.try_into().unwrap(), &mut buffer); + if bytes_read < 0 { + println!("Failed to read from file: {}", bytes_read); + close(fd.try_into().unwrap()); + return -1; + } + println!("Read {} bytes from file", bytes_read); + + // 将读å–的内容转æ¢ä¸ºå—ç¬¦ä¸²å¹¶æ‰“å° + let content = str::from_utf8(&buffer[..bytes_read as usize]).unwrap_or("<invalid UTF-8>"); + println!("File content: {}", content); + + // 关闿–‡ä»¶ + if close(fd.try_into().unwrap()) < 0 { + println!("Failed to close file"); + return -1; + } + println!("File closed successfully after reading"); + + 0 // æ£å¸¸é€€å‡º +} \ No newline at end of file diff --git a/vfs-defs/src/file.rs b/vfs-defs/src/file.rs index aac9504..8187700 100644 --- a/vfs-defs/src/file.rs +++ b/vfs-defs/src/file.rs @@ -83,7 +83,7 @@ pub trait File: Send + Sync{ self.get_inner().dentry.clone() } /// Read file to `buf` - fn read(&self, buf: &mut [u8]) -> usize{ + fn read(&self, buf: &mut [u8]) -> usize{ let mut offset = self.get_offset(); let read_size = self.read_at(*offset, buf); *offset += read_size; -- GitLab