diff options
Diffstat (limited to 'src/kernel/fs/elf.c')
-rw-r--r-- | src/kernel/fs/elf.c | 94 |
1 files changed, 37 insertions, 57 deletions
diff --git a/src/kernel/fs/elf.c b/src/kernel/fs/elf.c index fe024e3..aea191b 100644 --- a/src/kernel/fs/elf.c +++ b/src/kernel/fs/elf.c @@ -1,3 +1,5 @@ +#include <stdint.h> +#include <stddef.h> #include <kernel/system.h> #include <kernel/fs/elf.h> #include <kernel/lib/stdio.h> @@ -6,8 +8,9 @@ #include <kernel/memory/paging.h> #include <kernel/fs/ext2.h> #include <kernel/gdt/gdt.h> +#include <kernel/tasks/process.h> -int is_elf(elf_header_t *header) +int is_elf(struct elf_header *header) { if (header->ident[0] == ELF_MAG && header->ident[1] == 'E' && header->ident[2] == 'L' && header->ident[3] == 'F' && header->ident[4] == ELF_32 && @@ -18,75 +21,52 @@ int is_elf(elf_header_t *header) return 0; } -void elf_load(char *path) +struct process *elf_load(char *path) { uint8_t *file = read_file(path); if (!file) { warn("File or directory not found: %s", file); - return; + return NULL; } - elf_header_t *header = (elf_header_t *)file; - elf_program_header_t *program_header = (void *)header + header->phoff; + struct elf_header *header = (struct elf_header *)file; + struct elf_program_header *program_header = (void *)header + header->phoff; if (!is_elf(header)) { - warn("File not valid: %s", path); - return; + panic("File not valid"); } else { debug("File is valid: %s", path); } - uint32_t eip = 0; - uint32_t seg_begin, seg_end; - for (int i = 0; i < header->phnum; i++) { - if (program_header->type == 1) { - seg_begin = program_header->vaddr; - seg_end = seg_begin + program_header->memsz; + struct process *proc = process_make_new(); + proc->name = "TEST"; + proc->registers.eip = header->entry; + paging_switch_directory(proc->cr3); + uint32_t stk = (uint32_t)kmalloc_a(PAGE_S); + proc->registers.useresp = 0x40000000 - (PAGE_S / 2); + proc->registers.ebp = proc->registers.useresp; + proc->registers.esp = proc->registers.useresp; + paging_map_user(proc->cr3, stk, 0x40000000 - PAGE_S); - /* for (uint32_t z = 0; z < seg_end - seg_begin; z += 4096) */ - /* paging_map((uint32_t)seg_begin + z, (uint32_t)seg_begin + z, */ - /* PT_PRESENT | PT_RW | PT_USED | PT_ALL_PRIV); */ - - memcpy((void *)seg_begin, file + program_header->offset, + for (int i = 0; i < header->phnum; i++, program_header++) { + switch (program_header->type) { + case 0: + break; + case 1: + i += 0; + debug("Allocating space for ELF binary section..."); + uint32_t loc = (uint32_t)kmalloc_a(PAGE_S); + paging_map_user(proc->cr3, loc, program_header->vaddr); + memcpy((void *)program_header->vaddr, + ((void *)((uint32_t)file) + program_header->offset), program_header->filesz); - memset((void *)(seg_begin + program_header->filesz), 0, - program_header->memsz - program_header->filesz); - - // Code segment - if (program_header->flags == PF_X + PF_R + PF_W || - program_header->flags == PF_X + PF_R) { - debug("Found code segment"); - eip = header->entry + seg_begin; - } + if (program_header->filesz > PAGE_S) + panic("ELF binary section too large"); + break; + default: + warn("Unknown header type"); } - program_header++; - }; - - // Just some testing, will be moved later - uint32_t sp; - asm("mov %%esp, %0" : "=rm"(sp)); - set_kernel_stack(sp); - - // paging_switch_directory(1); - /* uint32_t esp = paging_alloc_pages(0x1000); */ - /* asm("mov %0, %%esp" ::"r"(esp + 0x1000)); */ + } - log("Jumping to usermode!"); - asm volatile("\ - cli; \ - mov $0x23, %%ax; \ - mov %%ax, %%ds; \ - mov %%ax, %%es; \ - mov %%ax, %%fs; \ - mov %%ax, %%gs; \ - mov %%esp, %%eax; \ - pushl $0x23; \ - pushl %%esp; \ - pushf; \ - push $0x1B; \ - push %0; \ - iret; \ - " - : - : "r"(eip)); -} + return proc; +}
\ No newline at end of file |