aboutsummaryrefslogtreecommitdiff
path: root/src/kernel/fs
diff options
context:
space:
mode:
authorMarvin Borner2020-04-01 22:31:45 +0200
committerMarvin Borner2020-04-01 22:31:45 +0200
commitf79ada76d2e4056ff5a81b53998d6d2696523d0f (patch)
treeff86621426999f4c2d1092880941fb3c330a4893 /src/kernel/fs
parentc966e3cdb52ae0daeac3c70f98ab8ee52b8c0077 (diff)
Some work on the elf loader
Diffstat (limited to 'src/kernel/fs')
-rw-r--r--src/kernel/fs/elf.c68
-rw-r--r--src/kernel/fs/elf.h5
-rw-r--r--src/kernel/fs/elfloader.c61
-rw-r--r--src/kernel/fs/load.c83
-rw-r--r--src/kernel/fs/load.h35
5 files changed, 71 insertions, 181 deletions
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 <kernel/system.h>
+#include <kernel/fs/elf.h>
+#include <kernel/lib/stdio.h>
+#include <kernel/memory/alloc.h>
+#include <kernel/lib/lib.h>
+#include <kernel/memory/paging.h>
+
+#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 <kernel/system.h>
-#include <kernel/fs/elf.h>
-#include <kernel/lib/stdio.h>
-#include <kernel/memory/alloc.h>
-#include <kernel/lib/lib.h>
-#include <kernel/memory/paging.h>
-#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 <kernel/fs/load.h>
-#include <kernel/fs/marfs/marfs.h>
-#include <kernel/fs/ata_pio.h>
-#include <kernel/fs/atapi_pio.h>
-#include <kernel/system.h>
-#include <kernel/fs/iso9660/iso9660.h>
-#include <kernel/memory/alloc.h>
-#include <kernel/lib/stdio.h>
-#include <kernel/lib/lib.h>
-
-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 <stdint.h>
-
-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