Switch ok with debug mode apps, implement sys_exit correctly later.

This commit is contained in:
Yifan Wu 2020-11-29 01:31:36 +08:00
parent 4e8059e222
commit 3f3e6b2b99
16 changed files with 244 additions and 147 deletions

94
os/src/loader.rs Normal file
View file

@ -0,0 +1,94 @@
use core::cell::RefCell;
use lazy_static::*;
use crate::trap::TrapContext;
use crate::task::TaskContext;
use crate::config::*;
#[repr(align(4096))]
struct KernelStack {
data: [u8; KERNEL_STACK_SIZE],
}
#[repr(align(4096))]
struct UserStack {
data: [u8; USER_STACK_SIZE],
}
static KERNEL_STACK: [KernelStack; MAX_APP_NUM] = [
KernelStack { data: [0; KERNEL_STACK_SIZE], };
MAX_APP_NUM
];
static USER_STACK: [UserStack; MAX_APP_NUM] = [
UserStack { data: [0; USER_STACK_SIZE], };
MAX_APP_NUM
];
impl KernelStack {
fn get_sp(&self) -> usize {
self.data.as_ptr() as usize + KERNEL_STACK_SIZE
}
pub fn push_context(&self, trap_cx: TrapContext, task_cx: TaskContext) -> &'static mut TaskContext {
let trap_cx_ptr = (self.get_sp() - core::mem::size_of::<TrapContext>()) as *mut TrapContext;
unsafe { *trap_cx_ptr = trap_cx; }
let task_cx_ptr = (trap_cx_ptr as usize - core::mem::size_of::<TaskContext>()) as *mut TaskContext;
unsafe { *task_cx_ptr = task_cx; }
unsafe { task_cx_ptr.as_mut().unwrap() }
}
}
impl UserStack {
fn get_sp(&self) -> usize {
self.data.as_ptr() as usize + USER_STACK_SIZE
}
}
fn get_base_i(app_id: usize) -> usize {
APP_BASE_ADDRESS + app_id * APP_SIZE_LIMIT
}
pub fn get_num_app() -> usize {
extern "C" { fn _num_app(); }
unsafe { (_num_app as usize as *const usize).read_volatile() }
}
pub fn load_apps() {
extern "C" { fn _num_app(); }
let num_app_ptr = _num_app as usize as *const usize;
let num_app = get_num_app();
let app_start = unsafe {
core::slice::from_raw_parts(num_app_ptr.add(1), num_app + 1)
};
// clear i-cache first
unsafe { llvm_asm!("fence.i" :::: "volatile"); }
// load apps
for i in 0..num_app {
println!("i = {}", i);
println!("[{:#x}, {:#x})", app_start[i], app_start[i + 1]);
let base_i = get_base_i(i);
// clear region
(base_i..base_i + APP_SIZE_LIMIT).for_each(|addr| unsafe {
(addr as *mut u8).write_volatile(0)
});
// load app from data section to memory
let src = unsafe {
core::slice::from_raw_parts(app_start[i] as *const u8, app_start[i + 1] - app_start[i])
};
let dst = unsafe {
core::slice::from_raw_parts_mut(base_i as *mut u8, src.len())
};
dst.copy_from_slice(src);
}
}
pub fn init_app_cx(app_id: usize) -> &'static TaskContext {
println!("app_id = {}, kernel_sp = {:#x}, user_sp = {:#x}",
app_id,
KERNEL_STACK[app_id].get_sp(),
USER_STACK[app_id].get_sp()
);
KERNEL_STACK[app_id].push_context(
TrapContext::app_init_context(get_base_i(app_id), USER_STACK[app_id].get_sp()),
TaskContext::goto_restore(),
)
}