From ea9c399dda5193a8832e18ce6a23a9f6446f94e0 Mon Sep 17 00:00:00 2001 From: Bahadir Balban Date: Tue, 6 Oct 2009 18:30:36 +0300 Subject: [PATCH] Progress on executing test0 from memfs file as an elf. Elf is recognised OK, but somehow section table is not read correctly. --- conts/posix/mm0/include/exec.h | 2 +- conts/posix/mm0/include/init.h | 2 +- conts/posix/mm0/mm/execve.c | 76 +++++++++++++++++++- conts/posix/mm0/mm/file.c | 2 +- conts/posix/mm0/mm/init.c | 8 --- conts/posix/mm0/mm/task.c | 2 +- conts/posix/test0/SConscript | 41 +++++++++-- conts/posix/test0/include/elf_wrapper.lds.in | 6 ++ loader/libs/elf/src/elf.c | 4 +- 9 files changed, 120 insertions(+), 23 deletions(-) create mode 100644 conts/posix/test0/include/elf_wrapper.lds.in diff --git a/conts/posix/mm0/include/exec.h b/conts/posix/mm0/include/exec.h index 4ca1381..43e5efe 100644 --- a/conts/posix/mm0/include/exec.h +++ b/conts/posix/mm0/include/exec.h @@ -9,7 +9,7 @@ /* * This presents extra executable file information that is * not present in the tcb, in a generic format. - */ + */ struct exec_file_desc { unsigned long text_offset; /* File offset of text section */ unsigned long data_offset; /* File offset of data section */ diff --git a/conts/posix/mm0/include/init.h b/conts/posix/mm0/include/init.h index e1945f8..60623a4 100644 --- a/conts/posix/mm0/include/init.h +++ b/conts/posix/mm0/include/init.h @@ -34,6 +34,6 @@ void init(void); /* TODO: Remove this stuff from here. */ int init_devzero(void); struct vm_file *get_devzero(void); -int init_boot_files(struct initdata *initdata); +int init_execve(char *path); #endif /* __MM_INIT_H__ */ diff --git a/conts/posix/mm0/mm/execve.c b/conts/posix/mm0/mm/execve.c index 3b54fc2..ec02123 100644 --- a/conts/posix/mm0/mm/execve.c +++ b/conts/posix/mm0/mm/execve.c @@ -1,4 +1,4 @@ -/* +/* It is safe when argc = 0 *//* * Program execution * * Copyright (C) 2008 Bahadir Balban @@ -19,7 +19,8 @@ #include #include #include - +#include +#include /* * Probes and parses the low-level executable file format and creates a @@ -33,6 +34,77 @@ int task_setup_from_executable(struct vm_file *vmfile, struct tcb *task, return elf_parse_executable(task, vmfile, efd); } +int init_execve(char *filepath) +{ + unsigned long vnum, length; + struct vm_file *vmfile; + struct exec_file_desc efd; + struct tcb *new_task; + struct task_ids ids = { + .tid = TASK_ID_INVALID, + .spid = TASK_ID_INVALID, + .tgid = TASK_ID_INVALID + }; + struct args_struct args = { .argc = 0 }; /* It is safe when argc = 0 */ + struct args_struct env = { .argc = 0 }; /* It is safe when argc = 0 */ + //struct tcb *self = find_task(self_tid()); + // int fd; + int err; + + /* Get file info from vfs */ + if ((err = vfs_open_bypath(filepath, &vnum, &length)) < 0) + return err; + + /* Create and get the file structure */ + if (IS_ERR(vmfile = do_open2(0, 0, vnum, length))) + return (int)vmfile; + +#if 0 + if ((fd = sys_open(self, filepath, + O_RDONLY, 0)) < 0) { + printf("FATAL: Could not open file " + "to execute initial task.\n"); + BUG(); + } +#endif + + if (IS_ERR(new_task = task_create(0, &ids, + THREAD_NEW_SPACE, + TCB_NO_SHARING))) { + vm_file_put(vmfile); /* FIXME: sys_close() ??? */ + return (int)new_task; + } + + /* Fill and validate tcb memory segment markers from executable file */ + if ((err = task_setup_from_executable(vmfile, new_task, &efd)) < 0) { + vm_file_put(vmfile); + kfree(new_task); + return err; + } + + /* Map task's new segment markers as virtual memory regions */ + if ((err = task_mmap_segments(new_task, vmfile, + &efd, &args, &env)) < 0) { + vm_file_put(vmfile); + kfree(new_task); + return err; + } + + /* Set up task registers via exchange_registers() */ + task_setup_registers(new_task, 0, + new_task->args_start, + new_task->pagerid); + + /* Add new task to global list */ + global_add_task(new_task); + + /* Start the task */ + task_start(new_task); + + return 0; +} + + int do_execve(struct tcb *sender, char *filename, struct args_struct *args, struct args_struct *env) { diff --git a/conts/posix/mm0/mm/file.c b/conts/posix/mm0/mm/file.c index fb89356..b8b6cfe 100644 --- a/conts/posix/mm0/mm/file.c +++ b/conts/posix/mm0/mm/file.c @@ -103,7 +103,7 @@ void print_vnode(struct vnode *v) int vfs_open_bypath(const char *pathname, unsigned long *vnum, unsigned long *length) { struct pathdata *pdata; - struct tcb *task; + struct tcb *task = 0; struct vnode *v; int retval; diff --git a/conts/posix/mm0/mm/init.c b/conts/posix/mm0/mm/init.c index bc872f6..dc60e79 100644 --- a/conts/posix/mm0/mm/init.c +++ b/conts/posix/mm0/mm/init.c @@ -436,14 +436,6 @@ void init_physmem(void) init_page_allocator(membank[0].free, membank[0].end); } -void init_execve(char *path) -{ - /* - * Find executable, and execute it by creating a new process - * rather than replacing the current image (which is the pager!) - */ -} - /* * To be removed later: This file copies in-memory elf image to the * initialized and formatted in-memory memfs filesystem. diff --git a/conts/posix/mm0/mm/task.c b/conts/posix/mm0/mm/task.c index 5d4e6e9..050cb32 100644 --- a/conts/posix/mm0/mm/task.c +++ b/conts/posix/mm0/mm/task.c @@ -411,7 +411,7 @@ struct tcb *task_create(struct tcb *parent, struct task_ids *ids, task->parent = parent; } } else { - struct tcb *pager = find_task(PAGER_TID); + struct tcb *pager = find_task(self_tid()); /* Initialise vfs specific fields. */ task->fs_data->rootdir = vfs_root.pivot; diff --git a/conts/posix/test0/SConscript b/conts/posix/test0/SConscript index a18d827..6603dc9 100644 --- a/conts/posix/test0/SConscript +++ b/conts/posix/test0/SConscript @@ -9,7 +9,7 @@ sys.path.append('../../../../') from config.lib import * from tools.pyelf.lmanext import * -src = [Glob('*.[cS]') + Glob('src/*.c') + Glob('src/arch/arm/*.c')] +src = [Glob('*.[c]') + Glob('test_exec.S') + Glob('src/*.c') + Glob('src/arch/arm/*.c')] asm_string = \ ''' @@ -33,7 +33,6 @@ lma_lds = Command('include/linker.lds', [previmage, 'include/linker.lds.in'], ge env = environment.Clone() test_exec_env = environment.Clone() - test_exec_env.Append(LIBS = ['posix', 'c-userspace']) test_exec_env.Append(LINKFLAGS = ['-T' + "test0/include/test_exec_linker.lds", '-u_start']) test_exec_env.Append(CPPFLAGS = ' -D__USERSPACE__') @@ -46,11 +45,41 @@ test_exec_asm = Command('test_exec.S', test_exec, generate_incbin_asm) env.Append(LIBS = ['posix', 'c-userspace']) env.Append(LINKFLAGS = ['-T' + lma_lds[0].path, '-u_start']) env.Append(CPPFLAGS = ' -D__USERSPACE__') +env.Replace(PROGSUFFIX = '') objs = env.Object(src + test_exec_asm) -test0 = env.Program('test0.elf', objs) +test0 = env.Program('test0', objs) + + +elf_wrap_string = \ +''' +.align 4 +.section .data +.incbin "%s" +''' + +def elf_wrap_asm(target, source, env): + with open(target[0].path, 'w+') as asm_out: + asm_out.write(elf_wrap_string % source[0].path) + +def elf_wrap_lds(target, source, env): + with open(source[1].path, 'r') as lds_in: + with open(target[0].path, 'w+') as lds_out: + linker_script = lds_in.read() + lds_out.write(linker_script % next_available_lma(source[0].path)) + +# This further wraps the test0 elf image in another elf. Required. +elf_wrap_env = environment.Clone() +elf_wrapped_asm = Command('test0_elf_wrapped.S', test0, elf_wrap_asm) +elf_wrapped_lds = Command('include/elf_wrapper.lds', [previmage, 'include/elf_wrapper.lds.in'], elf_wrap_lds) +elf_wrap_env.Append(LINKFLAGS = '-T' + elf_wrapped_lds[0].path) +elf_wrap_objs = elf_wrap_env.Object(elf_wrapped_asm) +test0_elf_elf = elf_wrap_env.Program('test0_elf.elf', elf_wrap_objs) + Depends(test0, objs) Depends(test0, lma_lds) Depends(lma_lds, previmage) -env.Depends(test0, test_exec) - -Return('test0') +Depends(test0, test_exec) +Depends(test0_elf_elf, elf_wrap_objs) +Depends(test0_elf_elf, test0) +Depends(test0_elf_elf, elf_wrapped_lds) +Return('test0_elf_elf') diff --git a/conts/posix/test0/include/elf_wrapper.lds.in b/conts/posix/test0/include/elf_wrapper.lds.in new file mode 100644 index 0000000..01beb52 --- /dev/null +++ b/conts/posix/test0/include/elf_wrapper.lds.in @@ -0,0 +1,6 @@ +SECTIONS +{ + . = %s; + .data : { *(.data) } + _end = .; +} diff --git a/loader/libs/elf/src/elf.c b/loader/libs/elf/src/elf.c index 3e421a9..73aa5e6 100644 --- a/loader/libs/elf/src/elf.c +++ b/loader/libs/elf/src/elf.c @@ -376,9 +376,7 @@ elf_loadFile(void *elfFile, bool phys) pheader_type = elf_getProgramHeaderType(elfFile, i); // printf("Elf program header type: %p\n", pheader_type); -/* Enable this one printf("Copying to range from 0x%x to 0x%x of size: 0x%x\n", (unsigned int)dest, (unsigned int)dest + (unsigned int)len, (unsigned int)len); - */ memcpy((void*) (uintptr_t) dest, (void*) (uintptr_t) src, len); dest += len; clrsize = elf_getProgramHeaderMemorySize(elfFile, i) - len; @@ -387,7 +385,7 @@ elf_loadFile(void *elfFile, bool phys) // printf("Memory cleared.\n"); } // And this one -// printf("\n"); + printf("\n"); return true; }