140fe15e0SLoGin use core::{fmt::Debug, ptr::null}; 240fe15e0SLoGin 340fe15e0SLoGin use alloc::{collections::BTreeMap, string::String, sync::Arc, vec::Vec}; 440fe15e0SLoGin 540fe15e0SLoGin use crate::{ 6b087521eSChiichen driver::base::block::SeekFrom, 740fe15e0SLoGin filesystem::vfs::{ 840fe15e0SLoGin file::{File, FileMode}, 940fe15e0SLoGin ROOT_INODE, 1040fe15e0SLoGin }, 1140fe15e0SLoGin libs::elf::ELF_LOADER, 1240fe15e0SLoGin mm::{ 1340fe15e0SLoGin ucontext::{AddressSpace, UserStack}, 1440fe15e0SLoGin VirtAddr, 1540fe15e0SLoGin }, 1640fe15e0SLoGin syscall::SystemError, 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)] 9640fe15e0SLoGin pub struct ExecParam<'a> { 9740fe15e0SLoGin file_path: &'a str, 9840fe15e0SLoGin file: Option<File>, 9940fe15e0SLoGin vm: Arc<AddressSpace>, 10040fe15e0SLoGin /// 一些标志位 10140fe15e0SLoGin flags: ExecParamFlags, 10240fe15e0SLoGin /// 用来初始化进程的一些信息。这些信息由二进制加载器和exec机制来共同填充 10340fe15e0SLoGin init_info: ProcInitInfo, 10440fe15e0SLoGin } 10540fe15e0SLoGin 10640fe15e0SLoGin #[derive(Debug, Eq, PartialEq)] 10740fe15e0SLoGin pub enum ExecLoadMode { 10840fe15e0SLoGin /// 以可执行文件的形式加载 10940fe15e0SLoGin Exec, 11040fe15e0SLoGin /// 以动态链接库的形式加载 11140fe15e0SLoGin DSO, 11240fe15e0SLoGin } 11340fe15e0SLoGin 11440fe15e0SLoGin #[allow(dead_code)] 11540fe15e0SLoGin impl<'a> ExecParam<'a> { 11640fe15e0SLoGin pub fn new(file_path: &'a str, vm: Arc<AddressSpace>, flags: ExecParamFlags) -> Self { 11740fe15e0SLoGin Self { 11840fe15e0SLoGin file_path, 11940fe15e0SLoGin file: None, 12040fe15e0SLoGin vm, 12140fe15e0SLoGin flags, 12240fe15e0SLoGin init_info: ProcInitInfo::new(), 12340fe15e0SLoGin } 12440fe15e0SLoGin } 12540fe15e0SLoGin 12640fe15e0SLoGin pub fn file_path(&self) -> &'a str { 12740fe15e0SLoGin self.file_path 12840fe15e0SLoGin } 12940fe15e0SLoGin 13040fe15e0SLoGin pub fn vm(&self) -> &Arc<AddressSpace> { 13140fe15e0SLoGin &self.vm 13240fe15e0SLoGin } 13340fe15e0SLoGin 13440fe15e0SLoGin pub fn flags(&self) -> &ExecParamFlags { 13540fe15e0SLoGin &self.flags 13640fe15e0SLoGin } 13740fe15e0SLoGin 13840fe15e0SLoGin pub fn init_info(&self) -> &ProcInitInfo { 13940fe15e0SLoGin &self.init_info 14040fe15e0SLoGin } 14140fe15e0SLoGin 14240fe15e0SLoGin pub fn init_info_mut(&mut self) -> &mut ProcInitInfo { 14340fe15e0SLoGin &mut self.init_info 14440fe15e0SLoGin } 14540fe15e0SLoGin 14640fe15e0SLoGin /// 获取加载模式 14740fe15e0SLoGin pub fn load_mode(&self) -> ExecLoadMode { 14840fe15e0SLoGin if self.flags.contains(ExecParamFlags::EXEC) { 14940fe15e0SLoGin ExecLoadMode::Exec 15040fe15e0SLoGin } else { 15140fe15e0SLoGin ExecLoadMode::DSO 15240fe15e0SLoGin } 15340fe15e0SLoGin } 15440fe15e0SLoGin 15540fe15e0SLoGin pub fn file_mut(&mut self) -> &mut File { 15640fe15e0SLoGin self.file.as_mut().unwrap() 15740fe15e0SLoGin } 15840fe15e0SLoGin } 15940fe15e0SLoGin 16040fe15e0SLoGin /// ## 加载二进制文件 16140fe15e0SLoGin pub fn load_binary_file(param: &mut ExecParam) -> Result<BinaryLoaderResult, SystemError> { 16240fe15e0SLoGin let inode = ROOT_INODE().lookup(param.file_path)?; 16340fe15e0SLoGin 16440fe15e0SLoGin // 读取文件头部,用于判断文件类型 16540fe15e0SLoGin let file = File::new(inode, FileMode::O_RDONLY)?; 16640fe15e0SLoGin param.file = Some(file); 16740fe15e0SLoGin let mut head_buf = [0u8; 512]; 16840fe15e0SLoGin param.file_mut().lseek(SeekFrom::SeekSet(0))?; 16940fe15e0SLoGin let _bytes = param.file_mut().read(512, &mut head_buf)?; 17040fe15e0SLoGin // kdebug!("load_binary_file: read {} bytes", _bytes); 17140fe15e0SLoGin 17240fe15e0SLoGin let mut loader = None; 17340fe15e0SLoGin for bl in BINARY_LOADERS.iter() { 17440fe15e0SLoGin let probe_result = bl.probe(param, &head_buf); 17540fe15e0SLoGin if probe_result.is_ok() { 17640fe15e0SLoGin loader = Some(bl); 17740fe15e0SLoGin break; 17840fe15e0SLoGin } 17940fe15e0SLoGin } 18040fe15e0SLoGin // kdebug!("load_binary_file: loader: {:?}", loader); 18140fe15e0SLoGin if loader.is_none() { 18240fe15e0SLoGin return Err(SystemError::ENOEXEC); 18340fe15e0SLoGin } 18440fe15e0SLoGin 18540fe15e0SLoGin let loader: &&dyn BinaryLoader = loader.unwrap(); 18640fe15e0SLoGin assert!(param.vm().is_current()); 18740fe15e0SLoGin // kdebug!("load_binary_file: to load with param: {:?}", param); 18840fe15e0SLoGin 18940fe15e0SLoGin let result: BinaryLoaderResult = loader 19040fe15e0SLoGin .load(param, &head_buf) 19140fe15e0SLoGin .unwrap_or_else(|e| panic!("load_binary_file failed: error: {e:?}, param: {param:?}")); 19240fe15e0SLoGin 19340fe15e0SLoGin // kdebug!("load_binary_file: load success"); 19440fe15e0SLoGin return Ok(result); 19540fe15e0SLoGin } 19640fe15e0SLoGin 19740fe15e0SLoGin /// 程序初始化信息,这些信息会被压入用户栈中 19840fe15e0SLoGin #[derive(Debug)] 19940fe15e0SLoGin pub struct ProcInitInfo { 200*865f4ba4SGnoCiYeH pub proc_name: String, 20140fe15e0SLoGin pub args: Vec<String>, 20240fe15e0SLoGin pub envs: Vec<String>, 20340fe15e0SLoGin pub auxv: BTreeMap<u8, usize>, 20440fe15e0SLoGin } 20540fe15e0SLoGin 20640fe15e0SLoGin impl ProcInitInfo { 20740fe15e0SLoGin pub fn new() -> Self { 20840fe15e0SLoGin Self { 209*865f4ba4SGnoCiYeH proc_name: String::new(), 21040fe15e0SLoGin args: Vec::new(), 21140fe15e0SLoGin envs: Vec::new(), 21240fe15e0SLoGin auxv: BTreeMap::new(), 21340fe15e0SLoGin } 21440fe15e0SLoGin } 21540fe15e0SLoGin 21640fe15e0SLoGin /// 把程序初始化信息压入用户栈中 21740fe15e0SLoGin /// 这个函数会把参数、环境变量、auxv等信息压入用户栈中 21840fe15e0SLoGin /// 21940fe15e0SLoGin /// ## 返回值 22040fe15e0SLoGin /// 22140fe15e0SLoGin /// 返回值是一个元组,第一个元素是最终的用户栈顶地址,第二个元素是环境变量pointer数组的起始地址 22240fe15e0SLoGin pub unsafe fn push_at( 22340fe15e0SLoGin &self, 22440fe15e0SLoGin ustack: &mut UserStack, 22540fe15e0SLoGin ) -> Result<(VirtAddr, VirtAddr), SystemError> { 22640fe15e0SLoGin // 先把程序的名称压入栈中 227*865f4ba4SGnoCiYeH self.push_str(ustack, &self.proc_name)?; 22840fe15e0SLoGin 22940fe15e0SLoGin // 然后把环境变量压入栈中 23040fe15e0SLoGin let envps = self 23140fe15e0SLoGin .envs 23240fe15e0SLoGin .iter() 23340fe15e0SLoGin .map(|s| { 23440fe15e0SLoGin self.push_str(ustack, s.as_str()).expect("push_str failed"); 23540fe15e0SLoGin ustack.sp() 23640fe15e0SLoGin }) 23740fe15e0SLoGin .collect::<Vec<_>>(); 23840fe15e0SLoGin 23940fe15e0SLoGin // 然后把参数压入栈中 24040fe15e0SLoGin let argps = self 24140fe15e0SLoGin .args 24240fe15e0SLoGin .iter() 24340fe15e0SLoGin .map(|s| { 24440fe15e0SLoGin self.push_str(ustack, s.as_str()).expect("push_str failed"); 24540fe15e0SLoGin ustack.sp() 24640fe15e0SLoGin }) 24740fe15e0SLoGin .collect::<Vec<_>>(); 24840fe15e0SLoGin 24940fe15e0SLoGin // 压入auxv 25040fe15e0SLoGin self.push_slice(ustack, &[null::<u8>(), null::<u8>()])?; 25140fe15e0SLoGin for (&k, &v) in self.auxv.iter() { 25240fe15e0SLoGin self.push_slice(ustack, &[k as usize, v])?; 25340fe15e0SLoGin } 25440fe15e0SLoGin 25540fe15e0SLoGin // 把环境变量指针压入栈中 25640fe15e0SLoGin self.push_slice(ustack, &[null::<u8>()])?; 25740fe15e0SLoGin self.push_slice(ustack, envps.as_slice())?; 25840fe15e0SLoGin 25940fe15e0SLoGin // 把参数指针压入栈中 26040fe15e0SLoGin self.push_slice(ustack, &[null::<u8>()])?; 26140fe15e0SLoGin self.push_slice(ustack, argps.as_slice())?; 26240fe15e0SLoGin 26340fe15e0SLoGin let argv_ptr = ustack.sp(); 26440fe15e0SLoGin 26540fe15e0SLoGin // 把argc压入栈中 26640fe15e0SLoGin self.push_slice(ustack, &[self.args.len()])?; 26740fe15e0SLoGin 26840fe15e0SLoGin return Ok((ustack.sp(), argv_ptr)); 26940fe15e0SLoGin } 27040fe15e0SLoGin 27140fe15e0SLoGin fn push_slice<T: Copy>(&self, ustack: &mut UserStack, slice: &[T]) -> Result<(), SystemError> { 27240fe15e0SLoGin let mut sp = ustack.sp(); 27340fe15e0SLoGin sp -= slice.len() * core::mem::size_of::<T>(); 27440fe15e0SLoGin sp -= sp.data() % core::mem::align_of::<T>(); 27540fe15e0SLoGin 27640fe15e0SLoGin unsafe { core::slice::from_raw_parts_mut(sp.data() as *mut T, slice.len()) } 27740fe15e0SLoGin .copy_from_slice(slice); 27840fe15e0SLoGin unsafe { 27940fe15e0SLoGin ustack.set_sp(sp); 28040fe15e0SLoGin } 28140fe15e0SLoGin 28240fe15e0SLoGin return Ok(()); 28340fe15e0SLoGin } 28440fe15e0SLoGin 28540fe15e0SLoGin fn push_str(&self, ustack: &mut UserStack, s: &str) -> Result<(), SystemError> { 28640fe15e0SLoGin self.push_slice(ustack, &[b'\0'])?; 28740fe15e0SLoGin self.push_slice(ustack, s.as_bytes())?; 28840fe15e0SLoGin return Ok(()); 28940fe15e0SLoGin } 29040fe15e0SLoGin } 291