添加了任务管理TaskManager的子功能, 修改了sys_exit为使用 switch进行切换
parent
feebb265d1
commit
8b3ae72470
@ -1,111 +1,111 @@
|
|||||||
use core::arch::asm;
|
// use core::arch::asm;
|
||||||
use lazy_static::*;
|
// use lazy_static::*;
|
||||||
use riscv::register::mcause::Trap;
|
// use riscv::register::mcause::Trap;
|
||||||
use crate::println;
|
// use crate::println;
|
||||||
use crate::sbi::shutdown;
|
// use crate::sbi::shutdown;
|
||||||
use crate::sync::UPSafeCell;
|
// use crate::sync::UPSafeCell;
|
||||||
use crate::trap::TrapContext;
|
// 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;
|
||||||
|
//
|
||||||
const MAX_APP_NUM: usize = 16; // 系统最大支持的运行程序数量
|
// 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启动栈不再被使用(首次运行run_next_app时被接管了 mv sp, a0)
|
// // 在此之后 应用使用UserStack, 而内核使用KernelStack, entry.asm设置的64k启动栈不再被使用(首次运行run_next_app时被接管了 mv sp, a0)
|
||||||
// KERNEL_STACK 保存的是 Trap Context
|
// // 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];
|
||||||
|
//
|
||||||
lazy_static! {
|
// lazy_static! {
|
||||||
static ref APP_MANAGER: UPSafeCell<AppManager> = unsafe {
|
// static ref APP_MANAGER: UPSafeCell<AppManager> = unsafe {
|
||||||
UPSafeCell::new({
|
// UPSafeCell::new({
|
||||||
extern "C" {
|
// extern "C" {
|
||||||
fn _num_app();
|
// fn _num_app();
|
||||||
}
|
// }
|
||||||
let num_app_ptr = _num_app as usize as *const usize;
|
// let num_app_ptr = _num_app as usize as *const usize;
|
||||||
let num_app = num_app_ptr.read_volatile(); // 用户app的总数量
|
// let num_app = num_app_ptr.read_volatile(); // 用户app的总数量
|
||||||
|
//
|
||||||
let mut app_start_lis: [usize; MAX_APP_NUM + 1] = [0; MAX_APP_NUM + 1]; // 创建一个数组, 用来保存每个app的起始位置
|
// let mut app_start_lis: [usize; MAX_APP_NUM + 1] = [0; MAX_APP_NUM + 1]; // 创建一个数组, 用来保存每个app的起始位置
|
||||||
|
//
|
||||||
// 得到每个app的起始地址
|
// // 得到每个app的起始地址
|
||||||
let mut app_start_lis: [usize; MAX_APP_NUM + 1] = [0; MAX_APP_NUM + 1];
|
// let mut app_start_lis: [usize; MAX_APP_NUM + 1] = [0; MAX_APP_NUM + 1];
|
||||||
let app_start_raw: &[usize] =
|
// let app_start_raw: &[usize] =
|
||||||
core::slice::from_raw_parts(num_app_ptr.add(1), num_app + 1);
|
// core::slice::from_raw_parts(num_app_ptr.add(1), num_app + 1);
|
||||||
app_start_lis[..=num_app].copy_from_slice(app_start_raw);
|
// app_start_lis[..=num_app].copy_from_slice(app_start_raw);
|
||||||
|
//
|
||||||
AppManager{
|
// AppManager{
|
||||||
num_app,
|
// num_app,
|
||||||
current_app: 0,
|
// current_app: 0,
|
||||||
app_start_lis
|
// app_start_lis
|
||||||
}
|
// }
|
||||||
})
|
// })
|
||||||
};
|
// };
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
// 由build.rs 生成的link_app.S, 根据里面的信息生成的结构体
|
// // 由build.rs 生成的link_app.S, 根据里面的信息生成的结构体
|
||||||
struct AppManager {
|
// struct AppManager {
|
||||||
num_app: usize, // 用户app数量
|
// num_app: usize, // 用户app数量
|
||||||
current_app: usize, // 当前需要执行的第几个app
|
// current_app: usize, // 当前需要执行的第几个app
|
||||||
app_start_lis: [usize; MAX_APP_NUM + 1], // 保存了每个app的起始位置, 后面会跳到这里, +1 是因为end的位置也占了一个usize, 需要知道end的位置
|
// app_start_lis: [usize; MAX_APP_NUM + 1], // 保存了每个app的起始位置, 后面会跳到这里, +1 是因为end的位置也占了一个usize, 需要知道end的位置
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
impl AppManager{
|
// impl AppManager{
|
||||||
fn show_app_info(&self){
|
// fn show_app_info(&self){
|
||||||
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]
|
||||||
);
|
// );
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
|
//
|
||||||
pub fn init() {
|
// pub fn init() {
|
||||||
APP_MANAGER.exclusive_access().show_app_info();
|
// APP_MANAGER.exclusive_access().show_app_info();
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
pub fn run_next_app() -> ! {
|
// pub fn run_next_app() -> ! {
|
||||||
// 得到下一个需要运行的app的入口地址
|
// // 得到下一个需要运行的app的入口地址
|
||||||
let mut app_manager = APP_MANAGER.exclusive_access();
|
// let mut app_manager = APP_MANAGER.exclusive_access();
|
||||||
let current_app = app_manager.current_app;
|
// let current_app = app_manager.current_app;
|
||||||
if current_app >= app_manager.num_app {
|
// if current_app >= app_manager.num_app {
|
||||||
shutdown();
|
// shutdown();
|
||||||
}
|
// }
|
||||||
let app_entry_ptr = app_manager.app_start_lis[current_app];
|
// let app_entry_ptr = app_manager.app_start_lis[current_app];
|
||||||
println!("------------- run_next_app load app {}, {:x}", current_app, app_entry_ptr);
|
// println!("------------- run_next_app load app {}, {:x}", current_app, app_entry_ptr);
|
||||||
app_manager.current_app += 1;
|
// app_manager.current_app += 1;
|
||||||
drop(app_manager);
|
// drop(app_manager);
|
||||||
|
//
|
||||||
|
//
|
||||||
extern "C" {
|
// extern "C" {
|
||||||
fn __restore(trap_context_ptr: usize);
|
// fn __restore(trap_context_ptr: usize);
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
unsafe {
|
// unsafe {
|
||||||
// 得到用户栈的栈顶
|
// // 得到用户栈的栈顶
|
||||||
let user_stack_top = USER_STACK.as_ptr() as usize + USER_STACK_SIZE;
|
// let user_stack_top = USER_STACK.as_ptr() as usize + USER_STACK_SIZE;
|
||||||
// 得到用户trap的上下文以及寄存器状态
|
// // 得到用户trap的上下文以及寄存器状态
|
||||||
let user_trap_context = TrapContext::from(app_entry_ptr, user_stack_top);
|
// let user_trap_context = TrapContext::from(app_entry_ptr, user_stack_top);
|
||||||
|
//
|
||||||
// 把用户trap copy到内核栈
|
// // 把用户trap copy到内核栈
|
||||||
let kernel_stack_top = KERNEL_STACK.as_ptr() as usize + KERNEL_STACK_SIZE; // 现在栈顶和栈底都在一个内存位置
|
// let kernel_stack_top = KERNEL_STACK.as_ptr() as usize + KERNEL_STACK_SIZE; // 现在栈顶和栈底都在一个内存位置
|
||||||
// 为trap context 分配栈空间
|
// // 为trap context 分配栈空间
|
||||||
let kernel_trap_context_ptr = (kernel_stack_top - core::mem::size_of::<TrapContext>()) as * mut TrapContext;
|
// let kernel_trap_context_ptr = (kernel_stack_top - core::mem::size_of::<TrapContext>()) as * mut TrapContext;
|
||||||
|
//
|
||||||
unsafe {
|
// unsafe {
|
||||||
// 把user_trap_context copy到内核栈顶
|
// // 把user_trap_context copy到内核栈顶
|
||||||
*kernel_trap_context_ptr = user_trap_context;
|
// *kernel_trap_context_ptr = user_trap_context;
|
||||||
// 返回现在的内核栈顶
|
// // 返回现在的内核栈顶
|
||||||
__restore(kernel_trap_context_ptr as *const _ as usize);
|
// __restore(kernel_trap_context_ptr as *const _ as usize);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
panic!("Unreachable in batch::run_current_app!");
|
// panic!("Unreachable in batch::run_current_app!");
|
||||||
}
|
// }
|
||||||
|
@ -1,9 +1,11 @@
|
|||||||
//! App management syscalls
|
//! App management syscalls
|
||||||
use crate::batch::run_next_app;
|
// use crate::batch::run_next_app;
|
||||||
use crate::println;
|
use crate::println;
|
||||||
|
use crate::task::exit_current_and_run_next;
|
||||||
|
|
||||||
/// 任务退出, 并立即切换任务
|
/// 任务退出, 并立即切换任务
|
||||||
pub fn sys_exit(exit_code: i32) -> ! {
|
pub fn sys_exit(exit_code: i32) -> ! {
|
||||||
println!("[kernel] Application exited with code {}", exit_code);
|
println!("[kernel] Application exited with code {}", exit_code);
|
||||||
run_next_app()
|
exit_current_and_run_next();
|
||||||
|
panic!("Unreachable in sys_exit!");
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue