add AppManager
This commit is contained in:
1
os/src/.gitignore
vendored
Normal file
1
os/src/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
link_app.asm
|
86
os/src/batch.rs
Normal file
86
os/src/batch.rs
Normal file
@@ -0,0 +1,86 @@
|
||||
use core::arch::asm;
|
||||
use core::cell::UnsafeCell;
|
||||
use lazy_static::lazy_static;
|
||||
use crate::println;
|
||||
|
||||
const MAX_APP_NUMBER: usize = 32;
|
||||
const APP_BASE_ADDRESS: usize = 0x80400000;
|
||||
const APP_SIZE_LIMIT: usize = 0x20000;
|
||||
|
||||
struct AppManager {
|
||||
app_count: usize,
|
||||
current: usize,
|
||||
start_addresses: [usize; MAX_APP_NUMBER + 1],
|
||||
}
|
||||
|
||||
lazy_static! {
|
||||
static ref APP_MANAGER: UnsafeCell<AppManager> = unsafe {
|
||||
UnsafeCell::new({
|
||||
extern "C" {
|
||||
fn _num_app();
|
||||
}
|
||||
|
||||
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(
|
||||
num_app_ptr.add(1), num_app + 1
|
||||
);
|
||||
start_addresses[..=num_app].copy_from_slice(start_addresses_raw);
|
||||
AppManager {
|
||||
app_count: num_app,
|
||||
current: 0,
|
||||
start_addresses
|
||||
}
|
||||
})
|
||||
};
|
||||
}
|
||||
|
||||
impl AppManager {
|
||||
pub fn print_app_information(&self) {
|
||||
println!("[kernel] Application count is {}.", self.app_count);
|
||||
|
||||
for i in 0..self.app_count {
|
||||
println!("[kernel] Application_{} ({:#x} -> {:#x})",
|
||||
i,
|
||||
self.start_addresses[i],
|
||||
self.start_addresses[i + 1]);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_current_app(&self) -> usize {
|
||||
self.current
|
||||
}
|
||||
|
||||
pub fn move_to_next_app(&mut self) {
|
||||
self.current += 1;
|
||||
}
|
||||
|
||||
unsafe fn load_app(&self, app_id: usize) {
|
||||
if app_id >= self.app_count {
|
||||
panic!("Application id is invalid!");
|
||||
}
|
||||
|
||||
println!("[kernel] Loading application_{}...", app_id);
|
||||
|
||||
core::slice::from_raw_parts_mut(
|
||||
APP_BASE_ADDRESS as *mut u8,
|
||||
APP_SIZE_LIMIT
|
||||
).fill(0);
|
||||
|
||||
let app_source = core::slice::from_raw_parts(
|
||||
self.start_addresses[app_id] as *const u8,
|
||||
self.start_addresses[app_id + 1] - self.start_addresses[app_id]
|
||||
);
|
||||
let app_destination = core::slice::from_raw_parts_mut(
|
||||
APP_BASE_ADDRESS as *mut u8,
|
||||
APP_SIZE_LIMIT
|
||||
);
|
||||
app_destination.copy_from_slice(app_source);
|
||||
|
||||
// 保证指令缓存的更新
|
||||
// 因为上述代码会修改指令数据段
|
||||
asm!("fence.i");
|
||||
}
|
||||
}
|
||||
|
@@ -7,8 +7,12 @@ use crate::utils::clear_bss;
|
||||
mod utils;
|
||||
mod sbi;
|
||||
mod console;
|
||||
mod batch;
|
||||
mod sync;
|
||||
|
||||
global_asm!(include_str!("entry.asm"));
|
||||
global_asm!(include_str!("link_app.asm"));
|
||||
|
||||
|
||||
#[no_mangle]
|
||||
fn rust_main() -> ! {
|
||||
|
1
os/src/sync.rs
Normal file
1
os/src/sync.rs
Normal file
@@ -0,0 +1 @@
|
||||
mod unsafe_cell;
|
24
os/src/sync/unsafe_cell.rs
Normal file
24
os/src/sync/unsafe_cell.rs
Normal file
@@ -0,0 +1,24 @@
|
||||
use core::cell::{RefCell, RefMut};
|
||||
|
||||
/// 只能在单核场景下保持安全的屑RefCell
|
||||
struct UnsafeCell<T> {
|
||||
inner_cell: RefCell<T>
|
||||
}
|
||||
|
||||
unsafe impl<T> Sync for UnsafeCell<T> {
|
||||
|
||||
}
|
||||
|
||||
impl<T> UnsafeCell<T> {
|
||||
pub unsafe fn new(value: T) -> UnsafeCell<T> {
|
||||
Self {
|
||||
inner_cell: RefCell::new(value)
|
||||
}
|
||||
}
|
||||
|
||||
/// 独占访问
|
||||
/// 当已被借用时访问会Panic
|
||||
pub fn exclusive_access(&self) -> RefMut<'_, T> {
|
||||
self.inner_cell.borrow_mut()
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user