Adds ELF loader to init.cpp

This commit is contained in:
Felix Queißner 2016-05-07 19:55:59 +02:00
parent c7973406c3
commit 72c33b4b05
4 changed files with 109 additions and 15 deletions

View file

@ -6,7 +6,7 @@ LD=ld
IDT_DISPATCH = _ZN3IDT8dispatchEP8CpuState
FLAGS = -mno-sse -DIDT_DISPATCH=$(IDT_DISPATCH) -ffreestanding -m32 -Werror -Wall -iquote include -iquote lists -O3 -g
FLAGS = -mno-sse -DIDT_DISPATCH=$(IDT_DISPATCH) -ffreestanding -m32 -Werror -Wall -iquote include -iquote lists -I../stdlib/include -O3 -g
ASFLAGS = $(FLAGS)
CFLAGS = $(FLAGS)
CXXFLAGS = $(FLAGS) -std=c++14 -fno-rtti -fno-exceptions -fno-leading-underscore -fno-use-cxa-atexit -nostdlib -fno-builtin
@ -15,11 +15,12 @@ SRCS = $(shell find -regextype egrep -regex '.*/.*\.(cpp|S|c)')
OBJS = $(addsuffix .o, $(notdir $(basename $(SRCS))))
LIBGCC = $(shell gcc -m32 -print-libgcc-file-name)
LIBSTD = ../stdlib/libstd.a
all: kernel-base.ker
kernel-base.ker: $(OBJS)
$(LD) -melf_i386 -Tlinker.ld -o kernel-base.ker $(addprefix obj/, $^) $(LIBGCC)
$(LD) -melf_i386 -Tlinker.ld -o kernel-base.ker $(addprefix obj/, $^) $(LIBGCC) $(LIBSTD)
%.o: %.cpp
$(CXX) $(CXXFLAGS) -c -o obj/$@ $<
@ -54,7 +55,7 @@ run:
-no-reboot \
-no-shutdown \
-serial stdio \
-initrd ../program0/program0.bin
-initrd ../program0/program
insight:
objdump -d kernel-base.ker | c++filt | less

View file

@ -0,0 +1,36 @@
#pragma once
#include <inttypes.h>
namespace elf
{
static const uint32_t MAGIC = 0x464C457F;
struct Header {
uint32_t magic;
uint32_t version;
uint64_t reserved;
uint64_t version2;
uint32_t entry;
uint32_t ph_offset;
uint32_t sh_offset;
uint32_t flags;
uint16_t header_size;
uint16_t ph_entry_size;
uint16_t ph_entry_count;
uint16_t sh_entry_size;
uint16_t sh_entry_count;
uint16_t sh_str_table_index;
} __attribute__((packed));
struct ProgramHeader {
uint32_t type;
uint32_t offset;
uint32_t virt_addr;
uint32_t phys_addr;
uint32_t file_size;
uint32_t mem_size;
uint32_t flags;
uint32_t alignment;
} __attribute__((packed));
}

View file

@ -8,6 +8,8 @@
#include "compat.h"
#include "io.hpp"
#include "vmm.hpp"
#include "elf.hpp"
#include "bsod.hpp"
#include "driver/timer.hpp"
#include "driver/keyboard.hpp"
@ -16,6 +18,8 @@
#include <inttypes.h>
#include <new>
#include <string.h>
using namespace multiboot;
using namespace console_tools;
@ -31,26 +35,76 @@ driver::Scheduler scheduler;
VMMContext *kernelContext;
static const uint32_t entryPointAddress = 0x40000000;
void run_program0(Module const & module)
{
for(uint32_t ptr = 0; ptr < module.size(); ptr += 0x1000)
{
using namespace elf;
const Header *header = module.start.data<elf::Header>();
ProgramHeader *ph;
int i;
if (header->magic != MAGIC) {
BSOD::die(Error::InvalidELFImage, "Keine gueltige ELF-Magic!\n");
return;
}
ph = (ProgramHeader*)(((char*) header) + header->ph_offset);
for (i = 0; i < header->ph_entry_count; i++, ph++) {
void* dest = (void*) ph->virt_addr;
void* src = ((char*) header) + ph->offset;
/* Nur Program Header vom Typ LOAD laden */
if (ph->type != 1) {
continue;
}
if(ph->virt_addr < entryPointAddress) {
BSOD::die(Error::InvalidELFImage, "A LOAD section tried to sneak into the kernel!");
}
for(uint32_t i = 0; i < ph->mem_size; i += 0x1000) {
kernelContext->provide(
virtual_t(0x40000000 + ptr),
virtual_t(ph->virt_addr + i),
VMMFlags::Writable | VMMFlags::UserSpace);
}
char * src = module.start.data<char>();
char * dst = (char*)0x40000000;
for(uint32_t ptr = 0; ptr < module.size(); ptr++)
{
dst[ptr] = src[ptr];
memset(dest, 0, ph->mem_size);
memcpy(dest, src, ph->file_size);
}
using EntryPoint = void (*)();
EntryPoint ep = (EntryPoint)0x40000000;
EntryPoint ep = (EntryPoint)entryPointAddress;
ep();
}
static void dump_elf(elf::Header *header)
{
using namespace elf;
ProgramHeader *ph;
int i;
/* Ist es ueberhaupt eine ELF-Datei? */
if (header->magic != MAGIC) {
BSOD::die(Error::InvalidELFImage, "Keine gueltige ELF-Magic!\n");
return;
}
ph = (ProgramHeader*)(((char*) header) + header->ph_offset);
for (i = 0; i < header->ph_entry_count; i++, ph++) {
void* dest = (void*) ph->virt_addr;
void* src = ((char*) header) + ph->offset;
Console::main
<< "Header: " << ph->type << ", "
<< "Source: " << src << ", "
<< "Dest: " << dest << ", "
<< "Memsize: " << ph->mem_size << ", "
<< "Filesize: " << ph->file_size
<< "\n";
}
}
extern "C" void init(Structure const & data)
{
Console::main
@ -154,6 +208,8 @@ extern "C" void init(Structure const & data)
if(data.modules.length > 0)
{
Console::main << "ELF Modukle:\n";
dump_elf(data.modules[0].start.data<elf::Header>());
run_program0(data.modules[0]);
}

View file

@ -3,3 +3,4 @@ ERROR(1, OutOfMemory, The system has run out of memory.)
ERROR(2, UnhandledException, An unhandled exception has occurred.)
ERROR(3, UnhandledInterrupt, An unhandled interrupt has occurred.)
ERROR(4, DriverAlreadyInstalled, A driver was already installed.)
ERROR(5, InvalidELFImage, The file beeing loaded is not a valid ELF file.)