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"); } // 加载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); } }