diff --git a/yak-kernel/CMakeLists.txt b/yak-kernel/CMakeLists.txt index 257e32d..8faf2c0 100644 --- a/yak-kernel/CMakeLists.txt +++ b/yak-kernel/CMakeLists.txt @@ -67,12 +67,22 @@ if (NOT IS_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/src/platform/${CMAKE_SYSTEM_PRO message(FATAL_ERROR "Unknown architecture ${CMAKE_CURRENT_SOURCE_DIR}/src/platform/${CMAKE_SYSTEM_PROCESSOR}") endif () -file(GLOB PLATFORM_SPECIFIC_SOURCES src/platform/x86_64/*.c) +file(GLOB PLATFORM_SPECIFIC_SOURCES src/platform/${CMAKE_SYSTEM_PROCESSOR}/*.c) +file(GLOB PLATFORM_SPECIFIC_ASM_SOURCES src/platform/${CMAKE_SYSTEM_PROCESSOR}/*.asm) + +file(GLOB CRTI src/platform/generic/crt/crti.c) +file(GLOB CRTN src/platform/generic/crt/crtn.c) # Define aggregate sources -set(KERNEL_SOURCE_FILES ${KERNEL_SOURCES} ${LIMINE_KERNEL_SOURCES} ${PLATFORM_GENERIC_SOURCES} ${PLATFORM_SPECIFIC_SOURCES}) +set(KERNEL_SOURCE_FILES + ${KERNEL_SOURCES} + ${LIMINE_KERNEL_SOURCES} + ${PLATFORM_GENERIC_SOURCES} + ${PLATFORM_SPECIFIC_SOURCES} + ${PLATFORM_SPECIFIC_ASM_SOURCES} +) # Define executable -add_executable(yak.elf ${KERNEL_SOURCE_FILES}) +add_executable(yak.elf ${CRTI} ${KERNEL_SOURCE_FILES} ${CRTN}) target_link_libraries(yak.elf PRIVATE ${BUILTINS_LIB}) target_include_directories(yak.elf PRIVATE include ../limine/include ${printf_library_SOURCE_DIR}/src)# ${printf_library_SOURCE_DIR}/src) \ No newline at end of file diff --git a/yak-kernel/include/yak/platform/generic/platform.h b/yak-kernel/include/yak/platform/generic/platform.h index 39a8283..9583e56 100644 --- a/yak-kernel/include/yak/platform/generic/platform.h +++ b/yak-kernel/include/yak/platform/generic/platform.h @@ -5,6 +5,18 @@ #ifndef YAK_PLATFORM_H #define YAK_PLATFORM_H +#if __x86_64__ || __x86_64 +#define HAS_INIT +#endif + +#ifdef HAS_INIT +void _init(); +void _fini(); +#else +#define _init +#define _fini +#endif + void platform_init(); void __attribute__((noreturn)) halt_forever(); diff --git a/yak-kernel/linker.lds b/yak-kernel/linker.lds index 10399e8..6a403a0 100644 --- a/yak-kernel/linker.lds +++ b/yak-kernel/linker.lds @@ -23,6 +23,8 @@ SECTIONS . = 0xffffffff80000000; .text : { + *(.init) + *(.fini) *(.text .text.*) } :text @@ -33,6 +35,20 @@ SECTIONS *(.rodata .rodata.*) } :rodata + /* Include the list of initialization functions sorted. */ + .init_array : + { + KEEP (*(.init_array.*)) + KEEP (*(.init_array)) + } :rodata + + /* Include the list of termination functions sorted. */ + .fini_array : + { + KEEP (*(SORT(.fini_array.*))) + KEEP (*(.fini_array)) + } :rodata + /* Move to the next memory page for .data */ . += CONSTANT(MAXPAGESIZE); diff --git a/yak-kernel/src/platform/generic/crt/crti.c b/yak-kernel/src/platform/generic/crt/crti.c new file mode 100644 index 0000000..1af732c --- /dev/null +++ b/yak-kernel/src/platform/generic/crt/crti.c @@ -0,0 +1,21 @@ +// +// Created by rick on 9-5-23. +// +// Based upon https://wiki.osdev.org/Calling_Global_Constructors +typedef void (*func_ptr)(void); + +extern func_ptr _init_array_start[0], _init_array_end[0]; +extern func_ptr _fini_array_start[0], _fini_array_end[0]; + +void _init(void) { + for (func_ptr *func = _init_array_start; func != _init_array_end; func++) + (*func)(); +} + +void _fini(void) { + for (func_ptr *func = _fini_array_start; func != _fini_array_end; func++) + (*func)(); +} + +func_ptr _init_array_start[0] __attribute__ ((used, section(".init_array"), aligned(sizeof(func_ptr)))) = {}; +func_ptr _fini_array_start[0] __attribute__ ((used, section(".fini_array"), aligned(sizeof(func_ptr)))) = {}; \ No newline at end of file diff --git a/yak-kernel/src/platform/generic/crt/crtn.c b/yak-kernel/src/platform/generic/crt/crtn.c new file mode 100644 index 0000000..a7b0df6 --- /dev/null +++ b/yak-kernel/src/platform/generic/crt/crtn.c @@ -0,0 +1,7 @@ +// +// Created by rick on 9-5-23. +// +typedef void (*func_ptr)(void); + +func_ptr _init_array_end[0] __attribute__ ((used, section(".init_array"), aligned(sizeof(func_ptr)))) = {}; +func_ptr _fini_array_end[0] __attribute__ ((used, section(".fini_array"), aligned(sizeof(func_ptr)))) = {}; \ No newline at end of file diff --git a/yak-kernel/src/rt/kmain.c b/yak-kernel/src/rt/kmain.c index 36bc581..829156d 100644 --- a/yak-kernel/src/rt/kmain.c +++ b/yak-kernel/src/rt/kmain.c @@ -3,6 +3,7 @@ #include "yak/platform/generic/platform.h" void kmain() { + _init(); // kmain is called from one of the bootloader implementations // perform platform specific initialisation @@ -10,4 +11,5 @@ void kmain() { // this should (eventually) be unreachable panic("End of kmain"); + _fini(); } \ No newline at end of file