|
|
|
@ -1,4 +1,10 @@
|
|
|
|
|
use crate::mm::{MemorySet, PhysPageNum, KERNEL_SPACE, VirtAddr};
|
|
|
|
|
use crate::mm::{
|
|
|
|
|
MemorySet,
|
|
|
|
|
PhysPageNum,
|
|
|
|
|
KERNEL_SPACE,
|
|
|
|
|
VirtAddr,
|
|
|
|
|
translated_refmut,
|
|
|
|
|
};
|
|
|
|
|
use crate::trap::{TrapContext, trap_handler};
|
|
|
|
|
use crate::config::{TRAP_CONTEXT};
|
|
|
|
|
use super::TaskContext;
|
|
|
|
@ -6,6 +12,7 @@ use super::{PidHandle, pid_alloc, KernelStack};
|
|
|
|
|
use alloc::sync::{Weak, Arc};
|
|
|
|
|
use alloc::vec;
|
|
|
|
|
use alloc::vec::Vec;
|
|
|
|
|
use alloc::string::String;
|
|
|
|
|
use spin::{Mutex, MutexGuard};
|
|
|
|
|
use crate::fs::{File, Stdin, Stdout};
|
|
|
|
|
|
|
|
|
@ -106,13 +113,35 @@ impl TaskControlBlock {
|
|
|
|
|
);
|
|
|
|
|
task_control_block
|
|
|
|
|
}
|
|
|
|
|
pub fn exec(&self, elf_data: &[u8]) {
|
|
|
|
|
pub fn exec(&self, elf_data: &[u8], args: Vec<String>) {
|
|
|
|
|
// memory_set with elf program headers/trampoline/trap context/user stack
|
|
|
|
|
let (memory_set, user_sp, entry_point) = MemorySet::from_elf(elf_data);
|
|
|
|
|
let (memory_set, mut user_sp, entry_point) = MemorySet::from_elf(elf_data);
|
|
|
|
|
let trap_cx_ppn = memory_set
|
|
|
|
|
.translate(VirtAddr::from(TRAP_CONTEXT).into())
|
|
|
|
|
.unwrap()
|
|
|
|
|
.ppn();
|
|
|
|
|
// push arguments on user stack
|
|
|
|
|
user_sp -= (args.len() + 1) * core::mem::size_of::<usize>();
|
|
|
|
|
let argv_base = user_sp;
|
|
|
|
|
let mut argv: Vec<_> = (0..=args.len())
|
|
|
|
|
.map(|arg| {
|
|
|
|
|
translated_refmut(
|
|
|
|
|
memory_set.token(),
|
|
|
|
|
(argv_base + arg * core::mem::size_of::<usize>()) as *mut usize
|
|
|
|
|
)
|
|
|
|
|
})
|
|
|
|
|
.collect();
|
|
|
|
|
*argv[args.len()] = 0;
|
|
|
|
|
for i in 0..args.len() {
|
|
|
|
|
user_sp -= args[i].len() + 1;
|
|
|
|
|
*argv[i] = user_sp;
|
|
|
|
|
let mut p = user_sp;
|
|
|
|
|
for c in args[i].as_bytes() {
|
|
|
|
|
*translated_refmut(memory_set.token(), p as *mut u8) = *c;
|
|
|
|
|
p += 1;
|
|
|
|
|
}
|
|
|
|
|
*translated_refmut(memory_set.token(), p as *mut u8) = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// **** hold current PCB lock
|
|
|
|
|
let mut inner = self.acquire_inner_lock();
|
|
|
|
@ -121,14 +150,16 @@ impl TaskControlBlock {
|
|
|
|
|
// update trap_cx ppn
|
|
|
|
|
inner.trap_cx_ppn = trap_cx_ppn;
|
|
|
|
|
// initialize trap_cx
|
|
|
|
|
let trap_cx = inner.get_trap_cx();
|
|
|
|
|
*trap_cx = TrapContext::app_init_context(
|
|
|
|
|
let mut trap_cx = TrapContext::app_init_context(
|
|
|
|
|
entry_point,
|
|
|
|
|
user_sp,
|
|
|
|
|
KERNEL_SPACE.lock().token(),
|
|
|
|
|
self.kernel_stack.get_top(),
|
|
|
|
|
trap_handler as usize,
|
|
|
|
|
);
|
|
|
|
|
trap_cx.x[10] = args.len();
|
|
|
|
|
trap_cx.x[11] = argv_base;
|
|
|
|
|
*inner.get_trap_cx() = trap_cx;
|
|
|
|
|
// **** release current PCB lock
|
|
|
|
|
}
|
|
|
|
|
pub fn fork(self: &Arc<TaskControlBlock>) -> Arc<TaskControlBlock> {
|
|
|
|
|