@@ -365,36 +365,129 @@ mod impls {
365365 }
366366
367367 impl Trace for SyscallContext {
368- // TODO: 实现 trace 系统调用
368+ // 实现 trace 系统调用
369369 #[ inline]
370- fn trace ( & self , _caller : Caller , _trace_request : usize , _id : usize , _data : usize ) -> isize {
371- tg_console:: log:: info!( "trace: not implemented" ) ;
372- -1
370+ fn trace ( & self , caller : tg_syscall:: Caller , trace_request : usize , id : usize , data : usize ) -> isize {
371+ let process = unsafe { PROCESSES . get_mut ( ) . get ( caller. entity ) } . unwrap ( ) ;
372+
373+ match trace_request {
374+ // 读取 id 地址处一个字节的值
375+ 0 => {
376+ // 检查地址是否用户可见且可读(需要 U、R、V 标志)
377+ const READABLE : VmFlags < Sv39 > = VmFlags :: build_from_str ( "U__RV" ) ;
378+ if let Some ( ptr) = process. address_space . translate :: < u8 > ( VAddr :: new ( id) , READABLE ) {
379+ unsafe { * ptr. as_ptr ( ) as isize }
380+ } else {
381+ -1
382+ }
383+ }
384+ // 写入 data(作为 u8)到 id 地址处
385+ 1 => {
386+ // 检查地址是否用户可见且可写(需要 U、W、V 标志)
387+ const WRITABLE : VmFlags < Sv39 > = VmFlags :: build_from_str ( "U_WRV" ) ;
388+ if let Some ( mut ptr) = process. address_space . translate :: < u8 > ( VAddr :: new ( id) , WRITABLE ) {
389+ unsafe { * ptr. as_mut ( ) = data as u8 } ;
390+ 0
391+ } else {
392+ -1
393+ }
394+ }
395+ // 其他情况返回 -1
396+ _ => -1 ,
397+ }
373398 }
374399 }
375400
376401 impl Memory for SyscallContext {
377- // TODO: 实现 mmap 系统调用
378- fn mmap (
379- & self ,
380- _caller : Caller ,
381- addr : usize ,
382- len : usize ,
383- prot : i32 ,
384- _flags : i32 ,
385- _fd : i32 ,
386- _offset : usize ,
387- ) -> isize {
388- tg_console:: log:: info!(
389- "mmap: addr = {addr:#x}, len = {len}, prot = {prot}, not implemented"
390- ) ;
391- -1
402+ // 实现 mmap 系统调用
403+ fn mmap ( & self , caller : Caller , addr : usize , len : usize , prot : i32 , _flags : i32 , _fd : i32 , _offset : usize ) -> isize {
404+ const PAGE_SIZE : usize = 1 << Sv39 :: PAGE_BITS ;
405+
406+ // 检查 addr 是否页对齐
407+ if addr & ( PAGE_SIZE - 1 ) != 0 {
408+ return -1 ;
409+ }
410+
411+ // 检查 prot 参数
412+ // prot & !0x7 != 0 (prot 其余位必须为 0)
413+ if prot & !0x7 != 0 {
414+ return -1 ;
415+ }
416+ // prot & 0x7 == 0 (这样的内存无意义)
417+ if prot & 0x7 == 0 {
418+ return -1 ;
419+ }
420+
421+ // len 为 0 时直接返回成功
422+ if len == 0 {
423+ return 0 ;
424+ }
425+
426+ // 计算页范围(向上取整)
427+ let start_vpn = VPN :: < Sv39 > :: new ( addr >> Sv39 :: PAGE_BITS ) ;
428+ let end_addr = addr + len;
429+ let end_vpn = VPN :: < Sv39 > :: new ( ( end_addr + PAGE_SIZE - 1 ) >> Sv39 :: PAGE_BITS ) ;
430+ let range = start_vpn..end_vpn;
431+
432+ let process = unsafe { PROCESSES . get_mut ( ) . get_mut ( caller. entity ) } . unwrap ( ) ;
433+
434+ // 检查是否与已有映射重叠
435+ if process. address_space . overlaps ( & range) {
436+ return -1 ;
437+ }
438+
439+ // 构建 VmFlags
440+ // prot: bit 0 = 可读(R), bit 1 = 可写(W), bit 2 = 可执行(X)
441+ // RISC-V PTE: bit 0 = V, bit 1 = R, bit 2 = W, bit 3 = X, bit 4 = U
442+ let mut flags_str: [ u8 ; 5 ] = * b"U___V" ;
443+ if prot & 0x4 != 0 {
444+ flags_str[ 1 ] = b'X' ;
445+ }
446+ if prot & 0x2 != 0 {
447+ flags_str[ 2 ] = b'W' ;
448+ }
449+ if prot & 0x1 != 0 {
450+ flags_str[ 3 ] = b'R' ;
451+ }
452+ let flags = VmFlags :: build_from_str ( unsafe { core:: str:: from_utf8_unchecked ( & flags_str) } ) ;
453+
454+ // 分配物理页并建立映射
455+ process. address_space . map_alloc ( range, flags) ;
456+
457+ 0
392458 }
393459
394- // TODO: 实现 munmap 系统调用
395- fn munmap ( & self , _caller : Caller , addr : usize , len : usize ) -> isize {
396- tg_console:: log:: info!( "munmap: addr = {addr:#x}, len = {len}, not implemented" ) ;
397- -1
460+ // 实现 munmap 系统调用
461+ fn munmap ( & self , caller : Caller , addr : usize , len : usize ) -> isize {
462+ const PAGE_SIZE : usize = 1 << Sv39 :: PAGE_BITS ;
463+
464+ // 检查 addr 是否页对齐
465+ if addr & ( PAGE_SIZE - 1 ) != 0 {
466+ return -1 ;
467+ }
468+
469+ // len 为 0 时直接返回成功
470+ if len == 0 {
471+ return 0 ;
472+ }
473+
474+ // 计算页范围(向上取整)
475+ let start_vpn = VPN :: < Sv39 > :: new ( addr >> Sv39 :: PAGE_BITS ) ;
476+ let end_addr = addr + len;
477+ let end_vpn = VPN :: < Sv39 > :: new ( ( end_addr + PAGE_SIZE - 1 ) >> Sv39 :: PAGE_BITS ) ;
478+ let range = start_vpn..end_vpn;
479+
480+ let process = unsafe { PROCESSES . get_mut ( ) . get_mut ( caller. entity ) } . unwrap ( ) ;
481+
482+ // 检查该范围是否完全被映射
483+ if !process. address_space . fully_mapped ( & range) {
484+ return -1 ;
485+ }
486+
487+ // 取消映射
488+ process. address_space . unmap ( range) ;
489+
490+ 0
398491 }
399492 }
400493}
0 commit comments