Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[submodule "lib/newlib-cygwin"]
path = lib/newlib-cygwin
url = https://sourceware.org/git/newlib-cygwin.git
9 changes: 7 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
.PHONY: all kernel clean format user initramfs
.PHONY: all lib kernel clean format user initramfs

all: kernel user initramfs
all: lib kernel user initramfs

kernel:
@echo "Building Kernel..."
Expand All @@ -12,12 +12,17 @@ user_bin:
@echo "Building user binaries..."
$(MAKE) -C user bin

lib:
$(MAKE) -C lib

initramfs: user
@( cd build/initramfs && find . -print | cpio -o -H newc -v ) > build/initramfs.cpio

format:
@echo "Formatting Kernel..."
$(MAKE) -C kernel format
@echo "Formatting Lib..."
$(MAKE) -C lib format
@echo "Formatting User..."
$(MAKE) -C user format

Expand Down
28 changes: 22 additions & 6 deletions build.sh
Original file line number Diff line number Diff line change
@@ -1,12 +1,7 @@
#!/bin/sh

export CC=x86_64-elf-gcc
export CXX=x86_64-elf-g++
export LD=x86_64-elf-ld
export AS=x86_64-elf-as
export AR=x86_64-elf-ar

NPROC=$(getconf _NPROCESSORS_ONLN)
ROOTDIR=$(pwd)

export MAKE=make
if [ "$(uname)" = "Darwin" ]; then
Expand Down Expand Up @@ -102,6 +97,27 @@ if [ "$BUILD_DOCS" = true ]; then
doxygen Doxyfile
fi

heading "Configuring libc" "1;33"

mkdir -p build/lib/newlib
cd build/lib/newlib
../../../lib/newlib-cygwin/configure --target=x86_64-elf --prefix=/usr --disable-multilib

heading "Building libc" "1;33"

$MAKE all -j$NPROC
$MAKE DESTDIR=$(pwd)/../../user tooldir=/usr install

cd "$ROOTDIR"

export CC=x86_64-elf-gcc
export CXX=x86_64-elf-g++
export LD=x86_64-elf-ld
export AS=x86_64-elf-as
export AR=x86_64-elf-ar

$MAKE -j$NPROC lib

heading "Building OS binaries" "1;33"

$MAKE -j$NPROC kernel
Expand Down
15 changes: 15 additions & 0 deletions lib/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
.PHONY: all libcos

all: libcos

libcos:
@echo "Building libcos..."
$(MAKE) -C cos

format:
@echo "Formatting libcos..."
$(MAKE) -C cos format

clean:
@echo "Cleaning libcos..."
$(MAKE) -C cos clean
110 changes: 110 additions & 0 deletions lib/cos/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
# This makefile is quite similar to the one used by the kernel, with
# the exception of some kernel-only flags that have been omitted here

override MAKEFLAGS += -rR
override TARGET := libcos.a

define DEFAULT_VAR =
ifeq ($(origin $1),default)
override $(1) := $(2)
endif
ifeq ($(origin $1),undefined)
override $(1) := $(2)
endif
endef

override DEFAULT_CC := x86_64-elf-gcc
$(eval $(call DEFAULT_VAR,CC,$(DEFAULT_CC)))

override DEFAULT_AR := x86_64-elf-ar
$(eval $(call DEFAULT_VAR,AR,$(DEFAULT_AR)))

override DEFAULT_CFLAGS := -g -O2 -pipe
$(eval $(call DEFAULT_VAR,CFLAGS,$(DEFAULT_CFLAGS)))

# User controllable C preprocessor flags. We set none by default.
override DEFAULT_CPPFLAGS :=
$(eval $(call DEFAULT_VAR,CPPFLAGS,$(DEFAULT_CPPFLAGS)))

# User controllable linker flags. We set none by default.
override DEFAULT_LDFLAGS :=
$(eval $(call DEFAULT_VAR,LDFLAGS,$(DEFAULT_LDFLAGS)))

# Internal C flags that should not be changed by the user.
override CFLAGS += \
-Wall \
-Wextra \
-Wstrict-prototypes \
-Wmissing-prototypes \
-Wmissing-declarations \
-std=gnu23 \
-ffreestanding \
-fno-stack-protector \
-fno-stack-check \
-fno-lto \
-fno-PIE \
-fno-PIC \
-m64 \
-march=x86-64 \
-mabi=sysv

override SYSROOT := $(abspath ../../build/user)

# Internal C preprocessor flags that should not be changed by the user.
override CPPFLAGS := \
-I $(SYSROOT)/usr/include \
-I include \
-I. \
$(CPPFLAGS) \
-MMD \
-MP

# Internal linker flags that should not be changed by the user.
override LDFLAGS += \
-nostdlib \
-static \
-m elf_x86_64 \
-z max-page-size=0x1000

ifeq ($(shell $(LD) --help 2>&1 | grep 'no-pie' >/dev/null 2>&1; echo $$?),0)
override LDFLAGS += -no-pie
endif

override CFILES := $(shell find -L . -type f -name '*.c')

override BUILD_DIR := ../../build/lib/libcos
override OUT_DIR := ../../build/user/usr/lib
override COMMON_INCLUDE_DIR := ../../build/user/usr/include

override OBJ := $(patsubst %.c,$(BUILD_DIR)/%.c.o,$(CFILES))
override HEADER_DEPS := $(patsubst %.c,$(BUILD_DIR)/%.c.d,$(CFILES))

.PHONY: all
all: $(OUT_DIR)/$(TARGET) $(OUT_DIR)/crt0.o

$(OUT_DIR)/crt0.o: src/crt0.S
@mkdir -p $(@D)
@printf "CC\t%s\n" $<
@$(CC) $(CFLAGS) $(CPPFLAGS) -c $< -o $@

$(OUT_DIR)/$(TARGET): $(OBJ)
@mkdir -p $(@D)
@printf "AR\t%s\n" $@
@$(AR) rcs $@ $(OBJ)
@mkdir -p $(COMMON_INCLUDE_DIR)
@cp -R include/* $(COMMON_INCLUDE_DIR)/

-include $(HEADER_DEPS)

$(BUILD_DIR)/%.c.o: %.c
@mkdir -p $(@D)
@printf "CC\t%s\n" $<
@$(CC) $(CFLAGS) $(CPPFLAGS) -c $< -o $@

.PHONY: clean
clean:
rm -rf $(BUILD_DIR)

.PHONY: format
format:
find . -type f \( -name '*.c' -o -name '*.h' \) ! -name 'limine.h' -exec clang-format -i {} +
6 changes: 6 additions & 0 deletions lib/cos/include/arch/x86_64-cos/fcntl.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#pragma once

#define O_RDONLY 0x0000
#define O_WRONLY 0x0001
#define O_RDWR 0x0002
#define O_CREAT 0x0040
24 changes: 24 additions & 0 deletions lib/cos/include/arch/x86_64-cos/syscalls.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#pragma once

#include <stdint.h>

#define SYSCALL_SYS_EXIT 1
#define SYSCALL_SYS_READ 3
#define SYSCALL_SYS_WRITE 4
#define SYSCALL_SYS_OPEN 5
#define SYSCALL_SYS_CLOSE 6
#define SYSCALL_SYS_LSEEK 19
#define SYSCALL_SYS_GETPID 20
#define SYSCALL_SYS_MKDIR 39
#define SYSCALL_SYS_BRK 45
#define SYSCALL_SYS_FORK 57
#define SYSCALL_SCHED_YIELD 158

static inline uint64_t syscall3 (uint64_t num, uint64_t arg1, uint64_t arg2, uint64_t arg3) {
uint64_t ret;
__asm__ volatile ("int $0x80"
: "=a"(ret)
: "a"(num), "D"(arg1), "S"(arg2), "d"(arg3) // rdi, rsi, rdx
: "memory");
return ret;
}
38 changes: 38 additions & 0 deletions lib/cos/include/arch/x86_64-cos/unistd.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
#pragma once

#include <stddef.h>
#include <stdint.h>

typedef long ssize_t;
typedef long off_t;
typedef int pid_t;
typedef unsigned int mode_t;

#ifdef __cplusplus
extern "C" {
#endif

void _exit (int status);
pid_t fork (void);
pid_t getpid (void);
int sched_yield (void);

int open (const char* pathname, int flags, ...);
int close (int fd);
ssize_t read (int fd, void* buf, size_t count);
ssize_t write (int fd, const void* buf, size_t count);
off_t lseek (int fd, off_t offset, int whence);

int mkdir (const char* pathname, mode_t mode);

uint64_t brk (void* addr);
void* sbrk (ptrdiff_t incr);

// TODO: implement stubs
int fstat (int file, struct stat* st);
int isatty (int file);
int kill (int pid, int sig);

#ifdef __cplusplus
}
#endif
4 changes: 4 additions & 0 deletions lib/cos/src/_exit.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#include <arch/x86_64-cos/syscalls.h>
#include <arch/x86_64-cos/unistd.h>

void _exit (int status) { (void)syscall3 (SYSCALL_SYS_EXIT, (uint64_t)status, 0, 0); }
4 changes: 4 additions & 0 deletions lib/cos/src/brk.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#include <arch/x86_64-cos/syscalls.h>
#include <arch/x86_64-cos/unistd.h>

uint64_t brk (void* addr) { return syscall3 (SYSCALL_SYS_BRK, (uint64_t)addr, 0, 0); }
4 changes: 4 additions & 0 deletions lib/cos/src/close.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#include <arch/x86_64-cos/syscalls.h>
#include <arch/x86_64-cos/unistd.h>

int close (int fd) { return (int)syscall3 (SYSCALL_SYS_CLOSE, (long)fd, 0, 0); }
24 changes: 24 additions & 0 deletions lib/cos/src/crt0.S
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
.section .text
.global _start
.type _start, @function

.extern main
.extern exit

_start:
xor %ebp, %ebp
and $-16, %rsp

// TODO: pass actual values, when we support that in the kernel
xor %edi, %edi // argc
xor %esi, %esi // argv
xor %edx, %edx // envp

call main

mov %eax, %edi
call exit

.Lhang:
hlt
jmp .Lhang
4 changes: 4 additions & 0 deletions lib/cos/src/fork.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#include <arch/x86_64-cos/syscalls.h>
#include <arch/x86_64-cos/unistd.h>

pid_t fork (void) { return (pid_t)syscall3 (SYSCALL_SYS_FORK, 0, 0, 0); }
4 changes: 4 additions & 0 deletions lib/cos/src/getpid.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#include <arch/x86_64-cos/syscalls.h>
#include <arch/x86_64-cos/unistd.h>

pid_t getpid (void) { return (pid_t)syscall3 (SYSCALL_SYS_GETPID, 0, 0, 0); }
6 changes: 6 additions & 0 deletions lib/cos/src/lseek.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#include <arch/x86_64-cos/syscalls.h>
#include <arch/x86_64-cos/unistd.h>

off_t lseek (int fd, off_t offset, int whence) {
return (off_t)syscall3 (SYSCALL_SYS_LSEEK, (long)fd, (long)offset, (long)whence);
}
6 changes: 6 additions & 0 deletions lib/cos/src/mkdir.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#include <arch/x86_64-cos/syscalls.h>
#include <arch/x86_64-cos/unistd.h>

int mkdir (const char* pathname, mode_t mode) {
return (int)syscall3 (SYSCALL_SYS_MKDIR, (long)pathname, (long)mode, 0);
}
17 changes: 17 additions & 0 deletions lib/cos/src/open.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#include <arch/x86_64-cos/fcntl.h>
#include <arch/x86_64-cos/syscalls.h>
#include <arch/x86_64-cos/unistd.h>
#include <stdarg.h>

int open (const char* pathname, int flags, ...) {
mode_t mode = 0;

if (flags & O_CREAT) {
va_list args;
va_start (args, flags);
mode = va_arg (args, mode_t);
va_end (args);
}

return (int)syscall3 (SYSCALL_SYS_OPEN, (long)pathname, (long)flags, (long)mode);
}
6 changes: 6 additions & 0 deletions lib/cos/src/read.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#include <arch/x86_64-cos/syscalls.h>
#include <arch/x86_64-cos/unistd.h>

ssize_t read (int fd, void* buf, size_t count) {
return syscall3 (SYSCALL_SYS_READ, (uint64_t)fd, (uint64_t)buf, (uint64_t)count);
}
20 changes: 20 additions & 0 deletions lib/cos/src/sbrk.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#include <arch/x86_64-cos/unistd.h>
#include <errno.h>
#include <sys/types.h>

void* sbrk (ptrdiff_t incr) {
static char* heap_end = 0;
char* prev_heap_end;

if (heap_end == 0) heap_end = (char*)brk (0);

prev_heap_end = heap_end;

if (brk (heap_end + incr) < 0) {
errno = ENOMEM;
return (void*)-1;
}

heap_end += incr;
return (void*)prev_heap_end;
}
4 changes: 4 additions & 0 deletions lib/cos/src/sched_yield.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#include <arch/x86_64-cos/syscalls.h>
#include <arch/x86_64-cos/unistd.h>

int sched_yield (void) { return (int)syscall3 (SYSCALL_SCHED_YIELD, 0, 0, 0); }
Loading
Loading