feature: added third_party TCC into userland

This commit is contained in:
boreddevnl 2026-05-09 01:11:29 +02:00
parent a62b22faa9
commit 230e404a98
57 changed files with 1289 additions and 26 deletions

View file

@ -213,6 +213,12 @@ $(BUILD_DIR)/initrd.tar: $(KERNEL_ELF)
mkdir -p $(BUILD_DIR)/initrd/root/Pictures mkdir -p $(BUILD_DIR)/initrd/root/Pictures
mkdir -p $(BUILD_DIR)/initrd/root/Documents mkdir -p $(BUILD_DIR)/initrd/root/Documents
mkdir -p $(BUILD_DIR)/initrd/root/Downloads mkdir -p $(BUILD_DIR)/initrd/root/Downloads
mkdir -p $(BUILD_DIR)/initrd/etc
mkdir -p $(BUILD_DIR)/initrd/usr/lib/tcc/include
mkdir -p $(BUILD_DIR)/initrd/usr/local/include
mkdir -p $(BUILD_DIR)/initrd/usr/include/sys
mkdir -p $(BUILD_DIR)/initrd/usr/include/libc
mkdir -p $(BUILD_DIR)/initrd/usr/lib
@printf "$(YELLOW)[COPY]$(RESET) Limine binaries + kernel for installer..." @printf "$(YELLOW)[COPY]$(RESET) Limine binaries + kernel for installer..."
@if [ -f limine/BOOTX64.EFI ]; then cp limine/BOOTX64.EFI $(BUILD_DIR)/initrd/boot/; fi @if [ -f limine/BOOTX64.EFI ]; then cp limine/BOOTX64.EFI $(BUILD_DIR)/initrd/boot/; fi
@ -228,6 +234,22 @@ $(BUILD_DIR)/initrd.tar: $(KERNEL_ELF)
fi \ fi \
done done
@printf "$(YELLOW)[COPY]$(RESET) TCC support files..."
@cp $(SRC_DIR)/userland/cli/third_party/tcc/libtcc1.a $(BUILD_DIR)/initrd/usr/lib/tcc/
@cp $(SRC_DIR)/userland/cli/third_party/tcc/libtcc1.a $(BUILD_DIR)/initrd/usr/lib/
@cp $(SRC_DIR)/userland/cli/third_party/tcc/include/*.h $(BUILD_DIR)/initrd/usr/lib/tcc/include/
@cp $(SRC_DIR)/userland/sdk/lib/libboredos.a $(BUILD_DIR)/initrd/usr/lib/
@cp $(SRC_DIR)/userland/sdk/lib/libc.a $(BUILD_DIR)/initrd/usr/lib/
@cp $(SRC_DIR)/userland/sdk/lib/libm.a $(BUILD_DIR)/initrd/usr/lib/
@cp $(SRC_DIR)/userland/bin/crt0.o $(BUILD_DIR)/initrd/usr/lib/crt0.o
@cp $(SRC_DIR)/userland/bin/crt0.o $(BUILD_DIR)/initrd/usr/lib/crt1.o
@cp $(SRC_DIR)/userland/bin/empty.o $(BUILD_DIR)/initrd/usr/lib/crti.o
@cp $(SRC_DIR)/userland/bin/empty.o $(BUILD_DIR)/initrd/usr/lib/crtn.o
@cp $(SRC_DIR)/userland/libc/*.h $(BUILD_DIR)/initrd/usr/include/
@cp $(SRC_DIR)/userland/libc/sys/*.h $(BUILD_DIR)/initrd/usr/include/sys/
@cp $(SRC_DIR)/userland/libc/*.h $(BUILD_DIR)/initrd/usr/include/libc/
@cp $(SRC_DIR)/userland/libc/*.h $(BUILD_DIR)/initrd/usr/local/include/
@printf "$(YELLOW)[COPY]$(RESET) Wallpapers..." @printf "$(YELLOW)[COPY]$(RESET) Wallpapers..."
@for f in $(SRC_DIR)/images/wallpapers/*; do \ @for f in $(SRC_DIR)/images/wallpapers/*; do \
if [ -f "$$f" ]; then \ if [ -f "$$f" ]; then \
@ -291,6 +313,7 @@ $(BUILD_DIR)/initrd.tar: $(KERNEL_ELF)
@if [ -f README.md ]; then printf " -> README.md"; cp README.md $(BUILD_DIR)/initrd/; fi @if [ -f README.md ]; then printf " -> README.md"; cp README.md $(BUILD_DIR)/initrd/; fi
@if [ -f LICENSE ]; then printf " -> LICENSE"; cp LICENSE $(BUILD_DIR)/initrd/; fi @if [ -f LICENSE ]; then printf " -> LICENSE"; cp LICENSE $(BUILD_DIR)/initrd/; fi
@if [ -f limine.conf ]; then printf " -> limine.conf"; cp limine.conf $(BUILD_DIR)/initrd/; fi @if [ -f limine.conf ]; then printf " -> limine.conf"; cp limine.conf $(BUILD_DIR)/initrd/; fi
@if [ -f $(SRC_DIR)/userland/gui/about.c ]; then printf " -> about.c"; cp $(SRC_DIR)/userland/gui/about.c $(BUILD_DIR)/initrd/; fi
@printf "$(YELLOW)[TAR]$(RESET) Creating initrd.tar..." @printf "$(YELLOW)[TAR]$(RESET) Creating initrd.tar..."
cd $(BUILD_DIR)/initrd && COPYFILE_DISABLE=1 tar --exclude="._*" -cf ../initrd.tar * cd $(BUILD_DIR)/initrd && COPYFILE_DISABLE=1 tar --exclude="._*" -cf ../initrd.tar *

View file

@ -15,7 +15,7 @@
static spinlock_t ramfs_lock = SPINLOCK_INIT; // Protects the RAM-based filesystem (/) static spinlock_t ramfs_lock = SPINLOCK_INIT; // Protects the RAM-based filesystem (/)
#define MAX_CLUSTERS 8192 #define MAX_CLUSTERS 32768
#define MAX_OPEN_HANDLES 32 #define MAX_OPEN_HANDLES 32
// In-memory FAT table // In-memory FAT table

View file

@ -16,7 +16,7 @@ APP_METADATA_SOURCE_LUA = cli/third_party/lua/boredos_onelua.c
APP_SOURCE_DIRS = . cli gui sys games net cli/third_party APP_SOURCE_DIRS = . cli gui sys games net cli/third_party
define app_source_for define app_source_for
$(if $(filter doom,$1),$(APP_METADATA_SOURCE_DOOM),$(if $(filter lua,$1),$(APP_METADATA_SOURCE_LUA),$(firstword $(foreach d,$(APP_SOURCE_DIRS),$(wildcard $(d)/$1.c))))) $(if $(filter doom,$1),$(APP_METADATA_SOURCE_DOOM),$(if $(filter lua,$1),$(APP_METADATA_SOURCE_LUA),$(if $(filter tcc,$1),cli/third_party/tcc/tcc.c,$(firstword $(foreach d,$(APP_SOURCE_DIRS),$(wildcard $(d)/$1.c))))))
endef endef
LIBC_SOURCES = $(wildcard libc/*.c) LIBC_SOURCES = $(wildcard libc/*.c)
@ -38,7 +38,7 @@ DOOM_OBJS = $(patsubst games/doom/%.c, $(BIN_DIR)/%.o, $(DOOM_SOURCES))
LUA_DIR = cli/third_party/lua LUA_DIR = cli/third_party/lua
LUA_CFLAGS = -std=gnu11 -ffreestanding -O2 -fno-stack-protector -fno-stack-check -fno-lto -fno-pie -m64 -march=x86-64 -mno-red-zone -isystem $(LUA_DIR)/sysinclude -I. -Ilibc -I$(LUA_DIR) -DLUA_USE_C89 -Wno-conversion -Wno-sign-conversion -Wno-double-promotion -Wno-unused-parameter -Wno-missing-declarations -Wno-shadow -Wno-undef -Wno-redundant-decls -Wno-old-style-definition -Wno-missing-prototypes -Wno-implicit-fallthrough -Wno-type-limits LUA_CFLAGS = -std=gnu11 -ffreestanding -O2 -fno-stack-protector -fno-stack-check -fno-lto -fno-pie -m64 -march=x86-64 -mno-red-zone -isystem $(LUA_DIR)/sysinclude -I. -Ilibc -I$(LUA_DIR) -DLUA_USE_C89 -Wno-conversion -Wno-sign-conversion -Wno-double-promotion -Wno-unused-parameter -Wno-missing-declarations -Wno-shadow -Wno-undef -Wno-redundant-decls -Wno-old-style-definition -Wno-missing-prototypes -Wno-implicit-fallthrough -Wno-type-limits
all: $(BIN_DIR) $(APP_ELFS) $(BIN_DIR)/doom.elf $(BIN_DIR)/lua.elf all: $(BIN_DIR) $(APP_ELFS) $(BIN_DIR)/doom.elf $(BIN_DIR)/lua.elf $(BIN_DIR)/tcc.elf $(BIN_DIR)/empty.o
$(BIN_DIR): $(BIN_DIR):
mkdir -p $(BIN_DIR) mkdir -p $(BIN_DIR)
@ -55,6 +55,11 @@ $(BIN_DIR)/libwidget.o: ../wm/libwidget.c | $(BIN_DIR)
$(BIN_DIR)/stb_image.o: stb_image.c | $(BIN_DIR) $(BIN_DIR)/stb_image.o: stb_image.c | $(BIN_DIR)
$(CC) $(CFLAGS) -c $< -o $@ $(CC) $(CFLAGS) -c $< -o $@
$(BIN_DIR)/empty.o: | $(BIN_DIR)
echo "section .text" > $(BIN_DIR)/empty.asm
$(AS) -f elf64 $(BIN_DIR)/empty.asm -o $@
rm $(BIN_DIR)/empty.asm
$(BIN_DIR)/%.note.c: $(APP_METADATA_TOOL) | $(BIN_DIR) $(BIN_DIR)/%.note.c: $(APP_METADATA_TOOL) | $(BIN_DIR)
src="$(call app_source_for,$*)"; \ src="$(call app_source_for,$*)"; \
if [ -z "$$src" ] || [ ! -f "$$src" ]; then \ if [ -z "$$src" ] || [ ! -f "$$src" ]; then \
@ -97,5 +102,23 @@ $(BIN_DIR)/lua_onelua.o: $(LUA_DIR)/boredos_onelua.c | $(BIN_DIR)
$(BIN_DIR)/lua.elf: $(LIBC_OBJS) $(BIN_DIR)/lua_onelua.o $(BIN_DIR)/lua.note.o $(BIN_DIR)/lua.elf: $(LIBC_OBJS) $(BIN_DIR)/lua_onelua.o $(BIN_DIR)/lua.note.o
$(LD) $(LDFLAGS) $^ -o $@ $(LD) $(LDFLAGS) $^ -o $@
# TCC - Tiny C Compiler
TCC_DIR = cli/third_party/tcc
$(BIN_DIR)/tcc.elf: $(LIBC_OBJS) $(BIN_DIR)/tcc.note.o sdk $(TCC_DIR)/tcc.c $(TCC_DIR)/config.h $(TCC_DIR)/tcc.h
cd $(TCC_DIR) && x86_64-elf-gcc -O2 -m64 -march=x86-64 -fno-stack-protector -fno-stack-check -fno-lto -fno-pie -ffreestanding -nostdlib -static -no-pie -DONE_SOURCE=1 -DTARGETOS_BoredOS=1 -I. -I../../../sdk/include -Ttext=0x40000000 tcc.c -o tcc.elf ../../../sdk/lib/libboredos.a
cp $(TCC_DIR)/tcc.elf $(BIN_DIR)/tcc.elf
cd $(TCC_DIR) && sh build_libtcc1.sh
# SDK target
SDK_DIR = sdk
sdk: $(LIBC_OBJS) $(BIN_DIR)/libui.o
mkdir -p $(SDK_DIR)/lib $(SDK_DIR)/include/sys
cp libc/*.h $(SDK_DIR)/include/
cp libc/sys/*.h $(SDK_DIR)/include/sys/
x86_64-elf-ar rcs $(SDK_DIR)/lib/libboredos.a $(LIBC_OBJS)
cp $(SDK_DIR)/lib/libboredos.a $(SDK_DIR)/lib/libc.a
cp $(SDK_DIR)/lib/libboredos.a $(SDK_DIR)/lib/libm.a
x86_64-elf-ar rcs $(SDK_DIR)/lib/libui.a $(BIN_DIR)/libui.o
clean: clean:
rm -rf $(BIN_DIR) rm -rf $(BIN_DIR) $(SDK_DIR)

View file

@ -337,6 +337,8 @@ int main(int argc, char **argv) {
if (copy_tree("/Library", "/mnt/Library") != 0) { serial_printf("[ERROR] copy /Library failed\n"); return 1; } if (copy_tree("/Library", "/mnt/Library") != 0) { serial_printf("[ERROR] copy /Library failed\n"); return 1; }
if (copy_tree("/docs", "/mnt/docs") != 0) { serial_printf("[ERROR] copy /docs failed\n"); return 1; } if (copy_tree("/docs", "/mnt/docs") != 0) { serial_printf("[ERROR] copy /docs failed\n"); return 1; }
if (copy_tree("/root", "/mnt/root") != 0) { serial_printf("[ERROR] copy /root failed\n"); return 1; } if (copy_tree("/root", "/mnt/root") != 0) { serial_printf("[ERROR] copy /root failed\n"); return 1; }
if (copy_tree("/usr", "/mnt/usr") != 0) { serial_printf("[ERROR] copy /usr failed\n"); return 1; }
if (copy_tree("/etc", "/mnt/etc") != 0) { serial_printf("[ERROR] copy /etc failed\n"); return 1; }
serial_printf("Copying kernel and initrd...\n"); serial_printf("Copying kernel and initrd...\n");
if (copy_file("/boot/boredos.elf", "/mnt/boot/boredos.elf") != 0) { if (copy_file("/boot/boredos.elf", "/mnt/boot/boredos.elf") != 0) {
@ -357,8 +359,9 @@ int main(int argc, char **argv) {
serial_printf("[WARNING] initrd.tar not found in live system (checked /boot/ and /)!\n"); serial_printf("[WARNING] initrd.tar not found in live system (checked /boot/ and /)!\n");
} }
copy_file_optional("README.md", "/mnt/README.md"); copy_file_optional("/README.md", "/mnt/README.md");
copy_file_optional("LICENSE", "/mnt/LICENSE"); copy_file_optional("/LICENSE", "/mnt/LICENSE");
copy_file_optional("/about.c", "/mnt/about.c");
uint64_t t1 = get_ticks(); uint64_t t1 = get_ticks();
serial_printf("Files copied (%llu ticks).\n", (unsigned long long)(t1 - t0)); serial_printf("Files copied (%llu ticks).\n", (unsigned long long)(t1 - t0));
} }

26
src/userland/crt1.asm Normal file
View file

@ -0,0 +1,26 @@
; Copyright (c) 2023-2026 Chris (boreddevnl)
; This software is released under the GNU General Public License v3.0. See LICENSE file for details.
; This header needs to maintain in any file it is present in, as per the GPL license terms.
; userland/crt0.asm
global _start
extern main
extern sys_exit
section .text
_start:
; The kernel loads the ELF and jumps here.
; RSP should point to the 0x800000 stack.
; Align the stack to 16 bytes for C functions (System V ABI)
and rsp, -16
; Call main(argc, argv)
call main
; If main returns, call exit(status)
mov rdi, rax ; Pass main's return value to exit syscall
call sys_exit
; Fallback halt if exit miraculously returns
.hang:
jmp .hang

3
src/userland/crti.asm Normal file
View file

@ -0,0 +1,3 @@
global _init
section .init
_init:

3
src/userland/crtn.asm Normal file
View file

@ -0,0 +1,3 @@
global _fini
section .fini
_fini:

View file

@ -52,26 +52,6 @@ static char* str_istrstr(const char* haystack, const char* needle) {
return NULL; return NULL;
} }
static long strtol(const char* nptr, char** endptr, int base) {
long res = 0;
while (*nptr == ' ' || *nptr == '\t' || *nptr == '\n' || *nptr == '\r') nptr++;
bool neg = false;
if (*nptr == '-') { neg = true; nptr++; }
else if (*nptr == '+') nptr++;
while (*nptr) {
int v = -1;
if (*nptr >= '0' && *nptr <= '9') v = *nptr - '0';
else if (*nptr >= 'a' && *nptr <= 'z') v = *nptr - 'a' + 10;
else if (*nptr >= 'A' && *nptr <= 'Z') v = *nptr - 'A' + 10;
if (v < 0 || v >= base) break;
res = res * base + v;
nptr++;
}
if (endptr) *endptr = (char*)nptr;
return neg ? -res : res;
}
#define TAG_NONE 0 #define TAG_NONE 0
#define TAG_IMG 1 #define TAG_IMG 1
#define TAG_INPUT 2 #define TAG_INPUT 2

View file

@ -0,0 +1,4 @@
#ifndef _ASSERT_H
#define _ASSERT_H
#define assert(x) ((void)0)
#endif

View file

@ -0,0 +1,9 @@
#ifndef _DLFCN_H
#define _DLFCN_H
#define RTLD_LAZY 0x00001
#define RTLD_NOW 0x00002
void *dlopen(const char *filename, int flag);
char *dlerror(void);
void *dlsym(void *handle, const char *symbol);
int dlclose(void *handle);
#endif

View file

@ -0,0 +1 @@
section .text

View file

@ -0,0 +1,7 @@
#ifndef _INTTYPES_H
#define _INTTYPES_H
#include <stdint.h>
#define PRId64 "lld"
#define PRIu64 "llu"
#define PRIx64 "llx"
#endif

View file

@ -157,3 +157,15 @@ double fclamp(double x, double lo, double hi) {
if (x > hi) return hi; if (x > hi) return hi;
return x; return x;
} }
double ldexp(double x, int exp) {
if (exp >= 0) { while (exp--) x *= 2.0; }
else { while (exp++) x /= 2.0; }
return x;
}
long double ldexpl(long double x, int exp) {
if (exp >= 0) { while (exp--) x *= 2.0L; }
else { while (exp++) x /= 2.0L; }
return x;
}

View file

@ -29,6 +29,7 @@ double log2(double x);
double log10(double x); double log10(double x);
double exp(double x); double exp(double x);
double ldexp(double x, int expn); double ldexp(double x, int expn);
long double ldexpl(long double x, int expn);
double frexp(double x, int *expn); double frexp(double x, int *expn);
double pow(double base, double exponent); double pow(double base, double exponent);
double atan2(double y, double x); double atan2(double y, double x);

View file

@ -3,6 +3,25 @@
#include <stdint.h> #include <stdint.h>
#include "errno.h" #include "errno.h"
#include "sys/mman.h"
void *mmap(void *addr, unsigned long length, int prot, int flags, int fd, long offset) {
(void)addr; (void)length; (void)prot; (void)flags; (void)fd; (void)offset;
errno = ENOSYS;
return MAP_FAILED;
}
int munmap(void *addr, unsigned long length) {
(void)addr; (void)length;
errno = ENOSYS;
return -1;
}
int mprotect(void *addr, unsigned long length, int prot) {
(void)addr; (void)length; (void)prot;
errno = ENOSYS;
return -1;
}
#include "fcntl.h" #include "fcntl.h"
#include "stdlib.h" #include "stdlib.h"
#include "string.h" #include "string.h"

View file

@ -1,4 +1,5 @@
#include "stdlib.h" #include "stdlib.h"
char **environ = 0;
#include "string.h" #include "string.h"
#include "errno.h" #include "errno.h"
#include "syscall.h" #include "syscall.h"
@ -176,3 +177,11 @@ __attribute__((weak)) double strtod(const char *nptr, char **endptr) {
} }
return sign * value; return sign * value;
} }
__attribute__((weak)) float strtof(const char *nptr, char **endptr) {
return (float)strtod(nptr, endptr);
}
__attribute__((weak)) long double strtold(const char *nptr, char **endptr) {
return (long double)strtod(nptr, endptr);
}

View file

@ -0,0 +1,22 @@
#ifndef _STDINT_H
#define _STDINT_H
typedef signed char int8_t;
typedef unsigned char uint8_t;
typedef short int16_t;
typedef unsigned short uint16_t;
typedef int int32_t;
typedef unsigned int uint32_t;
typedef long int64_t;
typedef unsigned long uint64_t;
#ifndef _INTPTR_T
#define _INTPTR_T
typedef long intptr_t;
#endif
#ifndef _UINTPTR_T
#define _UINTPTR_T
typedef unsigned long uintptr_t;
#endif
#endif

View file

@ -76,6 +76,19 @@ FILE *fopen(const char *path, const char *mode) {
return f; return f;
} }
FILE *fdopen(int fd, const char *mode) {
(void)mode;
if (fd < 0) return NULL;
FILE *f = (FILE *)malloc(sizeof(FILE));
if (!f) return NULL;
f->fd = fd;
f->eof = 0;
f->err = 0;
f->has_ungetc = 0;
f->ungetc_char = 0;
return f;
}
FILE *freopen(const char *path, const char *mode, FILE *stream) { FILE *freopen(const char *path, const char *mode, FILE *stream) {
int fd; int fd;
if (!stream) { if (!stream) {
@ -193,6 +206,10 @@ int getc(FILE *stream) {
return (int)ch; return (int)ch;
} }
int fgetc(FILE *stream) {
return getc(stream);
}
int ungetc(int c, FILE *stream) { int ungetc(int c, FILE *stream) {
if (!stream || c == EOF) { if (!stream || c == EOF) {
return EOF; return EOF;

View file

@ -25,8 +25,10 @@ extern FILE *stderr;
#define TMP_MAX 32 #define TMP_MAX 32
FILE *fopen(const char *path, const char *mode); FILE *fopen(const char *path, const char *mode);
FILE *fdopen(int fd, const char *mode);
FILE *freopen(const char *path, const char *mode, FILE *stream); FILE *freopen(const char *path, const char *mode, FILE *stream);
int fclose(FILE *stream); int fclose(FILE *stream);
int fgetc(FILE *stream);
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream); size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream); size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);
int fseek(FILE *stream, long offset, int whence); int fseek(FILE *stream, long offset, int whence);

View file

@ -234,6 +234,70 @@ int atoi(const char *nptr) {
return sign * res; return sign * res;
} }
long strtol(const char *nptr, char **endptr, int base) {
long res = 0;
int sign = 1;
while (*nptr == ' ' || *nptr == '\t' || *nptr == '\n' || *nptr == '\r') nptr++;
if (*nptr == '-') { sign = -1; nptr++; }
else if (*nptr == '+') nptr++;
if (base == 0) {
if (*nptr == '0') {
if (*(nptr+1) == 'x' || *(nptr+1) == 'X') { base = 16; nptr += 2; }
else base = 8;
} else base = 10;
} else if (base == 16) {
if (*nptr == '0' && (*(nptr+1) == 'x' || *(nptr+1) == 'X')) nptr += 2;
}
while (1) {
int val = -1;
if (*nptr >= '0' && *nptr <= '9') val = *nptr - '0';
else if (*nptr >= 'a' && *nptr <= 'f') val = *nptr - 'a' + 10;
else if (*nptr >= 'A' && *nptr <= 'F') val = *nptr - 'A' + 10;
if (val == -1 || val >= base) break;
res = res * base + val;
nptr++;
}
if (endptr) *endptr = (char *)nptr;
return sign * res;
}
unsigned long strtoul(const char *nptr, char **endptr, int base) {
return (unsigned long)strtol(nptr, endptr, base);
}
unsigned long long strtoull(const char *nptr, char **endptr, int base) {
return (unsigned long long)strtol(nptr, endptr, base);
}
static void swap(void *a, void *b, size_t size) {
char *ca = a, *cb = b;
while (size--) { char t = *ca; *ca++ = *cb; *cb++ = t; }
}
void qsort(void *base, size_t nmemb, size_t size, int (*compar)(const void *, const void *)) {
if (nmemb < 2) return;
char *pivot = (char *)base + (nmemb / 2) * size;
char *left = base;
char *right = (char *)base + (nmemb - 1) * size;
while (left <= right) {
while (compar(left, pivot) < 0) left += size;
while (compar(right, pivot) > 0) right -= size;
if (left <= right) {
swap(left, right, size);
if (pivot == left) pivot = right;
else if (pivot == right) pivot = left;
left += size;
right -= size;
}
}
if (base < (void*)right) qsort(base, (right - (char *)base) / size + 1, size, compar);
if ((void*)left < (char *)base + nmemb * size) qsort(left, ((char *)base + nmemb * size - left) / size, size, compar);
}
void itoa(int n, char *buf) { void itoa(int n, char *buf) {
if (n == 0) { if (n == 0) {
buf[0] = '0'; buf[1] = 0; return; buf[0] = '0'; buf[1] = 0; return;
@ -265,6 +329,13 @@ char* getcwd(char *buf, int size) {
return NULL; return NULL;
} }
char *realpath(const char *path, char *resolved_path) {
if (!resolved_path) resolved_path = malloc(1024);
if (!resolved_path) return NULL;
strcpy(resolved_path, path);
return resolved_path;
}
void sleep(int ms) { void sleep(int ms) {
sys_system(SYSTEM_CMD_SLEEP, ms, 0, 0, 0); sys_system(SYSTEM_CMD_SLEEP, ms, 0, 0, 0);
} }

View file

@ -3,6 +3,7 @@
#include <stddef.h> #include <stddef.h>
#include <stdint.h> #include <stdint.h>
extern char **environ;
void* malloc(size_t size); void* malloc(size_t size);
void free(void* ptr); void free(void* ptr);
@ -18,6 +19,12 @@ int atoi(const char *nptr);
void itoa(int n, char *buf); void itoa(int n, char *buf);
int abs(int x); int abs(int x);
double strtod(const char *nptr, char **endptr); double strtod(const char *nptr, char **endptr);
float strtof(const char *nptr, char **endptr);
long double strtold(const char *nptr, char **endptr);
long strtol(const char *nptr, char **endptr, int base);
unsigned long strtoul(const char *nptr, char **endptr, int base);
unsigned long long strtoull(const char *nptr, char **endptr, int base);
void qsort(void *base, size_t nmemb, size_t size, int (*compar)(const void *, const void *));
// IO functions // IO functions
void puts(const char *s); void puts(const char *s);
@ -31,6 +38,7 @@ void abort(void);
// System/Process functions // System/Process functions
int chdir(const char *path); int chdir(const char *path);
char* getcwd(char *buf, int size); char* getcwd(char *buf, int size);
char *realpath(const char *path, char *resolved_path);
int access(const char *pathname, int mode); int access(const char *pathname, int mode);
void sleep(int ms); void sleep(int ms);
void exit(int status); void exit(int status);

View file

@ -0,0 +1,14 @@
#ifndef _SYS_MMAN_H
#define _SYS_MMAN_H
#define PROT_READ 0x1
#define PROT_WRITE 0x2
#define PROT_EXEC 0x4
#define MAP_SHARED 0x01
#define MAP_PRIVATE 0x02
#define MAP_FIXED 0x10
#define MAP_ANONYMOUS 0x20
#define MAP_FAILED ((void *)-1)
void *mmap(void *addr, unsigned long length, int prot, int flags, int fd, long offset);
int munmap(void *addr, unsigned long length);
int mprotect(void *addr, unsigned long length, int prot);
#endif

View file

@ -0,0 +1,6 @@
#ifndef _SYS_TIME_H
#define _SYS_TIME_H
struct timeval { long tv_sec; long tv_usec; };
struct timezone { int tz_minuteswest; int tz_dsttime; };
int gettimeofday(struct timeval *tv, void *tz);
#endif

View file

@ -0,0 +1,3 @@
#ifndef _SYS_UCONTEXT_H
#define _SYS_UCONTEXT_H
#endif

View file

@ -3,6 +3,7 @@
#include "time.h" #include "time.h"
#include "stdio.h" #include "stdio.h"
#include "syscall.h" #include "syscall.h"
#include "sys/time.h"
static int _b_is_leap(int year) { static int _b_is_leap(int year) {
return ((year % 4) == 0 && (year % 100) != 0) || ((year % 400) == 0); return ((year % 4) == 0 && (year % 100) != 0) || ((year % 400) == 0);
@ -164,3 +165,13 @@ __attribute__((weak)) time_t mktime(struct tm *tm) {
tm->tm_min, tm->tm_min,
tm->tm_sec); tm->tm_sec);
} }
int gettimeofday(struct timeval *tv, void *tz) {
(void)tz;
if (tv) {
time_t t = time(NULL);
tv->tv_sec = (long)t;
tv->tv_usec = 0;
}
return 0;
}

View file

@ -0,0 +1,4 @@
#ifndef _ASSERT_H
#define _ASSERT_H
#define assert(x) ((void)0)
#endif

View file

@ -0,0 +1,18 @@
#ifndef BOREDOS_LIBC_CTYPE_H
#define BOREDOS_LIBC_CTYPE_H
int isdigit(int c);
int isalpha(int c);
int isalnum(int c);
int isspace(int c);
int isupper(int c);
int islower(int c);
int isxdigit(int c);
int iscntrl(int c);
int ispunct(int c);
int isprint(int c);
int isgraph(int c);
int tolower(int c);
int toupper(int c);
#endif

View file

@ -0,0 +1,9 @@
#ifndef _DLFCN_H
#define _DLFCN_H
#define RTLD_LAZY 0x00001
#define RTLD_NOW 0x00002
void *dlopen(const char *filename, int flag);
char *dlerror(void);
void *dlsym(void *handle, const char *symbol);
int dlclose(void *handle);
#endif

View file

@ -0,0 +1,27 @@
#ifndef BOREDOS_LIBC_ERRNO_H
#define BOREDOS_LIBC_ERRNO_H
extern int errno;
#define EDOM 33
#define E2BIG 7
#define ERANGE 34
#define EINVAL 22
#define EISDIR 21
#define ENOENT 2
#define ENOMEM 12
#define EACCES 13
#define EBADF 9
#define EIO 5
#define EEXIST 17
#define EAGAIN 11
#define EINTR 4
#define ECHILD 10
#define ENOTSUP 95
#define EPIPE 32
#define ENOTDIR 20
#define EBUSY 16
#define ESPIPE 29
#define ENOSYS 38
#endif

View file

@ -0,0 +1,27 @@
#ifndef BOREDOS_LIBC_FCNTL_H
#define BOREDOS_LIBC_FCNTL_H
#include "sys/types.h"
#define O_RDONLY 0x0000
#define O_WRONLY 0x0001
#define O_RDWR 0x0002
#define O_ACCMODE 0x0003
#define O_CREAT 0x0040
#define O_EXCL 0x0080
#define O_TRUNC 0x0200
#define O_APPEND 0x0400
#define O_NONBLOCK 0x0800
#define F_GETFL 3
#define F_SETFL 4
#define FD_CLOEXEC 1
int open(const char *pathname, int flags, ...);
int fcntl(int fd, int cmd, ...);
int dup(int oldfd);
int dup2(int oldfd, int newfd);
int pipe(int pipefd[2]);
#endif

View file

@ -0,0 +1,19 @@
#ifndef INPUT_H
#define INPUT_H
// Arrow keys
#define KEY_UP 17
#define KEY_DOWN 18
#define KEY_LEFT 19
#define KEY_RIGHT 20
// controls
#define KEY_ENTER 10
#define KEY_BACKSPACE 8
#define KEY_ESCAPE 27
#define KEY_SPACE 32
#define KEY_ALT 22
#define KEY_CTRL_L 21
#define KEY_TAB 9
#endif

View file

@ -0,0 +1,7 @@
#ifndef _INTTYPES_H
#define _INTTYPES_H
#include <stdint.h>
#define PRId64 "lld"
#define PRIu64 "llu"
#define PRIx64 "llx"
#endif

View file

@ -0,0 +1,78 @@
#ifndef LIBUI_H
#define LIBUI_H
#include <stdint.h>
#include <stdbool.h>
// GUI Command IDs
#define GUI_CMD_WINDOW_CREATE 1
#define GUI_CMD_DRAW_RECT 2
#define GUI_CMD_DRAW_STRING 3
#define GUI_CMD_MARK_DIRTY 4
#define GUI_CMD_GET_EVENT 5
#define GUI_CMD_DRAW_ROUNDED_RECT_FILLED 6
#define GUI_CMD_DRAW_IMAGE 7
#define GUI_CMD_GET_STRING_WIDTH 8
#define GUI_CMD_GET_FONT_HEIGHT 9
#define GUI_CMD_WINDOW_SET_RESIZABLE 14
#define GUI_CMD_DRAW_STRING_BITMAP 10
#define GUI_CMD_DRAW_STRING_SCALED 11
#define GUI_CMD_GET_STRING_WIDTH_SCALED 12
#define GUI_CMD_GET_FONT_HEIGHT_SCALED 13
#define GUI_CMD_WINDOW_SET_TITLE 15
#define GUI_CMD_SET_FONT 16
#define GUI_CMD_DRAW_STRING_SCALED_SLOPED 18
#define GUI_CMD_GET_SCREEN_SIZE 50
#define GUI_CMD_GET_SCREENBUFFER 51
#define GUI_CMD_SHOW_NOTIFICATION 52
#define GUI_CMD_GET_DATETIME 53
// Event Types
#define GUI_EVENT_NONE 0
#define GUI_EVENT_PAINT 1
#define GUI_EVENT_CLICK 2
#define GUI_EVENT_RIGHT_CLICK 3
#define GUI_EVENT_CLOSE 4
#define GUI_EVENT_KEY 5
#define GUI_EVENT_KEYUP 10
#define GUI_EVENT_MOUSE_DOWN 6
#define GUI_EVENT_MOUSE_UP 7
#define GUI_EVENT_MOUSE_MOVE 8
#define GUI_EVENT_MOUSE_WHEEL 9
#define GUI_EVENT_RESIZE 11
typedef struct {
int type;
int arg1; // CLICK: x / KEY: legacy char-or-compat key
int arg2; // CLICK: y / KEY: keycode
int arg3; // CLICK: button state / KEY: modifier mask
int arg4; // KEY: Unicode codepoint (0 if none)
} gui_event_t;
// Window Handle
typedef uint64_t ui_window_t;
// libui API
ui_window_t ui_window_create(const char *title, int x, int y, int w, int h);
bool ui_get_event(ui_window_t win, gui_event_t *ev);
void ui_draw_rect(ui_window_t win, int x, int y, int w, int h, uint32_t color);
void ui_draw_rounded_rect_filled(ui_window_t win, int x, int y, int w, int h, int radius, uint32_t color);
void ui_draw_string(ui_window_t win, int x, int y, const char *str, uint32_t color);
void ui_mark_dirty(ui_window_t win, int x, int y, int w, int h);
void ui_draw_image(ui_window_t win, int x, int y, int w, int h, uint32_t *image_data);
uint32_t ui_get_string_width(const char *str);
uint32_t ui_get_font_height(void);
void ui_get_screen_size(uint64_t *out_w, uint64_t *out_h);
void ui_draw_string_bitmap(ui_window_t win, int x, int y, const char *str, uint32_t color);
void ui_draw_string_scaled(ui_window_t win, int x, int y, const char *str, uint32_t color, float scale);
void ui_draw_string_scaled_sloped(ui_window_t win, int x, int y, const char *str, uint32_t color, float scale, float slope);
uint32_t ui_get_string_width_scaled(const char *str, float scale);
uint32_t ui_get_font_height_scaled(float scale);
void ui_window_set_title(ui_window_t win, const char *title);
void ui_window_set_resizable(ui_window_t win, bool resizable);
void ui_set_font(ui_window_t win, const char *path);
#endif

View file

@ -0,0 +1,22 @@
#ifndef BOREDOS_LIBC_LIMITS_H
#define BOREDOS_LIBC_LIMITS_H
#define CHAR_BIT 8
#define SCHAR_MIN (-128)
#define SCHAR_MAX 127
#define UCHAR_MAX 255
#define SHRT_MIN (-32768)
#define SHRT_MAX 32767
#define USHRT_MAX 65535
#define INT_MIN (-2147483647 - 1)
#define INT_MAX 2147483647
#define UINT_MAX 4294967295U
#define LONG_MIN (-9223372036854775807L - 1)
#define LONG_MAX 9223372036854775807L
#define ULONG_MAX 18446744073709551615UL
#define LLONG_MIN (-9223372036854775807LL - 1)
#define LLONG_MAX 9223372036854775807LL
#define ULLONG_MAX 18446744073709551615ULL
#define DBL_MAX 1.7976931348623157e+308
#endif

View file

@ -0,0 +1,30 @@
#ifndef BOREDOS_LIBC_LOCALE_H
#define BOREDOS_LIBC_LOCALE_H
struct lconv {
char *decimal_point;
char *thousands_sep;
char *grouping;
char *int_curr_symbol;
char *currency_symbol;
char *mon_decimal_point;
char *mon_thousands_sep;
char *mon_grouping;
char *positive_sign;
char *negative_sign;
char int_frac_digits;
char frac_digits;
char p_cs_precedes;
char p_sep_by_space;
char n_cs_precedes;
char n_sep_by_space;
char p_sign_posn;
char n_sign_posn;
};
#define LC_ALL 0
char *setlocale(int category, const char *locale);
struct lconv *localeconv(void);
#endif

View file

@ -0,0 +1,46 @@
// Copyright (c) 2023-2026 Chris (boreddevnl)
// This software is released under the GNU General Public License v3.0. See LICENSE file for details.
// This header needs to maintain in any file it is present in, as per the GPL license terms.
#ifndef MATH_H
#define MATH_H
#define M_PI 3.14159265358979323846
#define M_E 2.71828182845904523536
#define M_LN2 0.69314718055994530942
#define M_SQRT2 1.41421356237309504880
#define HUGE_VAL (1e300 * 1e300)
double fabs(double x);
double fmod(double x, double y);
double floor(double x);
double ceil(double x);
double sin(double x);
double cos(double x);
double tan(double x);
double sqrt(double x);
double log(double x);
double log2(double x);
double log10(double x);
double exp(double x);
double ldexp(double x, int expn);
long double ldexpl(long double x, int expn);
double frexp(double x, int *expn);
double pow(double base, double exponent);
double atan2(double y, double x);
double asin(double x);
double acos(double x);
double sinh(double x);
double cosh(double x);
double tanh(double x);
double hypot(double x, double y);
double fmin(double a, double b);
double fmax(double a, double b);
double fclamp(double x, double lo, double hi);
#endif /* MATH_H */

View file

@ -0,0 +1,20 @@
#ifndef BOREDOS_LIBC_SETJMP_H
#define BOREDOS_LIBC_SETJMP_H
#include <stdint.h>
typedef struct boredos_jmp_buf_s {
uint64_t rbx;
uint64_t rbp;
uint64_t r12;
uint64_t r13;
uint64_t r14;
uint64_t r15;
uint64_t rsp;
uint64_t rip;
} jmp_buf[1];
int setjmp(jmp_buf env) __attribute__((returns_twice, noinline));
void longjmp(jmp_buf env, int val) __attribute__((noreturn, noinline));
#endif

View file

@ -0,0 +1,37 @@
#ifndef BOREDOS_LIBC_SIGNAL_H
#define BOREDOS_LIBC_SIGNAL_H
#include "sys/types.h"
typedef void (*sighandler_t)(int);
typedef unsigned long sigset_t;
struct sigaction {
sighandler_t sa_handler;
sigset_t sa_mask;
int sa_flags;
};
#define SIG_DFL ((sighandler_t)0)
#define SIG_IGN ((sighandler_t)1)
#define SIG_ERR ((sighandler_t)-1)
#define SIGKILL 9
#define SIGTERM 15
#define SIGINT 2
#define SIG_BLOCK 0
#define SIG_UNBLOCK 1
#define SIG_SETMASK 2
#define SA_RESTART 0x10000000
#define SA_NODEFER 0x40000000
#define SA_RESETHAND 0x80000000
sighandler_t signal(int sig, sighandler_t handler);
int sigaction(int sig, const struct sigaction *act, struct sigaction *oldact);
int sigprocmask(int how, const sigset_t *set, sigset_t *oldset);
int sigpending(sigset_t *set);
int raise(int sig);
int kill(pid_t pid, int sig);
#endif

View file

@ -0,0 +1,22 @@
#ifndef _STDINT_H
#define _STDINT_H
typedef signed char int8_t;
typedef unsigned char uint8_t;
typedef short int16_t;
typedef unsigned short uint16_t;
typedef int int32_t;
typedef unsigned int uint32_t;
typedef long int64_t;
typedef unsigned long uint64_t;
#ifndef _INTPTR_T
#define _INTPTR_T
typedef long intptr_t;
#endif
#ifndef _UINTPTR_T
#define _UINTPTR_T
typedef unsigned long uintptr_t;
#endif
#endif

View file

@ -0,0 +1,61 @@
#ifndef BOREDOS_LIBC_STDIO_H
#define BOREDOS_LIBC_STDIO_H
#include <stdarg.h>
#include <stddef.h>
typedef struct BOREDOS_FILE {
int fd;
int eof;
int err;
int has_ungetc;
int ungetc_char;
} FILE;
extern FILE *stdin;
extern FILE *stdout;
extern FILE *stderr;
#define EOF (-1)
#define SEEK_SET 0
#define SEEK_CUR 1
#define SEEK_END 2
#define BUFSIZ 1024
#define FILENAME_MAX 260
#define TMP_MAX 32
FILE *fopen(const char *path, const char *mode);
FILE *fdopen(int fd, const char *mode);
FILE *freopen(const char *path, const char *mode, FILE *stream);
int fclose(FILE *stream);
int fgetc(FILE *stream);
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);
int fseek(FILE *stream, long offset, int whence);
long ftell(FILE *stream);
int getc(FILE *stream);
int ungetc(int c, FILE *stream);
char *fgets(char *s, int n, FILE *stream);
int fputs(const char *s, FILE *stream);
int feof(FILE *stream);
int ferror(FILE *stream);
void clearerr(FILE *stream);
int fflush(FILE *stream);
int fputc(int c, FILE *stream);
int putchar(int c);
int fprintf(FILE *stream, const char *fmt, ...);
int vfprintf(FILE *stream, const char *fmt, va_list ap);
long filelength(FILE *f);
int vsnprintf(char *str, size_t size, const char *fmt, va_list ap);
int snprintf(char *str, size_t size, const char *fmt, ...);
int sprintf(char *str, const char *fmt, ...);
int sscanf(const char *str, const char *fmt, ...);
int remove(const char *path);
int rename(const char *oldpath, const char *newpath);
FILE *tmpfile(void);
char *tmpnam(char *s);
void puts(const char *s);
void printf(const char *fmt, ...);
#endif

View file

@ -0,0 +1,47 @@
#ifndef STDLIB_H
#define STDLIB_H
#include <stddef.h>
#include <stdint.h>
extern char **environ;
void* malloc(size_t size);
void free(void* ptr);
void* calloc(size_t nmemb, size_t size);
void* realloc(void* ptr, size_t size);
void *memset(void *s, int c, size_t n);
void *memcpy(void *dest, const void *src, size_t n);
#include "string.h"
// Math/Utility functions
int atoi(const char *nptr);
void itoa(int n, char *buf);
int abs(int x);
double strtod(const char *nptr, char **endptr);
float strtof(const char *nptr, char **endptr);
long double strtold(const char *nptr, char **endptr);
long strtol(const char *nptr, char **endptr, int base);
unsigned long strtoul(const char *nptr, char **endptr, int base);
unsigned long long strtoull(const char *nptr, char **endptr, int base);
void qsort(void *base, size_t nmemb, size_t size, int (*compar)(const void *, const void *));
// IO functions
void puts(const char *s);
void printf(const char *fmt, ...);
// Runtime stubs
int system(const char *command);
char *getenv(const char *name);
void abort(void);
// System/Process functions
int chdir(const char *path);
char* getcwd(char *buf, int size);
char *realpath(const char *path, char *resolved_path);
int access(const char *pathname, int mode);
void sleep(int ms);
void exit(int status);
void _exit(int status);
#endif

View file

@ -0,0 +1,28 @@
#ifndef BOREDOS_LIBC_STRING_H
#define BOREDOS_LIBC_STRING_H
#include <stddef.h>
void *memmove(void *dest, const void *src, size_t n);
int memcmp(const void *s1, const void *s2, size_t n);
void *memcpy(void *dest, const void *src, size_t n);
void *memset(void *s, int c, size_t n);
void *memchr(const void *s, int c, size_t n);
char *strchr(const char *s, int c);
char *strrchr(const char *s, int c);
char *strpbrk(const char *s, const char *accept);
char *strstr(const char *haystack, const char *needle);
size_t strspn(const char *s, const char *accept);
size_t strcspn(const char *s, const char *reject);
size_t strlen(const char *s);
int strcmp(const char *s1, const char *s2);
int strncmp(const char *s1, const char *s2, size_t n);
int strncasecmp(const char *s1, const char *s2, size_t n);
int strcasecmp(const char *s1, const char *s2);
int strcoll(const char *s1, const char *s2);
char* strcpy(char *dest, const char *src);
char* strcat(char *dest, const char *src);
char *strdup(const char *s);
char *strerror(int errnum);
#endif

View file

@ -0,0 +1,14 @@
#ifndef _SYS_MMAN_H
#define _SYS_MMAN_H
#define PROT_READ 0x1
#define PROT_WRITE 0x2
#define PROT_EXEC 0x4
#define MAP_SHARED 0x01
#define MAP_PRIVATE 0x02
#define MAP_FIXED 0x10
#define MAP_ANONYMOUS 0x20
#define MAP_FAILED ((void *)-1)
void *mmap(void *addr, unsigned long length, int prot, int flags, int fd, long offset);
int munmap(void *addr, unsigned long length);
int mprotect(void *addr, unsigned long length, int prot);
#endif

View file

@ -0,0 +1,47 @@
#ifndef BOREDOS_LIBC_SYS_STAT_H
#define BOREDOS_LIBC_SYS_STAT_H
#include "types.h"
typedef long time_t;
struct stat {
unsigned long st_dev;
unsigned long st_ino;
mode_t st_mode;
unsigned long st_nlink;
uid_t st_uid;
gid_t st_gid;
unsigned long st_rdev;
int st_size;
long st_blksize;
long st_blocks;
time_t st_atime;
time_t st_mtime;
time_t st_ctime;
};
#define S_IFMT 0170000
#define S_IFIFO 0010000
#define S_IFCHR 0020000
#define S_IFDIR 0040000
#define S_IFREG 0100000
#define S_IRUSR 0400
#define S_IWUSR 0200
#define S_IXUSR 0100
#define S_IRGRP 0040
#define S_IWGRP 0020
#define S_IXGRP 0010
#define S_IROTH 0004
#define S_IWOTH 0002
#define S_IXOTH 0001
#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
int stat(const char *pathname, struct stat *statbuf);
int fstat(int fd, struct stat *statbuf);
int mkdir(const char *pathname, int mode);
#endif

View file

@ -0,0 +1,6 @@
#ifndef _SYS_TIME_H
#define _SYS_TIME_H
struct timeval { long tv_sec; long tv_usec; };
struct timezone { int tz_minuteswest; int tz_dsttime; };
int gettimeofday(struct timeval *tv, void *tz);
#endif

View file

@ -0,0 +1,11 @@
#ifndef BOREDOS_LIBC_SYS_TYPES_H
#define BOREDOS_LIBC_SYS_TYPES_H
typedef long ssize_t;
typedef long off_t;
typedef unsigned int mode_t;
typedef int pid_t;
typedef unsigned int uid_t;
typedef unsigned int gid_t;
#endif

View file

@ -0,0 +1,3 @@
#ifndef _SYS_UCONTEXT_H
#define _SYS_UCONTEXT_H
#endif

View file

@ -0,0 +1,15 @@
#ifndef BOREDOS_LIBC_SYS_WAIT_H
#define BOREDOS_LIBC_SYS_WAIT_H
#include "../sys/types.h"
#define WNOHANG 1
#define WEXITSTATUS(status) (((status) >> 8) & 0xff)
#define WIFEXITED(status) ((((status) & 0x7f) == 0) ? 1 : 0)
#define WTERMSIG(status) ((status) & 0x7f)
#define WIFSIGNALED(status) (((status) & 0x7f) != 0)
pid_t waitpid(pid_t pid, int *status, int options);
#endif

View file

@ -0,0 +1,292 @@
#ifndef SYSCALL_H
#define SYSCALL_H
#include <stdint.h>
#include <stddef.h>
#include <stdbool.h>
// Standard syscalls available from Kernel mode
#define SYS_EXIT 0
#define SYS_WRITE 1
#define SYS_GUI 3
#define SYS_FS 4
#define SYS_SYSTEM 5
#define SYS_KILL 10
#define SYS_SBRK 9
// FS Commands
#define FS_CMD_OPEN 1
#define FS_CMD_READ 2
#define FS_CMD_WRITE 3
#define FS_CMD_CLOSE 4
#define FS_CMD_SEEK 5
#define FS_CMD_TELL 6
#define FS_CMD_LIST 7
#define FS_CMD_DELETE 8
#define FS_CMD_SIZE 9
#define FS_CMD_MKDIR 10
#define FS_CMD_EXISTS 11
#define FS_CMD_GETCWD 12
#define FS_CMD_CHDIR 13
#define FS_CMD_GET_INFO 14
#define FS_CMD_DUP 15
#define FS_CMD_DUP2 16
#define FS_CMD_PIPE 17
#define FS_CMD_FCNTL 18
// System Commands (via SYS_SYSTEM)
#define SYSTEM_CMD_SET_BG_COLOR 1
#define SYSTEM_CMD_SET_BG_PATTERN 2
#define SYSTEM_CMD_SET_WALLPAPER 3
#define SYSTEM_CMD_SET_DESKTOP_PROP 4
#define SYSTEM_CMD_SET_MOUSE_SPEED 5
#define SYSTEM_CMD_NETWORK_INIT 6
#define SYSTEM_CMD_GET_DESKTOP_PROP 7
#define SYSTEM_CMD_GET_MOUSE_SPEED 8
#define SYSTEM_CMD_GET_WALLPAPER_THUMB 9
#define SYSTEM_CMD_CLEAR_SCREEN 10
#define SYSTEM_CMD_RTC_GET 11
#define SYSTEM_CMD_REBOOT 12
#define SYSTEM_CMD_SHUTDOWN 13
#define SYSTEM_CMD_BEEP 14
#define SYSTEM_CMD_GET_MEM_INFO 15
#define SYSTEM_CMD_GET_TICKS 16
#define SYSTEM_CMD_PCI_LIST 17
#define SYSTEM_CMD_NETWORK_DHCP 18
#define SYSTEM_CMD_NETWORK_GET_MAC 19
#define SYSTEM_CMD_NETWORK_GET_IP 20
#define SYSTEM_CMD_NETWORK_SET_IP 21
#define SYSTEM_CMD_UDP_SEND 22
#define SYSTEM_CMD_NETWORK_GET_STATS 23
#define SYSTEM_CMD_NETWORK_GET_GATEWAY 24
#define SYSTEM_CMD_NETWORK_GET_DNS 25
#define SYSTEM_CMD_ICMP_PING 26
#define SYSTEM_CMD_NETWORK_IS_INIT 27
#define SYSTEM_CMD_NETWORK_HAS_IP 30
#define SYSTEM_CMD_GET_SHELL_CONFIG 28
#define SYSTEM_CMD_NETWORK_GET_NIC_NAME 48
#define SYSTEM_CMD_SET_KEYBOARD_LAYOUT 49
#define SYSTEM_CMD_GET_KEYBOARD_LAYOUT 51
#define SYSTEM_CMD_SET_TEXT_COLOR 29
#define SYSTEM_CMD_SET_WALLPAPER_PATH 31
#define SYSTEM_CMD_RTC_SET 32
#define SYSTEM_CMD_TCP_CONNECT 33
#define SYSTEM_CMD_TCP_SEND 34
#define SYSTEM_CMD_TCP_RECV 35
#define SYSTEM_CMD_TCP_CLOSE 36
#define SYSTEM_CMD_DNS_LOOKUP 37
#define SYSTEM_CMD_SET_DNS 38
#define SYSTEM_CMD_NET_UNLOCK 39
#define SYSTEM_CMD_SET_FONT 40
#define SYSTEM_CMD_SLEEP 46
#define SYSTEM_CMD_SET_RAW_MODE 41
#define SYSTEM_CMD_TCP_RECV_NB 42
#define SYSTEM_CMD_YIELD 43
#define SYSTEM_CMD_SET_RESOLUTION 47
#define SYSTEM_CMD_PARALLEL_RUN 50
#define SYSTEM_CMD_TTY_CREATE 60
#define SYSTEM_CMD_TTY_READ_OUT 61
#define SYSTEM_CMD_TTY_WRITE_IN 62
#define SYSTEM_CMD_TTY_READ_IN 63
#define SYSTEM_CMD_SPAWN 64
#define SYSTEM_CMD_TTY_SET_FG 65
#define SYSTEM_CMD_TTY_GET_FG 66
#define SYSTEM_CMD_TTY_KILL_FG 67
#define SYSTEM_CMD_TTY_KILL_ALL 68
#define SYSTEM_CMD_TTY_DESTROY 69
#define SYSTEM_CMD_EXEC 70
#define SYSTEM_CMD_WAITPID 71
#define SYSTEM_CMD_KILL_SIGNAL 72
#define SYSTEM_CMD_SIGACTION 73
#define SYSTEM_CMD_SIGPROCMASK 74
#define SYSTEM_CMD_SIGPENDING 75
#define SYSTEM_CMD_GET_ELF_METADATA 76
#define SYSTEM_CMD_GET_ELF_PRIMARY_IMAGE 77
#define SPAWN_FLAG_TERMINAL 0x1
#define SPAWN_FLAG_INHERIT_TTY 0x2
#define SPAWN_FLAG_TTY_ID 0x4
#define SPAWN_FLAG_BACKGROUND 0x8
// ELF app metadata (mirrors src/sys/elf.h, kept in sync manually)
#define BOREDOS_APP_METADATA_MAX_APP_NAME 64
#define BOREDOS_APP_METADATA_MAX_DESCRIPTION 192
#define BOREDOS_APP_METADATA_MAX_IMAGES 4
#define BOREDOS_APP_METADATA_MAX_IMAGE_PATH 160
typedef struct __attribute__((packed)) {
uint32_t magic;
uint16_t version;
uint16_t image_count;
uint16_t reserved;
char app_name[BOREDOS_APP_METADATA_MAX_APP_NAME];
char description[BOREDOS_APP_METADATA_MAX_DESCRIPTION];
char images[BOREDOS_APP_METADATA_MAX_IMAGES][BOREDOS_APP_METADATA_MAX_IMAGE_PATH];
} boredos_app_metadata_t;
// Internal assembly entry into Ring 0
extern uint64_t syscall0(uint64_t sys_num);
extern uint64_t syscall1(uint64_t sys_num, uint64_t arg1);
extern uint64_t syscall2(uint64_t sys_num, uint64_t arg1, uint64_t arg2);
extern uint64_t syscall3(uint64_t sys_num, uint64_t arg1, uint64_t arg2, uint64_t arg3);
extern uint64_t syscall4(uint64_t sys_num, uint64_t arg1, uint64_t arg2, uint64_t arg3, uint64_t arg4);
extern uint64_t syscall5(uint64_t sys_num, uint64_t arg1, uint64_t arg2, uint64_t arg3, uint64_t arg4, uint64_t arg5);
// Public API
void sys_exit(int status);
int sys_write(int fd, const char *buf, int len);
void *sys_sbrk(int incr);
void sys_kill(int pid);
int sys_system(int cmd, uint64_t arg1, uint64_t arg2, uint64_t arg3, uint64_t arg4);
typedef struct {
char os_name[64];
char os_version[64];
char os_codename[64];
char kernel_name[64];
char kernel_version[64];
char build_date[64];
char build_time[64];
char build_arch[64];
} os_info_t;
int sys_get_os_info(os_info_t *info);
// FS API
int sys_open(const char *path, const char *mode);
int sys_read(int fd, void *buf, uint32_t len);
int sys_write_fs(int fd, const void *buf, uint32_t len);
void sys_close(int fd);
int sys_seek(int fd, int offset, int whence);
uint32_t sys_tell(int fd);
uint32_t sys_size(int fd);
int sys_delete(const char *path);
int sys_mkdir(const char *path);
int sys_exists(const char *path);
int sys_getcwd(char *buf, int size);
int sys_chdir(const char *path);
int sys_dup(int oldfd);
int sys_dup2(int oldfd, int newfd);
int sys_pipe(int pipefd[2]);
int sys_fcntl(int fd, int cmd, int val);
int sys_tty_create(void);
int sys_tty_read_out(int tty_id, char *buf, int len);
int sys_tty_write_in(int tty_id, const char *buf, int len);
int sys_tty_read_in(char *buf, int len);
int sys_spawn(const char *path, const char *args, uint64_t flags, uint64_t tty_id);
int sys_exec(const char *path, const char *args);
int sys_waitpid(int pid, int *status, int options);
int sys_kill_signal(int pid, int sig);
int sys_sigaction(int sig, const void *act, void *oldact);
int sys_sigprocmask(int how, const unsigned long *set, unsigned long *oldset);
int sys_sigpending(unsigned long *set);
int sys_tty_set_fg(int tty_id, int pid);
int sys_tty_get_fg(int tty_id);
int sys_tty_kill_fg(int tty_id);
int sys_tty_kill_all(int tty_id);
int sys_tty_destroy(int tty_id);
typedef struct {
char name[256];
uint32_t size;
uint8_t is_directory;
uint32_t start_cluster;
uint16_t write_date;
uint16_t write_time;
} FAT32_FileInfo;
int sys_list(const char *path, FAT32_FileInfo *entries, int max_entries);
int sys_get_file_info(const char *path, FAT32_FileInfo *info);
typedef struct {
uint32_t pid;
char name[64];
uint64_t ticks;
size_t used_memory;
uint32_t is_idle;
} ProcessInfo;
// Network API
typedef struct { uint8_t bytes[6]; } net_mac_address_t;
typedef struct { uint8_t bytes[4]; } net_ipv4_address_t;
int sys_network_init(void);
int sys_network_dhcp_acquire(void);
int sys_network_get_mac(net_mac_address_t *mac);
int sys_network_get_nic_name(char *name_out);
int sys_network_get_ip(net_ipv4_address_t *ip);
int sys_network_set_ip(const net_ipv4_address_t *ip);
int sys_network_get_stat(int stat_type);
int sys_network_get_gateway(net_ipv4_address_t *ip);
int sys_network_get_dns(net_ipv4_address_t *ip);
int sys_get_dns_server(net_ipv4_address_t *ip);
int sys_udp_send(const net_ipv4_address_t *dest_ip, uint16_t dest_port, uint16_t src_port, const void *data, size_t data_len);
int sys_icmp_ping(const net_ipv4_address_t *dest_ip);
int sys_network_is_initialized(void);
int sys_network_has_ip(void);
uint64_t sys_get_shell_config(const char *key);
void sys_set_text_color(uint32_t color);
int sys_tcp_connect(const net_ipv4_address_t *ip, uint16_t port);
int sys_tcp_send(const void *data, size_t len);
int sys_tcp_recv(void *buf, size_t max_len);
int sys_tcp_recv_nb(void *buf, size_t max_len);
int sys_tcp_close(void);
int sys_dns_lookup(const char *name, net_ipv4_address_t *out_ip);
int sys_set_dns_server(const net_ipv4_address_t *ip);
void sys_network_force_unlock(void);
void sys_yield(void);
// ELF metadata API
int sys_get_elf_metadata(const char *path, boredos_app_metadata_t *out_metadata);
int sys_get_elf_primary_image(const char *path, char *out_path, size_t out_path_size);
// Disk Management Syscalls
#define SYSTEM_CMD_DISK_GET_COUNT 100
#define SYSTEM_CMD_DISK_GET_INFO 101
#define SYSTEM_CMD_DISK_MOUNT 105
#define SYSTEM_CMD_DISK_UMOUNT 106
#define SYSTEM_CMD_DISK_RESCAN 107
#define SYSTEM_CMD_DISK_SYNC 109
#define SYSTEM_CMD_DISK_WRITE_GPT 102
#define SYSTEM_CMD_DISK_WRITE_MBR 103
#define SYSTEM_CMD_DISK_MKFS_FAT32 104
#define SYSTEM_CMD_DISK_REPLACE_KERNEL 108
typedef struct {
char devname[16];
char label[32];
uint32_t type;
uint32_t total_sectors;
bool is_partition;
bool is_fat32;
bool is_esp;
uint32_t lba_offset;
} disk_info_t;
typedef struct {
uint32_t lba_start;
uint32_t sector_count;
uint8_t part_type;
uint8_t flags;
char label[36];
} partition_spec_t;
#define PART_FLAG_ESP 0x01
#define MIN_INSTALL_SECTORS 2097152
int sys_disk_get_count(void);
int sys_disk_get_info(int index, disk_info_t *out);
int sys_disk_write_gpt(const char *devname, partition_spec_t *parts, int count);
int sys_disk_write_mbr(const char *devname, partition_spec_t *parts, int count);
int sys_disk_mkfs_fat32(const char *devname, const char *label);
int sys_disk_mount(const char *devname, const char *mountpoint);
int sys_disk_umount(const char *mountpoint);
int sys_disk_sync(const char *mountpoint);
int sys_disk_rescan(const char *devname);
int sys_disk_replace_kernel(const char *src_path, const char *esp_mountpoint);
#endif

View file

@ -0,0 +1,11 @@
#ifndef SYSCALL_USER_H
#define SYSCALL_USER_H
#include "syscall.h"
#include <stddef.h>
static inline void sys_serial_write(const char *str) {
syscall2(8, 0, (uint64_t)str);
}
#endif

View file

@ -0,0 +1,30 @@
#ifndef BOREDOS_LIBC_TIME_H
#define BOREDOS_LIBC_TIME_H
#include <stddef.h>
typedef long long time_t;
typedef unsigned long long clock_t;
#define CLOCKS_PER_SEC 3000000000ULL
struct tm {
int tm_sec;
int tm_min;
int tm_hour;
int tm_mday;
int tm_mon;
int tm_year;
int tm_wday;
int tm_yday;
int tm_isdst;
};
time_t time(time_t *out);
clock_t clock(void);
struct tm *localtime(const time_t *timer);
struct tm *gmtime(const time_t *timer);
size_t strftime(char *s, size_t max, const char *fmt, const struct tm *tm);
time_t mktime(struct tm *tm);
#endif

View file

@ -0,0 +1,30 @@
#ifndef BOREDOS_LIBC_UNISTD_H
#define BOREDOS_LIBC_UNISTD_H
#include <stddef.h>
#include "sys/types.h"
#define SEEK_SET 0
#define SEEK_CUR 1
#define SEEK_END 2
#define F_OK 0
#define X_OK 1
#define W_OK 2
#define R_OK 4
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 unlink(const char *pathname);
int isatty(int fd);
int execv(const char *path, char *const argv[]);
int execve(const char *path, char *const argv[], char *const envp[]);
int execvp(const char *file, char *const argv[]);
int execl(const char *path, const char *arg, ...);
int execlp(const char *file, const char *arg, ...);
int execle(const char *path, const char *arg, ...);
pid_t waitpid(pid_t pid, int *status, int options);
#endif

View file

@ -0,0 +1,25 @@
#ifndef UTF_8_H
#define UTF_8_H
#include <stdint.h>
// Decode one UTF-8 codepoint
// s: input string
// advance: number of bytes consumed
uint32_t text_decode_utf8(const char *s, int *advance);
// Encode one codepoint into UTF-8
// out must be at least 4 bytes
// return: number of bytes written
int text_encode_utf8(uint32_t cp, char *out);
// Move to next UTF-8 character
const char* text_next_utf8(const char *s);
// Move to previous UTF-8 character
const char* text_prev_utf8(const char *start, const char *s);
// Count characters (not bytes)
int text_strlen_utf8(const char *s);
#endif

Binary file not shown.

BIN
src/userland/sdk/lib/libc.a Normal file

Binary file not shown.

BIN
src/userland/sdk/lib/libm.a Normal file

Binary file not shown.

Binary file not shown.