Fetching buffer arguments from user space.
This commit is contained in:
parent
d38b24a9cb
commit
9366099b28
20 changed files with 405 additions and 82 deletions
|
@ -1,3 +1,5 @@
|
|||
use crate::trap::trap_return;
|
||||
|
||||
#[repr(C)]
|
||||
pub struct TaskContext {
|
||||
ra: usize,
|
||||
|
@ -5,10 +7,9 @@ pub struct TaskContext {
|
|||
}
|
||||
|
||||
impl TaskContext {
|
||||
pub fn goto_restore() -> Self {
|
||||
extern "C" { fn __restore(); }
|
||||
pub fn goto_trap_return() -> Self {
|
||||
Self {
|
||||
ra: __restore as usize,
|
||||
ra: trap_return as usize,
|
||||
s: [0; 12],
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,11 +3,13 @@ mod switch;
|
|||
mod task;
|
||||
|
||||
use crate::config::MAX_APP_NUM;
|
||||
use crate::loader::{get_num_app, init_app_cx};
|
||||
use crate::loader::{get_num_app, get_app_data};
|
||||
use crate::trap::TrapContext;
|
||||
use core::cell::RefCell;
|
||||
use lazy_static::*;
|
||||
use switch::__switch;
|
||||
use task::{TaskControlBlock, TaskStatus};
|
||||
use alloc::vec::Vec;
|
||||
|
||||
pub use context::TaskContext;
|
||||
|
||||
|
@ -17,7 +19,7 @@ pub struct TaskManager {
|
|||
}
|
||||
|
||||
struct TaskManagerInner {
|
||||
tasks: [TaskControlBlock; MAX_APP_NUM],
|
||||
tasks: Vec<TaskControlBlock>,
|
||||
current_task: usize,
|
||||
}
|
||||
|
||||
|
@ -25,14 +27,16 @@ unsafe impl Sync for TaskManager {}
|
|||
|
||||
lazy_static! {
|
||||
pub static ref TASK_MANAGER: TaskManager = {
|
||||
println!("init TASK_MANAGER");
|
||||
let num_app = get_num_app();
|
||||
let mut tasks = [
|
||||
TaskControlBlock { task_cx_ptr: 0, task_status: TaskStatus::UnInit };
|
||||
MAX_APP_NUM
|
||||
];
|
||||
println!("num_app = {}", num_app);
|
||||
let mut tasks: Vec<TaskControlBlock> = Vec::new();
|
||||
for i in 0..num_app {
|
||||
tasks[i].task_cx_ptr = init_app_cx(i) as * const _ as usize;
|
||||
tasks[i].task_status = TaskStatus::Ready;
|
||||
println!("creating TCB #{}", i);
|
||||
tasks.push(TaskControlBlock::new(
|
||||
get_app_data(i),
|
||||
i,
|
||||
));
|
||||
}
|
||||
TaskManager {
|
||||
num_app,
|
||||
|
@ -46,11 +50,14 @@ lazy_static! {
|
|||
|
||||
impl TaskManager {
|
||||
fn run_first_task(&self) {
|
||||
println!("into TaskManager::run_first_task");
|
||||
self.inner.borrow_mut().tasks[0].task_status = TaskStatus::Running;
|
||||
let next_task_cx = self.inner.borrow().tasks[0].get_task_cx_ptr2();
|
||||
println!("next_task_cx={:p} {:#x}", next_task_cx, unsafe { next_task_cx.read_volatile() });
|
||||
let _unused: usize = 0;
|
||||
unsafe {
|
||||
__switch(
|
||||
&0usize as *const _,
|
||||
&_unused as *const _,
|
||||
next_task_cx,
|
||||
);
|
||||
}
|
||||
|
@ -78,6 +85,18 @@ impl TaskManager {
|
|||
})
|
||||
}
|
||||
|
||||
fn get_current_token(&self) -> usize {
|
||||
let inner = self.inner.borrow();
|
||||
let current = inner.current_task;
|
||||
inner.tasks[current].get_user_token()
|
||||
}
|
||||
|
||||
fn get_current_trap_cx(&self) -> &mut TrapContext {
|
||||
let inner = self.inner.borrow();
|
||||
let current = inner.current_task;
|
||||
inner.tasks[current].get_trap_cx()
|
||||
}
|
||||
|
||||
fn run_next_task(&self) {
|
||||
if let Some(next) = self.find_next_task() {
|
||||
let mut inner = self.inner.borrow_mut();
|
||||
|
@ -123,4 +142,12 @@ pub fn suspend_current_and_run_next() {
|
|||
pub fn exit_current_and_run_next() {
|
||||
mark_current_exited();
|
||||
run_next_task();
|
||||
}
|
||||
|
||||
pub fn current_user_token() -> usize {
|
||||
TASK_MANAGER.get_current_token()
|
||||
}
|
||||
|
||||
pub fn current_trap_cx() -> &'static mut TrapContext {
|
||||
TASK_MANAGER.get_current_trap_cx()
|
||||
}
|
|
@ -1,12 +1,72 @@
|
|||
use crate::mm::{MemorySet, MapPermission, PhysPageNum, KERNEL_SPACE, VirtAddr};
|
||||
use crate::trap::{TrapContext, trap_handler};
|
||||
use crate::config::{TRAP_CONTEXT, kernel_stack_position};
|
||||
use super::TaskContext;
|
||||
|
||||
pub struct TaskControlBlock {
|
||||
pub task_cx_ptr: usize,
|
||||
pub task_status: TaskStatus,
|
||||
pub memory_set: MemorySet,
|
||||
pub trap_cx_ppn: PhysPageNum,
|
||||
pub base_size: usize,
|
||||
}
|
||||
|
||||
impl TaskControlBlock {
|
||||
pub fn get_task_cx_ptr2(&self) -> *const usize {
|
||||
&self.task_cx_ptr as *const usize
|
||||
}
|
||||
pub fn get_trap_cx(&self) -> &'static mut TrapContext {
|
||||
self.trap_cx_ppn.get_mut()
|
||||
}
|
||||
pub fn get_user_token(&self) -> usize {
|
||||
self.memory_set.token()
|
||||
}
|
||||
pub fn new(elf_data: &[u8], app_id: usize) -> Self {
|
||||
//println!("into TCB::new");
|
||||
// memory_set with elf program headers/trampoline/trap context/user stack
|
||||
let (memory_set, user_sp, entry_point) = MemorySet::from_elf(elf_data);
|
||||
//println!("user_sp={:#x},entry_point={:#}", user_sp, entry_point);
|
||||
let trap_cx_ppn = memory_set
|
||||
.translate(VirtAddr::from(TRAP_CONTEXT).into())
|
||||
.unwrap()
|
||||
.ppn();
|
||||
//println!("trap_cx_ppn={:?}", trap_cx_ppn);
|
||||
let task_status = TaskStatus::Ready;
|
||||
// map a kernel-stack in kernel space
|
||||
//println!("mapping kernel-stack!");
|
||||
let (kernel_stack_bottom, kernel_stack_top) = kernel_stack_position(app_id);
|
||||
//println!("kernel_stack={:#x},{:#x}", kernel_stack_bottom, kernel_stack_top);
|
||||
KERNEL_SPACE
|
||||
.lock()
|
||||
.insert_framed_area(
|
||||
kernel_stack_bottom.into(),
|
||||
kernel_stack_top.into(),
|
||||
MapPermission::R | MapPermission::W,
|
||||
);
|
||||
let task_cx_ptr = (kernel_stack_top - core::mem::size_of::<TaskContext>()) as *mut TaskContext;
|
||||
//println!("task_cx size={}", core::mem::size_of::<TaskContext>());
|
||||
//println!("init task_cx, ptr={:p}", task_cx_ptr);
|
||||
unsafe { *task_cx_ptr = TaskContext::goto_trap_return(); }
|
||||
//println!("after init task_cx");
|
||||
let task_control_block = Self {
|
||||
task_cx_ptr: task_cx_ptr as usize,
|
||||
task_status,
|
||||
memory_set,
|
||||
trap_cx_ppn,
|
||||
base_size: user_sp,
|
||||
};
|
||||
// prepare TrapContext in user space
|
||||
//println!("preparing trap_cx");
|
||||
let trap_cx = task_control_block.get_trap_cx();
|
||||
*trap_cx = TrapContext::app_init_context(
|
||||
entry_point,
|
||||
user_sp,
|
||||
KERNEL_SPACE.lock().token(),
|
||||
kernel_stack_top,
|
||||
trap_handler as usize,
|
||||
);
|
||||
task_control_block
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, PartialEq)]
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue