From 15f6fc4bda3e3c4b861784459109331666f3cdce Mon Sep 17 00:00:00 2001 From: Nathan Giddings Date: Sat, 18 Jul 2020 18:55:04 -0500 Subject: [PATCH] Started work on ELF loader --- src/Makefile.am | 2 +- src/elf.cpp | 39 +++++++++++++ src/elf.hpp | 142 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 182 insertions(+), 1 deletion(-) create mode 100644 src/elf.cpp create mode 100644 src/elf.hpp diff --git a/src/Makefile.am b/src/Makefile.am index 39ed1a4..e13f374 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,6 +1,6 @@ SUBDIRS = interrupts mmgr noinst_PROGRAMS = quark-kernel -quark_kernel_SOURCES = quarkkernel.cpp tty.cpp systeminfo.cpp util.cpp entry.S pio.S multiboot2header.S +quark_kernel_SOURCES = quarkkernel.cpp elf.cpp tty.cpp systeminfo.cpp util.cpp entry.S pio.S multiboot2header.S quark_kernel_LDADD = -lgcc mmgr/libmmgr.a interrupts/libinterrupts.a quark_kernel_CPPFLAGS = -ffreestanding -O0 -Wall -fno-exceptions -fno-rtti -ggdb quark_kernel_LDFLAGS = -T linker.ld -nostdlib diff --git a/src/elf.cpp b/src/elf.cpp new file mode 100644 index 0000000..ff503ab --- /dev/null +++ b/src/elf.cpp @@ -0,0 +1,39 @@ +#include "elf.hpp" +#include "util.hpp" + +kernel::ELF::ELF(void* location) +{ + this->location = location; +} + +void* kernel::ELF::entry() +{ + Header* fileHeader = (Header*) location; + return fileHeader->entry; +} + +int kernel::ELF::validate() +{ + Header* fileHeader = (Header*) location; + if(fileHeader->magic != 0x464c457f) + return -1; + else if((ISA) fileHeader->machine != HOST_ISA) + return -1; + else if((Endianness) fileHeader->endianness != Little) + return -1; + return 0; +} + +int kernel::ELF::load() +{ + Header* fileHeader = (Header*) location; + ProgramHeader* programHeader = (ProgramHeader*) ((size_t) location + fileHeader->phoffset); + int count = (int) fileHeader->phcount; + for(int i = 0; i < count; i++) + { + if((SegmentType) programHeader->type != Load) + continue; + memcpy(programHeader->vaddr, location + programHeader->offset, programHeader->filesize); + } + return 0; +} \ No newline at end of file diff --git a/src/elf.hpp b/src/elf.hpp new file mode 100644 index 0000000..bf62255 --- /dev/null +++ b/src/elf.hpp @@ -0,0 +1,142 @@ +#ifndef ELF_H +#define ELF_H + +#include + +#include "systypes.hpp" + +namespace kernel +{ + +class ELF +{ +public: + + enum Endianness + { + Little = 1, + Big = 2 + }; + + enum ISA + { + NA = 0x00, + x86 = 0x03, + MIPS = 0x08, + PPC = 0x14, + PPC64 = 0x15, + ARM = 0x28, + x86_64 = 0x3E, + aarch64 = 0xB7 + }; + + enum SegmentType + { + Unused = 0, + Load = 1, + Dynamic = 2 + }; + + struct Header + { + uint32_t magic; + char size; + char endianness; + char version; + char abi; + char abiVersion; + char reserved[7]; + uint16_t type; + uint16_t machine; + uint32_t _version; + void* entry; +#if defined __i386__ || defined __arm__ + uint32_t phoffset; + uint32_t shoffset; +#elif defined __x86_64__ || defined __aarch64__ + uint64_t phoffset; + uint64_t shoffset; +#endif + uint32_t flags; + uint16_t headerSize; + uint16_t phsize; + uint16_t phcount; + uint16_t shsize; + uint16_t shcount; + uint16_t shstrndx; + }; + + struct ProgramHeader + { + uint32_t type; +#if defined __i386__ || defined __arm__ + uint32_t offset; + void* vaddr; + physaddr_t paddr; + uint32_t filesize; + uint32_t memsize; + uint32_t flags; + uint32_t align; +#elif defined __x86_64__ || defined __aarch64__ + uint32_t flags; + uint64_t offset; + void* vaddr; + physaddr_t paddr; + uint64_t filesize; + uint64_t memsize; + uint64_t align; +#endif + }; + + struct SectionHeader + { + uint32_t name; + uint32_t type; +#if defined __i386__ || defined __arm__ + uint32_t flags; + void* addr; + uint32_t offset; + uint32_t size; + uint32_t link; + uint32_t info; + uint32_t align; + uint32_t entrysize; +#elif defined __x86_64__ || defined __aarch64__ + uint64_t flags; + void* addr; + uint64_t offset; + uint64_t size; + uint32_t link; + uint32_t info; + uint64_t align; + uint64_t entrysize; +#endif + }; + +#if defined __i386__ + static const ISA HOST_ISA = x86; +#elif defined __x86_64__ + static const ISA HOST_ISA = x86_64; +#elif defined __arm__ + static const ISA HOST_ISA = ARM; +#elif defined __aarch64__ + static const ISA HOST_ISA = aarch64; +#endif + + ELF(void* location); + + void* entry(); + + int validate(); + + int load(); + +private: + + void* location; + +}; + +} + +#endif \ No newline at end of file