diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/sys/include/sys/proc.h | 11 | ||||
-rw-r--r-- | src/sys/os/os_proc.c | 43 |
2 files changed, 54 insertions, 0 deletions
diff --git a/src/sys/include/sys/proc.h b/src/sys/include/sys/proc.h index d93f490..fe45506 100644 --- a/src/sys/include/sys/proc.h +++ b/src/sys/include/sys/proc.h @@ -136,6 +136,17 @@ int proc_add_range(struct proc *procp, vaddr_t va, paddr_t pa, size_t len); int proc_kill(struct proc *procp, int status); /* + * Spawn a process from a binary + * + * @path: Path to binary + * @envp: Environment block pointer + * + * Returns the PID of the new process on success, + * otherwise a less than zero value on error + */ +int proc_spawn(const char *path, struct penv_blk *envbp); + +/* * Initialize machine dependent state of a process * * @procp: New process data is written here diff --git a/src/sys/os/os_proc.c b/src/sys/os/os_proc.c index ad591e6..e32e59c 100644 --- a/src/sys/os/os_proc.c +++ b/src/sys/os/os_proc.c @@ -32,9 +32,13 @@ #include <sys/errno.h> #include <sys/cdefs.h> #include <sys/queue.h> +#include <sys/panic.h> #include <sys/proc.h> +#include <sys/cpuvar.h> +#include <os/systm.h> #include <vm/vm.h> #include <vm/physseg.h> +#include <os/elfload.h> #include <os/signal.h> #include <os/kalloc.h> #include <os/filedesc.h> @@ -169,3 +173,42 @@ proc_check_addr(struct proc *proc, uintptr_t addr, size_t len) return -EFAULT; } + +int +proc_spawn(const char *path, struct penv_blk *envbp) +{ + struct pcore *core; + struct loaded_elf elf; + struct proc *proc; + int error; + + if (path == NULL) { + return -EINVAL; + } + + /* Allocate a new process */ + proc = kalloc(sizeof(*proc)); + if (proc == NULL) { + return -ENOMEM; + } + + proc_init(proc, 0); + error = elf_load(path, proc, &elf); + if (error < 0) { + kfree(proc); + return error; + } + + core = cpu_sched(); + if (__unlikely(core == NULL)) { + panic("spawn: failed to arbitrate core\n"); + } + + if (envbp != NULL) { + memcpy(&proc->envblk, envbp, sizeof(proc->envblk)); + } + + md_set_ip(proc, elf.entrypoint); + sched_enq(&core->scq, proc); + return proc->pid; +} |