From 080151261b0993b888e4f5f822f2c86a47e0075e Mon Sep 17 00:00:00 2001 From: Matthias Kruk Date: Wed, 30 Oct 2019 17:14:20 +0900 Subject: [PATCH] Add implementation of process_fork(), modify process_create() so that it can be used to fork a running process --- kernel/core/process.c | 75 ++++++++++++++++++++++++++++++++++++++++ kernel/include/process.h | 4 +++ 2 files changed, 79 insertions(+) diff --git a/kernel/core/process.c b/kernel/core/process.c index 8f70ec9..306e9be 100644 --- a/kernel/core/process.c +++ b/kernel/core/process.c @@ -9,6 +9,27 @@ #include "fd.h" #include "sched.h" +/* FIXME: Remove struct stack_frame from process.c */ +struct stack_frame { + u32_t cr3; + u32_t ds; + u32_t edi; + u32_t esi; + u32_t ebp; + u32_t esp; + u32_t ebx; + u32_t edx; + u32_t ecx; + u32_t eax; + u32_t intn; + u32_t error; + u32_t eip; + u32_t cs; + u32_t eflags; + u32_t prevesp; + u32_t ss; +} __attribute__((packed)); + enum procstate { PROC_STATE_INIT = 0, PROC_STATE_READY, @@ -20,6 +41,7 @@ struct process { struct task *p_tasks; u32_t p_privl; pid_t p_id; + pid_t p_pid; struct { struct cxmsg *msg; @@ -81,13 +103,17 @@ static inline int DQ(process_t *p) return(ret_val); } +void* task_get_eip3(void); + int process_create(process_t **dst, pid_t pid, u32_t ppl, void *entry) { int ret_val; process_t *proc; + pid_t ppid; ret_val = -ENOMEM; proc = NULL; + ppid = 1; /* was a specific pid requested? */ if(pid != PID_ANY) { @@ -105,6 +131,16 @@ int process_create(process_t **dst, pid_t pid, u32_t ppl, void *entry) } } + if(entry == PROC_ENTRY_FORK || + entry == PROC_ENTRY_VFORK) { + task_t *ctask; + + /* inherit the ppl from the current task, in the case of fork and vfork */ + ctask = task_get_current(); + ppl = ctask->t_privl; + ppid = ctask->t_pid; + } + proc = kmalloc(sizeof(*proc)); if(proc) { @@ -130,6 +166,7 @@ int process_create(process_t **dst, pid_t pid, u32_t ppl, void *entry) } proc->p_privl = ppl; + proc->p_pid = ppid; if(pid == PID_ANY) { /* no specific pid requested */ @@ -138,6 +175,27 @@ int process_create(process_t **dst, pid_t pid, u32_t ppl, void *entry) proc->p_id = pid; } + if(entry == PROC_ENTRY_FORK || + entry == PROC_ENTRY_VFORK) { + struct stack_frame *stack0; + task_t *ctask; + + ctask = task_get_current(); + + /* + * In the case of fork() and vfork() we have to get the address that the + * interrupt is supposed to return to. The stack that the address was pushed + * onto is located at ctask->t_kstack. + */ + + stack0 = ((struct stack_frame*)(ctask->t_kstack + CONFIG_KERNEL_STACK_SIZE)) - 1; + + entry = (void*)stack0->eip; + dbg_printf("entry = 0x%08x\n", (u32_t)entry); + + for(;;); + } + task_prepare(proc->p_tasks, (u32_t)pdbr, (u32_t)entry, (u32_t)kstack + CONFIG_KERNEL_STACK_SIZE, (u32_t)ustack + CONFIG_USER_STACK_SIZE, ppl); @@ -473,3 +531,20 @@ int process_exit(process_t *proc, int status) return(ret_val); } + +int process_fork(int v) +{ + process_t *proc; + int ret_val; + + proc = process_get_current(); + ret_val = -EFAULT; + + if(proc) { + process_t *nproc; + + ret_val = process_create(&nproc, PID_ANY, proc->p_privl, PROC_ENTRY_FORK); + } + + return(ret_val); +} diff --git a/kernel/include/process.h b/kernel/include/process.h index 4c3baf3..480e2e0 100644 --- a/kernel/include/process.h +++ b/kernel/include/process.h @@ -22,6 +22,9 @@ #include #include +#define PROC_ENTRY_FORK ((void*)0) +#define PROC_ENTRY_VFORK ((void*)1) + typedef struct process process_t; int process_create(process_t**, pid_t, u32_t, void*); @@ -47,5 +50,6 @@ int process_signal(pid_t); void* process_get_tasks(process_t*); pid_t process_get_id(process_t*); int process_exit(process_t*, int); +int process_fork(int); #endif /* __PROCESS_H */ -- 2.47.3