From d11132ae23701779b4bb95a411c77e80976d51f5 Mon Sep 17 00:00:00 2001 From: linfeng <1925466036@qq.com> Date: Fri, 20 May 2022 18:54:24 +0800 Subject: [PATCH] fear: Support multi-program loading modify batch.rs --> loader.rs --- loongrCore/src/batch.rs | 7 +-- loongrCore/src/config.rs | 7 +++ loongrCore/src/loader.rs | 120 +++++++++++++++++++++++++++++++++++++ loongrCore/src/main.rs | 8 ++- loongrCore/src/trap/mod.rs | 2 +- user/Makefile | 9 +-- user/build.py | 23 +++++++ 7 files changed, 163 insertions(+), 13 deletions(-) create mode 100644 loongrCore/src/loader.rs create mode 100644 user/build.py diff --git a/loongrCore/src/batch.rs b/loongrCore/src/batch.rs index f1a193e..7054380 100644 --- a/loongrCore/src/batch.rs +++ b/loongrCore/src/batch.rs @@ -2,12 +2,7 @@ use crate::println; use crate::sync::UPSafeCell; use crate::trap::TrapContext; use lazy_static::*; - -const USER_STACK_SIZE: usize = 4096 * 2; -const KERNEL_STACK_SIZE: usize = 4096 * 2; -const MAX_APP_NUM: usize = 16; -const APP_BASE_ADDRESS: usize = 0x00200000; -const APP_SIZE_LIMIT: usize = 0x30000; +use crate::config::*; #[repr(align(4096))] struct KernelStack { diff --git a/loongrCore/src/config.rs b/loongrCore/src/config.rs index ae65765..9f5c10f 100644 --- a/loongrCore/src/config.rs +++ b/loongrCore/src/config.rs @@ -14,3 +14,10 @@ const LOONGARCH_CSR_DMWIN0: u32 = 0x180; const LOONGARCH_CSR_DMWIN1: u32 = 0x181; const LOONGARCH_CSR_DMWIN2: u32 = 0x182; const LOONGARCH_CSR_DMWIN3: u32 = 0x183; + + +pub const MAX_APP_NUM: usize = 10; +pub const APP_BASE_ADDRESS: usize = 0x00200000; //应用程åºèµ·å§‹åœ°å€ +pub const APP_SIZE_LIMIT: usize = 0x20000; //应用程åºçš„空间é™åˆ¶ +pub const USER_STACK_SIZE:usize = 4096*2;//ç”¨æˆ·æ ˆå¤§å° +pub const KERNEL_STACK_SIZE:usize = 4096*2;//å†…æ ¸æ ˆå¤§å° \ No newline at end of file diff --git a/loongrCore/src/loader.rs b/loongrCore/src/loader.rs new file mode 100644 index 0000000..1941b54 --- /dev/null +++ b/loongrCore/src/loader.rs @@ -0,0 +1,120 @@ +///将应用程åºå…¨éƒ¨åŠ è½½åˆ°å†…å˜ä¸ +use crate::config::*; +use core::slice::{from_raw_parts,from_raw_parts_mut}; +use crate::{INFO,DEBUG}; +use lazy_static::lazy_static; +use crate::trap::context::TrapContext; + +lazy_static!{ + static ref LOADAPP:usize = load_app(); +} +static mut CURRENTAPP:usize = 0; + +static KERNEL_STACK:KernelStack = KernelStack{data:[0;KERNEL_STACK_SIZE]}; +static USER_STACK:UserStack = UserStack{data:[0;USER_STACK_SIZE]}; + +#[repr(align(4096))] +struct KernelStack{ + data:[u8;KERNEL_STACK_SIZE] +} +#[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 + } +} + +impl KernelStack { + //获å–å†…æ ¸æ ˆæ ˆé¡¶åœ°å€ + fn get_sp(&self)->usize{ + self.data.as_ptr() as usize + KERNEL_STACK_SIZE + } + fn push_context(&self,cx:TrapContext)->&'static mut TrapContext{ + //åœ¨å†…æ ¸æ ˆä¸ŠåŽ‹å…¥trap上下文 + let cx_ptr = (self.get_sp()-core::mem::size_of::<TrapContext>() )as *mut TrapContext; + unsafe { + *cx_ptr = cx; + cx_ptr.as_mut().unwrap() + //è¿”å›žå†…æ ¸æ ˆåœ°å€ + } + } +} + + + fn load_app()->usize{ + extern "C"{ fn _num_app();} + //å–出app所在ä½ç½®çš„åœ°å€ + //link_apps按8å—节对其 + let num_app_ptr = _num_app as usize as *const usize;//å–åœ°å€ + let num_app = unsafe{ num_app_ptr.read_volatile()};//读内容 åº”ç”¨æ•°é‡ + let mut app_start :[usize;MAX_APP_NUM+1] = [0;MAX_APP_NUM+1]; + let app_start_raw:&[usize] = unsafe{ + //å½¢æˆä¸€ä¸ªæŒ‡é’ˆåˆ‡ç‰‡ï¼Œå˜æ”¾çš„三个应用的起始地å€å’Œæœ€åŽä¸€ä¸ªåº”ç”¨çš„å¼€å§‹åœ°å€ + from_raw_parts(num_app_ptr.add(1),num_app+1) + }; + app_start[..=num_app].copy_from_slice(app_start_raw);//å¤åˆ¶åœ°å€ + for i in 0..num_app{ + //æ¸…é™¤åº”ç”¨ç¨‹åºæ®µ + let app_i_address = get_base_address(i); + (app_i_address..app_i_address + APP_SIZE_LIMIT).for_each(|addr| { + unsafe { (addr as *mut u8).write_volatile(0); }//å–地å€å¹¶å†™å…¥0,以å—节写入 + }); + let app_src = unsafe{ + from_raw_parts( + app_start[i] as *const u8,//èµ·å§‹åœ°å€ + app_start[i + 1] - app_start[i],//长度,以å—节记 + ) + }; + let app_dst = unsafe{from_raw_parts_mut(app_i_address as *mut u8, app_src.len())}; + app_dst.copy_from_slice(app_src); //å†™å…¥æ•°æ® + } + num_app +} + +fn get_base_address(app_id:usize) ->usize{ + APP_BASE_ADDRESS + APP_SIZE_LIMIT*app_id +} + +pub fn init_load(){ + INFO!("[kernel] Loading {} apps...",*LOADAPP); + INFO!("[kernel] Apps all loaded!"); +} +pub fn run_next_app()->!{ + unsafe { + if CURRENTAPP >=*LOADAPP { + panic!("[kernel] Apps run over"); + } + } + + extern "C"{ + fn __restore(cx_addr:usize); //定义外部接å£ï¼Œæ¥è‡ªtrap.asm用于æ¢å¤ä¸Šä¸‹æ–‡ + } + unsafe { + CURRENTAPP +=1; + // DEBUG!("[kernel] Run the {} app!",CURRENTAPP-1); + } + // å¤ç”¨_restore函数 + // åœ¨å†…æ ¸æ ˆä¸ŠåŽ‹å…¥ä¸€ä¸ªTrap上下文 + // sepc 是应用程åºå…¥å£åœ°å€ 0x80400000 , + // å…¶ sp 寄å˜å™¨æŒ‡å‘ç”¨æˆ·æ ˆï¼Œå…¶sstatus çš„ SPP å—æ®µè¢«è®¾ç½®ä¸º User 。 + // push_context çš„è¿”å›žå€¼æ˜¯å†…æ ¸æ ˆåŽ‹å…¥ Trap 上下文之åŽçš„å†…æ ¸æ ˆé¡¶ï¼Œ + // 它会被作为 __restore çš„å‚ + unsafe { + // println!("[kernel] Begin run application!"); + __restore({ + KERNEL_STACK.push_context( + TrapContext::app_init_context( + get_base_address(CURRENTAPP-1), + USER_STACK.get_sp()))as * const _ as usize + } + ); + //æ¤æ—¶sp指å‘çš„æ˜¯ç”¨æˆ·æ ˆåœ°å€ï¼Œsscratch指å‘çš„æ˜¯å†…æ ¸æ ˆåœ°å€ + } + panic!("The end of application") +} \ No newline at end of file diff --git a/loongrCore/src/main.rs b/loongrCore/src/main.rs index 3b8db6e..927a7d6 100644 --- a/loongrCore/src/main.rs +++ b/loongrCore/src/main.rs @@ -16,6 +16,8 @@ mod syscall; mod test; mod trap; mod uart; +mod loader; + extern crate bit_field; extern crate rlibc; @@ -42,6 +44,8 @@ pub extern "C" fn main() { INFO!("{}", FLAG); trap::init(); // test_csr_register(); - batch::init(); - run_next_app(); + // batch::init(); + // run_next_app(); + loader::init_load(); + loader::run_next_app(); } diff --git a/loongrCore/src/trap/mod.rs b/loongrCore/src/trap/mod.rs index 3905844..f1a3a20 100644 --- a/loongrCore/src/trap/mod.rs +++ b/loongrCore/src/trap/mod.rs @@ -1,4 +1,4 @@ -mod context; +pub(crate) mod context; use crate::loong_arch::register::{ crmd::Crmd, ecfg::Ecfg, eentry::Eentry, estat::Estat, estat::Trap, diff --git a/user/Makefile b/user/Makefile index c59f294..5c62591 100644 --- a/user/Makefile +++ b/user/Makefile @@ -11,10 +11,11 @@ OBJDUMP := rust-objdump --arch-name=riscv64 OBJCOPY := loongarch64-unknown-linux-gnu-objcopy elf: - @cargo build --release - @echo $(APPS) - @echo $(ELFS) - @echo $(BINS) + @#cargo build --release + @#echo $(APPS) + @#echo $(ELFS) + @#echo $(BINS) + @python3 build.py binary: elf $(foreach elf, $(ELFS), $(OBJCOPY) $(elf) --strip-all -O binary $(patsubst $(TARGET_DIR)/%, $(TARGET_DIR)/%.bin, $(elf));) diff --git a/user/build.py b/user/build.py new file mode 100644 index 0000000..d5dd971 --- /dev/null +++ b/user/build.py @@ -0,0 +1,23 @@ +import os + +base_address = 0x00200000 +app_address = 0x20000 + +linker = "linker.ld" +apps = os.listdir("src/bin") +ori_text = []; +with open(linker,'r') as f: + for line in f.readlines(): + ori_text.append(line) +apps.sort() +for i,app in enumerate(apps): + app_name = app.split('.')[0] + with open(linker,'w+') as f: + for line in ori_text: + new_text = line.replace(hex(base_address),hex(base_address+app_address*i)) + f.write(new_text) + os.system('cargo build --bin {} --release'.format(app_name)) + print("[build.py] application {} start with address {}" .format(app, hex(base_address+app_address*i))) + with open(linker,"w+") as f: + for line in ori_text: + f.write(line) \ No newline at end of file -- GitLab