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/ --- kernel/include/stdio.h | 18 ---- kernel/include/stdlib.h | 15 ---- kernel/include/string.h | 20 ----- kernel/include/sys/cdefs.h | 6 -- kernel/makefile | 9 +- kernel/std/README.txt | 5 -- kernel/std/abort.c | 11 --- kernel/std/memcmp.c | 13 --- kernel/std/memcpy.c | 9 -- kernel/std/memmove.c | 14 --- kernel/std/memset.c | 8 -- kernel/std/printf.c | 192 ----------------------------------------- kernel/std/putchar.c | 9 -- kernel/std/puts.c | 5 -- kernel/std/strlen.c | 9 -- 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 ++ makefile | 17 ++-- 32 files changed, 428 insertions(+), 345 deletions(-) delete mode 100644 kernel/include/stdio.h delete mode 100644 kernel/include/stdlib.h delete mode 100644 kernel/include/string.h delete mode 100644 kernel/include/sys/cdefs.h delete mode 100644 kernel/std/README.txt delete mode 100644 kernel/std/abort.c delete mode 100644 kernel/std/memcmp.c delete mode 100644 kernel/std/memcpy.c delete mode 100644 kernel/std/memmove.c delete mode 100644 kernel/std/memset.c delete mode 100644 kernel/std/printf.c delete mode 100644 kernel/std/putchar.c delete mode 100644 kernel/std/puts.c delete mode 100644 kernel/std/strlen.c 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 diff --git a/kernel/include/stdio.h b/kernel/include/stdio.h deleted file mode 100644 index eb4e45b..0000000 --- a/kernel/include/stdio.h +++ /dev/null @@ -1,18 +0,0 @@ -#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/kernel/include/stdlib.h b/kernel/include/stdlib.h deleted file mode 100644 index 1d1ee32..0000000 --- a/kernel/include/stdlib.h +++ /dev/null @@ -1,15 +0,0 @@ -#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/kernel/include/string.h b/kernel/include/string.h deleted file mode 100644 index 4f6b5bd..0000000 --- a/kernel/include/string.h +++ /dev/null @@ -1,20 +0,0 @@ -#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/kernel/include/sys/cdefs.h b/kernel/include/sys/cdefs.h deleted file mode 100644 index 1e2c277..0000000 --- a/kernel/include/sys/cdefs.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _SYS_CDEFS_H -#define _SYS_CDEFS_H 1 - - - -#endif \ No newline at end of file diff --git a/kernel/makefile b/kernel/makefile index 6c563b8..a9407bd 100644 --- a/kernel/makefile +++ b/kernel/makefile @@ -1,5 +1,4 @@ # Kernel makefile -#absolute hell ifndef GAS GAS = i686-elf-as @@ -29,7 +28,7 @@ ifndef SYSROOT endif -LIBS = -nostdlib -lgcc +LIBS = -nostdlib -lgcc -lck #Find all the source files C_SOURCES := $(shell find $(PWD)/kernel -type f -name '*.c') @@ -44,8 +43,8 @@ OBJECTS := $(patsubst %.c,%.o,$(C_SOURCES)) OBJECTS += $(patsubst %.cpp,%.o,$(CPP_SOURCES)) OBJECTS += $(patsubst %.asm,%.o,$(ASMFILES)) -DEPFILES := $(patsubst %.c,%.d,$(SRCFILES)) -DEPFILES += $(patsubst %.cpp,%.d,$(SRCFILES)) +DEPFILES := $(patsubst %.c,%.d,$(C_SOURCES)) +DEPFILES += $(patsubst %.cpp,%.d,$(CPP_SOURCES)) LINKLST := crti.o LINKLST += $(CRTBEGIN) @@ -87,4 +86,4 @@ install-headers: clean: $(info [INFO] Cleaning) - rm ${OBJECTS} ${DEPFILES} crti.o crtn.o \ No newline at end of file + $(RM) ${OBJECTS} $(DEPFILES) crti.o crtn.o \ No newline at end of file diff --git a/kernel/std/README.txt b/kernel/std/README.txt deleted file mode 100644 index 2ad6cb4..0000000 --- a/kernel/std/README.txt +++ /dev/null @@ -1,5 +0,0 @@ -a temporary(?) libc for the kernel - -code from meaty skeleton from osdev.org - -todo: change back to .c and seperate it as a library or something \ No newline at end of file diff --git a/kernel/std/abort.c b/kernel/std/abort.c deleted file mode 100644 index 83873e8..0000000 --- a/kernel/std/abort.c +++ /dev/null @@ -1,11 +0,0 @@ -#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/kernel/std/memcmp.c b/kernel/std/memcmp.c deleted file mode 100644 index 93141e1..0000000 --- a/kernel/std/memcmp.c +++ /dev/null @@ -1,13 +0,0 @@ -#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/kernel/std/memcpy.c b/kernel/std/memcpy.c deleted file mode 100644 index 7e09be7..0000000 --- a/kernel/std/memcpy.c +++ /dev/null @@ -1,9 +0,0 @@ -#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/kernel/std/memmove.c b/kernel/std/memmove.c deleted file mode 100644 index 98c787f..0000000 --- a/kernel/std/memmove.c +++ /dev/null @@ -1,14 +0,0 @@ -#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/kernel/std/memset.c b/kernel/std/memset.c deleted file mode 100644 index 67dadfe..0000000 --- a/kernel/std/memset.c +++ /dev/null @@ -1,8 +0,0 @@ -#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/kernel/std/printf.c b/kernel/std/printf.c deleted file mode 100644 index fe45892..0000000 --- a/kernel/std/printf.c +++ /dev/null @@ -1,192 +0,0 @@ -#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/kernel/std/putchar.c b/kernel/std/putchar.c deleted file mode 100644 index c5a7976..0000000 --- a/kernel/std/putchar.c +++ /dev/null @@ -1,9 +0,0 @@ -#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/kernel/std/puts.c b/kernel/std/puts.c deleted file mode 100644 index 8c8c036..0000000 --- a/kernel/std/puts.c +++ /dev/null @@ -1,5 +0,0 @@ -#include - -int puts(const char* string) { - return printf("%s\n", string); -} \ No newline at end of file diff --git a/kernel/std/strlen.c b/kernel/std/strlen.c deleted file mode 100644 index 441622a..0000000 --- a/kernel/std/strlen.c +++ /dev/null @@ -1,9 +0,0 @@ -#include - -size_t strlen(const char* str) { - size_t len = 0; - while (str[len]) { - ++len; - } - return len; -} \ No newline at end of file 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 diff --git a/makefile b/makefile index e4934bf..8ec9152 100644 --- a/makefile +++ b/makefile @@ -16,11 +16,11 @@ ASMFLAGS = -felf32 .PHONY: all kernel.bin grub multiboot_test clean -all: kernel.bin grub +all: libck.a kernel.bin grub -#libc.a: -# $(info [INFO] Building libc) -# $(MAKE) -C ./libc/ ARCH=$(ARCH) PREFIX=$(PWD) CC=$(CC) CXX=$(CXX) LD=$(LD) NASM=$(NASM) SYSROOT=$(SYSROOT) +libck.a: + $(info [INFO] Building libck) + $(MAKE) -C ./libs/libck/ ARCH=$(ARCH) PREFIX=$(PWD) CC=$(CC) CXX=$(CXX) LD=$(LD) NASM=$(NASM) SYSROOT=$(SYSROOT) kernel.bin: $(info [INFO] Building kernel) @@ -35,11 +35,16 @@ grub: kernel.bin grub.cfg qemu: grub $(QEMU) -no-shutdown -no-reboot --serial stdio -s -m 512 -hda $(OS_NAME).iso -install: install-headers +install: install-headers install-libraries install-headers: $(MAKE) -C ./kernel/ install-headers SYSROOT=$(SYSROOT) + $(MAKE) -C ./libs/libck/ install-headers SYSROOT=$(SYSROOT) + +install-libraries: + $(MAKE) -C ./libs/libck/ install-lib SYSROOT=$(SYSROOT) clean: -@$(MAKE) -C ./kernel/ clean SYSROOT=$(SYSROOT) - -@$(RM) $(wildcard *.bin) + -@$(MAKE) -C ./libs/libck/ clean SYSROOT=$(SYSROOT) + -@$(RM) $(wildcard *.bin *.a) -- cgit v1.2.3-70-g09d2