From 018624dd5b1692b88f7b2e85652ea7b898043b6d Mon Sep 17 00:00:00 2001 From: Kimplul Date: Tue, 24 May 2022 23:28:37 +0300 Subject: make process loading more generic --- common/main.c | 10 ++++++++- common/proc.c | 60 +++++++++++++++--------------------------------------- common/tcb.c | 53 ++++++++++++++++++++++++++++++++++++++++++----- common/uapi/conf.c | 2 +- common/uapi/proc.c | 5 ++--- 5 files changed, 76 insertions(+), 54 deletions(-) (limited to 'common') diff --git a/common/main.c b/common/main.c index 9585f3d..a608266 100644 --- a/common/main.c +++ b/common/main.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include @@ -23,6 +24,7 @@ void __main main(void *fdt) setup_arch(fdt); init_pmem(fdt); + /* setup temporary virtual memory */ struct vmem *b = init_vmem(fdt); /* start up debugging in kernel IO */ @@ -30,5 +32,11 @@ void __main main(void *fdt) init_irq(fdt); init_timer(fdt); - init_proc(fdt, b); + init_proc(fdt); + /* free temporary virtual memory now that we're in the init process + * space */ + destroy_vmem(b); + + /* start running init program */ + run_init(cur_tcb(), fdt); } diff --git a/common/proc.c b/common/proc.c index f09e7c1..3f6da6d 100644 --- a/common/proc.c +++ b/common/proc.c @@ -9,62 +9,34 @@ #include #include #include +#include -/* TODO: add error checking */ -static vm_t __setup_call_stack(struct tcb *t, size_t bytes) +stat_t prepare_proc(struct tcb *t, vm_t bin, vm_t interp) { - pm_t offset = 0; - size_t pages = __pages(bytes); - vmflags_t flags = VM_V | VM_R | VM_W | VM_U; - for (size_t i = 1; i <= pages; ++i) { - offset = alloc_page(BASE_PAGE, offset); - map_vpage(t->b_r, offset, PROC_STACK_TOP - BASE_PAGE_SIZE * i, - flags, BASE_PAGE); - } - - return PROC_STACK_TOP - BASE_PAGE_SIZE * pages; + vm_t entry = load_elf(t, bin, interp); + if (!entry) + return ERR_INVAL; + + alloc_stacks(t); + prepare_thread(t); + set_return(entry); + return OK; } -static vm_t __setup_proc_stack(struct tcb *t, size_t bytes) -{ - return alloc_uvmem(t, bytes, VM_V | VM_R | VM_W | VM_U); -} - -stat_t init_proc(void *fdt, struct vmem *b) +stat_t init_proc(void *fdt) { init_tcbs(); /* TODO: cleanup or something */ - struct tcb *t = create_thread(NULL); + struct tcb *t = create_proc(NULL); if (!t) return ERR_OOMEM; - /* use existing branch */ - t->b_r = b; - init_uvmem(t, UVMEM_START, UVMEM_END); - - /* TODO: this stuff should be placed in __sys_exec */ - /* the binary gets to choose first what memory regions it requires */ - t->entry = load_elf(t, get_init_base(fdt), 0); - if (!t->entry) - return ERR_ADDR; - - t->proc_stack = __setup_proc_stack(t, __proc_stack_size); - if (!t->proc_stack) - return ERR_ADDR; - - t->proc_stack_top = t->proc_stack + __proc_stack_size; - - t->call_stack = __setup_call_stack(t, __call_stack_size); - if (!t->call_stack) - return ERR_ADDR; - t->call_stack_top = t->call_stack + __call_stack_size; - - flush_tlb(); - /* set current tcb */ use_tcb(t); + use_vmem(t->b_r); - /* TODO: move fdt into process space */ - return jump_to_userspace(t, 1, 0); + /* allocate stacks after ELF file to make sure nothing of importance + * clashes */ + return prepare_proc(t, get_init_base(fdt), 0); } diff --git a/common/tcb.c b/common/tcb.c index 6904208..0809829 100644 --- a/common/tcb.c +++ b/common/tcb.c @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -54,6 +55,45 @@ static id_t __alloc_tid(struct tcb *t) return ERR_NF; } +/* TODO: add error checking */ +static vm_t __setup_call_stack(struct tcb *t, size_t bytes) +{ + pm_t offset = 0; + size_t pages = __pages(bytes); + vmflags_t flags = VM_V | VM_R | VM_W | VM_U; + for (size_t i = 1; i <= pages; ++i) { + offset = alloc_page(BASE_PAGE, offset); + map_vpage(t->b_r, offset, PROC_STACK_TOP - BASE_PAGE_SIZE * i, + flags, BASE_PAGE); + } + + return PROC_STACK_TOP - BASE_PAGE_SIZE * pages; +} + +static vm_t __setup_thread_stack(struct tcb *t, size_t bytes) +{ + return alloc_uvmem(t, bytes, VM_V | VM_R | VM_W | VM_U); +} + +stat_t alloc_stacks(struct tcb *t) +{ + struct tcb *p = is_proc(t) ? t : t->proc; + + t->thread_stack = __setup_thread_stack(p, __thread_stack_size); + if (!t->thread_stack) + return ERR_OOMEM; + + t->call_stack = __setup_call_stack(p, __call_stack_size); + if (!t->call_stack) + return ERR_OOMEM; + + /* TODO: this only allows for a global stack size, what if a user wants + * per thread stack sizes? */ + t->thread_stack_top = t->thread_stack + __thread_stack_size; + t->call_stack_top = t->call_stack + __call_stack_size; + return OK; +} + struct tcb *create_thread(struct tcb *p) { hard_assert(tcbs, 0); @@ -70,13 +110,17 @@ struct tcb *create_thread(struct tcb *p) tcbs[tid] = t; t->tid = tid; - if (p) { + if (likely(p)) { t->pid = p->pid; t->proc = p; } else { + init_uvmem(t, UVMEM_START, UVMEM_END); t->pid = t->tid; + p = t; } + t->b_r = create_vmem(); + return t; } @@ -93,13 +137,12 @@ struct tcb *create_proc(struct tcb *p) hard_assert(tcbs, 0); /* create a new thread outside the current process */ - struct tcb *n = create_thread(0); - n->b_r = create_vmem(); + struct tcb *n = create_thread(NULL); + if (!n) + return 0; if (likely(p)) __clone_proc(p, n); /* we have a parent thread */ - else - init_uvmem(n, UVMEM_START, UVMEM_END); return n; } diff --git a/common/uapi/conf.c b/common/uapi/conf.c index a30333b..86846b2 100644 --- a/common/uapi/conf.c +++ b/common/uapi/conf.c @@ -9,7 +9,7 @@ #include #include -size_t __proc_stack_size = SZ_2M; +size_t __thread_stack_size = SZ_2M; size_t __call_stack_size = SZ_2M; SYSCALL_DEFINE2(conf)(sys_arg_t param, sys_arg_t val) diff --git a/common/uapi/proc.c b/common/uapi/proc.c index c898339..f8ceaa5 100644 --- a/common/uapi/proc.c +++ b/common/uapi/proc.c @@ -5,6 +5,7 @@ #include #include +#include #include #include @@ -53,9 +54,7 @@ SYSCALL_DEFINE2(exec)(sys_arg_t bin, sys_arg_t interp){ if (interp) clear_bit(b->flags, MR_KEEP); - /* TODO: set entry? */ - load_elf(r, b, i); - return (struct sys_ret){ OK, 0 }; + return (struct sys_ret){ prepare_proc(r, bin, interp), 0 }; } SYSCALL_DEFINE2(signal)(sys_arg_t tid, sys_arg_t signal){ -- cgit v1.3