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) .PHONY: $(PROJECTS)
$(PROJECTS): $(PROJECTS):
make -C $@ make -C $@ $(ARGS)

View file

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

View file

@ -21,6 +21,10 @@
#include <string.h> #include <string.h>
namespace vm {
#include <vm.h>
}
using namespace multiboot; using namespace multiboot;
using namespace console_tools; using namespace console_tools;
@ -35,6 +39,7 @@ driver::Keyboard keyboardDriver;
VMMContext * kernelContext; VMMContext * kernelContext;
/*
static const uint32_t entryPointAddress = 0x40000000; static const uint32_t entryPointAddress = 0x40000000;
void run_program0(Module const & module) void run_program0(Module const & module)
@ -55,7 +60,7 @@ void run_program0(Module const & module)
void* dest = (void*) ph->virt_addr; void* dest = (void*) ph->virt_addr;
void* src = ((char*) header) + ph->offset; void* src = ((char*) header) + ph->offset;
/* Nur Program Header vom Typ LOAD laden */ // Nur Program Header vom Typ LOAD laden
if (ph->type != 1) { if (ph->type != 1) {
continue; continue;
} }
@ -85,7 +90,7 @@ static void dump_elf(elf::Header *header)
ProgramHeader *ph; ProgramHeader *ph;
int i; int i;
/* Ist es ueberhaupt eine ELF-Datei? */ // Ist es ueberhaupt eine ELF-Datei?
if (header->magic != MAGIC) { if (header->magic != MAGIC) {
BSOD::die(Error::InvalidELFImage, "Keine gueltige ELF-Magic!\n"); BSOD::die(Error::InvalidELFImage, "Keine gueltige ELF-Magic!\n");
return; return;
@ -104,6 +109,12 @@ static void dump_elf(elf::Header *header)
<< "\n"; << "\n";
} }
} }
*/
static void strcpy(char *dst, const char *src)
{
while((*dst++ = *src++));
}
static void initializePMM(Structure const & data) static void initializePMM(Structure const & data)
{ {
@ -217,12 +228,92 @@ extern "C" void init(Structure const & data)
if(data.modules.length > 0) if(data.modules.length > 0)
{ {
Console::main << "ELF Modukle:\n"; // Console::main << "ELF Modukle:\n";
dump_elf(data.modules[0].start.data<elf::Header>()); // dump_elf(data.modules[0].start.data<elf::Header>());
run_program0(data.modules[0]); // 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); while(true);
} }
static_assert(sizeof(void*) == 4, "Target platform is not 32 bit."); 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

@ -3,4 +3,5 @@ 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.) 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_DISCARD: break;
case VM_OUTPUT_PUSH: vm_push(process, info.output); break; case VM_OUTPUT_PUSH: vm_push(process, info.output); break;
case VM_OUTPUT_JUMP: process->codePointer = info.output; break; case VM_OUTPUT_JUMP: process->codePointer = info.output; break;
case VM_OUTPUT_JUMPR:
process->codePointer += *((int32_t*)&info.output);
break;
default: default:
vm_assert(0, "Invalid instruction: invalid output."); vm_assert(0, "Invalid instruction: invalid output.");
} }

View file

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