/// Create a new process
///
/// Parse & relocate ELF
/// Create an initial VSpace
Create a new process
Parse & relocate ELF
Create an initial VSpace
Create a new process Parse & relocate ELF Create an initial VSpace
pub fn make_process<P: Process>(binary: &'static str) -> Result<Pid, KError> {
    KernelAllocator::try_refill_tcache(7, 1, MemType::Mem)?;
    let kcb = kcb::get_kcb();
    // Lookup binary of the process
    let mut mod_file = None;
    for module in &kcb.arch.kernel_args().modules {
        if module.name() == binary {
            mod_file = Some(module);
        }
    }
    let mod_file = mod_file.ok_or(KError::BinaryNotFound { binary })?;
    info!(
        "binary={} cmdline={} module={:?}",
        binary, kcb.cmdline.init_args, mod_file
    );
    let elf_module = unsafe {
        elfloader::ElfBinary::new(mod_file.as_slice()).map_err(|_e| KError::UnableToParseElf)?
    };
    // We don't have an offset for non-pie applications (i.e., rump apps)
    let offset = if !elf_module.is_pie() {
        VAddr::zero()
    } else {
        VAddr::from(ELF_OFFSET)
    };
    let mut data_sec_loader = DataSecAllocator {
        offset,
        frames: Vec::try_with_capacity(MAX_WRITEABLE_SECTIONS_PER_PROCESS)?,
    };
    elf_module
        .load(&mut data_sec_loader)
        .map_err(|_e| KError::UnableToLoad)?;
    let data_frames: Vec<Frame> = data_sec_loader.finish()?;
    debug_assert!(
        data_frames.len() <= MAX_WRITEABLE_SECTIONS_PER_PROCESS,
        "TODO(error-handlin): Maybe reject ELF files with more?"
    );
    // Allocate a new process
    kcb.replica
        .as_ref()
        .map_or(Err(KError::ReplicaNotSet), |(replica, token)| {
            let response = replica.execute_mut(nr::Op::AllocatePid, *token)?;
            if let nr::NodeResult::PidAllocated(pid) = response {
                cnrfs::MlnrKernelNode::add_process(pid)
                    .expect("TODO(error-handling): revert state");
                crate::nrproc::NrProcess::<P>::load(pid, mod_file, data_frames)
                    .expect("TODO(error-handling): revert state properly");
                Ok(pid)
            } else {
                Err(KError::ProcessLoadingFailed)
            }
        })
}
pub fn make_process < P : Process > ( binary : & ' static str ) -> Result < Pid , KError > { KernelAllocator :: try_refill_tcache ( 7 , 1 , MemType :: Mem ) ? ; let kcb = kcb :: get_kcb ( ) ; // Lookup binary of the process let mut mod_file = None ; for module in & kcb . arch . kernel_args ( ) . modules { if module . name ( ) == binary { mod_file = Some ( module ) ; } } let mod_file = mod_file . ok_or ( KError :: BinaryNotFound { binary } ) ? ; info ! ( " " binary kcb cmdline init_args mod_file ) ; let elf_module = unsafe { elfloader :: ElfBinary :: new ( mod_file . as_slice ( ) ) . map_err ( | _e | KError :: UnableToParseElf ) ? } ; // We don't have an offset for non-pie applications (i.e., rump apps) let offset = if ! elf_module . is_pie ( ) { VAddr :: zero ( ) } else { VAddr :: from ( ELF_OFFSET ) } ; let mut data_sec_loader = DataSecAllocator { offset , frames : Vec :: try_with_capacity ( MAX_WRITEABLE_SECTIONS_PER_PROCESS ) ? , } ; elf_module . load ( & mut data_sec_loader ) . map_err ( | _e | KError :: UnableToLoad ) ? ; let data_frames : Vec < Frame > = data_sec_loader . finish ( ) ? ; debug_assert ! ( data_frames len ( ) MAX_WRITEABLE_SECTIONS_PER_PROCESS " " ) ; // Allocate a new process kcb . replica . as_ref ( ) . map_or ( Err ( KError :: ReplicaNotSet ) , | ( replica , token ) | { let response = replica . execute_mut ( nr :: Op :: AllocatePid , * token ) ? ; if let nr :: NodeResult :: PidAllocated ( pid ) = response { cnrfs :: MlnrKernelNode :: add_process ( pid ) . expect ( " " ) ; crate :: nrproc :: NrProcess :: < P > :: load ( pid , mod_file , data_frames ) . expect ( " " ) ; Ok ( pid ) } else { Err ( KError :: ProcessLoadingFailed ) } } ) }
Create a new process
Parse & relocate ELF
Create an initial VSpace
Create a new process Parse & relocate ELF Create an initial VSpace
binary
&'static str