|
|
@ -1,6 +1,9 @@
|
|
|
|
|
|
|
|
use core::arch::asm;
|
|
|
|
use lazy_static::*;
|
|
|
|
use lazy_static::*;
|
|
|
|
|
|
|
|
use riscv::register::mcause::Trap;
|
|
|
|
use crate::println;
|
|
|
|
use crate::println;
|
|
|
|
use crate::sync::UPSafeCell;
|
|
|
|
use crate::sync::UPSafeCell;
|
|
|
|
|
|
|
|
use crate::trap::TrapContext;
|
|
|
|
|
|
|
|
|
|
|
|
const USER_STACK_SIZE: usize = 4096 * 2; // 栈大小为8kb
|
|
|
|
const USER_STACK_SIZE: usize = 4096 * 2; // 栈大小为8kb
|
|
|
|
const KERNEL_STACK_SIZE: usize = 4096 * 2;
|
|
|
|
const KERNEL_STACK_SIZE: usize = 4096 * 2;
|
|
|
@ -10,7 +13,9 @@ const MAX_APP_NUM: usize = 16; // 系统最大支持的运行程序数量
|
|
|
|
const APP_BASE_ADDRESS: usize = 0x80400000; // 载入的app的起始的地址
|
|
|
|
const APP_BASE_ADDRESS: usize = 0x80400000; // 载入的app的起始的地址
|
|
|
|
const APP_SIZE_LIMIT: usize = 0x20000; // app的最大的二进制文件能够使用的大小
|
|
|
|
const APP_SIZE_LIMIT: usize = 0x20000; // app的最大的二进制文件能够使用的大小
|
|
|
|
|
|
|
|
|
|
|
|
// 在此之后应用使用UserStack, 而内核使用KernelStack, entry.asm设置的64k启动栈不再被使用
|
|
|
|
// 在此之后 应用使用UserStack, 而内核使用KernelStack, entry.asm设置的64k启动栈不再被使用(首次运行run_next_app时被接管了 mv sp, a0)
|
|
|
|
|
|
|
|
// KERNEL_STACK 保存的是 Trap Context
|
|
|
|
|
|
|
|
|
|
|
|
static KERNEL_STACK: [u8; KERNEL_STACK_SIZE] = [0; KERNEL_STACK_SIZE];
|
|
|
|
static KERNEL_STACK: [u8; KERNEL_STACK_SIZE] = [0; KERNEL_STACK_SIZE];
|
|
|
|
static USER_STACK: [u8; USER_STACK_SIZE] = [0; USER_STACK_SIZE];
|
|
|
|
static USER_STACK: [u8; USER_STACK_SIZE] = [0; USER_STACK_SIZE];
|
|
|
|
|
|
|
|
|
|
|
@ -52,13 +57,38 @@ impl AppManager{
|
|
|
|
println!("[kernel] num_app = {}", self.num_app);
|
|
|
|
println!("[kernel] num_app = {}", self.num_app);
|
|
|
|
for i in 0..self.num_app {
|
|
|
|
for i in 0..self.num_app {
|
|
|
|
println!(
|
|
|
|
println!(
|
|
|
|
"[kernel] app_{} [{:#x}, {:#x})",
|
|
|
|
"[kernel] app_{} ({:#x}, {:#x})",
|
|
|
|
i,
|
|
|
|
i,
|
|
|
|
self.app_start_lis[i],
|
|
|
|
self.app_start_lis[i],
|
|
|
|
self.app_start_lis[i + 1]
|
|
|
|
self.app_start_lis[i + 1]
|
|
|
|
);
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 把app_idx位置的app 加载到指定的内存APP_BASE_ADDRESS位置
|
|
|
|
|
|
|
|
unsafe fn load_app(&self, app_idx: usize){
|
|
|
|
|
|
|
|
if app_idx >= self.num_app{
|
|
|
|
|
|
|
|
panic!("All applications completed!")
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
// 清空app执行区域的内存
|
|
|
|
|
|
|
|
core::slice::from_raw_parts_mut(APP_BASE_ADDRESS as *mut u8, APP_SIZE_LIMIT).fill(0);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 得到指定app_idx位置的数据(下一个位置的开始 - 需要运行app的开始 = 需要运行app的内存大小
|
|
|
|
|
|
|
|
let app_src = core::slice::from_raw_parts(self.app_start_lis[app_idx] as *const u8,
|
|
|
|
|
|
|
|
self.app_start_lis[app_idx + 1] - self.app_start_lis[app_idx]);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 把app的代码 copy到指定的运行的区域
|
|
|
|
|
|
|
|
let app_len = app_src.len();
|
|
|
|
|
|
|
|
if app_len > APP_SIZE_LIMIT {
|
|
|
|
|
|
|
|
panic!("app memory overrun!")
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
core::slice::from_raw_parts_mut(APP_BASE_ADDRESS as *mut u8, app_len)
|
|
|
|
|
|
|
|
.copy_from_slice(app_src);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 刷新cache
|
|
|
|
|
|
|
|
asm!("fence.i");
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -66,6 +96,41 @@ pub fn init() {
|
|
|
|
APP_MANAGER.exclusive_access().show_app_info();
|
|
|
|
APP_MANAGER.exclusive_access().show_app_info();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
pub fn run_next_app() -> *mut TrapContext{
|
|
|
|
|
|
|
|
// 运行一个新的app
|
|
|
|
|
|
|
|
// 把需要执行的指定app, 加载到执行位置APP_BASE_ADDRESS
|
|
|
|
|
|
|
|
// app_manager 需要drop 或者在一个作用域中, 因为这个函数不会返回, 后面直接进入用户态了
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
let mut app_manager = APP_MANAGER.exclusive_access();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
unsafe{
|
|
|
|
|
|
|
|
app_manager.load_app(app_manager.current_app);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
app_manager.current_app += 1;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
extern "C" {
|
|
|
|
|
|
|
|
fn __restore(trap_context_ptr: usize);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
unsafe {
|
|
|
|
|
|
|
|
// 得到用户栈的栈顶
|
|
|
|
|
|
|
|
let user_stack_top = USER_STACK.as_ptr() as usize + USER_STACK_SIZE;
|
|
|
|
|
|
|
|
// 得到用户trap的上下文以及寄存器状态
|
|
|
|
|
|
|
|
let user_trap_context = TrapContext::app_init_context(APP_BASE_ADDRESS, user_stack_top);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 把用户trap copy到内核栈, 并把内核栈栈顶返回
|
|
|
|
|
|
|
|
let kernel_stack_top = KERNEL_STACK.as_ptr() as usize + KERNEL_STACK_SIZE; // 现在栈顶和栈底都在一个内存位置
|
|
|
|
|
|
|
|
let kernel_trap_context_ptr = (kernel_stack_top - core::mem::size_of::<TrapContext>()) as * mut TrapContext; // 为trap context 分配栈空间
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
unsafe {
|
|
|
|
|
|
|
|
*kernel_trap_context_ptr = user_trap_context;
|
|
|
|
|
|
|
|
// 返回现在的内核栈顶
|
|
|
|
|
|
|
|
kernel_trap_context_ptr
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|