add: finish basic work

This commit is contained in:
2024-07-18 22:48:23 +08:00
parent c47d636498
commit 8cf6fdc9bf
13 changed files with 353 additions and 40 deletions

View File

@@ -1,7 +1,10 @@
use core::arch::asm;
use core::cell::UnsafeCell;
use lazy_static::lazy_static;
use crate::println;
use crate::log_information;
use crate::sync::single_cell::SingleCell;
use crate::trap::context::TrapContext;
const MAX_APP_NUMBER: usize = 32;
const APP_BASE_ADDRESS: usize = 0x80400000;
@@ -14,13 +17,13 @@ struct AppManager {
}
lazy_static! {
static ref APP_MANAGER: UnsafeCell<AppManager> = unsafe {
UnsafeCell::new({
static ref APP_MANAGER: SingleCell<AppManager> = unsafe {
SingleCell::new({
extern "C" {
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();
let mut start_addresses: [usize; MAX_APP_NUMBER + 1] = [0; MAX_APP_NUMBER + 1];
let start_addresses_raw: &[usize] = core::slice::from_raw_parts(
@@ -38,10 +41,10 @@ lazy_static! {
impl AppManager {
pub fn print_app_information(&self) {
println!("[kernel] Application count is {}.", self.app_count);
log_information!("[kernel] Application count is {}.", self.app_count);
for i in 0..self.app_count {
println!("[kernel] Application_{} ({:#x} -> {:#x})",
log_information!("[kernel] Application_{} ({:#x} -> {:#x})",
i,
self.start_addresses[i],
self.start_addresses[i + 1]);
@@ -61,7 +64,7 @@ impl AppManager {
panic!("Application id is invalid!");
}
println!("[kernel] Loading application_{}...", app_id);
log_information!("[kernel] Loading application_{}...", app_id);
core::slice::from_raw_parts_mut(
APP_BASE_ADDRESS as *mut u8,
@@ -74,7 +77,7 @@ impl AppManager {
);
let app_destination = core::slice::from_raw_parts_mut(
APP_BASE_ADDRESS as *mut u8,
APP_SIZE_LIMIT
app_source.len()
);
app_destination.copy_from_slice(app_source);
@@ -84,3 +87,72 @@ impl AppManager {
}
}
const USER_STACK_SIZE: usize = 4096 * 2;
const KERNEL_STACK_SIZE: usize = 4096 * 2;
#[repr(align(4096))]
struct UserStack {
data: [u8; USER_STACK_SIZE]
}
impl UserStack {
fn get_sp(&self) -> usize {
self.data.as_ptr() as usize + USER_STACK_SIZE
}
}
#[repr(align(4096))]
struct KernelStack {
data: [u8; KERNEL_STACK_SIZE]
}
impl KernelStack {
fn get_sp(&self) -> usize {
self.data.as_ptr() as usize + KERNEL_STACK_SIZE
}
pub fn push_context(&self, context: TrapContext) -> &'static mut TrapContext {
let context_pointer = (self.get_sp() - size_of::<TrapContext>()) as *mut TrapContext;
unsafe {
*context_pointer = context;
context_pointer.as_mut().unwrap()
}
}
}
static KERNEL_STACK: KernelStack = KernelStack { data: [0; KERNEL_STACK_SIZE]};
static USER_STACK: UserStack = UserStack { data: [0; USER_STACK_SIZE]};
pub fn print_app_information() {
let app_manager = APP_MANAGER.exclusive_borrow();
app_manager.print_app_information();
}
pub fn run_next_application() -> ! {
let mut app_manager = APP_MANAGER.exclusive_borrow();
let current_app = app_manager.get_current_app();
unsafe {
app_manager.load_app(current_app);
}
app_manager.move_to_next_app();
// We must drop resource manually
// As this function will never return!
drop(app_manager);
extern "C" {
fn __restore(context_address: usize);
}
unsafe {
let context_address = KERNEL_STACK.push_context(TrapContext::init_application_context(
APP_BASE_ADDRESS,
USER_STACK.get_sp()
)) as *const _ as usize;
__restore(context_address);
unreachable!()
}
}