diff --git a/kernel/Makefile b/kernel/Makefile index 9fb8f275..098181ef 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -1,4 +1,5 @@ CC=x86_64-elf-g++ +AS=x86_64-elf-as WARNING_FLAGS=-Wall -Wextra -pedantic -Wold-style-cast -Wshadow CPP_FLAGS=-masm=intel -Iinclude/ -nostdlib -O1 -std=c++11 -fno-exceptions -fno-rtti -ffreestanding -mno-red-zone -mno-mmx -mno-sse -mno-sse2 -mno-sse3 -mno-3dnow $(WARNING_FLAGS) @@ -10,13 +11,18 @@ KERNEL_O_FILES=kernel.o keyboard.o console.o kernel_utils.o timer.o shell.o util CRTBEGIN_OBJ:=$(shell $(CC) $(CFLAGS) -print-file-name=crtbegin.o) CRTEND_OBJ:=$(shell $(CC) $(CFLAGS) -print-file-name=crtend.o) -LINK_O_FILES=$(KERNEL_O_FILES) - +LINK_O_FILES=crti.o $(CRTBEGIN_OBJ) $(KERNEL_O_FILES) $(CRTEND_OBJ) crtn.o kernel.bin: $(LINK_O_FILES) $(CC) $(KERNEL_LINK_FLAGS) -o kernel.bin.o $(LINK_O_FILES) objcopy -R .note -R .comment -S -O binary kernel.bin.o kernel.bin +crti.o: src/crti.s + $(AS) -c src/crti.s -o crti.o + +crtn.o: src/crtn.s + $(AS) -c src/crtn.s -o crtn.o + kernel.o: src/kernel.cpp $(CC) $(KERNEL_FLAGS) -c src/kernel.cpp -o kernel.o diff --git a/kernel/include/keyboard.hpp b/kernel/include/keyboard.hpp index e840dc39..b44597f1 100644 --- a/kernel/include/keyboard.hpp +++ b/kernel/include/keyboard.hpp @@ -14,6 +14,7 @@ namespace keyboard { const char KEY_ENTER = 0x1C; const char KEY_BACKSPACE = 0x0E; +const char KEY_UP = 0x48; void install_driver(); char get_char(); diff --git a/kernel/include/thor.hpp b/kernel/include/thor.hpp index a6223a99..0c99dd2e 100644 --- a/kernel/include/thor.hpp +++ b/kernel/include/thor.hpp @@ -16,4 +16,21 @@ void operator delete(void* p); void* operator new[](uint64_t size); void operator delete[](void* p); +#define ATEXIT_MAX_FUNCS 128 + +extern "C" { + +typedef int uarch_t; + +struct atexit_func_entry_t { + void (*destructor_func)(void *); + void *obj_ptr; + void *dso_handle; +}; + +int __cxa_atexit(void (*f)(void *), void *objptr, void *dso); +void __cxa_finalize(void *f); + +} + #endif diff --git a/kernel/include/vector.hpp b/kernel/include/vector.hpp index d4b8971a..0b3da91c 100644 --- a/kernel/include/vector.hpp +++ b/kernel/include/vector.hpp @@ -40,6 +40,8 @@ public: rhs.data = nullptr; rhs._size = 0; rhs._capacity = 0; + + return *this; } ~vector(){ @@ -54,6 +56,10 @@ public: return _size; } + size_type capacity(){ + return _capacity; + } + //Modifiers void push_back(value_type& element){ diff --git a/kernel/src/crti.s b/kernel/src/crti.s new file mode 100644 index 00000000..1e7865e9 --- /dev/null +++ b/kernel/src/crti.s @@ -0,0 +1,18 @@ +/* x86_64 crti.s */ +.section .init +.global _init +.type _init, @function +_init: +push %rbp +movq %rsp, %rbp + +/* gcc will nicely put the contents of crtbegin.o's .init section here. */ + +.section .fini +.global _fini +.type _fini, @function +_fini: +push %rbp +movq %rsp, %rbp + +/* gcc will nicely put the contents of crtbegin.o's .fini section here. */ diff --git a/kernel/src/crtn.s b/kernel/src/crtn.s new file mode 100644 index 00000000..4bb8e0c5 --- /dev/null +++ b/kernel/src/crtn.s @@ -0,0 +1,11 @@ +/* x86_64 crtn.s */ + +.section .init + /* gcc will nicely put the contents of crtend.o's .init section here. */ + popq %rbp + ret + +.section .fini + /* gcc will nicely put the contents of crtend.o's .fini section here. */ + popq %rbp + ret diff --git a/kernel/src/kernel.cpp b/kernel/src/kernel.cpp index 9421e8e5..bf534ea7 100644 --- a/kernel/src/kernel.cpp +++ b/kernel/src/kernel.cpp @@ -13,12 +13,17 @@ extern "C" { +void _init(); + void __attribute__ ((section ("main_section"))) kernel_main(){ load_memory_map(); init_memory_manager(); install_timer(); keyboard::install_driver(); disks::detect_disks(); + + _init(); + init_shell(); return; diff --git a/kernel/src/shell.cpp b/kernel/src/shell.cpp index 32b8ec5d..7f709cf1 100644 --- a/kernel/src/shell.cpp +++ b/kernel/src/shell.cpp @@ -14,9 +14,12 @@ #include "utils.hpp" #include "memory.hpp" #include "disks.hpp" +#include "vector.hpp" namespace { +vector history; + //Declarations of the different functions void reboot_command(const char* params); @@ -84,6 +87,8 @@ void start_shell(){ } k_print("thor> "); + } else if(key == keyboard::KEY_UP){ + //TODO } else if(key == keyboard::KEY_BACKSPACE){ if(current_input_length > 0){ k_print('\b'); @@ -386,6 +391,7 @@ void init_shell(){ clear_command(0); k_print("thor> "); + k_print_line(history.capacity()); start_shell(); } diff --git a/kernel/src/thor.cpp b/kernel/src/thor.cpp index 55f72c8f..4135f153 100644 --- a/kernel/src/thor.cpp +++ b/kernel/src/thor.cpp @@ -23,3 +23,43 @@ void* operator new[](uint64_t size){ void operator delete[](void* p){ return k_free(p); } + +extern "C" { + +atexit_func_entry_t __atexit_funcs[ATEXIT_MAX_FUNCS]; +uarch_t __atexit_func_count = 0; + +int __cxa_atexit(void (*f)(void *), void *objptr, void *dso){ + if (__atexit_func_count >= ATEXIT_MAX_FUNCS) { + return -1; + } + __atexit_funcs[__atexit_func_count].destructor_func = f; + __atexit_funcs[__atexit_func_count].obj_ptr = objptr; + __atexit_funcs[__atexit_func_count].dso_handle = dso; + __atexit_func_count++; + return 0; /*I would prefer if functions returned 1 on success, but the ABI says...*/ +} + +void __cxa_finalize(void *f){ + uarch_t i = __atexit_func_count; + if (!f){ + while (i--){ + if (__atexit_funcs[i].destructor_func){ + (*__atexit_funcs[i].destructor_func)(__atexit_funcs[i].obj_ptr); + } + } + return; + } + + for ( ; i >= 0; --i){ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wpedantic" + if (__atexit_funcs[i].destructor_func == f){ + (*__atexit_funcs[i].destructor_func)(__atexit_funcs[i].obj_ptr); + __atexit_funcs[i].destructor_func = 0; + } +#pragma GCC diagnostic pop + } +} + +}