Fixes nasty memory leaks. Adds memory tracing. Adds serial console for advanced debugging. Implements malloc correctly.
This commit is contained in:
parent
5002d8728c
commit
e69a342b29
18 changed files with 516 additions and 117 deletions
2
Depfile
2
Depfile
|
@ -36,4 +36,4 @@ obj/main.o: scripts/main.ts
|
||||||
|
|
||||||
.PHONY: run
|
.PHONY: run
|
||||||
run:
|
run:
|
||||||
qemu-system-i386 -kernel kernel kernel
|
qemu-system-i386 -serial stdio -kernel kernel
|
||||||
|
|
70
Makefile
70
Makefile
|
@ -11,9 +11,9 @@ YACC = bison
|
||||||
|
|
||||||
# File Lists
|
# File Lists
|
||||||
SRCS_AS = asm/dynamic.S asm/intr_common_handler.S asm/multiboot.S asm/start.S
|
SRCS_AS = asm/dynamic.S asm/intr_common_handler.S asm/multiboot.S asm/start.S
|
||||||
SRCS_CC = src/console.c src/init.c src/interrupts.c src/malloc.c src/pmm.c src/stdlib.c src/timer.c src/vmm.c
|
SRCS_CC = src/console.c src/init.c src/interrupts.c src/malloc.c src/pmm.c src/serial.c src/stdlib.c src/timer.c src/vmm.c
|
||||||
SRCS_CXX = trainscript/tsvm.cpp src/cplusplus.cpp src/vm.cpp obj/trainscript.yy.cpp obj/trainscript.tab.cpp
|
SRCS_CXX = trainscript/tsvm.cpp src/cplusplus.cpp src/vm.cpp obj/trainscript.yy.cpp obj/trainscript.tab.cpp
|
||||||
OBJS = obj/tsvm.o obj/dynamic.o obj/intr_common_handler.o obj/multiboot.o obj/start.o obj/console.o obj/init.o obj/interrupts.o obj/malloc.o obj/pmm.o obj/stdlib.o obj/timer.o obj/vmm.o obj/cplusplus.o obj/vm.o obj/trainscript.yy.o obj/trainscript.tab.o obj/main.o
|
OBJS = obj/tsvm.o obj/dynamic.o obj/intr_common_handler.o obj/multiboot.o obj/start.o obj/console.o obj/init.o obj/interrupts.o obj/malloc.o obj/pmm.o obj/serial.o obj/stdlib.o obj/timer.o obj/vmm.o obj/cplusplus.o obj/vm.o obj/trainscript.yy.o obj/trainscript.tab.o obj/main.o
|
||||||
|
|
||||||
# Flags
|
# Flags
|
||||||
FLAGS = -m32 -Dnullptr=0 -D__cdecl="__attribute__((cdecl))" -mno-sse -mno-sse2 -mno-mmx
|
FLAGS = -m32 -Dnullptr=0 -D__cdecl="__attribute__((cdecl))" -mno-sse -mno-sse2 -mno-mmx
|
||||||
|
@ -27,40 +27,47 @@ all: kernel
|
||||||
|
|
||||||
.PHONY: clean
|
.PHONY: clean
|
||||||
clean:
|
clean:
|
||||||
$(RM) obj/trainscript.yy.cpp obj/trainscript.tab.cpp obj/tsvm.o obj/dynamic.o obj/intr_common_handler.o obj/multiboot.o obj/start.o obj/console.o obj/init.o obj/interrupts.o obj/malloc.o obj/pmm.o obj/stdlib.o obj/timer.o obj/vmm.o obj/cplusplus.o obj/vm.o obj/trainscript.yy.o obj/trainscript.tab.o obj/main.o
|
$(RM) obj/trainscript.yy.cpp obj/trainscript.tab.cpp obj/tsvm.o obj/dynamic.o obj/intr_common_handler.o obj/multiboot.o obj/start.o obj/console.o obj/init.o obj/interrupts.o obj/malloc.o obj/pmm.o obj/serial.o obj/stdlib.o obj/timer.o obj/vmm.o obj/cplusplus.o obj/vm.o obj/trainscript.yy.o obj/trainscript.tab.o obj/main.o
|
||||||
|
|
||||||
kernel: obj/tsvm.o obj/dynamic.o obj/intr_common_handler.o obj/multiboot.o obj/start.o obj/console.o obj/init.o obj/interrupts.o obj/malloc.o obj/pmm.o obj/stdlib.o obj/timer.o obj/vmm.o obj/cplusplus.o obj/vm.o obj/trainscript.yy.o obj/trainscript.tab.o obj/main.o
|
kernel: obj/tsvm.o obj/dynamic.o obj/intr_common_handler.o obj/multiboot.o obj/start.o obj/console.o obj/init.o obj/interrupts.o obj/malloc.o obj/pmm.o obj/serial.o obj/stdlib.o obj/timer.o obj/vmm.o obj/cplusplus.o obj/vm.o obj/trainscript.yy.o obj/trainscript.tab.o obj/main.o
|
||||||
$(LD) $(FLAGS) $(LDFLAGS) -o $@ obj/tsvm.o obj/dynamic.o obj/intr_common_handler.o obj/multiboot.o obj/start.o obj/console.o obj/init.o obj/interrupts.o obj/malloc.o obj/pmm.o obj/stdlib.o obj/timer.o obj/vmm.o obj/cplusplus.o obj/vm.o obj/trainscript.yy.o obj/trainscript.tab.o obj/main.o
|
$(LD) $(FLAGS) $(LDFLAGS) -o $@ obj/tsvm.o obj/dynamic.o obj/intr_common_handler.o obj/multiboot.o obj/start.o obj/console.o obj/init.o obj/interrupts.o obj/malloc.o obj/pmm.o obj/serial.o obj/stdlib.o obj/timer.o obj/vmm.o obj/cplusplus.o obj/vm.o obj/trainscript.yy.o obj/trainscript.tab.o obj/main.o
|
||||||
|
|
||||||
# src/console.c
|
# src/console.c
|
||||||
obj/console.o: src/console.c include/console.h include/stdlib.h \
|
obj/console.o: src/console.c include/console.h include/stdlib.h \
|
||||||
include/varargs.h
|
include/varargs.h include/config.h
|
||||||
$(CC) $(FLAGS) $(CCFLAGS) -o $@ -c src/console.c
|
$(CC) $(FLAGS) $(CCFLAGS) -o $@ -c src/console.c
|
||||||
|
|
||||||
# src/init.c
|
# src/init.c
|
||||||
obj/init.o: src/init.c include/kernel.h include/stdlib.h include/varargs.h \
|
obj/init.o: src/init.c include/kernel.h include/stdlib.h include/varargs.h \
|
||||||
include/console.h include/interrupts.h include/cpustate.h include/pmm.h \
|
include/config.h include/console.h include/interrupts.h \
|
||||||
include/multiboot.h include/vmm.h include/config.h include/timer.h
|
include/cpustate.h include/pmm.h include/multiboot.h include/vmm.h \
|
||||||
|
include/timer.h include/serial.h
|
||||||
$(CC) $(FLAGS) $(CCFLAGS) -o $@ -c src/init.c
|
$(CC) $(FLAGS) $(CCFLAGS) -o $@ -c src/init.c
|
||||||
|
|
||||||
# src/interrupts.c
|
# src/interrupts.c
|
||||||
obj/interrupts.o: src/interrupts.c include/interrupts.h include/cpustate.h \
|
obj/interrupts.o: src/interrupts.c include/interrupts.h include/cpustate.h \
|
||||||
include/console.h include/stdlib.h include/varargs.h include/io.h \
|
include/console.h include/stdlib.h include/varargs.h include/config.h \
|
||||||
src/intr_stubs.h
|
include/io.h src/intr_stubs.h
|
||||||
$(CC) $(FLAGS) $(CCFLAGS) -o $@ -c src/interrupts.c
|
$(CC) $(FLAGS) $(CCFLAGS) -o $@ -c src/interrupts.c
|
||||||
|
|
||||||
# src/malloc.c
|
# src/malloc.c
|
||||||
obj/malloc.o: src/malloc.c include/stdlib.h include/varargs.h
|
obj/malloc.o: src/malloc.c include/kernel.h include/stdlib.h \
|
||||||
|
include/varargs.h include/config.h include/console.h include/serial.h
|
||||||
$(CC) $(FLAGS) $(CCFLAGS) -o $@ -c src/malloc.c
|
$(CC) $(FLAGS) $(CCFLAGS) -o $@ -c src/malloc.c
|
||||||
|
|
||||||
# src/pmm.c
|
# src/pmm.c
|
||||||
obj/pmm.o: src/pmm.c include/pmm.h include/multiboot.h include/kernel.h \
|
obj/pmm.o: src/pmm.c include/pmm.h include/multiboot.h include/kernel.h \
|
||||||
include/stdlib.h include/varargs.h include/console.h
|
include/stdlib.h include/varargs.h include/config.h include/console.h
|
||||||
$(CC) $(FLAGS) $(CCFLAGS) -o $@ -c src/pmm.c
|
$(CC) $(FLAGS) $(CCFLAGS) -o $@ -c src/pmm.c
|
||||||
|
|
||||||
|
# src/serial.c
|
||||||
|
obj/serial.o: src/serial.c include/io.h include/serial.h include/stdlib.h \
|
||||||
|
include/varargs.h include/config.h
|
||||||
|
$(CC) $(FLAGS) $(CCFLAGS) -o $@ -c src/serial.c
|
||||||
|
|
||||||
# src/stdlib.c
|
# src/stdlib.c
|
||||||
obj/stdlib.o: src/stdlib.c include/stdlib.h include/varargs.h \
|
obj/stdlib.o: src/stdlib.c include/stdlib.h include/varargs.h \
|
||||||
include/kernel.h
|
include/config.h include/kernel.h
|
||||||
$(CC) $(FLAGS) $(CCFLAGS) -o $@ -c src/stdlib.c
|
$(CC) $(FLAGS) $(CCFLAGS) -o $@ -c src/stdlib.c
|
||||||
|
|
||||||
# src/timer.c
|
# src/timer.c
|
||||||
|
@ -76,29 +83,30 @@ obj/vmm.o: src/vmm.c include/config.h include/vmm.h include/pmm.h \
|
||||||
|
|
||||||
# trainscript/tsvm.cpp
|
# trainscript/tsvm.cpp
|
||||||
obj/tsvm.o: trainscript/tsvm.cpp include/stdlib.h include/varargs.h \
|
obj/tsvm.o: trainscript/tsvm.cpp include/stdlib.h include/varargs.h \
|
||||||
include/console.h trainscript/common.h trainscript/tsvm.hpp \
|
include/config.h include/console.h trainscript/common.h \
|
||||||
include/ker/string.hpp include/ker/vector.hpp include/ker/new.hpp \
|
trainscript/tsvm.hpp include/ker/string.hpp include/ker/vector.hpp \
|
||||||
include/ker/dictionary.hpp include/kernel.h include/ker/pair.hpp \
|
include/ker/new.hpp include/ker/dictionary.hpp include/kernel.h \
|
||||||
trainscript/typeid.hpp trainscript/trainscript.tab.hpp \
|
include/ker/pair.hpp trainscript/typeid.hpp \
|
||||||
trainscript/trainscript.l.h include/string.h
|
trainscript/trainscript.tab.hpp trainscript/trainscript.l.h \
|
||||||
|
include/string.h
|
||||||
$(CXX) $(FLAGS) $(CXXFLAGS) -o $@ -c trainscript/tsvm.cpp
|
$(CXX) $(FLAGS) $(CXXFLAGS) -o $@ -c trainscript/tsvm.cpp
|
||||||
|
|
||||||
# src/cplusplus.cpp
|
# src/cplusplus.cpp
|
||||||
obj/cplusplus.o: src/cplusplus.cpp include/stdlib.h include/varargs.h \
|
obj/cplusplus.o: src/cplusplus.cpp include/stdlib.h include/varargs.h \
|
||||||
include/console.h include/ker/new.hpp
|
include/config.h include/console.h include/ker/new.hpp
|
||||||
$(CXX) $(FLAGS) $(CXXFLAGS) -o $@ -c src/cplusplus.cpp
|
$(CXX) $(FLAGS) $(CXXFLAGS) -o $@ -c src/cplusplus.cpp
|
||||||
|
|
||||||
# src/vm.cpp
|
# src/vm.cpp
|
||||||
obj/vm.o: src/vm.cpp include/stdlib.h include/varargs.h include/timer.h \
|
obj/vm.o: src/vm.cpp include/stdlib.h include/varargs.h include/config.h \
|
||||||
include/dynamic.h src/../trainscript/tsvm.hpp include/console.h \
|
include/timer.h include/dynamic.h src/../trainscript/tsvm.hpp \
|
||||||
include/ker/string.hpp include/ker/vector.hpp include/ker/new.hpp \
|
include/console.h include/ker/string.hpp include/ker/vector.hpp \
|
||||||
include/ker/dictionary.hpp include/kernel.h include/ker/pair.hpp \
|
include/ker/new.hpp include/ker/dictionary.hpp include/kernel.h \
|
||||||
src/../trainscript/typeid.hpp
|
include/ker/pair.hpp src/../trainscript/typeid.hpp
|
||||||
$(CXX) $(FLAGS) $(CXXFLAGS) -o $@ -c src/vm.cpp
|
$(CXX) $(FLAGS) $(CXXFLAGS) -o $@ -c src/vm.cpp
|
||||||
|
|
||||||
# obj/trainscript.yy.cpp
|
# obj/trainscript.yy.cpp
|
||||||
obj/trainscript.yy.o: obj/trainscript.yy.cpp include/string.h \
|
obj/trainscript.yy.o: obj/trainscript.yy.cpp include/string.h \
|
||||||
include/stdlib.h include/varargs.h trainscript/common.h \
|
include/stdlib.h include/varargs.h include/config.h trainscript/common.h \
|
||||||
trainscript/tsvm.hpp include/console.h include/ker/string.hpp \
|
trainscript/tsvm.hpp include/console.h include/ker/string.hpp \
|
||||||
include/ker/vector.hpp include/ker/new.hpp include/ker/dictionary.hpp \
|
include/ker/vector.hpp include/ker/new.hpp include/ker/dictionary.hpp \
|
||||||
include/kernel.h include/ker/pair.hpp trainscript/typeid.hpp \
|
include/kernel.h include/ker/pair.hpp trainscript/typeid.hpp \
|
||||||
|
@ -107,11 +115,11 @@ obj/trainscript.yy.o: obj/trainscript.yy.cpp include/string.h \
|
||||||
|
|
||||||
# obj/trainscript.tab.cpp
|
# obj/trainscript.tab.cpp
|
||||||
obj/trainscript.tab.o: obj/trainscript.tab.cpp include/stdlib.h \
|
obj/trainscript.tab.o: obj/trainscript.tab.cpp include/stdlib.h \
|
||||||
include/varargs.h trainscript/common.h trainscript/tsvm.hpp \
|
include/varargs.h include/config.h trainscript/common.h \
|
||||||
include/console.h include/ker/string.hpp include/ker/vector.hpp \
|
trainscript/tsvm.hpp include/console.h include/ker/string.hpp \
|
||||||
include/ker/new.hpp include/ker/dictionary.hpp include/kernel.h \
|
include/ker/vector.hpp include/ker/new.hpp include/ker/dictionary.hpp \
|
||||||
include/ker/pair.hpp trainscript/typeid.hpp trainscript/trainscript.l.h \
|
include/kernel.h include/ker/pair.hpp trainscript/typeid.hpp \
|
||||||
include/string.h
|
trainscript/trainscript.l.h include/string.h
|
||||||
$(CXX) -iquotetrainscript $(FLAGS) $(CXXFLAGS) -o $@ -c obj/trainscript.tab.cpp
|
$(CXX) -iquotetrainscript $(FLAGS) $(CXXFLAGS) -o $@ -c obj/trainscript.tab.cpp
|
||||||
|
|
||||||
# asm/dynamic.S
|
# asm/dynamic.S
|
||||||
|
@ -149,4 +157,4 @@ obj/main.o: scripts/main.ts
|
||||||
|
|
||||||
.PHONY: run
|
.PHONY: run
|
||||||
run:
|
run:
|
||||||
qemu-system-i386 -kernel kernel kernel
|
qemu-system-i386 -serial stdio -kernel kernel
|
||||||
|
|
|
@ -15,3 +15,5 @@ Also it leaks memory. A lot of memory.
|
||||||
- Adding support for String Type
|
- Adding support for String Type
|
||||||
- Implement custom malloc that does what it should
|
- Implement custom malloc that does what it should
|
||||||
|
|
||||||
|
## Guidlines
|
||||||
|
- Calls to `die` or `die_extra` should follow the following scheme: `ContextName.ErrorName`
|
||||||
|
|
|
@ -3,3 +3,11 @@
|
||||||
/*
|
/*
|
||||||
#define USE_VIRTUAL_MEMORY_MANAGEMENT
|
#define USE_VIRTUAL_MEMORY_MANAGEMENT
|
||||||
//*/
|
//*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
#define USE_VERBOSE_MALLOC
|
||||||
|
//*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
#define USE_VERBOSE_FREE
|
||||||
|
//*/
|
||||||
|
|
|
@ -17,6 +17,13 @@ static inline void outb(uint16_t port, uint8_t data)
|
||||||
__asm__ volatile ("outb %0, %1" : : "a" (data), "Nd" (port));
|
__asm__ volatile ("outb %0, %1" : : "a" (data), "Nd" (port));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline uint8_t inb(uint16_t port)
|
||||||
|
{
|
||||||
|
uint8_t data;
|
||||||
|
__asm__ volatile ("inb %1, %0" : "=a" (data) : "d" (port));
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
#if defined(__cplusplus)
|
#if defined(__cplusplus)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -49,7 +49,7 @@ namespace ker
|
||||||
~String()
|
~String()
|
||||||
{
|
{
|
||||||
if(this->mText != nullptr) {
|
if(this->mText != nullptr) {
|
||||||
free(this->mText);
|
free(this->mText);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -136,7 +136,7 @@ namespace ker
|
||||||
void copyFrom(const uint8_t *bytes, size_t length)
|
void copyFrom(const uint8_t *bytes, size_t length)
|
||||||
{
|
{
|
||||||
if(this->mText != nullptr) {
|
if(this->mText != nullptr) {
|
||||||
free(this->mText);
|
// free(this->mText);
|
||||||
}
|
}
|
||||||
this->mText = (uint8_t*)malloc(length + 1);
|
this->mText = (uint8_t*)malloc(length + 1);
|
||||||
memcpy(this->mText, bytes, length);
|
memcpy(this->mText, bytes, length);
|
||||||
|
|
|
@ -66,7 +66,7 @@ namespace ker
|
||||||
~Vector()
|
~Vector()
|
||||||
{
|
{
|
||||||
if(this->mData != nullptr) {
|
if(this->mData != nullptr) {
|
||||||
free(this->mData);
|
free(this->mData);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
51
include/serial.h
Normal file
51
include/serial.h
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <inttypes.h>
|
||||||
|
|
||||||
|
#define SERIAL_IER 1
|
||||||
|
#define SERIAL_IIR 2
|
||||||
|
#define SERIAL_FCR 2
|
||||||
|
#define SERIAL_LCR 3
|
||||||
|
#define SERIAL_MCR 4
|
||||||
|
#define SERIAL_LSR 5
|
||||||
|
#define SERIAL_MSR 6
|
||||||
|
|
||||||
|
#define SERIAL_COM1 0x3F8
|
||||||
|
#define SERIAL_COM2 0x2F8
|
||||||
|
#define SERIAL_COM3 0x3E8
|
||||||
|
#define SERIAL_COM4 0x2E8
|
||||||
|
|
||||||
|
#define SERIAL_PARITY_NONE 0b000
|
||||||
|
#define SERIAL_PARITY_ODD 0b100
|
||||||
|
#define SERIAL_PARITY_EVEN 0b110
|
||||||
|
#define SERIAL_PARITY_HIGH 0b101
|
||||||
|
#define SERIAL_PARITY_LOW 0b111
|
||||||
|
|
||||||
|
#if defined(__cplusplus)
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void serial_init(uint16_t port, uint32_t baud, uint8_t parity, uint8_t bits);
|
||||||
|
|
||||||
|
int serial_can_read(uint16_t port);
|
||||||
|
|
||||||
|
int serial_can_write(uint16_t port);
|
||||||
|
|
||||||
|
void serial_write(uint16_t port, const uint8_t *data, size_t length);
|
||||||
|
|
||||||
|
void serial_read(uint16_t port, uint8_t *data, size_t length);
|
||||||
|
|
||||||
|
void serial_printf(uint16_t port, const char *format, ...);
|
||||||
|
|
||||||
|
static inline void serial_write_str(uint16_t port, const char *text)
|
||||||
|
{
|
||||||
|
while(*text) {
|
||||||
|
serial_write(port, (uint8_t*)text, 1);
|
||||||
|
text++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(__cplusplus)
|
||||||
|
}
|
||||||
|
#endif
|
|
@ -3,6 +3,7 @@
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include "varargs.h"
|
#include "varargs.h"
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
#if defined(__cplusplus)
|
#if defined(__cplusplus)
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
@ -12,6 +13,14 @@ char *itoa(int value, char *str, int base);
|
||||||
int atoi(const char *str);
|
int atoi(const char *str);
|
||||||
float atof(const char *str);
|
float atof(const char *str);
|
||||||
|
|
||||||
|
#if defined(USE_VERBOSE_MALLOC)
|
||||||
|
void *malloc_d(size_t,const char *,int);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(USE_VERBOSE_FREE)
|
||||||
|
void free_d(void *,const char*, int);
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Allocates a block of memory
|
* Allocates a block of memory
|
||||||
* @param size Minimum size of the memory block
|
* @param size Minimum size of the memory block
|
||||||
|
@ -132,6 +141,20 @@ static inline char * strdup(const char *str)
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int sprintf(char *target, const char *format, ...);
|
||||||
|
|
||||||
|
int vsprintf(char *target, const char *format, va_list vl);
|
||||||
|
|
||||||
#if defined(__cplusplus)
|
#if defined(__cplusplus)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(USE_VERBOSE_MALLOC)
|
||||||
|
#define malloc(size) malloc_d((size), __FILE__, __LINE__)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(USE_VERBOSE_FREE)
|
||||||
|
#define free(ptr) free_d((ptr), __FILE__, __LINE__)
|
||||||
|
#endif
|
||||||
|
|
|
@ -5,7 +5,7 @@ BEGIN
|
||||||
0 -> i;
|
0 -> i;
|
||||||
WHILE ((i + 1) -> i) <= 50 DO
|
WHILE ((i + 1) -> i) <= 50 DO
|
||||||
BEGIN
|
BEGIN
|
||||||
printInt(i);
|
print2Int(50 - i, i);
|
||||||
sleep(2);
|
sleep(2);
|
||||||
END
|
END
|
||||||
END
|
END
|
||||||
|
|
|
@ -188,50 +188,12 @@ void kputs(const char *str)
|
||||||
|
|
||||||
void kprintf(const char *format, ...)
|
void kprintf(const char *format, ...)
|
||||||
{
|
{
|
||||||
char buffer[32];
|
static char buffer[1024];
|
||||||
|
memset(buffer, 0, sizeof(buffer));
|
||||||
|
|
||||||
va_list vl;
|
va_list vl;
|
||||||
va_start(vl, format);
|
va_start(vl, format);
|
||||||
while(*format != 0)
|
vsprintf(buffer, format, vl);
|
||||||
{
|
|
||||||
char c = *(format++);
|
|
||||||
if(c == '%')
|
|
||||||
{
|
|
||||||
c = *(format++);
|
|
||||||
int i;
|
|
||||||
char *str;
|
|
||||||
switch(c)
|
|
||||||
{
|
|
||||||
case 'd':
|
|
||||||
case 'i':
|
|
||||||
i = va_arg(vl, int);
|
|
||||||
kputs(itoa(i, buffer, 10));
|
|
||||||
break;
|
|
||||||
case 'b':
|
|
||||||
i = va_arg(vl, int);
|
|
||||||
kputs(itoa(i, buffer, 2));
|
|
||||||
break;
|
|
||||||
case 'x':
|
|
||||||
case 'X':
|
|
||||||
i = va_arg(vl, int);
|
|
||||||
kputs(itoa(i, buffer, 16));
|
|
||||||
break;
|
|
||||||
case 'c':
|
|
||||||
c = va_arg(vl, int);
|
|
||||||
kputc(c);
|
|
||||||
break;
|
|
||||||
case 's':
|
|
||||||
str = va_arg(vl, char*);
|
|
||||||
kputs(str);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
kputc(c);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
kputc(c);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
va_end(vl);
|
va_end(vl);
|
||||||
|
kputs(buffer);
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#include <vmm.h>
|
#include <vmm.h>
|
||||||
#include <timer.h>
|
#include <timer.h>
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
|
#include <serial.h>
|
||||||
|
|
||||||
void die(const char *msg)
|
void die(const char *msg)
|
||||||
{
|
{
|
||||||
|
@ -160,13 +161,16 @@ void init(const MultibootStructure *mbHeader)
|
||||||
kclear();
|
kclear();
|
||||||
kputs("Welcome to \x12\x05trainOS\x12\x07!\n");
|
kputs("Welcome to \x12\x05trainOS\x12\x07!\n");
|
||||||
|
|
||||||
|
serial_init(SERIAL_COM1, 9600, SERIAL_PARITY_NONE, 8);
|
||||||
|
serial_write_str(SERIAL_COM1, "Debug Console Ready\n");
|
||||||
|
|
||||||
//dumpMB(mbHeader);
|
//dumpMB(mbHeader);
|
||||||
|
|
||||||
kputs("Initialize physical memory management: ");
|
kputs("Initialize physical memory management: ");
|
||||||
pmm_init(mbHeader);
|
pmm_init(mbHeader);
|
||||||
putsuccess();
|
putsuccess();
|
||||||
|
|
||||||
uint32_t freeMem = pmm_calc_free();
|
uint32_t freeMem = pmm_calc_free();
|
||||||
kprintf("Free memory: %d B, %d kB, %d MB\n", freeMem, freeMem >> 10, freeMem >> 20);
|
kprintf("Free memory: %d B, %d kB, %d MB\n", freeMem, freeMem >> 10, freeMem >> 20);
|
||||||
|
|
||||||
#if defined(USE_VIRTUAL_MEMORY_MANAGEMENT)
|
#if defined(USE_VIRTUAL_MEMORY_MANAGEMENT)
|
||||||
|
|
187
src/malloc.c
187
src/malloc.c
|
@ -1,37 +1,194 @@
|
||||||
|
#include <kernel.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <console.h>
|
||||||
|
#include <serial.h>
|
||||||
|
|
||||||
|
#undef malloc
|
||||||
|
#undef free
|
||||||
|
|
||||||
|
typedef struct List
|
||||||
|
{
|
||||||
|
size_t magic;
|
||||||
|
size_t length;
|
||||||
|
size_t used;
|
||||||
|
struct List *next;
|
||||||
|
} List;
|
||||||
|
|
||||||
size_t mallocCount = 0, freeCount = 0;
|
size_t mallocCount = 0, freeCount = 0;
|
||||||
size_t allocatedMemory = 0;
|
size_t allocatedMemory = 0;
|
||||||
|
|
||||||
|
static const size_t minimumAllocSize = 2 * sizeof(List);
|
||||||
static char * const malloc_heap_start = (char *)0x400000;
|
static char * const malloc_heap_start = (char *)0x400000;
|
||||||
static char * const malloc_heap_end = (char *)0x800000;
|
static char * const malloc_heap_end = (char *)0x10000000;
|
||||||
|
|
||||||
static char * current = nullptr;
|
List *listBegin = nullptr;
|
||||||
|
|
||||||
|
static void print_list()
|
||||||
|
{
|
||||||
|
List *list = listBegin;
|
||||||
|
serial_printf(SERIAL_COM1, "malloc list: \n");
|
||||||
|
while(list != nullptr)
|
||||||
|
{
|
||||||
|
if(list->magic != 0xDEADBEEF) {
|
||||||
|
die("malloc::print_list.InvalidMagicNumber");
|
||||||
|
}
|
||||||
|
serial_printf(SERIAL_COM1, "[%x -> %x] %d %d\n", list, list->next, list->used, list->length);
|
||||||
|
list = list->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void defragment()
|
||||||
|
{
|
||||||
|
List *list = listBegin;
|
||||||
|
if(list == nullptr) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for(; list->next != nullptr; list = list->next)
|
||||||
|
{
|
||||||
|
if(list->used != 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
while(list->next->used == 0) {
|
||||||
|
List *n = list->next->next;
|
||||||
|
list->length += list->next->length + sizeof(List);
|
||||||
|
list->next = n;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void *malloc(size_t len)
|
void *malloc(size_t len)
|
||||||
{
|
{
|
||||||
allocatedMemory += len;
|
// Prevent fragmentation, sacrifice memory
|
||||||
|
if(len < minimumAllocSize) {
|
||||||
|
len = minimumAllocSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(listBegin == nullptr) {
|
||||||
|
listBegin = (List*)malloc_heap_start;
|
||||||
|
listBegin->length = (intptr_t)malloc_heap_end - (intptr_t)malloc_heap_start - sizeof(List);
|
||||||
|
listBegin->used = 0;
|
||||||
|
listBegin->next = nullptr;
|
||||||
|
listBegin->magic = 0xDEADBEEF;
|
||||||
|
|
||||||
|
print_list();
|
||||||
|
}
|
||||||
|
|
||||||
|
List *cursor = listBegin;
|
||||||
|
|
||||||
|
// Find the first non-used List entry
|
||||||
|
while((cursor != nullptr) && ((cursor->used != 0) || (cursor->length < (len + sizeof(List))))) {
|
||||||
|
cursor = cursor->next;
|
||||||
|
}
|
||||||
|
if(cursor == nullptr) {
|
||||||
|
print_list();
|
||||||
|
die_extra("malloc.OutOfMemory", itoa(len, nullptr, 10));
|
||||||
|
}
|
||||||
|
|
||||||
|
if(cursor->length < (sizeof(List) + len)) {
|
||||||
|
die("malloc.FragmentationFailure");
|
||||||
|
}
|
||||||
|
|
||||||
|
if(cursor->length == len)
|
||||||
|
{
|
||||||
|
cursor->used = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Store total length
|
||||||
|
size_t newLength = cursor->length - sizeof(List) - len;
|
||||||
|
|
||||||
|
// Allocate the memory
|
||||||
|
cursor->used = 1;
|
||||||
|
cursor->length = len;
|
||||||
|
|
||||||
|
// Fragment list
|
||||||
|
List *newl = (List*)((char*)cursor + (sizeof(List) + cursor->length));
|
||||||
|
newl->length = newLength;
|
||||||
|
newl->used = 0;
|
||||||
|
newl->next = cursor->next;
|
||||||
|
newl->magic = 0xDEADBEEF;
|
||||||
|
|
||||||
|
cursor->next = newl;
|
||||||
|
}
|
||||||
|
|
||||||
|
allocatedMemory += len;
|
||||||
mallocCount++;
|
mallocCount++;
|
||||||
|
|
||||||
if(current == nullptr) {
|
return (void*)((char*)cursor + sizeof(List));
|
||||||
current = malloc_heap_start;
|
}
|
||||||
|
|
||||||
|
void* realloc (void* ptr, size_t size)
|
||||||
|
{
|
||||||
|
void *n = malloc(size);
|
||||||
|
memcpy(n, ptr, size);
|
||||||
|
free(ptr);
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
void free(void *ptr)
|
||||||
|
{
|
||||||
|
if(ptr == nullptr) {
|
||||||
|
// Valid behaviour!
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if((uintptr_t)ptr < (uintptr_t)malloc_heap_start) {
|
||||||
|
die_extra("free.InvalidFree", itoa(ptr, nullptr, 16));
|
||||||
|
}
|
||||||
|
freeCount++;
|
||||||
|
|
||||||
|
List *entry = (List*)((char*)ptr - sizeof(List));
|
||||||
|
if(entry->used == 0) {
|
||||||
|
die_extra("free.InvalidBlock", itoa(ptr, nullptr, 16));
|
||||||
|
}
|
||||||
|
if(entry->magic != 0xDEADBEEF) {
|
||||||
|
die_extra("free.InvalidBlockMagic: ", itoa(entry->magic, nullptr, 16));
|
||||||
}
|
}
|
||||||
|
|
||||||
void *ptr = current;
|
if(entry->length > 0x5000) {
|
||||||
current += len;
|
die_extra("free.InvalidSizedBlock: ", itoa(entry->length, nullptr, 10));
|
||||||
|
|
||||||
if((uintptr_t)current >= (uintptr_t)malloc_heap_end) {
|
|
||||||
die("malloc.OutOfMemory");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
allocatedMemory -= entry->length;
|
||||||
|
entry->used = 0;
|
||||||
|
|
||||||
|
defragment();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void *malloc_d(size_t len, const char *file, int line)
|
||||||
|
{
|
||||||
|
serial_write_str(SERIAL_COM1, "Allocate ");
|
||||||
|
serial_write_str(SERIAL_COM1, itoa(len, nullptr, 10));
|
||||||
|
serial_write_str(SERIAL_COM1, " bytes at ");
|
||||||
|
serial_write_str(SERIAL_COM1, file);
|
||||||
|
serial_write_str(SERIAL_COM1, ":");
|
||||||
|
serial_write_str(SERIAL_COM1, itoa(line, nullptr, 10));
|
||||||
|
serial_write_str(SERIAL_COM1, ": ");
|
||||||
|
|
||||||
|
void *ptr = malloc(len);
|
||||||
|
serial_write_str(SERIAL_COM1, itoa(ptr, nullptr, 16));
|
||||||
|
serial_write_str(SERIAL_COM1, "\n");
|
||||||
|
|
||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void free_d(void *ptr, const char *file, int line)
|
||||||
|
|
||||||
|
|
||||||
void free(void *__ptr)
|
|
||||||
{
|
{
|
||||||
freeCount++;
|
if(ptr == nullptr) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
List *entry = (List*)((char*)ptr - sizeof(List));
|
||||||
|
|
||||||
|
serial_write_str(SERIAL_COM1, "Free ");
|
||||||
|
serial_write_str(SERIAL_COM1, itoa(entry->length, nullptr, 10));
|
||||||
|
serial_write_str(SERIAL_COM1, " bytes at ");
|
||||||
|
serial_write_str(SERIAL_COM1, itoa(ptr, nullptr, 16));
|
||||||
|
serial_write_str(SERIAL_COM1, " in ");
|
||||||
|
serial_write_str(SERIAL_COM1, file);
|
||||||
|
serial_write_str(SERIAL_COM1, ":");
|
||||||
|
serial_write_str(SERIAL_COM1, itoa(line, nullptr, 10));
|
||||||
|
serial_write_str(SERIAL_COM1, ".\n");
|
||||||
|
free(ptr);
|
||||||
}
|
}
|
||||||
|
|
85
src/serial.c
Normal file
85
src/serial.c
Normal file
|
@ -0,0 +1,85 @@
|
||||||
|
#include <io.h>
|
||||||
|
#include <serial.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <varargs.h>
|
||||||
|
|
||||||
|
// Funktion zum initialisieren eines COM-Ports
|
||||||
|
void serial_init(uint16_t base, uint32_t baud, uint8_t parity, uint8_t bits)
|
||||||
|
{
|
||||||
|
// Teiler berechnen
|
||||||
|
union {
|
||||||
|
uint8_t b[2];
|
||||||
|
uint16_t w;
|
||||||
|
} divisor;
|
||||||
|
divisor.w = 115200/baud;
|
||||||
|
|
||||||
|
// Interrupt ausschalten
|
||||||
|
outb(base+SERIAL_IER,0x00);
|
||||||
|
|
||||||
|
// DLAB-Bit setzen
|
||||||
|
outb(base+SERIAL_LCR,0x80);
|
||||||
|
|
||||||
|
// Teiler (low) setzen
|
||||||
|
outb(base+0,divisor.b[0]);
|
||||||
|
|
||||||
|
// Teiler (high) setzen
|
||||||
|
outb(base+1,divisor.b[1]);
|
||||||
|
|
||||||
|
// Anzahl Bits, Parität, usw setzen (DLAB zurücksetzen)
|
||||||
|
outb(base+SERIAL_LCR,((parity&0x7)<<3)|((bits-5)&0x3));
|
||||||
|
|
||||||
|
// Initialisierung abschließen
|
||||||
|
outb(base+SERIAL_FCR,0xC7);
|
||||||
|
outb(base+SERIAL_MCR,0x0B);
|
||||||
|
}
|
||||||
|
|
||||||
|
int serial_can_write(uint16_t base)
|
||||||
|
{
|
||||||
|
return inb(base+SERIAL_LSR)&0x20;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Byte senden
|
||||||
|
void write_com(uint16_t base, uint8_t chr) {
|
||||||
|
while (serial_can_write(base)==0);
|
||||||
|
outb(base,chr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void serial_write(uint16_t port, const uint8_t *data, size_t length)
|
||||||
|
{
|
||||||
|
while(length--) {
|
||||||
|
write_com(port, *data++);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prüft, ob man bereits lesen kann
|
||||||
|
int serial_can_read(uint16_t base)
|
||||||
|
{
|
||||||
|
return inb(base+SERIAL_LSR)&1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Byte empfangen
|
||||||
|
static uint8_t read_serial(uint16_t base)
|
||||||
|
{
|
||||||
|
while (!serial_can_read(base));
|
||||||
|
return inb(base);
|
||||||
|
}
|
||||||
|
|
||||||
|
void serial_read(uint16_t port, uint8_t *data, size_t length)
|
||||||
|
{
|
||||||
|
while(length--) {
|
||||||
|
*data++ = read_serial(port);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void serial_printf(uint16_t port, const char *format, ...)
|
||||||
|
{
|
||||||
|
static char buffer[1024];
|
||||||
|
memset(buffer, 0, sizeof(buffer));
|
||||||
|
|
||||||
|
va_list vl;
|
||||||
|
va_start(vl, format);
|
||||||
|
vsprintf(buffer, format, vl);
|
||||||
|
va_end(vl);
|
||||||
|
|
||||||
|
serial_write_str(port, buffer);
|
||||||
|
}
|
101
src/stdlib.c
101
src/stdlib.c
|
@ -1,14 +1,6 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <kernel.h>
|
#include <kernel.h>
|
||||||
|
|
||||||
void* realloc (void* ptr, size_t size)
|
|
||||||
{
|
|
||||||
void *n = malloc(size);
|
|
||||||
memcpy(n, ptr, size);
|
|
||||||
free(ptr);
|
|
||||||
return n;
|
|
||||||
}
|
|
||||||
|
|
||||||
void exit(int errorCode)
|
void exit(int errorCode)
|
||||||
{
|
{
|
||||||
static char buffer[128];
|
static char buffer[128];
|
||||||
|
@ -38,6 +30,11 @@ char *itoa(int num, char *str, int base)
|
||||||
int i = 0;
|
int i = 0;
|
||||||
int isNegative = 0;
|
int isNegative = 0;
|
||||||
|
|
||||||
|
if(str == nullptr) {
|
||||||
|
static char tmp[64];
|
||||||
|
str = tmp;
|
||||||
|
}
|
||||||
|
|
||||||
/* Handle 0 explicitely, otherwise empty string is printed for 0 */
|
/* Handle 0 explicitely, otherwise empty string is printed for 0 */
|
||||||
if (num == 0)
|
if (num == 0)
|
||||||
{
|
{
|
||||||
|
@ -102,3 +99,91 @@ void *memmove( void *destination, const void *source, size_t num)
|
||||||
// TODO: Implement memmove
|
// TODO: Implement memmove
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int sprintf(char *target, const char *format, ...)
|
||||||
|
{
|
||||||
|
va_list vl;
|
||||||
|
va_start(vl, format);
|
||||||
|
int len = vsprintf(target, format, vl);
|
||||||
|
va_end(vl);
|
||||||
|
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
int vsprintf(char *target, const char *format, va_list vl)
|
||||||
|
{
|
||||||
|
int length = 0;
|
||||||
|
char buffer[32];
|
||||||
|
while(*format != 0)
|
||||||
|
{
|
||||||
|
char c = *(format++);
|
||||||
|
if(c == '%')
|
||||||
|
{
|
||||||
|
c = *(format++);
|
||||||
|
int i;
|
||||||
|
char *tmp;
|
||||||
|
size_t len;
|
||||||
|
switch(c)
|
||||||
|
{
|
||||||
|
case 'd':
|
||||||
|
case 'i':
|
||||||
|
i = va_arg(vl, int);
|
||||||
|
tmp = itoa(i, buffer, 10);
|
||||||
|
len = strlen(tmp);
|
||||||
|
if(target != nullptr) {
|
||||||
|
strcat(target, tmp);
|
||||||
|
target += len;
|
||||||
|
}
|
||||||
|
length += len;
|
||||||
|
break;
|
||||||
|
case 'b':
|
||||||
|
i = va_arg(vl, int);
|
||||||
|
tmp = itoa(i, buffer, 2);
|
||||||
|
len = strlen(tmp);
|
||||||
|
if(target != nullptr) {
|
||||||
|
strcat(target, tmp);
|
||||||
|
target += len;
|
||||||
|
}
|
||||||
|
length += len;
|
||||||
|
break;
|
||||||
|
case 'x':
|
||||||
|
case 'X':
|
||||||
|
i = va_arg(vl, int);
|
||||||
|
tmp = itoa(i, buffer, 16);
|
||||||
|
len = strlen(tmp);
|
||||||
|
if(target != nullptr) {
|
||||||
|
strcat(target, tmp);
|
||||||
|
target += len;
|
||||||
|
}
|
||||||
|
length += len;
|
||||||
|
break;
|
||||||
|
case 's':
|
||||||
|
tmp = va_arg(vl, char*);
|
||||||
|
len = strlen(tmp);
|
||||||
|
if(target != nullptr) {
|
||||||
|
strcat(target, tmp);
|
||||||
|
target += len;
|
||||||
|
}
|
||||||
|
length += len;
|
||||||
|
break;
|
||||||
|
case 'c':
|
||||||
|
c = va_arg(vl, int);
|
||||||
|
default:
|
||||||
|
if(target != nullptr) {
|
||||||
|
*target++ = c;
|
||||||
|
}
|
||||||
|
length += 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(target != nullptr) *target++ = c;
|
||||||
|
length += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(target != nullptr) {
|
||||||
|
target[length] = 0;
|
||||||
|
}
|
||||||
|
return length;
|
||||||
|
}
|
||||||
|
|
20
src/vm.cpp
20
src/vm.cpp
|
@ -93,24 +93,25 @@ Variable NativeMethod::invoke(Vector<Variable> arguments)
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t *stack = (uint8_t*)malloc(stackSize);
|
uint8_t *stack = (uint8_t*)malloc(stackSize);
|
||||||
|
uint8_t *stackPtr = stack;
|
||||||
for(int i = arguments.length() - 1; i >= 0; i--) {
|
for(int i = arguments.length() - 1; i >= 0; i--) {
|
||||||
switch(arguments[i].type.id) {
|
switch(arguments[i].type.id) {
|
||||||
case TypeID::Bool:
|
case TypeID::Bool:
|
||||||
*reinterpret_cast<Int*>(stack) = arguments[i].boolean ? 1 : 0;
|
*reinterpret_cast<Int*>(stackPtr) = arguments[i].boolean ? 1 : 0;
|
||||||
stack += sizeof(Int);
|
stackPtr += sizeof(Int);
|
||||||
break;
|
break;
|
||||||
case TypeID::Int:
|
case TypeID::Int:
|
||||||
*reinterpret_cast<Int*>(stack) = arguments[i].integer;
|
*reinterpret_cast<Int*>(stackPtr) = arguments[i].integer;
|
||||||
stack += sizeof(Int);
|
stackPtr += sizeof(Int);
|
||||||
break;
|
break;
|
||||||
case TypeID::Real:
|
case TypeID::Real:
|
||||||
*reinterpret_cast<Real*>(stack) = arguments[i].real;
|
*reinterpret_cast<Real*>(stackPtr) = arguments[i].real;
|
||||||
stack += sizeof(Real);
|
stackPtr += sizeof(Real);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dynamic_call(this->function, stack-stackSize, stackSize);
|
dynamic_call(this->function, stack, stackSize);
|
||||||
|
|
||||||
free(stack);
|
free(stack);
|
||||||
|
|
||||||
|
@ -121,6 +122,10 @@ extern "C" void __cdecl printInt(int i) {
|
||||||
kprintf("{%d}\n", i);
|
kprintf("{%d}\n", i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern "C" void __cdecl print2Int(int a, int b) {
|
||||||
|
kprintf("{%d;%d}\n", a, b);
|
||||||
|
}
|
||||||
|
|
||||||
struct NativeModuleDef
|
struct NativeModuleDef
|
||||||
{
|
{
|
||||||
const char *name;
|
const char *name;
|
||||||
|
@ -133,6 +138,7 @@ NativeModuleDef methods[] = {
|
||||||
{ "timer_get", "", (void*)timer_get },
|
{ "timer_get", "", (void*)timer_get },
|
||||||
{ "timer_set", "i", (void*)timer_set },
|
{ "timer_set", "i", (void*)timer_set },
|
||||||
{ "printInt", "i", (void*)printInt },
|
{ "printInt", "i", (void*)printInt },
|
||||||
|
{ "print2Int", "ii", (void*)print2Int },
|
||||||
{ nullptr, nullptr, 0 }
|
{ nullptr, nullptr, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,8 @@ SOURCES += \
|
||||||
trainscript/main.cpp \
|
trainscript/main.cpp \
|
||||||
src/timer.c \
|
src/timer.c \
|
||||||
src/cplusplus.cpp \
|
src/cplusplus.cpp \
|
||||||
src/vm.cpp
|
src/vm.cpp \
|
||||||
|
src/serial.c
|
||||||
|
|
||||||
HEADERS += \
|
HEADERS += \
|
||||||
include/console.h \
|
include/console.h \
|
||||||
|
@ -40,7 +41,8 @@ HEADERS += \
|
||||||
include/string.h \
|
include/string.h \
|
||||||
include/ker/new.hpp \
|
include/ker/new.hpp \
|
||||||
include/dynamic.h \
|
include/dynamic.h \
|
||||||
include/config.h
|
include/config.h \
|
||||||
|
include/serial.h
|
||||||
|
|
||||||
DISTFILES += \
|
DISTFILES += \
|
||||||
asm/intr_common_handler.S \
|
asm/intr_common_handler.S \
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
extern "C" {
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <console.h>
|
#include <console.h>
|
||||||
}
|
|
||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
|
||||||
|
@ -41,21 +39,22 @@ namespace trainscript
|
||||||
|
|
||||||
Module *VM::load(const void *buffer, size_t length)
|
Module *VM::load(const void *buffer, size_t length)
|
||||||
{
|
{
|
||||||
void *internalStorage = malloc(length);
|
char *internalStorage = (char*)malloc(length);
|
||||||
memcpy(internalStorage, buffer, length);
|
memcpy(internalStorage, buffer, length);
|
||||||
|
|
||||||
Module *module = new Module();
|
Module *module = new Module();
|
||||||
|
|
||||||
ParserData data;
|
ParserData data;
|
||||||
|
memset(&data, 0, sizeof(data));
|
||||||
data.buffer = reinterpret_cast<char*>(internalStorage);
|
data.buffer = reinterpret_cast<char*>(internalStorage);
|
||||||
data.index = 0;
|
data.index = 0;
|
||||||
data.length = length;
|
data.length = length;
|
||||||
data.module = module;
|
data.module = module;
|
||||||
|
|
||||||
yylex_init_extra(&data, &data.scanner);
|
yylex_init_extra(&data, &data.scanner);
|
||||||
|
|
||||||
bool valid = yyparse(&data) == 0;
|
bool valid = yyparse(&data) == 0;
|
||||||
|
|
||||||
yylex_destroy(data.scanner);
|
yylex_destroy(data.scanner);
|
||||||
|
|
||||||
free(internalStorage);
|
free(internalStorage);
|
||||||
|
|
||||||
for(size_t i = 0; i < 256; i++) {
|
for(size_t i = 0; i < 256; i++) {
|
||||||
|
|
Loading…
Reference in a new issue