adding support to global constructors

Adding suuport to global construcors as per
https://wiki.osdev.org/Calling_Global_Constructors
This commit is contained in:
brenozd
2024-10-29 09:43:13 -03:00
parent c54d8df483
commit 6cd0ae1ccd
9 changed files with 112 additions and 21 deletions

View File

@@ -1,3 +1,4 @@
# To include `version.h`
include_directories("${CMAKE_CURRENT_SOURCE_DIR}") include_directories("${CMAKE_CURRENT_SOURCE_DIR}")
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/kernel/) add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/kernel)

View File

@@ -1,10 +1,34 @@
add_executable(appa-os kernel.c) # Dummy `null.c` so we can create an OBJ lib from kernel.c and link in the correct order
execute_process(COMMAND ${PROJECT_SOURCE_DIR}/scripts/versioning.sh WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/null.c" "int main() { return 0; }")
OUTPUT_VARIABLE appa-os_VERSION) add_executable(${PROJECT_NAME} "${CMAKE_CURRENT_BINARY_DIR}/null.c")
message(STATUS "Building [appa-os] version ${appa-os_VERSION}") # Execute versioning script
execute_process(COMMAND ${PROJECT_SOURCE_DIR}/scripts/versioning.sh WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
OUTPUT_VARIABLE ${PROJECT_NAME}_VERSION)
# Set target name to be "${PROJECT_NAME}.bin"
set_target_properties(${PROJECT_NAME} PROPERTIES PREFIX "")
set_target_properties(${PROJECT_NAME} PROPERTIES OUTPUT_NAME "${PROJECT_NAME}")
set_target_properties(${PROJECT_NAME} PROPERTIES SUFFIX ".bin")
message(STATUS "Building [${PROJECT_NAME}] version ${${PROJECT_NAME}_VERSION}")
# Set linking options to link kernel bin
target_link_options(
${PROJECT_NAME}
PRIVATE
-T
${CMAKE_CURRENT_SOURCE_DIR}/linker.ld
-ffreestanding
-O2
-nostdlib)
# OBJ library to link in the correct order
add_library(${PROJECT_NAME}-obj OBJECT ${CMAKE_CURRENT_SOURCE_DIR}/kernel.c)
# Set compile options to have better code on .c and .h files
target_compile_options( target_compile_options(
appa-os ${PROJECT_NAME}-obj
PRIVATE PRIVATE
$<$<COMPILE_LANGUAGE:C>: $<$<COMPILE_LANGUAGE:C>:
# Do not assume that libc standard is present # Do not assume that libc standard is present
@@ -32,21 +56,19 @@ target_compile_options(
"-Werror=implicit" "-Werror=implicit"
"-Werror=incompatible-pointer-types" "-Werror=incompatible-pointer-types"
"-Werror=int-conversion">) "-Werror=int-conversion">)
target_link_options(
appa-os
PRIVATE
-T
${CMAKE_CURRENT_SOURCE_DIR}/linker.ld
-ffreestanding
-O2
-nostdlib)
set_target_properties(appa-os PROPERTIES PREFIX "")
set_target_properties(appa-os PROPERTIES OUTPUT_NAME "appa-os")
set_target_properties(appa-os PROPERTIES SUFFIX ".bin")
file(GLOB ASM_FILES CONFIGURE_DEPENDS *.s) # Gather all .c and .h to generate kernel object files
file(GLOB C_FILES CONFIGURE_DEPENDS *.c) file(GLOB C_FILES CONFIGURE_DEPENDS *.c)
file(GLOB H_FILES CONFIGURE_DEPENDS *.h) file(GLOB H_FILES CONFIGURE_DEPENDS *.h)
target_sources(appa-os PRIVATE ${C_FILES} ${ASM_FILES} PUBLIC ${H_FILES}) target_sources(${PROJECT_NAME}-kernel PRIVATE ${C_FILES} PUBLIC ${H_FILES})
target_include_directories(appa-os PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) target_include_directories(${PROJECT_NAME}-kernel PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
# Add complementary files
add_subdirectory("${CMAKE_CURRENT_SOURCE_DIR}/boot")
add_subdirectory("${CMAKE_CURRENT_SOURCE_DIR}/crt")
# Make sure to build boot and CRT before the kernel itself
# https://wiki.osdev.org/Calling_Global_Constructors#GNU_Compiler_Collection_-_System_V_ABI
target_link_libraries(${PROJECT_NAME} PRIVATE ${PROJECT_NAME}-crti ${PROJECT_NAME}-crtbegin ${PROJECT_NAME}-boot
${PROJECT_NAME}-kernel ${PROJECT_NAME}-crtend ${PROJECT_NAME}-crtn)

View File

@@ -0,0 +1,6 @@
add_library(${PROJECT_NAME}-boot OBJECT)
file(GLOB ASM_FILES CONFIGURE_DEPENDS *.s)
target_sources(${PROJECT_NAME}-boot PRIVATE ${ASM_FILES})
target_include_directories(${PROJECT_NAME}-boot PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})

View File

@@ -0,0 +1,28 @@
# Gather crtbegin.o and crtend.o from toolchain
execute_process(
COMMAND ${CMAKE_C_COMPILER} -print-file-name=crtbegin.o
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
OUTPUT_VARIABLE CRTBEGIN_O
OUTPUT_STRIP_TRAILING_WHITESPACE)
message(STATUS "Using crtbegin.o as ${CRTBEGIN_O}")
add_library(${PROJECT_NAME}-crtbegin OBJECT IMPORTED GLOBAL)
set_property(TARGET ${PROJECT_NAME}-crtbegin PROPERTY IMPORTED_OBJECTS ${CRTBEGIN_O})
execute_process(
COMMAND ${CMAKE_C_COMPILER} -print-file-name=crtend.o
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
OUTPUT_VARIABLE CRTEND_O
OUTPUT_STRIP_TRAILING_WHITESPACE)
message(STATUS "Using crtend.o as ${CRTEND_O}")
add_library(${PROJECT_NAME}-crtend OBJECT IMPORTED GLOBAL)
set_property(TARGET ${PROJECT_NAME}-crtend PROPERTY IMPORTED_OBJECTS ${CRTEND_O})
# Build own crt
if(CMAKE_SYSTEM_PROCESSOR MATCHES "(i686)|(x86)|(X86)|(amd64)|(AMD64)")
add_subdirectory("${CMAKE_CURRENT_SOURCE_DIR}/x86")
add_library(${PROJECT_NAME}-crti ALIAS ${PROJECT_NAME}-crti-x86)
add_library(${PROJECT_NAME}-crtn ALIAS ${PROJECT_NAME}-crtn-x86)
else()
message(FATAL_ERROR "Unsupported CRT for ${CMAKE_SYSTEM_PROCESSOR}")
endif()

View File

@@ -0,0 +1,2 @@
add_library(${PROJECT_NAME}-crti-x86 OBJECT crti.s)
add_library(${PROJECT_NAME}-crtn-x86 OBJECT crtn.s)

20
src/kernel/crt/x86/crti.s Normal file
View File

@@ -0,0 +1,20 @@
// x86 crti.s
.section .init
.global _init
.type _init, @function
_init:
push %ebp
movl %esp, %ebp
// gcc will nicely put the contents of crtbegin.o's .init section here.
.section .fini
.global _fini
.type _fini, @function
_fini:
push %ebp
movl %esp, %ebp
// gcc will nicely put the contents of crtbegin.o's .fini section here.

12
src/kernel/crt/x86/crtn.s Normal file
View File

@@ -0,0 +1,12 @@
// x86 crtn.s
.section .init
// gcc will nicely put the contents of crtend.o's .init section here.
popl %ebp
ret
.section .fini
// gcc will nicely put the contents of crtend.o's .fini section here.
popl %ebp
ret

View File

@@ -13,5 +13,5 @@ set(CMAKE_CXX_COMPILER_WORKS TRUE)
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE BOTH) set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)