From bb59107bd06a6a252b3743f17e55e3c17896db35 Mon Sep 17 00:00:00 2001 From: EmulatedSeasons <89668582+EmulatedSeasons@users.noreply.github.com> Date: Sun, 7 Jan 2024 03:19:28 -0500 Subject: moved kernel libc stuff to libs/libck/ --- libs/libck/README.txt | 5 ++ libs/libck/abort.c | 11 +++ libs/libck/include/stdio.h | 18 ++++ libs/libck/include/stdlib.h | 15 ++++ libs/libck/include/string.h | 20 +++++ libs/libck/include/sys/cdefs.h | 6 ++ libs/libck/libck.a | Bin 0 -> 38554 bytes libs/libck/makefile | 79 +++++++++++++++++ libs/libck/memcmp.c | 13 +++ libs/libck/memcpy.c | 9 ++ libs/libck/memmove.c | 14 +++ libs/libck/memset.c | 8 ++ libs/libck/printf.c | 192 +++++++++++++++++++++++++++++++++++++++++ libs/libck/putchar.c | 9 ++ libs/libck/puts.c | 5 ++ libs/libck/strlen.c | 9 ++ 16 files changed, 413 insertions(+) create mode 100644 libs/libck/README.txt create mode 100644 libs/libck/abort.c create mode 100644 libs/libck/include/stdio.h create mode 100644 libs/libck/include/stdlib.h create mode 100644 libs/libck/include/string.h create mode 100644 libs/libck/include/sys/cdefs.h create mode 100644 libs/libck/libck.a create mode 100644 libs/libck/makefile create mode 100644 libs/libck/memcmp.c create mode 100644 libs/libck/memcpy.c create mode 100644 libs/libck/memmove.c create mode 100644 libs/libck/memset.c create mode 100644 libs/libck/printf.c create mode 100644 libs/libck/putchar.c create mode 100644 libs/libck/puts.c create mode 100644 libs/libck/strlen.c (limited to 'libs') diff --git a/libs/libck/README.txt b/libs/libck/README.txt new file mode 100644 index 0000000..6806bd4 --- /dev/null +++ b/libs/libck/README.txt @@ -0,0 +1,5 @@ +a temporary(?) libc for the kernel + +code based off meaty skeleton from osdev.org + +todo: \ No newline at end of file diff --git a/libs/libck/abort.c b/libs/libck/abort.c new file mode 100644 index 0000000..83873e8 --- /dev/null +++ b/libs/libck/abort.c @@ -0,0 +1,11 @@ +#include +#include + +__attribute__((__noreturn__)) +void abort(void) { + // TODO: Add proper kernel panic. + printf("kernel: panic: abort()\n"); + asm volatile("hlt"); + while (1) { } + __builtin_unreachable(); +} \ No newline at end of file diff --git a/libs/libck/include/stdio.h b/libs/libck/include/stdio.h new file mode 100644 index 0000000..eb4e45b --- /dev/null +++ b/libs/libck/include/stdio.h @@ -0,0 +1,18 @@ +#ifndef _STDIO_H +#define _STDIO_H 1 + +#define EOF (-1) + +#ifdef __cplusplus +extern "C" { +#endif + +int printf(const char* __restrict, ...); +int putchar(int); +int puts(const char*); + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/libs/libck/include/stdlib.h b/libs/libck/include/stdlib.h new file mode 100644 index 0000000..1d1ee32 --- /dev/null +++ b/libs/libck/include/stdlib.h @@ -0,0 +1,15 @@ +#ifndef _STDLIB_H +#define _STDLIB_H 1 + +#ifdef __cplusplus +extern "C" { +#endif + +__attribute__((__noreturn__)) +void abort(void); + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/libs/libck/include/string.h b/libs/libck/include/string.h new file mode 100644 index 0000000..4f6b5bd --- /dev/null +++ b/libs/libck/include/string.h @@ -0,0 +1,20 @@ +#ifndef _STRING_H +#define _STRING_H 1 + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +int memcmp(const void*, const void*, size_t); +void* memcpy(void* __restrict, const void* __restrict, size_t); +void* memmove(void*, const void*, size_t); +void* memset(void*, int, size_t); +size_t strlen(const char*); + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/libs/libck/include/sys/cdefs.h b/libs/libck/include/sys/cdefs.h new file mode 100644 index 0000000..1e2c277 --- /dev/null +++ b/libs/libck/include/sys/cdefs.h @@ -0,0 +1,6 @@ +#ifndef _SYS_CDEFS_H +#define _SYS_CDEFS_H 1 + + + +#endif \ No newline at end of file diff --git a/libs/libck/libck.a b/libs/libck/libck.a new file mode 100644 index 0000000..1dba359 Binary files /dev/null and b/libs/libck/libck.a differ diff --git a/libs/libck/makefile b/libs/libck/makefile new file mode 100644 index 0000000..5f7b270 --- /dev/null +++ b/libs/libck/makefile @@ -0,0 +1,79 @@ +# libck makefile + +ifndef AR + AR = i686-elf-ar +endif + +ifndef CFLAGS + CFLAGS = -ffreestanding -Wall -Wextra -g -std=gnu11 -O2 -Iinclude + CFLAGS += --sysroot="$(SYSROOT)" + CFLAGS += -isystem="/usr/include" +endif + +ifndef CXXFLAGS + CXXFLAGS = -ffreestanding -Wall -Wextra -fno-exceptions -fno-rtti -D__is_kernel -g -O2 -Iinclude + CXXFLAGS += -Iinclude + CXXFLAGS += --sysroot="$(SYSROOT)" + CXXFLAGS += -isystem="/usr/include" +endif + +ifndef LDFLAGS + LDFLAGS = -T arch/$(ARCH)/linker.ld -ffreestanding -g -O2 -Iinclude + LDFLAGS += --sysroot="$(SYSROOT)" + LDFLAGS += -isystem="/usr/include" +endif + +ifndef SYSROOT + $(error No sysroot specified) +endif + + +LIBS = -nostdlib -lgcc + +#Find all the source files +C_SOURCES := $(shell find $(PWD) -type f -name '*.c') +#CPP_SOURCES := $(shell find $(PWD)/kernel -type f -name '*.cpp') +HEADERS := $(shell find $(PWD) -type f -name '*.h') +#ASMFILES := $(shell find $(PWD) -type f -name '*.asm') + +OBJECTS := $(patsubst %.c,%.o,$(C_SOURCES)) +# OBJECTS += $(patsubst %.cpp,%.o,$(CPP_SOURCES)) +# OBJECTS += $(patsubst %.asm,%.o,$(ASMFILES)) + +DEPFILES := $(patsubst %.c,%.d,$(C_SOURCES)) +# DEPFILES += $(patsubst %.cpp,%.d,$(CPP_SOURCES)) + +LINKLST += $(OBJECTS) +LINKLST += $(LIBS) + +-include $(DEPFILES) + +.PHONY: all install-headers install-lib clean + +all: libck.a install-headers install-lib + +libck.a: ${OBJECTS} + $(info [INFO] Linking $<) + $(AR) rcs $@ $(OBJECTS) + +%.o: %.cpp + $(info [INFO] Compiling $<) + $(CXX) ${CXXFLAGS} -MMD -MP -c $< -o $@ + +%.o: %.c + $(info [INFO] Compiling $<) + $(CC) $(CFLAGS) -MMD -MP -c $< -o $@ + +%.o: %.asm + $(info [INFO] Assembling $<) + $(NASM) $< -felf32 -o $@ -g + +install-headers: + cp -r --preserve=timestamps include/. $(SYSROOT)/usr/include + +install-lib: libck.a + cp -r $< $(SYSROOT)/usr/lib/. + +clean: + $(info [INFO] Cleaning) + $(RM) ${OBJECTS} $(DEPFILES) \ No newline at end of file diff --git a/libs/libck/memcmp.c b/libs/libck/memcmp.c new file mode 100644 index 0000000..93141e1 --- /dev/null +++ b/libs/libck/memcmp.c @@ -0,0 +1,13 @@ +#include + +int memcmp(const void* aptr, const void* bptr, size_t size) { + const unsigned char* a = (const unsigned char*) aptr; + const unsigned char* b = (const unsigned char*) bptr; + for (size_t i = 0; i < size; i++) { + if (a[i] < b[i]) + return -1; + else if (b[i] < a[i]) + return 1; + } + return 0; +} \ No newline at end of file diff --git a/libs/libck/memcpy.c b/libs/libck/memcpy.c new file mode 100644 index 0000000..7e09be7 --- /dev/null +++ b/libs/libck/memcpy.c @@ -0,0 +1,9 @@ +#include + +void* memcpy(void* restrict dstptr, const void* restrict srcptr, size_t size) { + unsigned char* dst = (unsigned char*) dstptr; + const unsigned char* src = (const unsigned char*) srcptr; + for (size_t i=0; i < size; i++) + dst[i] = src[i]; + return dstptr; +} \ No newline at end of file diff --git a/libs/libck/memmove.c b/libs/libck/memmove.c new file mode 100644 index 0000000..98c787f --- /dev/null +++ b/libs/libck/memmove.c @@ -0,0 +1,14 @@ +#include + +void* memmove(void* dstptr, const void* srcptr, size_t size) { + unsigned char* dst = (unsigned char*) dstptr; + const unsigned char* src = (const unsigned char*) srcptr; + if (dst < src) { + for (size_t i = 0; i < size; i++) + dst[i] = src[i]; + } else { + for (size_t i = size; i != 0; i--) + dst[i-1] = src[i-1]; + } + return dstptr; +} \ No newline at end of file diff --git a/libs/libck/memset.c b/libs/libck/memset.c new file mode 100644 index 0000000..67dadfe --- /dev/null +++ b/libs/libck/memset.c @@ -0,0 +1,8 @@ +#include + +void* memset(void* bufptr, int value, size_t size) { + unsigned char* buf = (unsigned char*) bufptr; + for (size_t i = 0; i < size; i++) + buf[i] = (unsigned char) value; + return bufptr; +} \ No newline at end of file diff --git a/libs/libck/printf.c b/libs/libck/printf.c new file mode 100644 index 0000000..fe45892 --- /dev/null +++ b/libs/libck/printf.c @@ -0,0 +1,192 @@ +#include +#include +#include +#include +#include +#include + +static bool print(const char* data, size_t length) { + const unsigned char* bytes = (const unsigned char*) data; + for (size_t i = 0; i < length; i++) + if (putchar(bytes[i]) == EOF) + return false; + return true; +} + +// for %d and %x. +static const char* itoa(unsigned int num, char* str, unsigned int base) { + asm("xchgw %bx, %bx"); + int cou = 0; // nt + + if (num == 0) { // 0 + str[cou] = '0'; + str[++cou] = '\0'; + return str; + } + + while (num) + { + unsigned int rem = (num % base); + // brings the number up to ascii 0 + the digit + if (rem > 9) { + str[cou] = rem + '7'; // 7 = 55 + 10(A) = 65 + } else { + str[cou] = rem + '0'; + } + num /= base; + ++cou; + } + + // reverse the string + for (int i = 0; i < cou; i++) { + char temp = str[i]; + str[i] = str[cou - i - 1]; + str[cou - 1] = temp; + } + + str[cou] = '\0'; + return str; +} + +// have no idea if there's a better way to do this. for %lx +static const char* itoa_u64(unsigned long long num, char* str, int base) { + int cou = 0; // nt + + if (num == 0) { // 0 + str[cou] = '0'; + str[++cou] = '\0'; + return str; + } + + while (num) + { + unsigned long long rem = num % base; + // brings the number up to ascii 0 + the digit + if (rem > 9) { + str[cou] = rem + '7'; // 7 = 55 + 10(A) = 65 + } else { + str[cou] = rem + '0'; + } + num /= base; + ++cou; + } + + // reverse the string + for (int i = 0; i < cou; i++) { + char temp = str[i]; + str[i] = str[cou - i - 1]; + str[cou - 1] = temp; + } + + str[cou] = '\0'; + return str; +} + +int printf(const char* restrict format, ...) { + va_list parameters; + va_start(parameters, format); + + int written = 0; + + while (*format != '\0') { + size_t maxrem = INT_MAX - written; + + if (format[0] != '%' || format[1] == '%') { + if (format[0] == '%') + format++; + size_t amount = 1; + while (format[amount] && format[amount] != '%') + amount++; + if (maxrem < amount) { + // TODO: Set errno to EOVERFLOW. + return -1; + } + if (!print(format, amount)) + return -1; + format += amount; + written += amount; + continue; + } + + const char* format_begun_at = format++; + + if (*format == 'c') { + format++; + char c = (char) va_arg(parameters, int /* char promotes to int */); + if (!maxrem) { + // TODO: Set errno to EOVERFLOW. + return -1; + } + if (!print(&c, sizeof(c))) + return -1; + written++; + } else if (*format == 'd') { + format++; + char str[20]; // probably a long enough buffer + unsigned int d = va_arg(parameters, unsigned int); + itoa(d, str, 10); + size_t len = strlen(str); + if (maxrem < len) { + // TODO: Set errno to EOVERFLOW. + return -1; + } + if (!print(str, len)) + return -1; + written += len; + } else if (*format == 'x') { + format++; + char str[20]; // probably a long enough buffer + unsigned int d = va_arg(parameters, unsigned int); + itoa(d, str, 16); + size_t len = strlen(str); + if (maxrem < len) { + // TODO: Set errno to EOVERFLOW. + return -1; + } + if (!print(str, len)) + return -1; + written += len; + } else if (*format == 'l') { // for %lx and others that start with l + format++; + if (*format == 'x') { + format++; + char str[20]; // probably a long enough buffer + unsigned long long d = va_arg(parameters, unsigned long long); + itoa_u64(d, str, 16); + size_t len = strlen(str); + if (maxrem < len) { + // TODO: Set errno to EOVERFLOW. + return -1; + } + if (!print(str, len)) + return -1; + written += len; + } + } else if (*format == 's') { + format++; + const char* str = va_arg(parameters, const char*); + size_t len = strlen(str); + if (maxrem < len) { + // TODO: Set errno to EOVERFLOW. + return -1; + } + if (!print(str, len)) + return -1; + written += len; + } else { + format = format_begun_at; + size_t len = strlen(format); + if (maxrem < len) { + // TODO: Set errno to EOVERFLOW. + return -1; + } + if (!print(format, len)) + return -1; + written += len; + format += len; + } + } + + va_end(parameters); + return written; +} \ No newline at end of file diff --git a/libs/libck/putchar.c b/libs/libck/putchar.c new file mode 100644 index 0000000..c5a7976 --- /dev/null +++ b/libs/libck/putchar.c @@ -0,0 +1,9 @@ +#include + +#include + +int putchar(int ic) { + char c = (char) ic; + terminal_write(&c, sizeof(c)); + return ic; +} \ No newline at end of file diff --git a/libs/libck/puts.c b/libs/libck/puts.c new file mode 100644 index 0000000..8c8c036 --- /dev/null +++ b/libs/libck/puts.c @@ -0,0 +1,5 @@ +#include + +int puts(const char* string) { + return printf("%s\n", string); +} \ No newline at end of file diff --git a/libs/libck/strlen.c b/libs/libck/strlen.c new file mode 100644 index 0000000..441622a --- /dev/null +++ b/libs/libck/strlen.c @@ -0,0 +1,9 @@ +#include + +size_t strlen(const char* str) { + size_t len = 0; + while (str[len]) { + ++len; + } + return len; +} \ No newline at end of file -- cgit v1.2.3-70-g09d2