diff --git a/Makefile b/Makefile index 739cb3f..9de28a6 100644 --- a/Makefile +++ b/Makefile @@ -30,8 +30,8 @@ all: kernel clean: $(RM) 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/cpp-test.o obj/vm.o obj/casts.o obj/cpustatetype.o obj/io.o obj/main.o -kernel: 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/cpp-test.o obj/vm.o obj/casts.o obj/cpustatetype.o obj/io.o obj/main.o conductance/assembly.o conductance/compoundtype.o conductance/instructions.o conductance/opcodes.o conductance/process.o conductance/string.o conductance/thread.o conductance/virtualmachine.o conductance/vmpointertype.o conductance/vmprimitivetype.o conductance/vmtype.o conductance/vmvalue.o conductance/vmvoidtype.o - $(LD) $(FLAGS) $(LDFLAGS) -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/cpp-test.o obj/vm.o obj/casts.o obj/cpustatetype.o obj/io.o obj/main.o conductance/assembly.o conductance/compoundtype.o conductance/instructions.o conductance/opcodes.o conductance/process.o conductance/string.o conductance/thread.o conductance/virtualmachine.o conductance/vmpointertype.o conductance/vmprimitivetype.o conductance/vmtype.o conductance/vmvalue.o conductance/vmvoidtype.o +kernel: 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/cpp-test.o obj/vm.o obj/casts.o obj/cpustatetype.o obj/io.o obj/main.o conductance/assembly.o conductance/compoundtype.o conductance/instructions.o conductance/process.o conductance/string.o conductance/thread.o conductance/virtualmachine.o conductance/vmpointertype.o conductance/vmprimitivetype.o conductance/vmtype.o conductance/vmvalue.o conductance/vmvoidtype.o + $(LD) $(FLAGS) $(LDFLAGS) -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/cpp-test.o obj/vm.o obj/casts.o obj/cpustatetype.o obj/io.o obj/main.o conductance/assembly.o conductance/compoundtype.o conductance/instructions.o conductance/process.o conductance/string.o conductance/thread.o conductance/virtualmachine.o conductance/vmpointertype.o conductance/vmprimitivetype.o conductance/vmtype.o conductance/vmvalue.o conductance/vmvoidtype.o # src/console.c obj/console.o: src/console.c include/console.h include/kstdlib.h \ @@ -99,7 +99,7 @@ obj/cpp-test.o: src/cpp-test.cpp include/console.h include/ker/string.hpp \ obj/vm.o: src/vm.cpp include/kstdlib.h include/varargs.h include/config.h \ include/malloc.h include/timer.h include/dynamic.h include/console.h \ include/interrupts.h include/cpustate.h src/../csl/cpustatetype.hpp \ - src/../csl/io.hpp src/../csl/casts.hpp include/io.h + src/../csl/io.hpp src/../csl/casts.hpp $(CXX) -iquoteobj $(FLAGS) $(CXXFLAGS) -o $@ -c src/vm.cpp # csl/casts.cpp diff --git a/conductance/Makefile b/conductance/Makefile index f7edb1b..c88114c 100644 --- a/conductance/Makefile +++ b/conductance/Makefile @@ -50,7 +50,6 @@ SOURCES = ../../Electronics/Electronics/Conductance/types/compoundtype.cpp ../../Electronics/Electronics/Conductance/types/vmprimitivetype.cpp \ ../../Electronics/Electronics/Conductance/types/vmvoidtype.cpp \ ../../Electronics/Electronics/Conductance/assembly.cpp \ - ../../Electronics/Electronics/Conductance/opcodes.cpp \ ../../Electronics/Electronics/Conductance/virtualmachine.cpp \ ../../Electronics/Electronics/Conductance/vmtype.cpp \ ../../Electronics/Electronics/Conductance/vmvalue.cpp \ @@ -63,7 +62,6 @@ OBJECTS = compoundtype.o \ vmprimitivetype.o \ vmvoidtype.o \ assembly.o \ - opcodes.o \ virtualmachine.o \ vmtype.o \ vmvalue.o \ @@ -232,7 +230,6 @@ DIST = /usr/lib/qt/mkspecs/features/spec_pre.prf \ ../../Electronics/Electronics/Conductance/types/vmprimitivetype.cpp \ ../../Electronics/Electronics/Conductance/types/vmvoidtype.cpp \ ../../Electronics/Electronics/Conductance/assembly.cpp \ - ../../Electronics/Electronics/Conductance/opcodes.cpp \ ../../Electronics/Electronics/Conductance/virtualmachine.cpp \ ../../Electronics/Electronics/Conductance/vmtype.cpp \ ../../Electronics/Electronics/Conductance/vmvalue.cpp \ @@ -693,20 +690,6 @@ assembly.o: ../../Electronics/Electronics/Conductance/assembly.cpp ../../Electro ../../Electronics/Electronics/Tools/binaryreader.hpp $(CXX) -c $(CXXFLAGS) $(INCPATH) -o assembly.o ../../Electronics/Electronics/Conductance/assembly.cpp -opcodes.o: ../../Electronics/Electronics/Conductance/opcodes.cpp ../../Electronics/Electronics/Conductance/opcodes.hpp \ - /home/felix/projects/trainOS/include/ker/dictionary.hpp \ - /home/felix/projects/trainOS/include/kernel.h \ - /home/felix/projects/trainOS/include/ker/pair.hpp \ - /home/felix/projects/trainOS/include/ker/vector.hpp \ - /home/felix/projects/trainOS/include/kstdlib.h \ - /home/felix/projects/trainOS/include/varargs.h \ - /home/felix/projects/trainOS/include/config.h \ - /home/felix/projects/trainOS/include/malloc.h \ - /home/felix/projects/trainOS/include/ker/new.hpp \ - /home/felix/projects/trainOS/include/ker/string.hpp \ - ../../Electronics/Electronics/Tools/fixedstring.hpp - $(CXX) -c $(CXXFLAGS) $(INCPATH) -o opcodes.o ../../Electronics/Electronics/Conductance/opcodes.cpp - virtualmachine.o: ../../Electronics/Electronics/Conductance/virtualmachine.cpp /home/felix/projects/trainOS/include/kstdlib.h \ /home/felix/projects/trainOS/include/varargs.h \ /home/felix/projects/trainOS/include/config.h \ diff --git a/csl/cpustatetype.cpp b/csl/cpustatetype.cpp index fbc5946..9cb5070 100644 --- a/csl/cpustatetype.cpp +++ b/csl/cpustatetype.cpp @@ -4,6 +4,8 @@ #include +VMText text("hello!"); + static CompoundType type { "CPUSTATE", { diff --git a/include/ker/string.hpp b/include/ker/string.hpp index 60df5ec..6720154 100644 --- a/include/ker/string.hpp +++ b/include/ker/string.hpp @@ -94,7 +94,7 @@ namespace ker ~String() { - if(this->mText != nullptr) { + if(this->mText != nullptr) { free(this->mText); } } diff --git a/kernel.ld b/kernel.ld index 16201af..7fcfe93 100644 --- a/kernel.ld +++ b/kernel.ld @@ -27,10 +27,14 @@ SECTIONS } .data ALIGN(4096) : { start_ctors = .; - KEEP(*( .init_array )); - KEEP(*(SORT_BY_INIT_PRIORITY( .init_array.* ))); + KEEP(*( .init_array )); + KEEP(*(SORT_BY_INIT_PRIORITY( .init_array.* ))); end_ctors = .; + start_dtors = .; + *(.dtors) + end_dtors = .; + *(.data) } .rodata ALIGN(4096) : { diff --git a/scripts/main.cu b/scripts/main.cu index 69f3014..e346e26 100644 --- a/scripts/main.cu +++ b/scripts/main.cu @@ -1,5 +1,7 @@ NATIVE print(...); +NATIVE shutdown(); + NATIVE outb(port : UINT16, value : UINT8); NATIVE inb(port : UINT16) → UINT8; @@ -61,6 +63,9 @@ BEGIN IF id = 33 THEN inb(96u16) → scancode; print("keypress: ", scancode, "\n"); + IF scancode = 1u8 THEN + shutdown(); + END END END diff --git a/scripts/main.cu.spark b/scripts/main.cu.spark index 9d0ac9d..f64d25b 100644 --- a/scripts/main.cu.spark +++ b/scripts/main.cu.spark @@ -1,9 +1,10 @@ ; ============================================= ; compiled with Copper 1.0 -; 2015-10-11 12:46:04 +; 2015-10-11 17:43:16 ; ============================================= ; native method: print(…) +; native method: shutdown(…) ; native method: outb(…) ; native method: inb(…) → UINT8 ; native method: toInt8(…) → INT8 @@ -26,6 +27,7 @@ + ; 0, sendCommand sendCommand: pushnil ; return value @@ -128,6 +130,14 @@ irq: pusht "keypress: " calln print 3 + load 1 + pushi 3 1 + op2 5 + jmp_if_not _private_7 + calln shutdown 0 + +_private_7: + _private_6: ret diff --git a/src/cplusplus.cpp b/src/cplusplus.cpp index 5595461..205d98a 100644 --- a/src/cplusplus.cpp +++ b/src/cplusplus.cpp @@ -75,21 +75,13 @@ extern "C" void cpp_init() typedef void (*destructor)(); -/* + // Im Linkerskript definiert extern "C" destructor start_dtors; extern "C" destructor end_dtors; -extern "C" void initialiseDestructors(); - -// Ruft die Konstruktoren für globale/statische Objekte auf -void initialiseDestructors() -{ - for (destructor* i = &start_dtors;i != &end_dtors;++i) - (*i)(); -} -*/ extern "C" void cpp_exit() { - initialiseConstructors(); + for (destructor* i = &start_dtors; i != &end_dtors;++i) + (*i)(); } diff --git a/src/init.c b/src/init.c index 735f954..0d4574d 100644 --- a/src/init.c +++ b/src/init.c @@ -210,7 +210,7 @@ void init(const MultibootStructure *mbHeader) kputs("\n"); - vm_start(); + vm_start(); irq_disable(); diff --git a/src/malloc.c b/src/malloc.c index a94d8d2..1a30b53 100644 --- a/src/malloc.c +++ b/src/malloc.c @@ -10,6 +10,8 @@ static const uint32_t magic = 0xDEADBEEF; +#define STACKDEPTH 8 + typedef struct List { #if defined(USE_MAGIC_SECURED_MALLOC) @@ -21,6 +23,7 @@ typedef struct List #if defined(ENABLE_MALLOC_MONITORING) const char *allocationFile; int allocationLine; + void *stacktrace[STACKDEPTH]; #endif } List; @@ -77,6 +80,16 @@ void malloc_print_list(int freeList) list->used ? list->allocationLine : 0, list->used, list->length); + serial_printf(SERIAL_COM1," "); + for(int i = 0; i < STACKDEPTH; i++) { + serial_printf(SERIAL_COM1, "%x ", list->stacktrace[i]); + } + serial_printf(SERIAL_COM1,"\n"); + + serial_printf(SERIAL_COM1,"["); + serial_write(SERIAL_COM1, (char*)list + sizeof(List), list->length); + serial_printf(SERIAL_COM1,"]"); + /* kprintf("[%x -> %x] (%s:%d) %d %d\n", list, @@ -191,6 +204,14 @@ void *malloc(size_t len) newl->next = cursor->next; #if defined(USE_MAGIC_SECURED_MALLOC) newl->hash = hash(newl); + newl->stacktrace[0] = __builtin_return_address(1); + newl->stacktrace[1] = __builtin_return_address(2); + newl->stacktrace[2] = __builtin_return_address(3); + newl->stacktrace[3] = __builtin_return_address(4); + newl->stacktrace[4] = __builtin_return_address(5); + newl->stacktrace[5] = __builtin_return_address(6); + newl->stacktrace[6] = __builtin_return_address(7); + newl->stacktrace[7] = __builtin_return_address(8); #endif cursor->next = newl; diff --git a/src/vm.cpp b/src/vm.cpp index ee4c489..86bad88 100644 --- a/src/vm.cpp +++ b/src/vm.cpp @@ -55,35 +55,6 @@ ExceptionCode printArguments(VMValue &, const VMArray &args) return ExceptionCode::None; } -#include - -ExceptionCode vmOutB(VMValue &, const VMArray &args) -{ - if(args.length() != 2) - return ExceptionCode::InvalidArgument; - if(args[0].type() != VMType::UInt16) - return ExceptionCode::InvalidArgument; - if(args[1].type() != VMType::UInt8) - return ExceptionCode::InvalidArgument; - - outb(args[0].value(), args[1].value()); - - return ExceptionCode::None; -} - -ExceptionCode vmInB(VMValue &result, const VMArray &args) -{ - if(args.length() != 1) - return ExceptionCode::InvalidArgument; - if(args[0].type() != VMType::UInt16) - return ExceptionCode::InvalidArgument; - - result = VMValue::UInt8( - inb(args[0].value())); - - return ExceptionCode::None; -} - struct dtortest { void *mem; @@ -146,90 +117,111 @@ const char *execptionName(ExceptionCode ex) } } +static bool shutdownRequested = false; + +ExceptionCode shutdown(VMValue &, const VMArray &) +{ + shutdownRequested = true; + return ExceptionCode::None; +} + +int ReferenceCounted::counter = 0; + extern "C" void vm_start() { // intr_set_handler(0x20, vm_handle_interrupt); intr_set_handler(0x21, vm_handle_interrupt); - VirtualMachine machine; - machine.type("CPUSTATE") = csl::CpuStateType; - machine.import("print") = printArguments; - machine.import("inb") = csl::inb; - machine.import("outb") = csl::outb; + { + VirtualMachine machine; + machine.type("CPUSTATE") = csl::CpuStateType; + machine.import("print") = printArguments; + machine.import("shutdown") = shutdown; - machine.import("toInt8") = csl::toInt8; - machine.import("toInt16") = csl::toInt16; - machine.import("toInt32") = csl::toInt32; - machine.import("toUInt8") = csl::toUInt8; - machine.import("toUInt16") = csl::toUInt16; - machine.import("toUInt32") = csl::toUInt32; + machine.import("inb") = csl::inb; + machine.import("outb") = csl::outb; - Assembly *assembly = machine.load(mainAssembly.ptr, mainAssembly.size); - if(assembly == nullptr) { - kprintf("failed to load assembly :(\n"); - return; - } + machine.import("toInt8") = csl::toInt8; + machine.import("toInt16") = csl::toInt16; + machine.import("toInt32") = csl::toInt32; + machine.import("toUInt8") = csl::toUInt8; + machine.import("toUInt16") = csl::toUInt16; + machine.import("toUInt32") = csl::toUInt32; - Process *irqService = machine.createProcess(assembly, true); - if(irqService == nullptr) { - kprintf("Failed to create process.\n"); - return; - } + Assembly *assembly = machine.load(mainAssembly.ptr, mainAssembly.size); + if(assembly == nullptr) { + kprintf("failed to load assembly :(\n"); + return; + } - Thread *mainThread = irqService->mainThread(); + Process *irqService = machine.createProcess(assembly, true); + if(irqService == nullptr) { + kprintf("Failed to create process.\n"); + return; + } - uint32_t irqRoutine = irqService->assembly()->exports()["irq"]; + Thread *mainThread = irqService->mainThread(); - bool osIsFailed = false; + uint32_t irqRoutine = irqService->assembly()->exports()["irq"]; - while(machine.step()) - { - // check for IRQ requests - do - { - // atomic checking for existing IRQ item - irq_disable(); - bool hasItem = (irqFiFo.read < irqFiFo.write); - irq_enable(); + bool osIsFailed = false; - if(hasItem == false) { - break; // we don't have anything to read - } + while((shutdownRequested == false) && machine.step()) + { + // check for IRQ requests + do + { + // atomic checking for existing IRQ item + irq_disable(); + bool hasItem = (irqFiFo.read < irqFiFo.write); + irq_enable(); - CpuState *cpu = &irqFiFo.items[irqFiFo.read]; + if(hasItem == false) { + break; // we don't have anything to read + } - auto *thread = irqService->createThread(irqRoutine); - thread->start({ - VMValue::Int32(cpu->intr), - csl::createCpuState(cpu) - }); + CpuState *cpu = &irqFiFo.items[irqFiFo.read]; - irqFiFo.read += 1; + /* + Thread *thread = irqService->createThread(irqRoutine); + thread->start({ + VMValue::Int32(cpu->intr), + csl::createCpuState(cpu) + }); + thread->release(); + // */ + irqFiFo.read += 1; - irq_disable(); - // When fifo is emptied, reset list pointers - if(irqFiFo.read == irqFiFo.write) { - irqFiFo.read = 0; - irqFiFo.write = 0; - } - irq_enable(); - } while(true); + irq_disable(); + // When fifo is emptied, reset list pointers + if(irqFiFo.read == irqFiFo.write) { + irqFiFo.read = 0; + irqFiFo.write = 0; + } + irq_enable(); + } while(true); - if(mainThread->isRunning() == false) { - if(osIsFailed == false) { - osIsFailed = true; + if(mainThread->isRunning() == false) { + if(osIsFailed == false) { + osIsFailed = true; - kprintf("OS failed with: %s\n", execptionName(mainThread->exception())); - } - } - } - mainThread->release(); + kprintf("OS failed with: %s\n", execptionName(mainThread->exception())); - irqService->release(); - irqService = nullptr; + shutdownRequested = true; + } + } + } + mainThread->release(); + mainThread = nullptr; - assembly->release(); + irqService->release(); + irqService = nullptr; + assembly->release(); + assembly = nullptr; + } kprintf("\n"); + kprintf("unreleased objects: %d\n", ReferenceCounted::counter); + kprintf("\n"); } diff --git a/traceback.lua b/traceback.lua new file mode 100644 index 0000000..aa0a8dc --- /dev/null +++ b/traceback.lua @@ -0,0 +1,10 @@ +io.write("Input stacktrace from kernel:\n") +local line = io.read("*line") + +for addr in line:gmatch("(%w+)") do +-- io.write(("-"):rep(80).."\n") +-- io.write("address: " .. addr .. "\n") +-- io.write(("-"):rep(80).."\n") +-- os.execute("objdump -d kernel | grep "..addr:lower().." -A 3 -B 10") + os.execute([[objdump -d kernel | grep -i ]]..addr..[[ -B 50 | grep -e ">:$" | tail -n 1 | sed -E "s|.*<(.*)>:|\1|" | c++filt]]) +end