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
|
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)
|
ASFLAGS = $(FLAGS)
|
||||||
CFLAGS = $(FLAGS)
|
CFLAGS = $(FLAGS)
|
||||||
CXXFLAGS = $(FLAGS) -std=c++14 -fno-rtti -fno-exceptions -fno-leading-underscore -fno-use-cxa-atexit -nostdlib -fno-builtin
|
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))))
|
OBJS = $(addsuffix .o, $(notdir $(basename $(SRCS))))
|
||||||
|
|
||||||
LIBGCC = $(shell gcc -m32 -print-libgcc-file-name)
|
LIBGCC = $(shell gcc -m32 -print-libgcc-file-name)
|
||||||
|
LIBSTD = ../stdlib/libstd.a
|
||||||
|
|
||||||
all: kernel-base.ker
|
all: kernel-base.ker
|
||||||
|
|
||||||
kernel-base.ker: $(OBJS)
|
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
|
%.o: %.cpp
|
||||||
$(CXX) $(CXXFLAGS) -c -o obj/$@ $<
|
$(CXX) $(CXXFLAGS) -c -o obj/$@ $<
|
||||||
|
@ -54,7 +55,7 @@ run:
|
||||||
-no-reboot \
|
-no-reboot \
|
||||||
-no-shutdown \
|
-no-shutdown \
|
||||||
-serial stdio \
|
-serial stdio \
|
||||||
-initrd ../program0/program0.bin
|
-initrd ../program0/program
|
||||||
|
|
||||||
insight:
|
insight:
|
||||||
objdump -d kernel-base.ker | c++filt | less
|
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 "compat.h"
|
||||||
#include "io.hpp"
|
#include "io.hpp"
|
||||||
#include "vmm.hpp"
|
#include "vmm.hpp"
|
||||||
|
#include "elf.hpp"
|
||||||
|
#include "bsod.hpp"
|
||||||
|
|
||||||
#include "driver/timer.hpp"
|
#include "driver/timer.hpp"
|
||||||
#include "driver/keyboard.hpp"
|
#include "driver/keyboard.hpp"
|
||||||
|
@ -16,6 +18,8 @@
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include <new>
|
#include <new>
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
using namespace multiboot;
|
using namespace multiboot;
|
||||||
using namespace console_tools;
|
using namespace console_tools;
|
||||||
|
|
||||||
|
@ -31,26 +35,76 @@ driver::Scheduler scheduler;
|
||||||
|
|
||||||
VMMContext *kernelContext;
|
VMMContext *kernelContext;
|
||||||
|
|
||||||
|
static const uint32_t entryPointAddress = 0x40000000;
|
||||||
|
|
||||||
void run_program0(Module const & module)
|
void run_program0(Module const & module)
|
||||||
{
|
{
|
||||||
for(uint32_t ptr = 0; ptr < module.size(); ptr += 0x1000)
|
using namespace elf;
|
||||||
{
|
|
||||||
kernelContext->provide(
|
const Header *header = module.start.data<elf::Header>();
|
||||||
virtual_t(0x40000000 + ptr),
|
|
||||||
VMMFlags::Writable | VMMFlags::UserSpace);
|
ProgramHeader *ph;
|
||||||
|
int i;
|
||||||
|
if (header->magic != MAGIC) {
|
||||||
|
BSOD::die(Error::InvalidELFImage, "Keine gueltige ELF-Magic!\n");
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
char * src = module.start.data<char>();
|
|
||||||
char * dst = (char*)0x40000000;
|
ph = (ProgramHeader*)(((char*) header) + header->ph_offset);
|
||||||
for(uint32_t ptr = 0; ptr < module.size(); ptr++)
|
for (i = 0; i < header->ph_entry_count; i++, ph++) {
|
||||||
{
|
void* dest = (void*) ph->virt_addr;
|
||||||
dst[ptr] = src[ptr];
|
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(ph->virt_addr + i),
|
||||||
|
VMMFlags::Writable | VMMFlags::UserSpace);
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(dest, 0, ph->mem_size);
|
||||||
|
memcpy(dest, src, ph->file_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
using EntryPoint = void (*)();
|
using EntryPoint = void (*)();
|
||||||
EntryPoint ep = (EntryPoint)0x40000000;
|
EntryPoint ep = (EntryPoint)entryPointAddress;
|
||||||
ep();
|
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)
|
extern "C" void init(Structure const & data)
|
||||||
{
|
{
|
||||||
Console::main
|
Console::main
|
||||||
|
@ -154,6 +208,8 @@ extern "C" void init(Structure const & data)
|
||||||
|
|
||||||
if(data.modules.length > 0)
|
if(data.modules.length > 0)
|
||||||
{
|
{
|
||||||
|
Console::main << "ELF Modukle:\n";
|
||||||
|
dump_elf(data.modules[0].start.data<elf::Header>());
|
||||||
run_program0(data.modules[0]);
|
run_program0(data.modules[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,4 +2,5 @@ ERROR(0, Success, Nothing went wrong. This should never encounter
|
||||||
ERROR(1, OutOfMemory, The system has run out of memory.)
|
ERROR(1, OutOfMemory, The system has run out of memory.)
|
||||||
ERROR(2, UnhandledException, An unhandled exception has occurred.)
|
ERROR(2, UnhandledException, An unhandled exception has occurred.)
|
||||||
ERROR(3, UnhandledInterrupt, An unhandled interrupt has occurred.)
|
ERROR(3, UnhandledInterrupt, An unhandled interrupt has occurred.)
|
||||||
ERROR(4, DriverAlreadyInstalled, A driver was already installed.)
|
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