Switch to C for userspace, with a very bare-bones libc!!
Some checks failed
continuous-integration/drone/push Build is failing

This commit is contained in:
apio 2023-01-06 13:31:14 +01:00
parent b27cefb9c5
commit 129e3c434a
Signed by: apio
GPG Key ID: B8A7D06E42258954
21 changed files with 339 additions and 36 deletions

1
.gitignore vendored
View File

@ -4,3 +4,4 @@ build/
initrd/boot/moon
env-local.sh
initrd/bin/**
base/

View File

@ -5,9 +5,10 @@ set(CMAKE_CXX_COMPILER_WORKS 1)
set(CMAKE_CROSSCOMPILING true)
project(Luna LANGUAGES C CXX ASM_NASM VERSION 0.1.0)
project(Luna LANGUAGES C CXX ASM ASM_NASM VERSION 0.1.0)
set(LUNA_ROOT ${CMAKE_CURRENT_LIST_DIR})
set(LUNA_BASE ${CMAKE_CURRENT_LIST_DIR}/base)
set(ARCH $ENV{ARCH})
@ -17,6 +18,7 @@ endif()
set(CMAKE_C_COMPILER ${ARCH}-luna-gcc)
set(CMAKE_CXX_COMPILER ${ARCH}-luna-g++)
set(CMAKE_ASM_COMPILER ${ARCH}-luna-gcc)
set(CMAKE_ASM_NASM_OBJECT_FORMAT elf64)
@ -27,5 +29,6 @@ set(CMAKE_FIND_ROOT_PATH ${LUNA_ROOT}/toolchain/x86-64-luna)
message(STATUS "Configuring Luna for ${ARCH}")
add_subdirectory(luna)
add_subdirectory(libc)
add_subdirectory(kernel)
add_subdirectory(apps)

View File

@ -1,6 +1,7 @@
function(luna_app SOURCE_FILE APP_NAME)
add_executable(${APP_NAME} ${SOURCE_FILE})
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/${APP_NAME}" DESTINATION ${LUNA_ROOT}/initrd/bin)
add_dependencies(${APP_NAME} libc)
install(TARGETS ${APP_NAME} DESTINATION ${LUNA_ROOT}/initrd/bin)
endfunction()
luna_app(app.asm app)
luna_app(app.c app)

View File

@ -1,17 +0,0 @@
section .text
global _start
_start:
mov rax, 1
mov rdi, message
int 42h
mov rax, 1
mov rdi, message2
int 42h
mov rax, 0
int 42h
section .rodata
message:
db "Hello!", 0xa, 0
message2:
db "I am an app", 0xa, 0

9
apps/app.c Normal file
View File

@ -0,0 +1,9 @@
#include <stdio.h>
#include <stdlib.h>
int main()
{
for (int i = 0; i < strtol("010", NULL, 0); i++) { console_print("."); }
console_print("\n");
}

61
libc/CMakeLists.txt Normal file
View File

@ -0,0 +1,61 @@
file(GLOB HEADERS include/*.h)
set(SOURCES
${HEADERS}
src/stdio.cpp
src/stdlib.cpp
src/unistd.cpp
)
if(${ARCH} STREQUAL "x86_64")
set(SOURCES
${SOURCES}
src/arch/x86_64/syscall.S
)
endif()
add_library(crt0 STATIC src/arch/${ARCH}/crt0.S)
add_custom_command(
TARGET crt0
COMMAND "${CMAKE_COMMAND}" -E copy $<TARGET_OBJECTS:crt0> ${LUNA_BASE}/usr/lib/crt0.o
)
add_library(crti STATIC src/arch/${ARCH}/crti.S)
add_custom_command(
TARGET crti
COMMAND "${CMAKE_COMMAND}" -E copy $<TARGET_OBJECTS:crti> ${LUNA_BASE}/usr/lib/crti.o
)
add_library(crtn STATIC src/arch/${ARCH}/crtn.S)
add_custom_command(
TARGET crt0
COMMAND "${CMAKE_COMMAND}" -E copy $<TARGET_OBJECTS:crtn> ${LUNA_BASE}/usr/lib/crtn.o
)
add_library(bare_libc STATIC ${SOURCES})
target_link_libraries(bare_libc PUBLIC luna)
target_include_directories(bare_libc PUBLIC include/)
target_compile_options(bare_libc PRIVATE -Wall -Wextra -Werror -pedantic -nostdlib)
target_link_options(bare_libc PRIVATE -nostdlib)
set_target_properties(bare_libc PROPERTIES CXX_STANDARD 20)
add_custom_target(libc
COMMAND ${CMAKE_AR} -x $<TARGET_FILE:bare_libc>
COMMAND ${CMAKE_AR} -x $<TARGET_FILE:luna>
COMMAND ${CMAKE_AR} -rcs ${CMAKE_CURRENT_BINARY_DIR}/libc.a *.o
COMMAND rm *.o
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
DEPENDS bare_libc luna
)
add_custom_command(
TARGET libc
COMMAND "${CMAKE_COMMAND}" -E copy ${CMAKE_CURRENT_BINARY_DIR}/libc.a ${LUNA_BASE}/usr/lib/libc.a
)
file(WRITE "${LUNA_BASE}/usr/lib/libm.a" "INPUT(libc.a)")

10
libc/include/bits/attrs.h Normal file
View File

@ -0,0 +1,10 @@
#ifndef _BITS_ATTRS_H
#define _BITS_ATTRS_H
#if !defined(_STDLIB_H)
#error "Never include bits/attrs.h directly; use one of the standard library headers."
#endif
#define __noreturn __attribute__((noreturn))
#endif

15
libc/include/stdio.h Normal file
View File

@ -0,0 +1,15 @@
#ifndef _STDIO_H
#define _STDIO_H
#ifdef __cplusplus
extern "C"
{
#endif
void console_print(const char*);
#ifdef __cplusplus
}
#endif
#endif

73
libc/include/stdlib.h Normal file
View File

@ -0,0 +1,73 @@
#ifndef _STDLIB_H
#define _STDLIB_H
#include <bits/attrs.h>
#include <stddef.h>
typedef struct
{
int quot;
int rem;
} div_t;
typedef struct
{
long quot;
long rem;
} ldiv_t;
typedef struct
{
long long quot;
long long rem;
} lldiv_t;
#ifdef __cplusplus
extern "C"
{
#endif
int abs(int);
long labs(long);
long long llabs(long long);
div_t div(int, int);
ldiv_t ldiv(long, long);
lldiv_t lldiv(long long, long long);
void* malloc(size_t);
void* calloc(size_t, size_t);
void* realloc(void*, size_t);
void free(void*);
__noreturn void abort();
int atexit(void (*)(void));
int atoi(const char*);
long atol(const char*);
long long atoll(const char*);
double atof(const char*);
double strtod(const char*, char**);
long strtol(const char*, char**, int);
unsigned long strtoul(const char*, char**, int);
int rand();
void srand(int);
__noreturn void exit(int);
int system(const char*);
char* getenv(const char*);
void qsort(void*, size_t, size_t, int (*)(const void*, const void*));
void* bsearch(const void*, const void*, size_t, size_t, int (*)(const void*, const void*));
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,6 @@
#ifndef _SYS_SYSCALL_H
#define _SYS_SYSCALL_H
#include <luna/Syscall.h>
#endif

9
libc/include/sys/types.h Normal file
View File

@ -0,0 +1,9 @@
#ifndef _SYS_TYPES_H
#define _SYS_TYPES_H
#define __need_size_t
#include <stddef.h>
typedef int pid_t;
#endif

15
libc/include/unistd.h Normal file
View File

@ -0,0 +1,15 @@
#ifndef _UNISTD_H
#define _UNISTD_H
#ifdef __cplusplus
extern "C"
{
#endif
long syscall(long, ...);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,20 @@
.section .text
.global _start
.extern exit
_start:
# Set up end of the stack frame linked list.
movq $0, %rbp
pushq %rbp # rip=0
pushq %rbp # rbp=0
movq %rsp, %rbp
# Run the global constructors.
call _init
# Run main
call main
# Terminate the process with the exit code.
movl %eax, %edi
call exit

View File

@ -0,0 +1,13 @@
.section .init
.global _init
_init:
push %rbp
movq %rsp, %rbp
/* gcc will nicely put the contents of crtbegin.o's .init section here. */
.section .fini
.global _fini
_fini:
push %rbp
movq %rsp, %rbp
/* gcc will nicely put the contents of crtbegin.o's .fini section here. */

View File

@ -0,0 +1,9 @@
.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

View File

@ -0,0 +1,10 @@
.global arch_invoke_syscall
arch_invoke_syscall:
mov %rdi, %rax
mov %rsi, %rdi
mov %rdx, %rsi
mov %rcx, %rdx
mov %r8, %r10
mov %r9, %r8
int $66
ret

11
libc/src/stdio.cpp Normal file
View File

@ -0,0 +1,11 @@
#include <stdio.h>
#include <sys/syscall.h>
#include <unistd.h>
extern "C"
{
void console_print(const char* str)
{
syscall(SYS_console_print, str);
}
}

30
libc/src/stdlib.cpp Normal file
View File

@ -0,0 +1,30 @@
#include <luna/NumberParsing.h>
#include <stdlib.h>
#include <sys/syscall.h>
#include <unistd.h>
extern "C"
{
// FIXME: Check for overflow in both strtol() and strtoul().
long strtol(const char* str, char** endptr, int base)
{
return (long)parse_signed_integer(str, const_cast<const char**>(endptr), base);
}
unsigned long strtoul(const char* str, char** endptr, int base)
{
return (unsigned long)parse_unsigned_integer(str, const_cast<const char**>(endptr), base);
}
__noreturn void abort()
{
syscall(SYS_exit);
__builtin_unreachable();
}
__noreturn void exit(int)
{
syscall(SYS_exit);
__builtin_unreachable();
}
}

26
libc/src/unistd.cpp Normal file
View File

@ -0,0 +1,26 @@
#include <stdarg.h>
#include <stdint.h>
#include <unistd.h>
extern "C" long arch_invoke_syscall(long, uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t);
extern "C"
{
long syscall(long num, ...)
{
va_list ap;
va_start(ap, num);
uintptr_t arg0 = va_arg(ap, uintptr_t);
uintptr_t arg1 = va_arg(ap, uintptr_t);
uintptr_t arg2 = va_arg(ap, uintptr_t);
uintptr_t arg3 = va_arg(ap, uintptr_t);
uintptr_t arg4 = va_arg(ap, uintptr_t);
long rc = arch_invoke_syscall(num, arg0, arg1, arg2, arg3, arg4);
va_end(ap);
return rc;
}
}

View File

@ -36,24 +36,23 @@ target_compile_options(luna-freestanding PRIVATE -nostdlib -mcmodel=kernel)
target_include_directories(luna-freestanding PUBLIC include/)
set_target_properties(luna-freestanding PROPERTIES CXX_STANDARD 20)
#add_library(luna ${SOURCES})
#target_compile_options(luna PRIVATE -Wall -Wextra -Werror -Wvla)
#target_compile_options(luna PRIVATE -Wdisabled-optimization -Wformat=2 -Winit-self)
#target_compile_options(luna PRIVATE -Wmissing-include-dirs -Wswitch-default -Wcast-qual -Wundef)
#target_compile_options(luna PRIVATE -Wcast-align -Wwrite-strings -Wlogical-op -Wredundant-decls -Wshadow -Wconversion)
#target_compile_options(luna PRIVATE -fno-asynchronous-unwind-tables -fno-omit-frame-pointer)
#target_include_directories(luna PUBLIC include/)
#set_target_properties(luna PROPERTIES CXX_STANDARD 20)
add_library(luna ${SOURCES})
target_compile_options(luna PRIVATE -Wall -Wextra -Werror -Wvla)
target_compile_options(luna PRIVATE -Wdisabled-optimization -Wformat=2 -Winit-self)
target_compile_options(luna PRIVATE -Wmissing-include-dirs -Wswitch-default -Wcast-qual -Wundef)
target_compile_options(luna PRIVATE -Wcast-align -Wwrite-strings -Wlogical-op -Wredundant-decls -Wshadow -Wconversion)
target_compile_options(luna PRIVATE -fno-asynchronous-unwind-tables -fno-omit-frame-pointer -std=c++20)
target_include_directories(luna PUBLIC include/)
if("${ARCH}" MATCHES "x86_64")
target_compile_options(luna-freestanding PRIVATE -mno-red-zone)
target_compile_options(luna-freestanding PRIVATE -mno-80387 -mno-mmx -mno-sse -mno-sse2)
target_compile_definitions(luna-freestanding PUBLIC ARCH_X86_64)
#target_compile_definitions(luna PUBLIC ARCH_X86_64)
target_compile_definitions(luna PUBLIC ARCH_X86_64)
endif()
if(LUNA_DEBUG_SYMBOLS)
message(STATUS "Building Luna with debug symbols")
#target_compile_options(luna PRIVATE -ggdb)
target_compile_options(luna PRIVATE -ggdb)
target_compile_options(luna-freestanding PRIVATE -ggdb)
endif()

View File

@ -7,8 +7,7 @@ cd $LUNA_ROOT
mkdir -p $LUNA_BASE
mkdir -p $LUNA_BASE/usr/include
mkdir -p $LUNA_BASE/usr/include/moon
mkdir -p $LUNA_BASE/usr/include/luna
cp -RT kernel/**/*.h $LUNA_BASE/usr/include/moon
cp -RT luna/include/luna/*.h $LUNA_BASE/usr/include/luna
cp -RT libc/include/ $LUNA_BASE/usr/include
cp -RT luna/include/luna/ $LUNA_BASE/usr/include/luna