From 13e91ed7354864497951aa113e11e7b637375e71 Mon Sep 17 00:00:00 2001 From: Tateisi Date: Sun, 3 Aug 2025 06:54:14 +0800 Subject: [PATCH] ch2: Batch system AppManager --- os/Cargo.lock | 7 ++++ os/Cargo.toml | 1 + os/src/batch.rs | 87 ++++++++++++++++++++++++++++++++++++++++++++++ os/src/main.rs | 3 ++ os/src/sync/mod.rs | 3 ++ os/src/sync/up.rs | 18 ++++++++++ 6 files changed, 119 insertions(+) create mode 100644 os/src/batch.rs create mode 100644 os/src/sync/mod.rs create mode 100644 os/src/sync/up.rs diff --git a/os/Cargo.lock b/os/Cargo.lock index ca0229b..58d7cf0 100644 --- a/os/Cargo.lock +++ b/os/Cargo.lock @@ -2,6 +2,12 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" + [[package]] name = "log" version = "0.4.22" @@ -12,6 +18,7 @@ checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" name = "os" version = "0.1.0" dependencies = [ + "lazy_static", "log", "sbi-rt", ] diff --git a/os/Cargo.toml b/os/Cargo.toml index 534f0dd..c9551ee 100644 --- a/os/Cargo.toml +++ b/os/Cargo.toml @@ -4,5 +4,6 @@ version = "0.1.0" edition = "2021" [dependencies] +lazy_static = "1.5.0" log = "0.4.22" sbi-rt = "0.0.3" diff --git a/os/src/batch.rs b/os/src/batch.rs new file mode 100644 index 0000000..7c80ae9 --- /dev/null +++ b/os/src/batch.rs @@ -0,0 +1,87 @@ +use core::{arch::asm, slice}; + +use lazy_static::*; +use log::info; + +use crate::{sbi::shutdown, sync::UPSafeCell}; + +const MAX_APP_NUM: usize = 16; +const APP_BASE_ADDRESS: usize = 0x80400000; +const APP_SIZE_LIMIT: usize = 0x20000; + +struct AppManager { + num_app: usize, + current_app: usize, + app_start: [usize; MAX_APP_NUM + 1], +} + +impl AppManager { + pub fn print_app_info(&self) { + info!(target: "kernel", "num_app = {}", self.num_app); + for i in 0..self.num_app { + info!(target: "kernel", "app_{} [{:#x}, {:#x}]", i, self.app_start[i], self.app_start[i + 1]); + } + } + + pub fn get_current_app(&self) -> usize { + self.current_app + } + + pub fn move_to_next_app(&mut self) { + self.current_app += 1; + } + + unsafe fn load_app(&self, app_id: usize) { + if app_id >= self.num_app { + info!(target: "kernel", "All applications completed"); + shutdown(false); + } + info!(target: "kernel", "Loading app_{}", app_id); + + slice::from_raw_parts_mut(APP_BASE_ADDRESS as *mut u8, APP_SIZE_LIMIT).fill(0); + let app_src = slice::from_raw_parts(self.app_start[app_id] as *const u8, self.app_start[app_id + 1] - self.app_start[app_id]); + let app_dst = slice::from_raw_parts_mut(APP_BASE_ADDRESS as *mut u8, app_src.len()); + app_dst.copy_from_slice(app_src); + asm!("fence.i"); + } +} + +lazy_static! { + static ref APP_MANAGER: UPSafeCell = unsafe { + UPSafeCell::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 app_start: [usize; MAX_APP_NUM + 1] = [0; MAX_APP_NUM + 1]; + let app_start_raw: &[usize] = slice::from_raw_parts(num_app_ptr.add(1), num_app + 1); + app_start[..=num_app].copy_from_slice(app_start_raw); + AppManager { + num_app, + current_app: 0, + app_start, + } + }) + }; +} + +pub fn init() { +} + +pub fn print_app_info() { + APP_MANAGER.exclusive_access().print_app_info(); +} + +pub fn run_next_app() -> ! { + let mut app_manager = APP_MANAGER.exclusive_access(); + let current_app = app_manager.get_current_app(); + unsafe { + app_manager.load_app(current_app); + } + app_manager.move_to_next_app(); + drop(app_manager); + + // todo +} \ No newline at end of file diff --git a/os/src/main.rs b/os/src/main.rs index c41ee8c..abc0fe9 100644 --- a/os/src/main.rs +++ b/os/src/main.rs @@ -8,6 +8,9 @@ mod logger; #[macro_use] mod console; +mod batch; +mod sync; + use core::arch::global_asm; use log::{debug, error, info, trace, warn}; diff --git a/os/src/sync/mod.rs b/os/src/sync/mod.rs new file mode 100644 index 0000000..7729524 --- /dev/null +++ b/os/src/sync/mod.rs @@ -0,0 +1,3 @@ +mod up; + +pub use up::UPSafeCell; \ No newline at end of file diff --git a/os/src/sync/up.rs b/os/src/sync/up.rs new file mode 100644 index 0000000..8ace25a --- /dev/null +++ b/os/src/sync/up.rs @@ -0,0 +1,18 @@ +use core::cell::{RefCell, RefMut}; + +pub struct UPSafeCell { + inner: RefCell +} + +unsafe impl Sync for UPSafeCell {} + +impl UPSafeCell { + pub unsafe fn new(value: T) -> Self { + Self { + inner: RefCell::new(value) + } + } + pub fn exclusive_access(&self) -> RefMut<'_, T> { + self.inner.borrow_mut() + } +} \ No newline at end of file