Adds ELF loader to init.cpp
This commit is contained in:
parent
c7973406c3
commit
72c33b4b05
4 changed files with 109 additions and 15 deletions
|
@ -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
|
||||
|
|
36
prototypes/base/include/elf.hpp
Normal file
36
prototypes/base/include/elf.hpp
Normal 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));
|
||||
}
|
|
@ -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]);
|
||||
}
|
||||
|
||||
|
|
|
@ -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.)
|
Loading…
Reference in a new issue