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 /// 检查二进制文件是否为当前加载器支持的格式 2440fe15e0SLoGin fn probe(self: &'static Self, param: &ExecParam, buf: &[u8]) -> Result<(), ExecError>; 2540fe15e0SLoGin 2640fe15e0SLoGin fn load( 2740fe15e0SLoGin self: &'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 } 7140fe15e0SLoGin 7240fe15e0SLoGin impl Into<SystemError> for ExecError { 7340fe15e0SLoGin fn into(self) -> SystemError { 7440fe15e0SLoGin match self { 7540fe15e0SLoGin ExecError::NotExecutable => SystemError::ENOEXEC, 7640fe15e0SLoGin ExecError::WrongArchitecture => SystemError::EOPNOTSUPP_OR_ENOTSUP, 7740fe15e0SLoGin ExecError::PermissionDenied => SystemError::EACCES, 7840fe15e0SLoGin ExecError::NotSupported => SystemError::EOPNOTSUPP_OR_ENOTSUP, 7940fe15e0SLoGin ExecError::ParseError => SystemError::ENOEXEC, 8040fe15e0SLoGin ExecError::OutOfMemory => SystemError::ENOMEM, 8140fe15e0SLoGin ExecError::InvalidParemeter => SystemError::EINVAL, 8240fe15e0SLoGin ExecError::BadAddress(_addr) => SystemError::EFAULT, 8340fe15e0SLoGin ExecError::Other(_msg) => SystemError::ENOEXEC, 8440fe15e0SLoGin } 8540fe15e0SLoGin } 8640fe15e0SLoGin } 8740fe15e0SLoGin 8840fe15e0SLoGin bitflags! { 8940fe15e0SLoGin pub struct ExecParamFlags: u32 { 9040fe15e0SLoGin // 是否以可执行文件的形式加载 9140fe15e0SLoGin const EXEC = 1 << 0; 9240fe15e0SLoGin } 9340fe15e0SLoGin } 9440fe15e0SLoGin 9540fe15e0SLoGin #[derive(Debug)] 96*a02ce654SChiichen pub struct ExecParam { 97*a02ce654SChiichen file: File, 9840fe15e0SLoGin vm: Arc<AddressSpace>, 9940fe15e0SLoGin /// 一些标志位 10040fe15e0SLoGin flags: ExecParamFlags, 10140fe15e0SLoGin /// 用来初始化进程的一些信息。这些信息由二进制加载器和exec机制来共同填充 10240fe15e0SLoGin init_info: ProcInitInfo, 10340fe15e0SLoGin } 10440fe15e0SLoGin 10540fe15e0SLoGin #[derive(Debug, Eq, PartialEq)] 10640fe15e0SLoGin pub enum ExecLoadMode { 10740fe15e0SLoGin /// 以可执行文件的形式加载 10840fe15e0SLoGin Exec, 10940fe15e0SLoGin /// 以动态链接库的形式加载 11040fe15e0SLoGin DSO, 11140fe15e0SLoGin } 11240fe15e0SLoGin 11340fe15e0SLoGin #[allow(dead_code)] 114*a02ce654SChiichen impl ExecParam { 115*a02ce654SChiichen pub fn new( 116*a02ce654SChiichen file_path: &str, 117*a02ce654SChiichen vm: Arc<AddressSpace>, 118*a02ce654SChiichen flags: ExecParamFlags, 119*a02ce654SChiichen ) -> Result<Self, SystemError> { 120*a02ce654SChiichen let inode = ROOT_INODE().lookup(file_path)?; 121*a02ce654SChiichen 122*a02ce654SChiichen // 读取文件头部,用于判断文件类型 123*a02ce654SChiichen let file = File::new(inode, FileMode::O_RDONLY)?; 124*a02ce654SChiichen 125*a02ce654SChiichen Ok(Self { 126*a02ce654SChiichen file, 12740fe15e0SLoGin vm, 12840fe15e0SLoGin flags, 12940fe15e0SLoGin init_info: ProcInitInfo::new(), 130*a02ce654SChiichen }) 13140fe15e0SLoGin } 13240fe15e0SLoGin 13340fe15e0SLoGin pub fn vm(&self) -> &Arc<AddressSpace> { 13440fe15e0SLoGin &self.vm 13540fe15e0SLoGin } 13640fe15e0SLoGin 13740fe15e0SLoGin pub fn flags(&self) -> &ExecParamFlags { 13840fe15e0SLoGin &self.flags 13940fe15e0SLoGin } 14040fe15e0SLoGin 14140fe15e0SLoGin pub fn init_info(&self) -> &ProcInitInfo { 14240fe15e0SLoGin &self.init_info 14340fe15e0SLoGin } 14440fe15e0SLoGin 14540fe15e0SLoGin pub fn init_info_mut(&mut self) -> &mut ProcInitInfo { 14640fe15e0SLoGin &mut self.init_info 14740fe15e0SLoGin } 14840fe15e0SLoGin 14940fe15e0SLoGin /// 获取加载模式 15040fe15e0SLoGin pub fn load_mode(&self) -> ExecLoadMode { 15140fe15e0SLoGin if self.flags.contains(ExecParamFlags::EXEC) { 15240fe15e0SLoGin ExecLoadMode::Exec 15340fe15e0SLoGin } else { 15440fe15e0SLoGin ExecLoadMode::DSO 15540fe15e0SLoGin } 15640fe15e0SLoGin } 15740fe15e0SLoGin 15840fe15e0SLoGin pub fn file_mut(&mut self) -> &mut File { 159*a02ce654SChiichen &mut self.file 16040fe15e0SLoGin } 16140fe15e0SLoGin } 16240fe15e0SLoGin 16340fe15e0SLoGin /// ## 加载二进制文件 16440fe15e0SLoGin pub fn load_binary_file(param: &mut ExecParam) -> Result<BinaryLoaderResult, SystemError> { 16540fe15e0SLoGin // 读取文件头部,用于判断文件类型 16640fe15e0SLoGin let mut head_buf = [0u8; 512]; 16740fe15e0SLoGin param.file_mut().lseek(SeekFrom::SeekSet(0))?; 16840fe15e0SLoGin let _bytes = param.file_mut().read(512, &mut head_buf)?; 16940fe15e0SLoGin // kdebug!("load_binary_file: read {} bytes", _bytes); 17040fe15e0SLoGin 17140fe15e0SLoGin let mut loader = None; 17240fe15e0SLoGin for bl in BINARY_LOADERS.iter() { 17340fe15e0SLoGin let probe_result = bl.probe(param, &head_buf); 17440fe15e0SLoGin if probe_result.is_ok() { 17540fe15e0SLoGin loader = Some(bl); 17640fe15e0SLoGin break; 17740fe15e0SLoGin } 17840fe15e0SLoGin } 17940fe15e0SLoGin // kdebug!("load_binary_file: loader: {:?}", loader); 18040fe15e0SLoGin if loader.is_none() { 18140fe15e0SLoGin return Err(SystemError::ENOEXEC); 18240fe15e0SLoGin } 18340fe15e0SLoGin 18440fe15e0SLoGin let loader: &&dyn BinaryLoader = loader.unwrap(); 18540fe15e0SLoGin assert!(param.vm().is_current()); 18640fe15e0SLoGin // kdebug!("load_binary_file: to load with param: {:?}", param); 18740fe15e0SLoGin 18840fe15e0SLoGin let result: BinaryLoaderResult = loader 18940fe15e0SLoGin .load(param, &head_buf) 19040fe15e0SLoGin .unwrap_or_else(|e| panic!("load_binary_file failed: error: {e:?}, param: {param:?}")); 19140fe15e0SLoGin 19240fe15e0SLoGin // kdebug!("load_binary_file: load success"); 19340fe15e0SLoGin return Ok(result); 19440fe15e0SLoGin } 19540fe15e0SLoGin 19640fe15e0SLoGin /// 程序初始化信息,这些信息会被压入用户栈中 19740fe15e0SLoGin #[derive(Debug)] 19840fe15e0SLoGin pub struct ProcInitInfo { 199865f4ba4SGnoCiYeH pub proc_name: String, 20040fe15e0SLoGin pub args: Vec<String>, 20140fe15e0SLoGin pub envs: Vec<String>, 20240fe15e0SLoGin pub auxv: BTreeMap<u8, usize>, 20340fe15e0SLoGin } 20440fe15e0SLoGin 20540fe15e0SLoGin impl ProcInitInfo { 20640fe15e0SLoGin pub fn new() -> Self { 20740fe15e0SLoGin Self { 208865f4ba4SGnoCiYeH proc_name: String::new(), 20940fe15e0SLoGin args: Vec::new(), 21040fe15e0SLoGin envs: Vec::new(), 21140fe15e0SLoGin auxv: BTreeMap::new(), 21240fe15e0SLoGin } 21340fe15e0SLoGin } 21440fe15e0SLoGin 21540fe15e0SLoGin /// 把程序初始化信息压入用户栈中 21640fe15e0SLoGin /// 这个函数会把参数、环境变量、auxv等信息压入用户栈中 21740fe15e0SLoGin /// 21840fe15e0SLoGin /// ## 返回值 21940fe15e0SLoGin /// 22040fe15e0SLoGin /// 返回值是一个元组,第一个元素是最终的用户栈顶地址,第二个元素是环境变量pointer数组的起始地址 22140fe15e0SLoGin pub unsafe fn push_at( 22240fe15e0SLoGin &self, 22340fe15e0SLoGin ustack: &mut UserStack, 22440fe15e0SLoGin ) -> Result<(VirtAddr, VirtAddr), SystemError> { 22540fe15e0SLoGin // 先把程序的名称压入栈中 226865f4ba4SGnoCiYeH self.push_str(ustack, &self.proc_name)?; 22740fe15e0SLoGin 22840fe15e0SLoGin // 然后把环境变量压入栈中 22940fe15e0SLoGin let envps = self 23040fe15e0SLoGin .envs 23140fe15e0SLoGin .iter() 23240fe15e0SLoGin .map(|s| { 23340fe15e0SLoGin self.push_str(ustack, s.as_str()).expect("push_str failed"); 23440fe15e0SLoGin ustack.sp() 23540fe15e0SLoGin }) 23640fe15e0SLoGin .collect::<Vec<_>>(); 23740fe15e0SLoGin 23840fe15e0SLoGin // 然后把参数压入栈中 23940fe15e0SLoGin let argps = self 24040fe15e0SLoGin .args 24140fe15e0SLoGin .iter() 24240fe15e0SLoGin .map(|s| { 24340fe15e0SLoGin self.push_str(ustack, s.as_str()).expect("push_str failed"); 24440fe15e0SLoGin ustack.sp() 24540fe15e0SLoGin }) 24640fe15e0SLoGin .collect::<Vec<_>>(); 24740fe15e0SLoGin 24840fe15e0SLoGin // 压入auxv 24940fe15e0SLoGin self.push_slice(ustack, &[null::<u8>(), null::<u8>()])?; 25040fe15e0SLoGin for (&k, &v) in self.auxv.iter() { 25140fe15e0SLoGin self.push_slice(ustack, &[k as usize, v])?; 25240fe15e0SLoGin } 25340fe15e0SLoGin 25440fe15e0SLoGin // 把环境变量指针压入栈中 25540fe15e0SLoGin self.push_slice(ustack, &[null::<u8>()])?; 25640fe15e0SLoGin self.push_slice(ustack, envps.as_slice())?; 25740fe15e0SLoGin 25840fe15e0SLoGin // 把参数指针压入栈中 25940fe15e0SLoGin self.push_slice(ustack, &[null::<u8>()])?; 26040fe15e0SLoGin self.push_slice(ustack, argps.as_slice())?; 26140fe15e0SLoGin 26240fe15e0SLoGin let argv_ptr = ustack.sp(); 26340fe15e0SLoGin 26440fe15e0SLoGin // 把argc压入栈中 26540fe15e0SLoGin self.push_slice(ustack, &[self.args.len()])?; 26640fe15e0SLoGin 26740fe15e0SLoGin return Ok((ustack.sp(), argv_ptr)); 26840fe15e0SLoGin } 26940fe15e0SLoGin 27040fe15e0SLoGin fn push_slice<T: Copy>(&self, ustack: &mut UserStack, slice: &[T]) -> Result<(), SystemError> { 27140fe15e0SLoGin let mut sp = ustack.sp(); 27240fe15e0SLoGin sp -= slice.len() * core::mem::size_of::<T>(); 27340fe15e0SLoGin sp -= sp.data() % core::mem::align_of::<T>(); 27440fe15e0SLoGin 27540fe15e0SLoGin unsafe { core::slice::from_raw_parts_mut(sp.data() as *mut T, slice.len()) } 27640fe15e0SLoGin .copy_from_slice(slice); 27740fe15e0SLoGin unsafe { 27840fe15e0SLoGin ustack.set_sp(sp); 27940fe15e0SLoGin } 28040fe15e0SLoGin 28140fe15e0SLoGin return Ok(()); 28240fe15e0SLoGin } 28340fe15e0SLoGin 28440fe15e0SLoGin fn push_str(&self, ustack: &mut UserStack, s: &str) -> Result<(), SystemError> { 28540fe15e0SLoGin self.push_slice(ustack, &[b'\0'])?; 28640fe15e0SLoGin self.push_slice(ustack, s.as_bytes())?; 28740fe15e0SLoGin return Ok(()); 28840fe15e0SLoGin } 28940fe15e0SLoGin } 290