aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/std
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/std')
-rw-r--r--kernel/std/README.txt5
-rw-r--r--kernel/std/abort.c11
-rw-r--r--kernel/std/memcmp.c13
-rw-r--r--kernel/std/memcpy.c9
-rw-r--r--kernel/std/memmove.c14
-rw-r--r--kernel/std/memset.c8
-rw-r--r--kernel/std/printf.c80
-rw-r--r--kernel/std/putchar.c9
-rw-r--r--kernel/std/puts.c5
-rw-r--r--kernel/std/strlen.c9
10 files changed, 163 insertions, 0 deletions
diff --git a/kernel/std/README.txt b/kernel/std/README.txt
new file mode 100644
index 0000000..2ad6cb4
--- /dev/null
+++ b/kernel/std/README.txt
@@ -0,0 +1,5 @@
+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
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..c383cad
--- /dev/null
+++ b/kernel/std/printf.c
@@ -0,0 +1,80 @@
+#include <limits.h>
+#include <stdbool.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <string.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;
+}
+
+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 == '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..c5a7976
--- /dev/null
+++ b/kernel/std/putchar.c
@@ -0,0 +1,9 @@
+#include <stdio.h>
+
+#include <arch/i386/tmtty.h>
+
+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
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