全局的任务管理器完成
parent
a667808a28
commit
feebb265d1
@ -1,2 +1,6 @@
|
||||
pub const APP_BASE_ADDRESS: usize = 0x80400000; // 载入的app的起始的地址
|
||||
pub const APP_SIZE_LIMIT: usize = 0x20000; // app的最大的二进制文件能够使用的大小
|
||||
pub const APP_SIZE_LIMIT: usize = 0x20000; // app的最大的二进制文件能够使用的大小
|
||||
pub const MAX_APP_NUM: usize = 4; // 支持最大的用户应用数量
|
||||
|
||||
pub const USER_STACK_SIZE: usize = 4096 * 2; // 栈大小为8kb
|
||||
pub const KERNEL_STACK_SIZE: usize = 4096 * 2;
|
@ -1,13 +1,35 @@
|
||||
|
||||
|
||||
// TCB的字段 用来保存cpu 在内核切换人物的时候 寄存器还有栈顶的信息, 这个结构体将来会传到 switch.S 中的汇编中
|
||||
#[derive(Copy, Clone)]
|
||||
#[repr(C)]
|
||||
pub struct TaskContext{
|
||||
ra: usize, // 保存了进行切换之后需要 跳转继续执行的地址
|
||||
sp: usize, // 当前任务的内核栈的栈顶
|
||||
ra: usize, // 保存了进行切换完毕之后需要 跳转继续执行的地址
|
||||
sp: usize, // 当前任务的在内核中的内核栈的栈顶, 这个会被switch 保存与恢复
|
||||
s: [usize; 12] // 当前任务内核 有必要 保存的寄存器
|
||||
}
|
||||
|
||||
|
||||
impl TaskContext{
|
||||
// 初始的内容
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
ra: 0,
|
||||
sp: 0,
|
||||
s: [0; 12],
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// 从kernel_stack_ptr 创建一个 任务上下文
|
||||
// 并把任务上下文的返回地址设置为 trap.S的返回符号的地方
|
||||
pub fn from(kernel_stack_ptr: usize) -> Self{
|
||||
extern "C" {
|
||||
fn __restore();
|
||||
}
|
||||
Self {
|
||||
ra: __restore as usize,
|
||||
sp: kernel_stack_ptr,
|
||||
s: [0; 12],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,3 +1,78 @@
|
||||
use lazy_static::lazy_static;
|
||||
use crate::config::MAX_APP_NUM;
|
||||
use crate::sync::UPSafeCell;
|
||||
use crate::task::task::{TaskControlBlock, TaskStatus};
|
||||
use crate::loader::{get_num_app, init_app_cx};
|
||||
use crate::println;
|
||||
use crate::task::context::TaskContext;
|
||||
|
||||
mod context;
|
||||
mod switch;
|
||||
mod task;
|
||||
mod task;
|
||||
|
||||
|
||||
// 公开到外部的一个全局任务管理器的结构体
|
||||
pub struct TaskManager {
|
||||
num_app: usize, // app的数量 这个在os运行之后就不会有变化
|
||||
inner: UPSafeCell<TaskManagerInner>, // 这个内部TaskControlBlock 会随着系统运行发生变化
|
||||
}
|
||||
|
||||
impl TaskManager {
|
||||
fn run_first_task(&self){
|
||||
println!("run_first_task");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 不公开的结构体, 有一个MAX_APP_NUM大小的数组, 用来保存TCB, 和当前任务的的TCB的下标
|
||||
struct TaskManagerInner {
|
||||
tasks: [TaskControlBlock; MAX_APP_NUM],
|
||||
current_task: usize,
|
||||
}
|
||||
|
||||
lazy_static!{
|
||||
pub static ref TASK_MANAGER: TaskManager = {
|
||||
// 得到app的总数
|
||||
let num_app = get_num_app();
|
||||
|
||||
// 初始化内核中的任务列表
|
||||
let mut tasks = [
|
||||
TaskControlBlock {
|
||||
task_cx: TaskContext::new(),
|
||||
// UnInit 这个tcb 还没用户应用填充加载
|
||||
task_status: TaskStatus::UnInit
|
||||
};
|
||||
MAX_APP_NUM
|
||||
];
|
||||
|
||||
// 初始化用户的应用对应的 TCB
|
||||
for i in 0..num_app {
|
||||
// 初始化用户应用的内核栈
|
||||
let kernel_app_stack_ptr = init_app_cx(i);
|
||||
|
||||
// 从 初始内核栈的栈顶(保存 trap_context的位置) 创建 任务context
|
||||
let task_context = TaskContext::from(kernel_app_stack_ptr);
|
||||
|
||||
// 把内核栈的信息保存到 TCB中
|
||||
tasks[i].task_cx = task_context;
|
||||
|
||||
// 初始为 准备好的状态
|
||||
tasks[i].task_status = TaskStatus::Ready
|
||||
};
|
||||
|
||||
TaskManager {
|
||||
num_app,
|
||||
inner: unsafe {
|
||||
UPSafeCell::new(TaskManagerInner {
|
||||
tasks,
|
||||
current_task: 0,
|
||||
})
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
pub fn run_first_task() {
|
||||
TASK_MANAGER.run_first_task();
|
||||
}
|
||||
|
Loading…
Reference in New Issue