From 3d8c59d4ac80ea105d9ad2d9e4d994805b57aacd Mon Sep 17 00:00:00 2001 From: zhangxinyu <840317537@qq.com> Date: Tue, 23 May 2023 14:41:16 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E4=B8=80=E4=B8=AAloader?= =?UTF-8?q?=E6=A8=A1=E5=9D=97=E7=94=A8=E6=9D=A5=E5=8A=A0=E8=BD=BD=E6=89=80?= =?UTF-8?q?=E6=9C=89=E7=9A=84app,=20=E4=B8=80=E8=B5=B7=E5=88=B0=E5=86=85?= =?UTF-8?q?=E5=AD=98=E4=B8=AD=E7=9A=84=E6=8C=87=E5=AE=9A=E4=BD=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ch3-coop/os/build.rs | 1 + ch3-coop/os/src/loader.rs | 54 +++++++++++++++++++++++++++++++++++++++ ch3-coop/os/src/main.rs | 13 ++++++---- 3 files changed, 63 insertions(+), 5 deletions(-) create mode 100644 ch3-coop/os/src/loader.rs diff --git a/ch3-coop/os/build.rs b/ch3-coop/os/build.rs index 026b308..0d4cdb2 100644 --- a/ch3-coop/os/build.rs +++ b/ch3-coop/os/build.rs @@ -2,6 +2,7 @@ use std::fs::{read_dir, File}; use std::io::{Result, Write}; fn main() { + // 主要功能是把用户的应用程序加载到内核中 println!("cargo:rerun-if-changed=../user/src/"); println!("cargo:rerun-if-changed={}", TARGET_PATH); insert_app_data().unwrap(); diff --git a/ch3-coop/os/src/loader.rs b/ch3-coop/os/src/loader.rs new file mode 100644 index 0000000..b5fa6d5 --- /dev/null +++ b/ch3-coop/os/src/loader.rs @@ -0,0 +1,54 @@ +use core::arch::asm; + +use crate::config::*; + +extern "C" { + fn _num_app(); +} + +// 得到用户app的数量 +fn get_num_app() -> usize{ + unsafe{ + _num_app as usize as *const usize.read_volatile() + } +} + +// 把把 app一次性都加载到内存, 并分配二进制空间 +pub fn load_app() { + // 得到符号位 + let num_app_ptr = _num_app as usize as *const usize; + + // 得到 符号开始的前8个字节, 这里保存的app的数量 + let num_app = get_num_app(); + + // 得到 app数组的起始位置 num_app_ptr.add(1)跳过上方的 metadata, num_app+1 是确保切免得长度足够, 因为后面还有一个符号在linker.ld中 .quad app_2_end 表示结束的内存地址 + let app_start = unsafe { + core::slice::from_raw_parts(num_app_ptr.add(1), num_app+1) + }; + + // 清除缓存 + unsafe { asm!("fence.i" :::: "volatile"); } + + // 加载app + for app_id in 0..num_app { + // 得到每个app的起始位置 + let base_ptr = APP_BASE_ADDRESS + app_id * APP_SIZE_LIMIT; + + // 清理这个应用可以占用的内存(好像可以不用做吧? 下面直接dst.copy_from_slice全部覆盖了) + (base_ptr..base_ptr + APP_SIZE_LIMIT).for_each(|addr| unsafe { + (addr as *mut u8).write_volatile(0) + }); + + // 加载 app_start 处二进制数据到内存里 + let src = unsafe { + let app_size = app_start[app_id + 1] - app_start[app_id]; // 下一个app的起始位置, 减去当前的起始位置就是app的大小 + core::slice::from_raw_parts(app_start[app_id] as *const u8, app_size) + }; + + // 得到app占用的内存, 后面需要把app 二进制数据加载到这里 + let dst = unsafe { + core::slice::from_raw_parts_mut(base_ptr as *mut u8, src.len()) + }; + dst.copy_from_slice(src); + } +} \ No newline at end of file diff --git a/ch3-coop/os/src/main.rs b/ch3-coop/os/src/main.rs index 5dbc93a..ffc78a9 100644 --- a/ch3-coop/os/src/main.rs +++ b/ch3-coop/os/src/main.rs @@ -8,10 +8,12 @@ use lang_items::console; pub mod lang_items; pub mod sbi; -pub mod batch; +// pub mod batch; pub mod sync; -pub mod trap; +// pub mod trap; pub mod syscall; +pub mod loader; +pub mod config; // 汇编脚本引入, 调整内核的内存布局之后, 会跳入到 rust_main中执行 global_asm!(include_str!("entry.asm")); @@ -36,9 +38,10 @@ 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); - trap::init(); - batch::init(); - batch::run_next_app(); + loader::load_app(); + // trap::init(); + // batch::init(); + // batch::run_next_app(); } /// ## 初始化bss段