Merge branch 'master' of ssh://github/MasterQ32/DasOS
This commit is contained in:
commit
25904a69d9
8 changed files with 152 additions and 24 deletions
|
@ -213,6 +213,12 @@ The math command is a compound operator that contains all
|
||||||
ALU operations. The ALU operation is selected
|
ALU operations. The ALU operation is selected
|
||||||
by the `cmdinfo`.
|
by the `cmdinfo`.
|
||||||
|
|
||||||
|
If an ALU operation takes two operands, the right hand side is
|
||||||
|
defined by `input0`, the left hand side is defined by `input1`.
|
||||||
|
This allows a configuration such that the right hand side operand
|
||||||
|
is taken by the argument of the instruction instead of beeing popped
|
||||||
|
from the stack.
|
||||||
|
|
||||||
| cmdinfo | Operation | Forumla |
|
| cmdinfo | Operation | Forumla |
|
||||||
|---------|-----------------------------|-----------------|
|
|---------|-----------------------------|-----------------|
|
||||||
| 0 | Addition | input1 + input0 |
|
| 0 | Addition | input1 + input0 |
|
||||||
|
@ -260,10 +266,11 @@ is set when the highest bit is set.
|
||||||
Each instruction can emit an output value. The output can be used in the following ways:
|
Each instruction can emit an output value. The output can be used in the following ways:
|
||||||
|
|
||||||
| # | Output | Effect |
|
| # | Output | Effect |
|
||||||
|---|---------|--------------------------------------------------------------|
|
|---|---------|-----------------------------------------------------------------------------|
|
||||||
| 0 | discard | The output value is discarded. |
|
| 0 | discard | The output value is discarded. |
|
||||||
| 1 | push | The output is pushed to the stack. |
|
| 1 | push | The output is pushed to the stack. |
|
||||||
| 2 | jump | The code pointer is set to the output, thus a jump is taken. |
|
| 2 | jump | The code pointer is set to the output, thus a jump is taken. |
|
||||||
|
| 3 | jumpr | The code pointer is increased by the output, thus a relative jump is taken. |
|
||||||
|
|
||||||
### Argument
|
### Argument
|
||||||
The instruction argument can provide static input which can be used
|
The instruction argument can provide static input which can be used
|
||||||
|
|
|
@ -5,4 +5,4 @@ all: $(PROJECTS)
|
||||||
|
|
||||||
.PHONY: $(PROJECTS)
|
.PHONY: $(PROJECTS)
|
||||||
$(PROJECTS):
|
$(PROJECTS):
|
||||||
make -C $@
|
make -C $@ $(ARGS)
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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.");
|
||||||
|
}
|
||||||
|
}
|
|
@ -4,3 +4,4 @@ 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.)
|
|
@ -9,12 +9,31 @@ static void cmd_copy(CommandInfo *info)
|
||||||
|
|
||||||
static void cmd_load(Process *p, CommandInfo *info)
|
static void cmd_load(Process *p, CommandInfo *info)
|
||||||
{
|
{
|
||||||
info->output = vm_read_byte(p, info->input0);
|
info->output = 0;
|
||||||
|
switch(info->additional) {
|
||||||
|
case 2:
|
||||||
|
info->output|=(uint32_t)(vm_read_byte(p, info->input0+3))<<24;
|
||||||
|
info->output|=(uint32_t)(vm_read_byte(p, info->input0+2))<<16;
|
||||||
|
case 1:
|
||||||
|
info->output|=(uint32_t)(vm_read_byte(p, info->input0+1))<< 8;
|
||||||
|
case 0:
|
||||||
|
info->output|=(uint32_t)(vm_read_byte(p, info->input0+0))<< 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void cmd_store(Process *p, CommandInfo *info)
|
static void cmd_store(Process *p, CommandInfo *info)
|
||||||
{
|
{
|
||||||
|
switch(info->additional) {
|
||||||
|
case 2:
|
||||||
|
vm_write_byte(p, info->input0+3, info->input1>>24);
|
||||||
|
vm_write_byte(p, info->input0+2, info->input1>>16);
|
||||||
|
case 1:
|
||||||
|
vm_write_byte(p, info->input0+1, info->input1>>8);
|
||||||
|
case 0:
|
||||||
vm_write_byte(p, info->input0, info->input1);
|
vm_write_byte(p, info->input0, info->input1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
info->output = info->input1;
|
info->output = info->input1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -182,6 +201,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.");
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
Loading…
Reference in a new issue