diff --git a/ch2/os/Cargo.toml b/ch2/os/Cargo.toml index c02e785..dd3234d 100644 --- a/ch2/os/Cargo.toml +++ b/ch2/os/Cargo.toml @@ -7,4 +7,8 @@ edition = "2021" # 设置release模式下保存调试信息 [profile.release] -debug=true \ No newline at end of file +debug=true + +[dependencies] +riscv = { git = "https://github.com/rcore-os/riscv", features = ["inline-asm"] } +lazy_static = { version = "1.4.0", features = ["spin_no_std"] } \ No newline at end of file diff --git a/ch2/os/src/batch.rs b/ch2/os/src/batch.rs new file mode 100644 index 0000000..c8c4d72 --- /dev/null +++ b/ch2/os/src/batch.rs @@ -0,0 +1,72 @@ +use lazy_static::*; +use crate::println; +use crate::sync::UPSafeCell; + +const USER_STACK_SIZE: usize = 4096 * 2; // 栈大小为8kb +const KERNEL_STACK_SIZE: usize = 4096 * 2; + +const MAX_APP_NUM: usize = 16; // 系统最大支持的运行程序数量 + +const APP_BASE_ADDRESS: usize = 0x80400000; // 载入的app的起始的地址 +const APP_SIZE_LIMIT: usize = 0x20000; // app的最大的二进制文件能够使用的大小 + +// 在此之后应用使用UserStack, 而内核使用KernelStack, entry.asm设置的64k启动栈不再被使用 +static KERNEL_STACK: [u8; KERNEL_STACK_SIZE] = [0; KERNEL_STACK_SIZE]; +static USER_STACK: [u8; USER_STACK_SIZE] = [0; USER_STACK_SIZE]; + +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(); // 用户app的总数量 + + let mut app_start_lis: [usize; MAX_APP_NUM + 1] = [0; MAX_APP_NUM + 1]; // 创建一个数组, 用来保存每个app的起始位置 + + // 得到每个app的起始地址 + let mut app_start_lis: [usize; MAX_APP_NUM + 1] = [0; MAX_APP_NUM + 1]; + let app_start_raw: &[usize] = + core::slice::from_raw_parts(num_app_ptr.add(1), num_app + 1); + app_start_lis[..=num_app].copy_from_slice(app_start_raw); + + AppManager{ + num_app, + current_app: 0, + app_start_lis + } + }) + }; +} + +// 由build.rs 生成的link_app.S, 根据里面的信息生成的结构体 +struct AppManager { + num_app: usize, // 用户app数量 + current_app: usize, // 当前需要执行的第几个app + app_start_lis: [usize; MAX_APP_NUM + 1], // 保存了每个app的起始位置, 后面会跳到这里, +1 是因为end的位置也占了一个usize, 需要知道end的位置 +} + +impl AppManager{ + fn show_app_info(&self){ + println!("[kernel] num_app = {}", self.num_app); + for i in 0..self.num_app { + println!( + "[kernel] app_{} [{:#x}, {:#x})", + i, + self.app_start_lis[i], + self.app_start_lis[i + 1] + ); + } + } +} + + +pub fn init() { + APP_MANAGER.exclusive_access().show_app_info(); +} + + + + + diff --git a/ch2/os/src/main.rs b/ch2/os/src/main.rs index bcbe1e2..4933aed 100644 --- a/ch2/os/src/main.rs +++ b/ch2/os/src/main.rs @@ -6,12 +6,17 @@ use core::arch::global_asm; use sbi::{console_put_char, shutdown}; use lang_items::console; -mod lang_items; -mod sbi; +pub mod lang_items; +pub mod sbi; +pub mod batch; +pub mod sync; // 汇编脚本引入, 调整内核的内存布局之后, 会跳入到 rust_main中执行 global_asm!(include_str!("entry.asm")); +// 引入用户的二进制文件 +global_asm!(include_str!("link_app.S")); + extern "C" { fn stext(); fn etext(); @@ -29,7 +34,7 @@ pub fn rust_main(){ println!("sbss: {:#x}, ebss: {:#x}", sbss as usize, ebss as usize); println!("boot_stack_top_bound: {:#x}, boot_stack_lower_bound: {:#x}", boot_stack_top_bound as usize, boot_stack_lower_bound as usize); - panic!("my panic"); + batch::init(); } /// ## 初始化bss段