Only support processes with a single thread.
(self: &Arc<Self>, elf_data: &[u8], args: Vec<String>)
| 133 | |
| 134 | /// Only support processes with a single thread. |
| 135 | pub fn exec(self: &Arc<Self>, elf_data: &[u8], args: Vec<String>) { |
| 136 | assert_eq!(self.inner_exclusive_access().thread_count(), 1); |
| 137 | // memory_set with elf program headers/trampoline/trap context/user stack |
| 138 | let (memory_set, ustack_base, entry_point) = MemorySet::from_elf(elf_data); |
| 139 | let new_token = memory_set.token(); |
| 140 | // substitute memory_set |
| 141 | self.inner_exclusive_access().memory_set = memory_set; |
| 142 | // then we alloc user resource for main thread again |
| 143 | // since memory_set has been changed |
| 144 | let task = self.inner_exclusive_access().get_task(0); |
| 145 | let mut task_inner = task.inner_exclusive_access(); |
| 146 | task_inner.res.as_mut().unwrap().ustack_base = ustack_base; |
| 147 | task_inner.res.as_mut().unwrap().alloc_user_res(); |
| 148 | task_inner.trap_cx_ppn = task_inner.res.as_mut().unwrap().trap_cx_ppn(); |
| 149 | // push arguments on user stack |
| 150 | let mut user_sp = task_inner.res.as_mut().unwrap().ustack_top(); |
| 151 | user_sp -= (args.len() + 1) * core::mem::size_of::<usize>(); |
| 152 | let argv_base = user_sp; |
| 153 | let mut argv: Vec<_> = (0..=args.len()) |
| 154 | .map(|arg| { |
| 155 | translated_refmut( |
| 156 | new_token, |
| 157 | (argv_base + arg * core::mem::size_of::<usize>()) as *mut usize, |
| 158 | ) |
| 159 | }) |
| 160 | .collect(); |
| 161 | *argv[args.len()] = 0; |
| 162 | for i in 0..args.len() { |
| 163 | user_sp -= args[i].len() + 1; |
| 164 | *argv[i] = user_sp; |
| 165 | let mut p = user_sp; |
| 166 | for c in args[i].as_bytes() { |
| 167 | *translated_refmut(new_token, p as *mut u8) = *c; |
| 168 | p += 1; |
| 169 | } |
| 170 | *translated_refmut(new_token, p as *mut u8) = 0; |
| 171 | } |
| 172 | // make the user_sp aligned to 8B for k210 platform |
| 173 | user_sp -= user_sp % core::mem::size_of::<usize>(); |
| 174 | // initialize trap_cx |
| 175 | let mut trap_cx = TrapContext::app_init_context( |
| 176 | entry_point, |
| 177 | user_sp, |
| 178 | KERNEL_SPACE.exclusive_access().token(), |
| 179 | task.kstack.get_top(), |
| 180 | trap_handler as usize, |
| 181 | ); |
| 182 | trap_cx.x[10] = args.len(); |
| 183 | trap_cx.x[11] = argv_base; |
| 184 | *task_inner.get_trap_cx() = trap_cx; |
| 185 | } |
| 186 | |
| 187 | /// Only support processes with a single thread. |
| 188 | pub fn fork(self: &Arc<Self>) -> Arc<Self> { |
no test coverage detected