140fe15e0SLoGin use core::{fmt::Debug, ptr::null}; 240fe15e0SLoGin 340fe15e0SLoGin use alloc::{collections::BTreeMap, string::String, sync::Arc, vec::Vec}; 491e9d4abSLoGin use system_error::SystemError; 540fe15e0SLoGin 640fe15e0SLoGin use crate::{ 7b087521eSChiichen driver::base::block::SeekFrom, 840fe15e0SLoGin filesystem::vfs::{ 940fe15e0SLoGin file::{File, FileMode}, 1040fe15e0SLoGin ROOT_INODE, 1140fe15e0SLoGin }, 1240fe15e0SLoGin libs::elf::ELF_LOADER, 1340fe15e0SLoGin mm::{ 1440fe15e0SLoGin ucontext::{AddressSpace, UserStack}, 1540fe15e0SLoGin VirtAddr, 1640fe15e0SLoGin }, 1740fe15e0SLoGin }; 1840fe15e0SLoGin 1940fe15e0SLoGin /// 系统支持的所有二进制文件加载器的列表 2040fe15e0SLoGin const BINARY_LOADERS: [&'static dyn BinaryLoader; 1] = [&ELF_LOADER]; 2140fe15e0SLoGin 2240fe15e0SLoGin pub trait BinaryLoader: 'static + Debug { 2340fe15e0SLoGin /// 检查二进制文件是否为当前加载器支持的格式 24b5b571e0SLoGin fn probe(&'static self, param: &ExecParam, buf: &[u8]) -> Result<(), ExecError>; 2540fe15e0SLoGin 2640fe15e0SLoGin fn load( 27b5b571e0SLoGin &'static self, 2840fe15e0SLoGin param: &mut ExecParam, 2940fe15e0SLoGin head_buf: &[u8], 3040fe15e0SLoGin ) -> Result<BinaryLoaderResult, ExecError>; 3140fe15e0SLoGin } 3240fe15e0SLoGin 3340fe15e0SLoGin /// 二进制文件加载结果 3440fe15e0SLoGin #[derive(Debug)] 3540fe15e0SLoGin pub struct BinaryLoaderResult { 3640fe15e0SLoGin /// 程序入口地址 3740fe15e0SLoGin entry_point: VirtAddr, 3840fe15e0SLoGin } 3940fe15e0SLoGin 4040fe15e0SLoGin impl BinaryLoaderResult { 4140fe15e0SLoGin pub fn new(entry_point: VirtAddr) -> Self { 4240fe15e0SLoGin Self { entry_point } 4340fe15e0SLoGin } 4440fe15e0SLoGin 4540fe15e0SLoGin pub fn entry_point(&self) -> VirtAddr { 4640fe15e0SLoGin self.entry_point 4740fe15e0SLoGin } 4840fe15e0SLoGin } 4940fe15e0SLoGin 5040fe15e0SLoGin #[allow(dead_code)] 5140fe15e0SLoGin #[derive(Debug)] 5240fe15e0SLoGin pub enum ExecError { 5340fe15e0SLoGin /// 二进制文件不可执行 5440fe15e0SLoGin NotExecutable, 5540fe15e0SLoGin /// 二进制文件不是当前架构的 5640fe15e0SLoGin WrongArchitecture, 5740fe15e0SLoGin /// 访问权限不足 5840fe15e0SLoGin PermissionDenied, 5940fe15e0SLoGin /// 不支持的操作 6040fe15e0SLoGin NotSupported, 6140fe15e0SLoGin /// 解析文件本身的时候出现错误(比如一些字段本身不合法) 6240fe15e0SLoGin ParseError, 6340fe15e0SLoGin /// 内存不足 6440fe15e0SLoGin OutOfMemory, 6540fe15e0SLoGin /// 参数错误 6640fe15e0SLoGin InvalidParemeter, 6740fe15e0SLoGin /// 无效的地址 6840fe15e0SLoGin BadAddress(Option<VirtAddr>), 6940fe15e0SLoGin Other(String), 7040fe15e0SLoGin } 71b5b571e0SLoGin impl From<ExecError> for SystemError { 72b5b571e0SLoGin fn from(val: ExecError) -> Self { 73b5b571e0SLoGin match val { 7440fe15e0SLoGin ExecError::NotExecutable => SystemError::ENOEXEC, 75b5b571e0SLoGin ExecError::WrongArchitecture => SystemError::ENOEXEC, 7640fe15e0SLoGin ExecError::PermissionDenied => SystemError::EACCES, 77b5b571e0SLoGin ExecError::NotSupported => SystemError::ENOSYS, 7840fe15e0SLoGin ExecError::ParseError => SystemError::ENOEXEC, 7940fe15e0SLoGin ExecError::OutOfMemory => SystemError::ENOMEM, 8040fe15e0SLoGin ExecError::InvalidParemeter => SystemError::EINVAL, 8140fe15e0SLoGin ExecError::BadAddress(_addr) => SystemError::EFAULT, 8240fe15e0SLoGin ExecError::Other(_msg) => SystemError::ENOEXEC, 8340fe15e0SLoGin } 8440fe15e0SLoGin } 8540fe15e0SLoGin } 8640fe15e0SLoGin 8740fe15e0SLoGin bitflags! { 8840fe15e0SLoGin pub struct ExecParamFlags: u32 { 8940fe15e0SLoGin // 是否以可执行文件的形式加载 9040fe15e0SLoGin const EXEC = 1 << 0; 9140fe15e0SLoGin } 9240fe15e0SLoGin } 9340fe15e0SLoGin 9440fe15e0SLoGin #[derive(Debug)] 95a02ce654SChiichen pub struct ExecParam { 96a02ce654SChiichen file: File, 9740fe15e0SLoGin vm: Arc<AddressSpace>, 9840fe15e0SLoGin /// 一些标志位 9940fe15e0SLoGin flags: ExecParamFlags, 10040fe15e0SLoGin /// 用来初始化进程的一些信息。这些信息由二进制加载器和exec机制来共同填充 10140fe15e0SLoGin init_info: ProcInitInfo, 10240fe15e0SLoGin } 10340fe15e0SLoGin 10440fe15e0SLoGin #[derive(Debug, Eq, PartialEq)] 10540fe15e0SLoGin pub enum ExecLoadMode { 10640fe15e0SLoGin /// 以可执行文件的形式加载 10740fe15e0SLoGin Exec, 10840fe15e0SLoGin /// 以动态链接库的形式加载 10940fe15e0SLoGin DSO, 11040fe15e0SLoGin } 11140fe15e0SLoGin 11240fe15e0SLoGin #[allow(dead_code)] 113a02ce654SChiichen impl ExecParam { 114a02ce654SChiichen pub fn new( 115a02ce654SChiichen file_path: &str, 116a02ce654SChiichen vm: Arc<AddressSpace>, 117a02ce654SChiichen flags: ExecParamFlags, 118a02ce654SChiichen ) -> Result<Self, SystemError> { 119a02ce654SChiichen let inode = ROOT_INODE().lookup(file_path)?; 120a02ce654SChiichen 121a02ce654SChiichen // 读取文件头部,用于判断文件类型 122a02ce654SChiichen let file = File::new(inode, FileMode::O_RDONLY)?; 123a02ce654SChiichen 124a02ce654SChiichen Ok(Self { 125a02ce654SChiichen file, 12640fe15e0SLoGin vm, 12740fe15e0SLoGin flags, 12840fe15e0SLoGin init_info: ProcInitInfo::new(), 129a02ce654SChiichen }) 13040fe15e0SLoGin } 13140fe15e0SLoGin 13240fe15e0SLoGin pub fn vm(&self) -> &Arc<AddressSpace> { 13340fe15e0SLoGin &self.vm 13440fe15e0SLoGin } 13540fe15e0SLoGin 13640fe15e0SLoGin pub fn flags(&self) -> &ExecParamFlags { 13740fe15e0SLoGin &self.flags 13840fe15e0SLoGin } 13940fe15e0SLoGin 14040fe15e0SLoGin pub fn init_info(&self) -> &ProcInitInfo { 14140fe15e0SLoGin &self.init_info 14240fe15e0SLoGin } 14340fe15e0SLoGin 14440fe15e0SLoGin pub fn init_info_mut(&mut self) -> &mut ProcInitInfo { 14540fe15e0SLoGin &mut self.init_info 14640fe15e0SLoGin } 14740fe15e0SLoGin 14840fe15e0SLoGin /// 获取加载模式 14940fe15e0SLoGin pub fn load_mode(&self) -> ExecLoadMode { 15040fe15e0SLoGin if self.flags.contains(ExecParamFlags::EXEC) { 15140fe15e0SLoGin ExecLoadMode::Exec 15240fe15e0SLoGin } else { 15340fe15e0SLoGin ExecLoadMode::DSO 15440fe15e0SLoGin } 15540fe15e0SLoGin } 15640fe15e0SLoGin 15740fe15e0SLoGin pub fn file_mut(&mut self) -> &mut File { 158a02ce654SChiichen &mut self.file 15940fe15e0SLoGin } 16040fe15e0SLoGin } 16140fe15e0SLoGin 16240fe15e0SLoGin /// ## 加载二进制文件 16340fe15e0SLoGin pub fn load_binary_file(param: &mut ExecParam) -> Result<BinaryLoaderResult, SystemError> { 16440fe15e0SLoGin // 读取文件头部,用于判断文件类型 16540fe15e0SLoGin let mut head_buf = [0u8; 512]; 16640fe15e0SLoGin param.file_mut().lseek(SeekFrom::SeekSet(0))?; 16740fe15e0SLoGin let _bytes = param.file_mut().read(512, &mut head_buf)?; 168*2eab6dd7S曾俊 // debug!("load_binary_file: read {} bytes", _bytes); 16940fe15e0SLoGin 17040fe15e0SLoGin let mut loader = None; 17140fe15e0SLoGin for bl in BINARY_LOADERS.iter() { 17240fe15e0SLoGin let probe_result = bl.probe(param, &head_buf); 17340fe15e0SLoGin if probe_result.is_ok() { 17440fe15e0SLoGin loader = Some(bl); 17540fe15e0SLoGin break; 17640fe15e0SLoGin } 17740fe15e0SLoGin } 178*2eab6dd7S曾俊 // debug!("load_binary_file: loader: {:?}", loader); 17940fe15e0SLoGin if loader.is_none() { 18040fe15e0SLoGin return Err(SystemError::ENOEXEC); 18140fe15e0SLoGin } 18240fe15e0SLoGin 18340fe15e0SLoGin let loader: &&dyn BinaryLoader = loader.unwrap(); 18440fe15e0SLoGin assert!(param.vm().is_current()); 185*2eab6dd7S曾俊 // debug!("load_binary_file: to load with param: {:?}", param); 18640fe15e0SLoGin 18740fe15e0SLoGin let result: BinaryLoaderResult = loader 18840fe15e0SLoGin .load(param, &head_buf) 18940fe15e0SLoGin .unwrap_or_else(|e| panic!("load_binary_file failed: error: {e:?}, param: {param:?}")); 19040fe15e0SLoGin 191*2eab6dd7S曾俊 // debug!("load_binary_file: load success: {result:?}"); 19240fe15e0SLoGin return Ok(result); 19340fe15e0SLoGin } 19440fe15e0SLoGin 19540fe15e0SLoGin /// 程序初始化信息,这些信息会被压入用户栈中 19640fe15e0SLoGin #[derive(Debug)] 19740fe15e0SLoGin pub struct ProcInitInfo { 198865f4ba4SGnoCiYeH pub proc_name: String, 19940fe15e0SLoGin pub args: Vec<String>, 20040fe15e0SLoGin pub envs: Vec<String>, 20140fe15e0SLoGin pub auxv: BTreeMap<u8, usize>, 20240fe15e0SLoGin } 20340fe15e0SLoGin 20440fe15e0SLoGin impl ProcInitInfo { 20540fe15e0SLoGin pub fn new() -> Self { 20640fe15e0SLoGin Self { 207865f4ba4SGnoCiYeH proc_name: String::new(), 20840fe15e0SLoGin args: Vec::new(), 20940fe15e0SLoGin envs: Vec::new(), 21040fe15e0SLoGin auxv: BTreeMap::new(), 21140fe15e0SLoGin } 21240fe15e0SLoGin } 21340fe15e0SLoGin 21440fe15e0SLoGin /// 把程序初始化信息压入用户栈中 21540fe15e0SLoGin /// 这个函数会把参数、环境变量、auxv等信息压入用户栈中 21640fe15e0SLoGin /// 21740fe15e0SLoGin /// ## 返回值 21840fe15e0SLoGin /// 21940fe15e0SLoGin /// 返回值是一个元组,第一个元素是最终的用户栈顶地址,第二个元素是环境变量pointer数组的起始地址 22040fe15e0SLoGin pub unsafe fn push_at( 22140fe15e0SLoGin &self, 22240fe15e0SLoGin ustack: &mut UserStack, 22340fe15e0SLoGin ) -> Result<(VirtAddr, VirtAddr), SystemError> { 22440fe15e0SLoGin // 先把程序的名称压入栈中 225865f4ba4SGnoCiYeH self.push_str(ustack, &self.proc_name)?; 22640fe15e0SLoGin 22740fe15e0SLoGin // 然后把环境变量压入栈中 22840fe15e0SLoGin let envps = self 22940fe15e0SLoGin .envs 23040fe15e0SLoGin .iter() 23140fe15e0SLoGin .map(|s| { 23240fe15e0SLoGin self.push_str(ustack, s.as_str()).expect("push_str failed"); 23340fe15e0SLoGin ustack.sp() 23440fe15e0SLoGin }) 23540fe15e0SLoGin .collect::<Vec<_>>(); 23640fe15e0SLoGin 23740fe15e0SLoGin // 然后把参数压入栈中 23840fe15e0SLoGin let argps = self 23940fe15e0SLoGin .args 24040fe15e0SLoGin .iter() 24140fe15e0SLoGin .map(|s| { 24240fe15e0SLoGin self.push_str(ustack, s.as_str()).expect("push_str failed"); 24340fe15e0SLoGin ustack.sp() 24440fe15e0SLoGin }) 24540fe15e0SLoGin .collect::<Vec<_>>(); 24640fe15e0SLoGin 24740fe15e0SLoGin // 压入auxv 24840fe15e0SLoGin self.push_slice(ustack, &[null::<u8>(), null::<u8>()])?; 24940fe15e0SLoGin for (&k, &v) in self.auxv.iter() { 25040fe15e0SLoGin self.push_slice(ustack, &[k as usize, v])?; 25140fe15e0SLoGin } 25240fe15e0SLoGin 25340fe15e0SLoGin // 把环境变量指针压入栈中 25440fe15e0SLoGin self.push_slice(ustack, &[null::<u8>()])?; 25540fe15e0SLoGin self.push_slice(ustack, envps.as_slice())?; 25640fe15e0SLoGin 25740fe15e0SLoGin // 把参数指针压入栈中 25840fe15e0SLoGin self.push_slice(ustack, &[null::<u8>()])?; 25940fe15e0SLoGin self.push_slice(ustack, argps.as_slice())?; 26040fe15e0SLoGin 26140fe15e0SLoGin let argv_ptr = ustack.sp(); 26240fe15e0SLoGin 26340fe15e0SLoGin // 把argc压入栈中 26440fe15e0SLoGin self.push_slice(ustack, &[self.args.len()])?; 26540fe15e0SLoGin 26640fe15e0SLoGin return Ok((ustack.sp(), argv_ptr)); 26740fe15e0SLoGin } 26840fe15e0SLoGin 26940fe15e0SLoGin fn push_slice<T: Copy>(&self, ustack: &mut UserStack, slice: &[T]) -> Result<(), SystemError> { 27040fe15e0SLoGin let mut sp = ustack.sp(); 271b5b571e0SLoGin sp -= core::mem::size_of_val(slice); 27240fe15e0SLoGin sp -= sp.data() % core::mem::align_of::<T>(); 27340fe15e0SLoGin 27440fe15e0SLoGin unsafe { core::slice::from_raw_parts_mut(sp.data() as *mut T, slice.len()) } 27540fe15e0SLoGin .copy_from_slice(slice); 27640fe15e0SLoGin unsafe { 27740fe15e0SLoGin ustack.set_sp(sp); 27840fe15e0SLoGin } 27940fe15e0SLoGin 28040fe15e0SLoGin return Ok(()); 28140fe15e0SLoGin } 28240fe15e0SLoGin 28340fe15e0SLoGin fn push_str(&self, ustack: &mut UserStack, s: &str) -> Result<(), SystemError> { 28440fe15e0SLoGin self.push_slice(ustack, &[b'\0'])?; 28540fe15e0SLoGin self.push_slice(ustack, s.as_bytes())?; 28640fe15e0SLoGin return Ok(()); 28740fe15e0SLoGin } 28840fe15e0SLoGin } 289