diff --git a/.gitignore b/.gitignore index 058e67a8..1fb154f7 100644 --- a/.gitignore +++ b/.gitignore @@ -6,4 +6,6 @@ initrd/boot/moon.elf kernel/bin/moon.elf initrd/sys/moon.sym initrd/bin/** -apps/bin/** \ No newline at end of file +apps/bin/** +base/usr/include/** +base/usr/lib/** \ No newline at end of file diff --git a/Makefile b/Makefile index 20ab9997..e06ab762 100644 --- a/Makefile +++ b/Makefile @@ -1,12 +1,13 @@ -build: $(LUNA_ROOT)/kernel/bin/moon.elf apps-build +build: $(LUNA_ROOT)/kernel/bin/moon.elf apps-build libc-build -clean: moon-clean initrd-clean apps-clean +clean: moon-clean initrd-clean apps-clean libc-clean initrd-clean: rm -f $(LUNA_ROOT)/initrd/boot/moon.elf $(LUNA_ROOT)/Luna.iso rm -rf $(LUNA_ROOT)/initrd/bin -install: $(LUNA_ROOT)/initrd/boot/moon.elf apps-install +install: $(LUNA_ROOT)/initrd/boot/moon.elf apps-install libc-install include kernel/Makefile -include apps/Makefile \ No newline at end of file +include apps/Makefile +include libs/libc/Makefile \ No newline at end of file diff --git a/libs/libc/Makefile b/libs/libc/Makefile new file mode 100644 index 00000000..e48f0f1d --- /dev/null +++ b/libs/libc/Makefile @@ -0,0 +1,76 @@ +LIBC_DIR := $(LUNA_ROOT)/libs/libc +LIBC_SRC := $(LIBC_DIR)/src +LIBC_OBJ := $(LIBC_DIR)/lib +LIBC_BIN := $(LIBC_DIR)/bin + +LIBC_CC := x86_64-elf-gcc +LIBC_CXX := x86_64-elf-g++ +LIBC_NASM := nasm +LIBC_AR := x86_64-elf-ar + +LIBC_CFLAGS := -Wall -Wextra -Werror -Os -ffreestanding -nostdlib -fno-omit-frame-pointer -mno-mmx -mno-sse -mno-sse2 -I$(LIBC_DIR)/include -isystem $(LIBC_DIR)/include +LIBC_CXXFLAGS := -fno-rtti -fno-exceptions +LIBC_NASMFLAGS := -felf64 + +rwildcard=$(foreach d,$(wildcard $(1:=/*)),$(call rwildcard,$d,$2) $(filter $(subst *,%,$2),$d)) + +LIBC_CXX_SRC = $(call rwildcard,$(LIBC_SRC),*.cpp) +LIBC_C_SRC = $(call rwildcard,$(LIBC_SRC),*.c) +LIBC_NASM_SRC = $(call rwildcard,$(LIBC_SRC),*.asm) + +LIBC_OBJS = $(patsubst $(LIBC_SRC)/%.cpp, $(LIBC_OBJ)/%.cpp.o, $(LIBC_CXX_SRC)) +LIBC_OBJS += $(patsubst $(LIBC_SRC)/%.c, $(LIBC_OBJ)/%.c.o, $(LIBC_C_SRC)) +LIBC_OBJS += $(patsubst $(LIBC_SRC)/%.asm, $(LIBC_OBJ)/%.asm.o, $(LIBC_NASM_SRC)) + +$(LIBC_OBJ)/%.cpp.o: $(LIBC_SRC)/%.cpp + @mkdir -p $(@D) + $(LIBC_CXX) $(LIBC_CFLAGS) $(LIBC_CXXFLAGS) -o $@ -c $^ + +$(LIBC_OBJ)/%.c.o: $(LIBC_SRC)/%.c + @mkdir -p $(@D) + $(LIBC_CC) $(LIBC_CFLAGS) -o $@ -c $^ + +$(LIBC_OBJ)/%.asm.o: $(LIBC_SRC)/%.asm + @mkdir -p $(@D) + $(LIBC_NASM) $(LIBC_NASMFLAGS) -o $@ $^ + +$(LIBC_BIN)/libc.a: $(LIBC_OBJS) + @mkdir -p $(@D) + $(LIBC_AR) rcs $@ $(LIBC_OBJS) + +$(LIBC_BIN)/crt0.o: $(LIBC_DIR)/crt0.asm + @mkdir -p $(@D) + $(LIBC_NASM) $(LIBC_NASMFLAGS) -o $@ $^ + +$(LIBC_BIN)/crti.o: $(LIBC_DIR)/crti.asm + @mkdir -p $(@D) + $(LIBC_NASM) $(LIBC_NASMFLAGS) -o $@ $^ + +$(LIBC_BIN)/crtn.o: $(LIBC_DIR)/crtn.asm + @mkdir -p $(@D) + $(LIBC_NASM) $(LIBC_NASMFLAGS) -o $@ $^ + +libc-build: $(LIBC_BIN)/crt0.o $(LIBC_BIN)/crti.o $(LIBC_BIN)/crtn.o $(LIBC_BIN)/libc.a + +$(LUNA_ROOT)/base/usr/lib/libc.a: $(LIBC_BIN)/libc.a + @mkdir -p $(@D) + cp $^ $@ + +$(LUNA_ROOT)/base/usr/lib/crt0.o: $(LIBC_BIN)/crt0.o + @mkdir -p $(@D) + cp $^ $@ + +$(LUNA_ROOT)/base/usr/lib/crti.o: $(LIBC_BIN)/crti.o + @mkdir -p $(@D) + cp $^ $@ + +$(LUNA_ROOT)/base/usr/lib/crtn.o: $(LIBC_BIN)/crtn.o + @mkdir -p $(@D) + cp $^ $@ + +libc-install: $(LUNA_ROOT)/base/usr/lib/libc.a $(LUNA_ROOT)/base/usr/lib/crt0.o $(LUNA_ROOT)/base/usr/lib/crti.o $(LUNA_ROOT)/base/usr/lib/crtn.o + +libc-clean: + rm -rf $(LIBC_OBJ)/* + rm -rf $(LIBC_BIN)/* + rm -f $(LUNA_ROOT)/base/usr/lib/libc.a \ No newline at end of file diff --git a/libs/libc/bin/libc.a b/libs/libc/bin/libc.a new file mode 100644 index 00000000..e9905a6c Binary files /dev/null and b/libs/libc/bin/libc.a differ diff --git a/libs/libc/crt0.asm b/libs/libc/crt0.asm new file mode 100644 index 00000000..be8192e0 --- /dev/null +++ b/libs/libc/crt0.asm @@ -0,0 +1,29 @@ +section .text + +extern _init +extern main +extern _fini +extern exit + +global _start +_start: + ; Set up end of the stack frame linked list. + xor rbp, rbp + push rbp ; rip=0 + push rbp ; rbp=0 + mov rbp, rsp + + call _init + + mov rdi, 0 ; argc = 0 + mov rsi, 0 ; argv = 0 + + call main + + push rax + + call _fini + + pop rdi + + call exit \ No newline at end of file diff --git a/libs/libc/crti.asm b/libs/libc/crti.asm new file mode 100644 index 00000000..6b5aed06 --- /dev/null +++ b/libs/libc/crti.asm @@ -0,0 +1,11 @@ +section .init +global _init +_init: + push rbp + mov rbp, rsp + +section .fini +global _fini +_fini: + push rbp + mov rbp, rsp \ No newline at end of file diff --git a/libs/libc/crtn.asm b/libs/libc/crtn.asm new file mode 100644 index 00000000..5d8b3e55 --- /dev/null +++ b/libs/libc/crtn.asm @@ -0,0 +1,7 @@ +section .init + pop rbp + ret + +section .fini + pop rbp + ret \ No newline at end of file diff --git a/libs/libc/include/errno.h b/libs/libc/include/errno.h new file mode 100644 index 00000000..e69de29b diff --git a/libs/libc/include/luna/syscall.h b/libs/libc/include/luna/syscall.h new file mode 100644 index 00000000..938008f0 --- /dev/null +++ b/libs/libc/include/luna/syscall.h @@ -0,0 +1,17 @@ +#ifndef _SYSCALL_H +#define _SYSCALL_H + +#define SYS_exit 0 + +#ifdef __cplusplus +extern "C" +{ +#endif + + void __syscall0(int sys_num); + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/libs/libc/include/stdio.h b/libs/libc/include/stdio.h new file mode 100644 index 00000000..6baf5713 --- /dev/null +++ b/libs/libc/include/stdio.h @@ -0,0 +1,36 @@ +#ifndef _STDIO_H +#define _STDIO_H + +#include +#include + +#define SEEK_SET 0 + +typedef struct +{ + int unused; +} FILE; + +#ifdef __cplusplus +extern "C" +{ +#endif + + extern FILE* stderr; +#define stderr stderr + int fclose(FILE*); + int fflush(FILE*); + FILE* fopen(const char*, const char*); + int fprintf(FILE*, const char*, ...); + size_t fread(void*, size_t, size_t, FILE*); + int fseek(FILE*, long, int); + long ftell(FILE*); + size_t fwrite(const void*, size_t, size_t, FILE*); + void setbuf(FILE*, char*); + int vfprintf(FILE*, const char*, va_list); + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/libs/libc/include/stdlib.h b/libs/libc/include/stdlib.h new file mode 100644 index 00000000..7c27024d --- /dev/null +++ b/libs/libc/include/stdlib.h @@ -0,0 +1,25 @@ +#ifndef _STDLIB_H +#define _STDLIB_H + +#include + +#define noreturn __attribute__((noreturn)) + +#ifdef __cplusplus +extern "C" +{ +#endif + + noreturn void abort(); + noreturn void exit(int); + int atexit(void (*)(void)); + int atoi(const char*); + void free(void*); + char* getenv(const char*); + void* malloc(size_t); + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/libs/libc/include/string.h b/libs/libc/include/string.h new file mode 100644 index 00000000..a20b2fe7 --- /dev/null +++ b/libs/libc/include/string.h @@ -0,0 +1,23 @@ +#ifndef _STRING_H +#define _STRING_H + +#include + +#ifdef __cplusplus +extern "C" +{ +#endif + + void* memcpy(void*, const void*, size_t); + void* memset(void*, int, size_t); + char* strcpy(char*, const char*); + size_t strlen(const char*); + char* strcpy(char*, const char*); + char* strchr(const char*, int); + char* strcat(char*, const char*); + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/libs/libc/include/sys/types.h b/libs/libc/include/sys/types.h new file mode 100644 index 00000000..6147106a --- /dev/null +++ b/libs/libc/include/sys/types.h @@ -0,0 +1,4 @@ +#ifndef _SYS_TYPES_H +#define _SYS_TYPES_H +typedef long int pid_t; +#endif \ No newline at end of file diff --git a/libs/libc/include/time.h b/libs/libc/include/time.h new file mode 100644 index 00000000..e69de29b diff --git a/libs/libc/include/unistd.h b/libs/libc/include/unistd.h new file mode 100644 index 00000000..cdc2e435 --- /dev/null +++ b/libs/libc/include/unistd.h @@ -0,0 +1,15 @@ +#ifndef _UNISTD_H +#define _UNISTD_H +#include +#ifdef __cplusplus +extern "C" +{ +#endif + int execv(const char*, char* const[]); + int execve(const char*, char* const[], char* const[]); + int execvp(const char*, char* const[]); + pid_t fork(void); +#ifdef __cplusplus +} +#endif +#endif \ No newline at end of file diff --git a/libs/libc/src/luna/syscall.cpp b/libs/libc/src/luna/syscall.cpp new file mode 100644 index 00000000..3328d381 --- /dev/null +++ b/libs/libc/src/luna/syscall.cpp @@ -0,0 +1,10 @@ +#include +#include + +extern "C" +{ + void __syscall0(int sys_num) + { + asm volatile("int $0x42" : : "a"(sys_num)); + } +} \ No newline at end of file diff --git a/libs/libc/src/stdio.cpp b/libs/libc/src/stdio.cpp new file mode 100644 index 00000000..0b548b8e --- /dev/null +++ b/libs/libc/src/stdio.cpp @@ -0,0 +1,45 @@ +#include + +extern "C" +{ + int fclose(FILE*) + { + return -1; + } + int fflush(FILE*) + { + return -1; + } + FILE* fopen(const char*, const char*) + { + return 0; + } + int fprintf(FILE*, const char*, ...) + { + return -1; + } + size_t fread(void*, size_t, size_t, FILE*) + { + return 0; + } + int fseek(FILE*, long, int) + { + return -1; + } + long ftell(FILE*) + { + return -1; + } + size_t fwrite(const void*, size_t, size_t, FILE*) + { + return 0; + } + void setbuf(FILE*, char*) + { + return; + } + int vfprintf(FILE*, const char*, va_list) + { + return -1; + } +} \ No newline at end of file diff --git a/libs/libc/src/stdlib.cpp b/libs/libc/src/stdlib.cpp new file mode 100644 index 00000000..31f7d6a5 --- /dev/null +++ b/libs/libc/src/stdlib.cpp @@ -0,0 +1,40 @@ +#include +#include + +#define maybe_unused __attribute__((maybe_unused)) +#define unused __attribute__((unused)) + +extern "C" +{ + noreturn void abort() + { + exit(-1); + } + + noreturn void exit(int) + { + __syscall0(SYS_exit); + __builtin_unreachable(); + } + + int atexit(void (*)(void)) + { + return -1; + } + int atoi(const char*) + { + return 0; + } + void free(void*) + { + return; + } + char* getenv(const char*) + { + return 0; + } + void* malloc(size_t) + { + return 0; + } +} \ No newline at end of file diff --git a/libs/libc/src/string.cpp b/libs/libc/src/string.cpp new file mode 100644 index 00000000..d776c0e5 --- /dev/null +++ b/libs/libc/src/string.cpp @@ -0,0 +1,47 @@ +#include + +extern "C" +{ + void* memcpy(void* dest, const void* src, size_t n) + { + for (size_t i = 0; i < n; ++i) { *((char*)dest + i) = *((char*)src + i); } + return dest; + } + + void* memset(void* dest, int c, size_t n) + { + for (size_t i = 0; i < n; ++i) { *((char*)dest + i) = (char)c; } + return dest; + } + + size_t strlen(const char* s) + { + const char* i = s; + for (; *i; ++i) + ; + return (i - s); + } + + char* strcpy(char* dest, const char* src) + { + memcpy(dest, src, strlen(src) + 1); + return dest; + } + + char* strcat(char* dest, const char* src) + { + size_t dest_len = strlen(dest); + size_t i; + + for (i = 0; *(src + i); i++) *(char*)(dest + dest_len + i) = *(char*)(src + i); + + *(char*)(dest + dest_len + i) = '\0'; + + return dest; + } + + char* strchr(const char*, int) + { + return 0; + } +} \ No newline at end of file diff --git a/libs/libc/src/unistd.cpp b/libs/libc/src/unistd.cpp new file mode 100644 index 00000000..7e2dc820 --- /dev/null +++ b/libs/libc/src/unistd.cpp @@ -0,0 +1,21 @@ +#include + +extern "C" +{ + int execv(const char*, char* const[]) + { + return -1; + } + int execve(const char*, char* const[], char* const[]) + { + return -1; + } + int execvp(const char*, char* const[]) + { + return -1; + } + pid_t fork(void) + { + return -1; + } +} \ No newline at end of file diff --git a/tools/install-headers.sh b/tools/install-headers.sh new file mode 100755 index 00000000..26b7d736 --- /dev/null +++ b/tools/install-headers.sh @@ -0,0 +1,13 @@ +#!/bin/sh + +set -e +source $(dirname $0)/env.sh + +cd $LUNA_ROOT + +mkdir -p base +mkdir -p base/usr/include +mkdir -p base/usr/include/moon + +cp -RT libs/libc/include base/usr/include +cp -RT kernel/include base/usr/include/moon \ No newline at end of file