First, primitive single threaded VM integration.

This commit is contained in:
Felix Queißner 2016-05-30 19:48:07 +02:00
parent c32d30506b
commit 6de1a70574
6 changed files with 117 additions and 15 deletions

View file

@ -5,4 +5,4 @@ all: $(PROJECTS)
.PHONY: $(PROJECTS)
$(PROJECTS):
make -C $@
make -C $@ $(ARGS)

View file

@ -4,23 +4,27 @@ CC=gcc
CXX=g++
LD=ld
LIBGCC = $(shell gcc -m32 -print-libgcc-file-name)
LIBSTD = ../stdlib/libstd.a
LIBVM = ../supervm/libvm.a
IDT_DISPATCH = _ZN3IDT8dispatchEP8CpuState
FLAGS = -mno-sse -DIDT_DISPATCH=$(IDT_DISPATCH) -ffreestanding -m32 -Werror -Wall -iquote include -iquote lists -I../stdlib/include -O3 -g
INCLUDE_DIRS = ../stdlib/include ../supervm/
FLAGS = -mno-sse -DIDT_DISPATCH=$(IDT_DISPATCH) -ffreestanding -m32 -Werror -Wall -iquote include -iquote lists $(addprefix -I, $(INCLUDE_DIRS)) -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
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
LIBS = $(LIBGCC) $(LIBSTD) $(LIBVM)
all: kernel-base.ker
kernel-base.ker: $(OBJS)
$(LD) -melf_i386 -Tlinker.ld -o kernel-base.ker $(addprefix obj/, $^) $(LIBGCC) $(LIBSTD)
$(LD) -melf_i386 -Tlinker.ld -o kernel-base.ker $(addprefix obj/, $^) $(LIBS)
%.o: %.cpp
$(CXX) $(CXXFLAGS) -c -o obj/$@ $<
@ -46,8 +50,8 @@ kernel-base.ker: $(OBJS)
# -initrd file use 'file' as initial ram disk
# -dtb file use 'file' as device tree image
run:
echo `pwd`
qemu-system-i386 \
-kernel kernel-base.ker \
-m 64 \
@ -55,7 +59,7 @@ run:
-no-reboot \
-no-shutdown \
-serial stdio \
-initrd ../program0/program
-initrd `pwd`/../supervm-asm/testcode.bin
insight:
objdump -d kernel-base.ker | c++filt | less

View file

@ -21,6 +21,10 @@
#include <string.h>
namespace vm {
#include <vm.h>
}
using namespace multiboot;
using namespace console_tools;
@ -35,6 +39,7 @@ driver::Keyboard keyboardDriver;
VMMContext * kernelContext;
/*
static const uint32_t entryPointAddress = 0x40000000;
void run_program0(Module const & module)
@ -55,7 +60,7 @@ void run_program0(Module const & module)
void* dest = (void*) ph->virt_addr;
void* src = ((char*) header) + ph->offset;
/* Nur Program Header vom Typ LOAD laden */
// Nur Program Header vom Typ LOAD laden
if (ph->type != 1) {
continue;
}
@ -85,7 +90,7 @@ static void dump_elf(elf::Header *header)
ProgramHeader *ph;
int i;
/* Ist es ueberhaupt eine ELF-Datei? */
// Ist es ueberhaupt eine ELF-Datei?
if (header->magic != MAGIC) {
BSOD::die(Error::InvalidELFImage, "Keine gueltige ELF-Magic!\n");
return;
@ -104,6 +109,12 @@ static void dump_elf(elf::Header *header)
<< "\n";
}
}
*/
static void strcpy(char *dst, const char *src)
{
while((*dst++ = *src++));
}
static void initializePMM(Structure const & data)
{
@ -217,12 +228,92 @@ 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]);
// Console::main << "ELF Modukle:\n";
// dump_elf(data.modules[0].start.data<elf::Header>());
// run_program0(data.modules[0]);
vm::Module module = {
.code = reinterpret_cast<vm::Instruction*>(data.modules[0].start.data()),
.length = data.modules[0].size() / sizeof(vm::Instruction),
};
Console::main << "Loaded instructions: " << module.length << "\n";
uint8_t page0[64];
uint8_t page1[64];
strcpy((char*)page0, "Hallo Welt!\nDies ist die erste Ausgabe durch die VM.");
uint8_t *pages[2];
pages[0] = page0;
pages[1] = page1;
vm::VirtualMemoryMap mmap = {
.pageSize = 64,
.length = 2,
.pages = pages,
};
vm::Process process = {
.module = &module,
.tag = (void*)1,
.codePointer = 0,
.stackPointer = 0,
.basePointer = 0,
.flags = 0,
.stack = { 0 },
.mmap = mmap,
};
auto *p = &process;
while(vm::vm_step_process(p) && p->tag) {
//Console::main << "?";
// dump_proc(p);
}
}
while(true);
}
static_assert(sizeof(void*) == 4, "Target platform is not 32 bit.");
namespace vm
{
extern "C" void vm_assert(int assertion, const char *msg)
{
if(assertion != 0)
return;
BSOD::die(Error::VMError, msg);
}
extern "C" void vm_syscall(Process *p, CommandInfo *info)
{
switch(info->additional)
{
case 0: // EXIT
p->tag = NULL;
break;
case 1:
Console::main << (char)info->input0;
break;
case 2:
Console::main << info->input0;
break;
default:
Console::main << "[SYSCALL " << info->additional << "]";
break;
}
}
extern "C" void vm_hwio(Process *p, CommandInfo *info)
{
BSOD::die(Error::VMError, "hwio not implemented yet.");
}
}

View file

@ -4,3 +4,4 @@ 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.)
ERROR(6, VMError, The virtual machine has failed.)

View file

@ -182,6 +182,9 @@ int vm_step_process(Process *process)
case VM_OUTPUT_DISCARD: break;
case VM_OUTPUT_PUSH: vm_push(process, info.output); break;
case VM_OUTPUT_JUMP: process->codePointer = info.output; break;
case VM_OUTPUT_JUMPR:
process->codePointer += *((int32_t*)&info.output);
break;
default:
vm_assert(0, "Invalid instruction: invalid output.");
}

View file

@ -5,6 +5,7 @@
#if defined(__cplusplus)
extern "C" {
#define _Static_assert static_assert
#endif
#if !defined(VM_STACKSIZE)
@ -57,6 +58,7 @@ extern "C" {
#define VM_OUTPUT_DISCARD 0
#define VM_OUTPUT_PUSH 1
#define VM_OUTPUT_JUMP 2
#define VM_OUTPUT_JUMPR 3
#define VM_FLAG_Z (1<<0)
#define VM_FLAG_N (1<<1)
@ -179,4 +181,5 @@ void vm_hwio(Process *process, CommandInfo *info);
#if defined(__cplusplus)
}
#undef _Static_assert
#endif