14fda81ceSLoGin use alloc::{string::String, vec::Vec}; 2*471d65cfSLoGin use riscv::register::sstatus::{Sstatus, FS, SPP}; 391e9d4abSLoGin use system_error::SystemError; 44fda81ceSLoGin 5*471d65cfSLoGin use crate::{ 6*471d65cfSLoGin arch::{interrupt::TrapFrame, CurrentIrqArch}, 7*471d65cfSLoGin exception::InterruptArch, 8*471d65cfSLoGin kdebug, 9*471d65cfSLoGin mm::ucontext::AddressSpace, 10*471d65cfSLoGin process::{ 11*471d65cfSLoGin exec::{load_binary_file, ExecParam, ExecParamFlags}, 12*471d65cfSLoGin ProcessManager, 13*471d65cfSLoGin }, 14*471d65cfSLoGin syscall::Syscall, 15*471d65cfSLoGin }; 164fda81ceSLoGin 174fda81ceSLoGin impl Syscall { 184fda81ceSLoGin pub fn do_execve( 194fda81ceSLoGin path: String, 204fda81ceSLoGin argv: Vec<String>, 214fda81ceSLoGin envp: Vec<String>, 224fda81ceSLoGin regs: &mut TrapFrame, 234fda81ceSLoGin ) -> Result<(), SystemError> { 24*471d65cfSLoGin // 关中断,防止在设置地址空间的时候,发生中断,然后进调度器,出现错误。 25*471d65cfSLoGin let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() }; 26*471d65cfSLoGin let pcb = ProcessManager::current_pcb(); 27*471d65cfSLoGin // crate::kdebug!( 28*471d65cfSLoGin // "pid: {:?} do_execve: path: {:?}, argv: {:?}, envp: {:?}\n", 29*471d65cfSLoGin // pcb.pid(), 30*471d65cfSLoGin // path, 31*471d65cfSLoGin // argv, 32*471d65cfSLoGin // envp 33*471d65cfSLoGin // ); 34*471d65cfSLoGin 35*471d65cfSLoGin let mut basic_info = pcb.basic_mut(); 36*471d65cfSLoGin // 暂存原本的用户地址空间的引用(因为如果在切换页表之前释放了它,可能会造成内存use after free) 37*471d65cfSLoGin let old_address_space = basic_info.user_vm(); 38*471d65cfSLoGin 39*471d65cfSLoGin // 在pcb中原来的用户地址空间 40*471d65cfSLoGin unsafe { 41*471d65cfSLoGin basic_info.set_user_vm(None); 42*471d65cfSLoGin } 43*471d65cfSLoGin // 创建新的地址空间并设置为当前地址空间 44*471d65cfSLoGin let address_space = AddressSpace::new(true).expect("Failed to create new address space"); 45*471d65cfSLoGin unsafe { 46*471d65cfSLoGin basic_info.set_user_vm(Some(address_space.clone())); 47*471d65cfSLoGin } 48*471d65cfSLoGin 49*471d65cfSLoGin // to avoid deadlock 50*471d65cfSLoGin drop(basic_info); 51*471d65cfSLoGin 52*471d65cfSLoGin assert!( 53*471d65cfSLoGin AddressSpace::is_current(&address_space), 54*471d65cfSLoGin "Failed to set address space" 55*471d65cfSLoGin ); 56*471d65cfSLoGin // kdebug!("Switch to new address space"); 57*471d65cfSLoGin 58*471d65cfSLoGin // 切换到新的用户地址空间 59*471d65cfSLoGin unsafe { address_space.read().user_mapper.utable.make_current() }; 60*471d65cfSLoGin 61*471d65cfSLoGin drop(old_address_space); 62*471d65cfSLoGin drop(irq_guard); 63*471d65cfSLoGin // kdebug!("to load binary file"); 64*471d65cfSLoGin let mut param = ExecParam::new(path.as_str(), address_space.clone(), ExecParamFlags::EXEC)?; 65*471d65cfSLoGin 66*471d65cfSLoGin // 加载可执行文件 67*471d65cfSLoGin let load_result = load_binary_file(&mut param) 68*471d65cfSLoGin .unwrap_or_else(|e| panic!("Failed to load binary file: {:?}, path: {:?}", e, path)); 69*471d65cfSLoGin // kdebug!("load binary file done"); 70*471d65cfSLoGin // kdebug!("argv: {:?}, envp: {:?}", argv, envp); 71*471d65cfSLoGin param.init_info_mut().args = argv; 72*471d65cfSLoGin param.init_info_mut().envs = envp; 73*471d65cfSLoGin 74*471d65cfSLoGin // 把proc_init_info写到用户栈上 75*471d65cfSLoGin let mut ustack_message = unsafe { 76*471d65cfSLoGin address_space 77*471d65cfSLoGin .write() 78*471d65cfSLoGin .user_stack_mut() 79*471d65cfSLoGin .expect("No user stack found") 80*471d65cfSLoGin .clone_info_only() 81*471d65cfSLoGin }; 82*471d65cfSLoGin let (user_sp, argv_ptr) = unsafe { 83*471d65cfSLoGin param 84*471d65cfSLoGin .init_info() 85*471d65cfSLoGin .push_at( 86*471d65cfSLoGin // address_space 87*471d65cfSLoGin // .write() 88*471d65cfSLoGin // .user_stack_mut() 89*471d65cfSLoGin // .expect("No user stack found"), 90*471d65cfSLoGin &mut ustack_message, 91*471d65cfSLoGin ) 92*471d65cfSLoGin .expect("Failed to push proc_init_info to user stack") 93*471d65cfSLoGin }; 94*471d65cfSLoGin address_space.write().user_stack = Some(ustack_message); 95*471d65cfSLoGin 96*471d65cfSLoGin // kdebug!("write proc_init_info to user stack done"); 97*471d65cfSLoGin 98*471d65cfSLoGin regs.a0 = param.init_info().args.len(); 99*471d65cfSLoGin regs.a1 = argv_ptr.data(); 100*471d65cfSLoGin 101*471d65cfSLoGin // 设置系统调用返回时的寄存器状态 102*471d65cfSLoGin regs.sp = user_sp.data(); 103*471d65cfSLoGin 104*471d65cfSLoGin regs.epc = load_result.entry_point().data(); 105*471d65cfSLoGin regs.status.update_spp(SPP::User); 106*471d65cfSLoGin regs.status.update_fs(FS::Clean); 107*471d65cfSLoGin regs.status.update_sie(true); 108*471d65cfSLoGin regs.status.update_sum(true); 109*471d65cfSLoGin 110*471d65cfSLoGin drop(param); 111*471d65cfSLoGin 112*471d65cfSLoGin return Ok(()); 1134fda81ceSLoGin } 1144fda81ceSLoGin 1154fda81ceSLoGin /// ## 用于控制和查询与体系结构相关的进程特定选项 1164fda81ceSLoGin pub fn arch_prctl(option: usize, arg2: usize) -> Result<usize, SystemError> { 1174fda81ceSLoGin unimplemented!("Syscall::arch_prctl") 1184fda81ceSLoGin } 1194fda81ceSLoGin } 120