From f79ada76d2e4056ff5a81b53998d6d2696523d0f Mon Sep 17 00:00:00 2001 From: Marvin Borner Date: Wed, 1 Apr 2020 22:31:45 +0200 Subject: Some work on the elf loader --- src/kernel/fs/elf.c | 68 ++++++++++++++++++++++++++++++++++++++ src/kernel/fs/elf.h | 5 +-- src/kernel/fs/elfloader.c | 61 ---------------------------------- src/kernel/fs/load.c | 83 ----------------------------------------------- src/kernel/fs/load.h | 35 -------------------- 5 files changed, 71 insertions(+), 181 deletions(-) create mode 100644 src/kernel/fs/elf.c delete mode 100644 src/kernel/fs/elfloader.c delete mode 100644 src/kernel/fs/load.c delete mode 100644 src/kernel/fs/load.h diff --git a/src/kernel/fs/elf.c b/src/kernel/fs/elf.c new file mode 100644 index 0000000..2f1b463 --- /dev/null +++ b/src/kernel/fs/elf.c @@ -0,0 +1,68 @@ +#include +#include +#include +#include +#include +#include + +#define USER_OFFSET 0x40000000 +#define USER_STACK 0xF0000000 +#define PT_LOAD 0x1 + +int is_elf(char *elf_data) +{ + elf_header_t *header = (elf_header_t *)elf_data; + if (header->ident[0] == 0x7f && header->ident[1] == 'E' && header->ident[2] == 'L' && + header->ident[3] == 'F') { + serial_printf("Buffer is valid ELF file!"); + return 1; + } + return 0; +} + +uint32_t load_elf(char *elf_data) +{ + uint32_t v_begin, v_end; + elf_header_t *hdr; + elf_program_header_t *p_entry; + elf_section_header_t *s_entry; + + hdr = (elf_header_t *)elf_data; + p_entry = (elf_program_header_t *)(elf_data + hdr->phoff); + + s_entry = (elf_section_header_t *)(elf_data + hdr->shoff); + + if (is_elf(elf_data) == 0) + return 0; + + for (int pe = 0; pe < hdr->phnum; pe++, p_entry++) { + if (p_entry->type == PT_LOAD) { + v_begin = p_entry->vaddr; + v_end = p_entry->vaddr + p_entry->memsz; + if (v_begin < USER_OFFSET) { + printf("INFO: load_elf(): can't load executable below %x\n", + USER_OFFSET); + return 0; + } + + if (v_end > USER_STACK) { + printf("INFO: load_elf(): can't load executable above %x\n", + USER_STACK); + return 0; + } + + printf("ELF: entry flags: %x (%d)\n", p_entry->flags, p_entry->flags); + + memcpy((uint8_t *)v_begin, (uint8_t *)(elf_data + p_entry->offset), + p_entry->filesz); + if (p_entry->memsz > p_entry->filesz) { + char *p = (char *)p_entry->vaddr; + for (int i = p_entry->filesz; i < (int)(p_entry->memsz); i++) { + p[i] = 0; + } + } + } + } + + return hdr->entry; +} diff --git a/src/kernel/fs/elf.h b/src/kernel/fs/elf.h index ea8493b..ee89000 100644 --- a/src/kernel/fs/elf.h +++ b/src/kernel/fs/elf.h @@ -48,6 +48,7 @@ typedef struct { uint32_t align; } elf_program_header_t; -void elf_init(); +int is_elf(char *data); +uint32_t load_elf(char *elf_data); -#endif \ No newline at end of file +#endif diff --git a/src/kernel/fs/elfloader.c b/src/kernel/fs/elfloader.c deleted file mode 100644 index fa537f6..0000000 --- a/src/kernel/fs/elfloader.c +++ /dev/null @@ -1,61 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include "load.h" - -int elf_probe(uint8_t *buf) -{ - elf_header_t *header = (elf_header_t *)buf; - if (header->ident[0] == 0x7f && header->ident[1] == 'E' && header->ident[2] == 'L' && - header->ident[3] == 'F') { - serial_printf("Buffer is valid ELF file!"); - return 1; - } - return 0; -} - -uint8_t elf_start(uint8_t *buf) -{ - elf_header_t *header = (elf_header_t *)buf; - serial_printf("Type: %s%s%s", header->ident[4] == 1 ? "32bit " : "64 bit", - header->ident[5] == 1 ? "Little Endian " : "Big endian ", - header->ident[6] == 1 ? "True ELF " : "buggy ELF "); - if (header->type != 2) { - serial_printf("File is not executable!"); - return 0; - } - - uint32_t phys_loc = loader_get_unused_load_location(); - elf_program_header_t *ph = (elf_program_header_t *)(buf + header->phoff); - for (int i = 0; i < header->phnum; i++, ph++) { - switch (ph->type) { - case 0: - break; - case 1: - serial_printf( - "LOAD: offset 0x%x vaddr 0x%x paddr 0x%x filesz 0x%x memsz 0x%x", - ph->offset, ph->vaddr, ph->paddr, ph->filesz, ph->memsz); - paging_map(phys_loc, ph->vaddr, PT_PRESENT | PT_RW | PT_USED); - halt_loop(); - memcpy((void *)ph->vaddr, buf + ph->offset, ph->filesz); - break; - default: - serial_printf("Unsupported type! Bail out!"); - return 0; - } - } - - return 0; -} - -void elf_init() -{ - loader_t *elfloader = (loader_t *)kmalloc(sizeof(loader_t)); - elfloader->name = "ELF32"; - elfloader->probe = (void *)elf_probe; - elfloader->start = (void *)elf_start; - register_loader(elfloader); -} \ No newline at end of file diff --git a/src/kernel/fs/load.c b/src/kernel/fs/load.c deleted file mode 100644 index d6451c7..0000000 --- a/src/kernel/fs/load.c +++ /dev/null @@ -1,83 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -void load_binaries() -{ - userspace = (uint32_t)kmalloc(10000); - font = (struct font *)kmalloc(100000); - ; // High quality shit - - uint8_t boot_drive_id = (uint8_t)(*((uint8_t *)0x9000)); - if (boot_drive_id != 0xE0) { - struct ata_interface *primary_master = new_ata(1, 0x1F0); - marfs_init(primary_master); - marfs_read_whole_file(4, (uint8_t *)userspace); - marfs_read_whole_file(5, (uint8_t *)font); - } else { - char *font_p[] = { "FONT.BIN" }; - struct iso9660_entity *font_e = ISO9660_get(font_p, 1); - if (!font_e) - panic("Font not found!"); - ATAPI_granular_read(1 + (font_e->length / 2048), font_e->lba, (uint8_t *)font); - kfree(font_e); - - char *user_p[] = { "USER.BIN" }; - struct iso9660_entity *user_e = ISO9660_get(user_p, 1); - if (!user_e) - panic("Userspace binary not found!"); - ATAPI_granular_read(1 + (user_e->length / 2048), user_e->lba, (uint8_t *)userspace); - kfree(user_e); - } - vga_log("Successfully loaded binaries"); -} - -#define MAX_LOADERS 16 - -loader_t **loaders = 0; -uint8_t last_loader = 0; - -uint32_t last_load_loc = 0x400000; - -void loader_init() -{ - serial_printf("Setting up loader"); - loaders = (loader_t **)kmalloc(MAX_LOADERS * sizeof(uint32_t)); - memset(loaders, 0, MAX_LOADERS * sizeof(uint32_t)); -} - -void register_loader(loader_t *load) -{ - if (last_loader + 1 > MAX_LOADERS) - return; - if (!load) - return; - loaders[last_loader] = load; - last_loader++; - serial_printf("Registered %s loader as id %d", load->name, last_loader - 1); -} - -uint32_t loader_get_unused_load_location() -{ - last_load_loc += 0x400000; - return last_load_loc; -} - -uint8_t exec_start(uint8_t *buf) -{ - for (int i = 0; i < MAX_LOADERS; i++) { - if (!loaders[i]) - break; - void *priv = loaders[i]->probe(buf); - if (priv) { - return loaders[i]->start(buf, priv); - } - } - return 0; -} \ No newline at end of file diff --git a/src/kernel/fs/load.h b/src/kernel/fs/load.h deleted file mode 100644 index 0343092..0000000 --- a/src/kernel/fs/load.h +++ /dev/null @@ -1,35 +0,0 @@ -#ifndef MELVIX_LOAD_H -#define MELVIX_LOAD_H - -#include - -uint32_t userspace; - -struct font *font; - -struct font { - uint16_t font_32[758][32]; - uint16_t font_24[758][24]; - uint8_t font_16[758][16]; - uint16_t cursor[19]; -}; - -void load_binaries(); - -typedef struct { - char *name; - - void *(*probe)(uint8_t *buf); - - uint8_t (*start)(uint8_t *buf, void *priv); -} loader_t; - -void loader_init(); - -void register_loader(loader_t *load); - -uint8_t exec_start(uint8_t *buf); - -uint32_t loader_get_unused_load_location(); - -#endif \ No newline at end of file -- cgit v1.2.3