14fda81ceSLoGin use alloc::{string::String, vec::Vec}; 2*f75cb0f8SLoGin use riscv::register::sstatus::{FS, SPP}; 391e9d4abSLoGin use system_error::SystemError; 44fda81ceSLoGin 5471d65cfSLoGin use crate::{ 6471d65cfSLoGin arch::{interrupt::TrapFrame, CurrentIrqArch}, 7471d65cfSLoGin exception::InterruptArch, 8471d65cfSLoGin mm::ucontext::AddressSpace, 9471d65cfSLoGin process::{ 10471d65cfSLoGin exec::{load_binary_file, ExecParam, ExecParamFlags}, 11471d65cfSLoGin ProcessManager, 12471d65cfSLoGin }, 13471d65cfSLoGin syscall::Syscall, 14471d65cfSLoGin }; 154fda81ceSLoGin 164fda81ceSLoGin impl Syscall { 174fda81ceSLoGin pub fn do_execve( 184fda81ceSLoGin path: String, 194fda81ceSLoGin argv: Vec<String>, 204fda81ceSLoGin envp: Vec<String>, 214fda81ceSLoGin regs: &mut TrapFrame, 224fda81ceSLoGin ) -> Result<(), SystemError> { 23471d65cfSLoGin // 关中断,防止在设置地址空间的时候,发生中断,然后进调度器,出现错误。 24471d65cfSLoGin let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() }; 25471d65cfSLoGin let pcb = ProcessManager::current_pcb(); 26471d65cfSLoGin // crate::kdebug!( 27471d65cfSLoGin // "pid: {:?} do_execve: path: {:?}, argv: {:?}, envp: {:?}\n", 28471d65cfSLoGin // pcb.pid(), 29471d65cfSLoGin // path, 30471d65cfSLoGin // argv, 31471d65cfSLoGin // envp 32471d65cfSLoGin // ); 33471d65cfSLoGin 34471d65cfSLoGin let mut basic_info = pcb.basic_mut(); 35471d65cfSLoGin // 暂存原本的用户地址空间的引用(因为如果在切换页表之前释放了它,可能会造成内存use after free) 36471d65cfSLoGin let old_address_space = basic_info.user_vm(); 37471d65cfSLoGin 38471d65cfSLoGin // 在pcb中原来的用户地址空间 39471d65cfSLoGin unsafe { 40471d65cfSLoGin basic_info.set_user_vm(None); 41471d65cfSLoGin } 42471d65cfSLoGin // 创建新的地址空间并设置为当前地址空间 43471d65cfSLoGin let address_space = AddressSpace::new(true).expect("Failed to create new address space"); 44471d65cfSLoGin unsafe { 45471d65cfSLoGin basic_info.set_user_vm(Some(address_space.clone())); 46471d65cfSLoGin } 47471d65cfSLoGin 48471d65cfSLoGin // to avoid deadlock 49471d65cfSLoGin drop(basic_info); 50471d65cfSLoGin 51471d65cfSLoGin assert!( 52471d65cfSLoGin AddressSpace::is_current(&address_space), 53471d65cfSLoGin "Failed to set address space" 54471d65cfSLoGin ); 55471d65cfSLoGin // kdebug!("Switch to new address space"); 56471d65cfSLoGin 57471d65cfSLoGin // 切换到新的用户地址空间 58471d65cfSLoGin unsafe { address_space.read().user_mapper.utable.make_current() }; 59471d65cfSLoGin 60471d65cfSLoGin drop(old_address_space); 61471d65cfSLoGin drop(irq_guard); 62471d65cfSLoGin // kdebug!("to load binary file"); 63471d65cfSLoGin let mut param = ExecParam::new(path.as_str(), address_space.clone(), ExecParamFlags::EXEC)?; 64471d65cfSLoGin 65471d65cfSLoGin // 加载可执行文件 66*f75cb0f8SLoGin let load_result = load_binary_file(&mut param)?; 67471d65cfSLoGin // kdebug!("load binary file done"); 68471d65cfSLoGin // kdebug!("argv: {:?}, envp: {:?}", argv, envp); 69471d65cfSLoGin param.init_info_mut().args = argv; 70471d65cfSLoGin param.init_info_mut().envs = envp; 71471d65cfSLoGin 72471d65cfSLoGin // 把proc_init_info写到用户栈上 73471d65cfSLoGin let mut ustack_message = unsafe { 74471d65cfSLoGin address_space 75471d65cfSLoGin .write() 76471d65cfSLoGin .user_stack_mut() 77471d65cfSLoGin .expect("No user stack found") 78471d65cfSLoGin .clone_info_only() 79471d65cfSLoGin }; 80471d65cfSLoGin let (user_sp, argv_ptr) = unsafe { 81471d65cfSLoGin param 82471d65cfSLoGin .init_info() 83471d65cfSLoGin .push_at( 84471d65cfSLoGin // address_space 85471d65cfSLoGin // .write() 86471d65cfSLoGin // .user_stack_mut() 87471d65cfSLoGin // .expect("No user stack found"), 88471d65cfSLoGin &mut ustack_message, 89471d65cfSLoGin ) 90471d65cfSLoGin .expect("Failed to push proc_init_info to user stack") 91471d65cfSLoGin }; 92471d65cfSLoGin address_space.write().user_stack = Some(ustack_message); 93471d65cfSLoGin 94471d65cfSLoGin // kdebug!("write proc_init_info to user stack done"); 95471d65cfSLoGin 96471d65cfSLoGin regs.a0 = param.init_info().args.len(); 97471d65cfSLoGin regs.a1 = argv_ptr.data(); 98471d65cfSLoGin 99471d65cfSLoGin // 设置系统调用返回时的寄存器状态 100471d65cfSLoGin regs.sp = user_sp.data(); 101471d65cfSLoGin 102471d65cfSLoGin regs.epc = load_result.entry_point().data(); 103471d65cfSLoGin regs.status.update_spp(SPP::User); 104471d65cfSLoGin regs.status.update_fs(FS::Clean); 105471d65cfSLoGin regs.status.update_sie(true); 106471d65cfSLoGin regs.status.update_sum(true); 107471d65cfSLoGin 108471d65cfSLoGin drop(param); 109471d65cfSLoGin 110471d65cfSLoGin return Ok(()); 1114fda81ceSLoGin } 1124fda81ceSLoGin 1134fda81ceSLoGin /// ## 用于控制和查询与体系结构相关的进程特定选项 1144fda81ceSLoGin pub fn arch_prctl(option: usize, arg2: usize) -> Result<usize, SystemError> { 1154fda81ceSLoGin unimplemented!("Syscall::arch_prctl") 1164fda81ceSLoGin } 1174fda81ceSLoGin } 118