全局的任务管理器完成
parent
a667808a28
commit
feebb265d1
@ -1,2 +1,6 @@
|
|||||||
pub const APP_BASE_ADDRESS: usize = 0x80400000; // 载入的app的起始的地址
|
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 中的汇编中
|
// TCB的字段 用来保存cpu 在内核切换人物的时候 寄存器还有栈顶的信息, 这个结构体将来会传到 switch.S 中的汇编中
|
||||||
|
#[derive(Copy, Clone)]
|
||||||
|
#[repr(C)]
|
||||||
pub struct TaskContext{
|
pub struct TaskContext{
|
||||||
ra: usize, // 保存了进行切换之后需要 跳转继续执行的地址
|
ra: usize, // 保存了进行切换完毕之后需要 跳转继续执行的地址
|
||||||
sp: usize, // 当前任务的内核栈的栈顶
|
sp: usize, // 当前任务的在内核中的内核栈的栈顶, 这个会被switch 保存与恢复
|
||||||
s: [usize; 12] // 当前任务内核 有必要 保存的寄存器
|
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 context;
|
||||||
mod switch;
|
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