diff options
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/include/stdio.h | 18 | ||||
| -rw-r--r-- | kernel/include/stdlib.h | 15 | ||||
| -rw-r--r-- | kernel/include/string.h | 20 | ||||
| -rw-r--r-- | kernel/include/sys/cdefs.h | 6 | ||||
| -rw-r--r-- | kernel/makefile | 16 | ||||
| -rw-r--r-- | kernel/std/README.txt | 3 | ||||
| -rw-r--r-- | kernel/std/abort.c | 11 | ||||
| -rw-r--r-- | kernel/std/memcmp.c | 13 | ||||
| -rw-r--r-- | kernel/std/memcpy.c | 9 | ||||
| -rw-r--r-- | kernel/std/memmove.c | 14 | ||||
| -rw-r--r-- | kernel/std/memset.c | 8 | ||||
| -rw-r--r-- | kernel/std/printf.c | 199 | ||||
| -rw-r--r-- | kernel/std/putchar.c | 11 | ||||
| -rw-r--r-- | kernel/std/puts.c | 5 | ||||
| -rw-r--r-- | kernel/std/strlen.c | 9 |
15 files changed, 350 insertions, 7 deletions
diff --git a/kernel/include/stdio.h b/kernel/include/stdio.h new file mode 100644 index 0000000..eb4e45b --- /dev/null +++ b/kernel/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/kernel/include/stdlib.h b/kernel/include/stdlib.h new file mode 100644 index 0000000..1d1ee32 --- /dev/null +++ b/kernel/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/kernel/include/string.h b/kernel/include/string.h new file mode 100644 index 0000000..4f6b5bd --- /dev/null +++ b/kernel/include/string.h @@ -0,0 +1,20 @@ +#ifndef _STRING_H
+#define _STRING_H 1
+
+#include <stddef.h>
+
+#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 new file mode 100644 index 0000000..1e2c277 --- /dev/null +++ b/kernel/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/kernel/makefile b/kernel/makefile index a855808..52f4d00 100644 --- a/kernel/makefile +++ b/kernel/makefile @@ -20,20 +20,22 @@ ifndef SYSROOT $(error No sysroot specified)
endif
-LIBS = -nostdlib -lc -lgcc
+LIBS = -nostdlib -lgcc
#Find all the source files
+C_SRCS := $(shell find . -type f -name '*.c' -not -path './arch/*') \
+ $(shell find $(PWD)/kernel/arch/$(ARCH) -type f -name '*.c')
CPP_SRCS := $(shell find . -type f -name '*.cpp' -not -path './arch/*') \
$(shell find $(PWD)/kernel/arch/$(ARCH) -type f -name '*.cpp')
HEADERS := $(shell find ./include -type f -name '*.h')
ASMFILES := $(shell find . -type f -name '*.asm' -not -path './arch/*') \
$(shell find $(PWD)/kernel/arch/$(ARCH) -type f -name '*.asm')
-#OBJS := $(patsubst %.c,%.o,$(C_SOURCES))
-OBJS := $(patsubst %.cpp,%.o,$(CPP_SRCS))
+OBJS := $(patsubst %.c,%.o,$(C_SRCS))
+OBJS += $(patsubst %.cpp,%.o,$(CPP_SRCS))
OBJS += $(patsubst %.asm,%.o,$(ASMFILES))
-#DEPFILES := $(patsubst %.c,%.d,$(C_SOURCES))
+DEPFILES := $(patsubst %.c,%.d,$(C_SOURCES))
DEPFILES := $(patsubst %.cpp,%.d,$(CPP_SRCS))
# LINKLST := crti.o
@@ -62,7 +64,7 @@ kernel.bin: ${OBJS} $(CC) $(CFLAGS) -MMD -MP -c $< -o $@
%.o: %.asm
- $(info [INFO] Assembling $<)
+# $(info [INFO] Assembling $<)
$(NASM) $< $(ASMFLAGS) -o $@ -g
# crti.o:
@@ -71,8 +73,8 @@ kernel.bin: ${OBJS} # crtn.o:
# $(NASM) arch/$(ARCH)/crtn.asm $(ASMFLAGS) -o $@
-install-headers: $(HEADERS)
- cp -r --preserve=timestamps include/. $(SYSROOT)/usr/include
+# install-headers: $(HEADERS)
+# cp -r --preserve=timestamps include/. $(SYSROOT)/usr/include
clean:
$(info [INFO] Cleaning)
diff --git a/kernel/std/README.txt b/kernel/std/README.txt new file mode 100644 index 0000000..ef7c787 --- /dev/null +++ b/kernel/std/README.txt @@ -0,0 +1,3 @@ +some libc functions for the kernel
+
+code based off meaty skeleton from osdev.org
diff --git a/kernel/std/abort.c b/kernel/std/abort.c new file mode 100644 index 0000000..83873e8 --- /dev/null +++ b/kernel/std/abort.c @@ -0,0 +1,11 @@ +#include <stdio.h>
+#include <stdlib.h>
+
+__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 new file mode 100644 index 0000000..93141e1 --- /dev/null +++ b/kernel/std/memcmp.c @@ -0,0 +1,13 @@ +#include <string.h>
+
+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 new file mode 100644 index 0000000..7e09be7 --- /dev/null +++ b/kernel/std/memcpy.c @@ -0,0 +1,9 @@ +#include <string.h>
+
+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 new file mode 100644 index 0000000..98c787f --- /dev/null +++ b/kernel/std/memmove.c @@ -0,0 +1,14 @@ +#include <string.h>
+
+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 new file mode 100644 index 0000000..67dadfe --- /dev/null +++ b/kernel/std/memset.c @@ -0,0 +1,8 @@ +#include <string.h>
+
+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 new file mode 100644 index 0000000..0bb5506 --- /dev/null +++ b/kernel/std/printf.c @@ -0,0 +1,199 @@ +#include <limits.h>
+#include <stdbool.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdint.h>
+
+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) {
+ 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
+ size_t start = 0;
+ size_t end = cou - 1;
+ while (start < end) {
+ char temp = str[start];
+ str[start] = str[end];
+ str[end] = temp;
+ ++start;
+ --end;
+ }
+
+ 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) {
+ size_t 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
+ size_t start = 0;
+ size_t end = cou - 1;
+ while (start < end) {
+ char temp = str[start];
+ str[start] = str[end];
+ str[end] = temp;
+ ++start;
+ --end;
+ }
+
+ 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 new file mode 100644 index 0000000..f0f5783 --- /dev/null +++ b/kernel/std/putchar.c @@ -0,0 +1,11 @@ +#include <stdio.h>
+
+//#include <arch/i386/tmtty.h>
+#include <arch/x86_64/serial.h>
+
+int putchar(int ic) {
+ char c = (char) ic;
+ serial_putchar(c);
+ //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 new file mode 100644 index 0000000..8c8c036 --- /dev/null +++ b/kernel/std/puts.c @@ -0,0 +1,5 @@ +#include <stdio.h>
+
+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 new file mode 100644 index 0000000..441622a --- /dev/null +++ b/kernel/std/strlen.c @@ -0,0 +1,9 @@ +#include <string.h>
+
+size_t strlen(const char* str) {
+ size_t len = 0;
+ while (str[len]) {
+ ++len;
+ }
+ return len;
+}
\ No newline at end of file |
