diff --git a/init/init.c b/init/init.c index 1f4bf37..fe8a2ca 100644 --- a/init/init.c +++ b/init/init.c @@ -4,7 +4,6 @@ int main(int argc, char **argv) { (void) argc; (void) argv; - fork(); for(;;); return 0; } diff --git a/kernel/boot/kmain.c b/kernel/boot/kmain.c index 11c4aec..68de325 100644 --- a/kernel/boot/kmain.c +++ b/kernel/boot/kmain.c @@ -12,6 +12,7 @@ #include #include +int kernel_execve(process_t *p, void *image, char *argv[], char *envp[]); int kmain(uint64_t multiboot_magic, void *multiboot_data) { debug_init(); @@ -29,12 +30,13 @@ int kmain(uint64_t multiboot_magic, void *multiboot_data) debug_info("Syscall enabled:%d\n", CPUID_FEATURE_SYSCALL); process_t *p1 = process_spawn(0); - thread_t *th = exec_elf(p1, mboot_data.init); + char *args[] = {"init", "Hello, arg", "5", 0}; + char *env[] = {"OS=mittos64", 0}; + thread_t *th = exec_elf(p1, mboot_data.init, args, env); scheduler_insert(th); procmm_print_map(p1->mmap); - asm("sti"); debug_info("BOOT COMPLETE\n"); schedule(); diff --git a/kernel/include/elf.h b/kernel/include/elf.h index 3cf05a1..6362d00 100644 --- a/kernel/include/elf.h +++ b/kernel/include/elf.h @@ -4,4 +4,4 @@ #include void *load_elf(process_t *p, void *data); -thread_t *exec_elf(process_t *p, void *image); +thread_t *exec_elf(process_t *p, void *image, char *argv[], char *envp[]); diff --git a/kernel/include/process.h b/kernel/include/process.h index dda4fbc..56edc07 100644 --- a/kernel/include/process.h +++ b/kernel/include/process.h @@ -62,5 +62,5 @@ void procmm_free_map(process_t *proc); void procmm_print_map(procmm_mmap_t *map); procmm_area_t *procmm_map(procmm_mmap_t *map, uintptr_t start, uintptr_t end, uint64_t flags); void procmm_unmap(procmm_area_t *a); -uintptr_t procmm_setup(process_t *proc); +int procmm_setup(process_t *proc, size_t brk_size); registers_t *procmm_page_fault(registers_t *r); diff --git a/kernel/proc/exec_elf.c b/kernel/proc/exec_elf.c index af6653d..1461322 100644 --- a/kernel/proc/exec_elf.c +++ b/kernel/proc/exec_elf.c @@ -1,14 +1,80 @@ #include #include #include +#include +#include +#include -thread_t *exec_elf(process_t *p, void *image) +thread_t *exec_elf(process_t *p, void *image, char *argv[], char *envp[]) { + int argc = 0, envc=0; + // Count strings and save their lengths + int len = 0; + while(argv[argc]){ + len += strlen(argv[argc]) + 1; + argc++; + } + len += (argc+1)*sizeof(char *); + while(envp[envc]) + { + len += strlen(envp[envc]) + 1; + envc++; + } + len += (envc+1)*sizeof(char *); + len += sizeof(size_t)*2; + len += sizeof(char); + + // Replace process memory space with new image void *entry = load_elf(p, image); - debug("Address:%x\n", entry); - procmm_setup(p); + procmm_setup(p, len); + + // We will write to process memory, so let's switch to it + vmm_set_P4(p->mmap->P4); + + + // Memory layout of area before BRK + // argv[] + // 0 + // envp[] + // 0 + // auxv[] + // arguments + // env strings + // 0 + // BRK points here + void *pos = (void *)p->mmap->brk->start; + char **_argv = pos; + pos = incptr(pos, (argc+1)*sizeof(char *)); + char **_envp = pos; + pos = incptr(pos, (envc+1)*sizeof(char *)); + size_t *_auxv = pos; + pos = incptr(pos, sizeof(size_t)*2); + + // Copy arguments + for(int i = 0; i < argc; i++) + { + size_t len = strlen(argv[i]) + 1; + _argv[i] = pos; + memcpy(_argv[i], argv[i], len); + pos = incptr(pos, len); + } + _argv[argc] = 0; + // Copy environment strings + for(int i = 0; i < envc; i++) + { + size_t len = strlen(envp[i]) + 1; + _envp[i] = pos; + memcpy(_envp[i], envp[i], len); + pos = incptr(pos, len); + } + _envp[envc] = 0; + // No auxiliary vectors for now + _auxv[0] = 0; + thread_t *th = new_thread((void *)entry, 1); process_attach(p, th); + th->r.rsi = (uint64_t)_argv; + th->r.rdi = argc; return th; } diff --git a/kernel/proc/procmm.c b/kernel/proc/procmm.c index f225fc0..eb320af 100644 --- a/kernel/proc/procmm.c +++ b/kernel/proc/procmm.c @@ -103,13 +103,13 @@ void procmm_unmap(procmm_area_t *a) kfree(a); } -uintptr_t procmm_setup(process_t *proc) +int procmm_setup(process_t *proc, size_t brk_size) { procmm_mmap_t *map = proc->mmap; procmm_area_t *last_a = map->areas.prev; uintptr_t brk_start = (last_a->end + PAGE_SIZE) & ~(PAGE_SIZE-1); - map->brk = procmm_map(map, brk_start, brk_start, 0); + map->brk = procmm_map(map, brk_start, brk_start + brk_size, 0); map->stack = procmm_map(map, USERSPACE_TOP, USERSPACE_TOP, 0); diff --git a/libc/crt0.S b/libc/crt0.S index c8bfc72..09ac95f 100644 --- a/libc/crt0.S +++ b/libc/crt0.S @@ -13,10 +13,12 @@ call _init - pop rdi pop rsi + pop rdx + movabs rax, offset main + mov rdi, rax - call main + call __libc_start_main call _fini diff --git a/libc/syscalls.c b/libc/syscalls.c index 4502984..7eca91d 100644 --- a/libc/syscalls.c +++ b/libc/syscalls.c @@ -46,8 +46,3 @@ long __syscall_common(long num, ...) while(1); return 0; } - -struct pthread *__pthread_self() -{ - return 0; -} diff --git a/libc/thread.c b/libc/thread.c new file mode 100644 index 0000000..fa6ace2 --- /dev/null +++ b/libc/thread.c @@ -0,0 +1,21 @@ +#include "syscalls.h" + +struct pthread *__pt; + +struct pthread *__pthread_self() +{ + return __pt; +} + +SYSCALL_DEF(set_thread_area) +{ + SYSCALL_INIT(void *, ptr); + __pt = ptr; + return 0; +} + +SYSCALL_DEF(set_tid_address) +{ + SYSCALL_INIT(); + return 0; +}