extern"C" { fn__restore(cx_addr: usize); } unsafe { __restore(KERNEL_STACK.push_context( TrapContext::app_init_context(APP_BASE_ADDRESS, USER_STACK.get_sp()) // This context store the ptr to UserStack for restoration ) as *const _ asusize); }
Construct User App
Link app binary to kernel with specify memory layout
Read the layout, use AppManager to maintain and store
Load app from memory layout, copy consecutively to APP_BASE_ADDRESS(Currently we have no ability to dynamically read address)
// part of read in static init of AppManager let num_app_ptr = _num_app asusizeas *constusize; let num_app = num_app_ptr.read_volatile(); letmut app_start: [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[..=num_app].copy_from_slice(app_start_raw);
Load App:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
// part of code of copying to kernel asm!("fence.i"); // clear app area core::slice::from_raw_parts_mut( APP_BASE_ADDRESS as *mutu8, APP_SIZE_LIMIT ).fill(0); let app_src = core::slice::from_raw_parts( self.app_start[app_id] as *constu8, self.app_start[app_id + 1] - self.app_start[app_id] ); let app_dst = core::slice::from_raw_parts_mut( APP_BASE_ADDRESS as *mutu8, app_src.len() ); app_dst.copy_from_slice(app_src);
pubfnrun_next_app() -> ! { letmut 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); // before this we have to drop local variables related to resources manually // and release the resources extern"C" { fn__restore(cx_addr: usize); } unsafe { __restore(KERNEL_STACK.push_context( TrapContext::app_init_context(APP_BASE_ADDRESS, USER_STACK.get_sp()) ) as *const _ asusize); } panic!("Unreachable in batch::run_current_app!"); }