From 8a9208612eec8ddae4c418485d848ecfa0613699 Mon Sep 17 00:00:00 2001 From: Anton Kling Date: Mon, 30 Oct 2023 22:12:14 +0100 Subject: Meta: Move kernel and userland to their own folders. This is to allow both the kernel and the userland to share certain header files and to make the folder structure a bit more clear. --- kernel/libc/exit/assert.c | 12 ++++++ kernel/libc/include/assert.h | 19 +++++++++ kernel/libc/include/errno.h | 85 ++++++++++++++++++++++++++++++++++++++ kernel/libc/include/limits.h | 1 + kernel/libc/include/stdio.h | 9 ++++ kernel/libc/include/stdlib.h | 0 kernel/libc/include/string.h | 19 +++++++++ kernel/libc/include/time.h | 6 +++ kernel/libc/include/types.h | 27 ++++++++++++ kernel/libc/stdio/print.c | 97 ++++++++++++++++++++++++++++++++++++++++++++ kernel/libc/string/copy.c | 26 ++++++++++++ kernel/libc/string/isequal.c | 15 +++++++ kernel/libc/string/memcmp.c | 12 ++++++ kernel/libc/string/memcpy.c | 20 +++++++++ kernel/libc/string/memset.c | 9 ++++ kernel/libc/string/strcat.c | 6 +++ kernel/libc/string/strcmp.c | 8 ++++ kernel/libc/string/strcpy.c | 8 ++++ kernel/libc/string/strlcpy.c | 21 ++++++++++ kernel/libc/string/strlen.c | 8 ++++ kernel/libc/string/strncpy.c | 11 +++++ 21 files changed, 419 insertions(+) create mode 100644 kernel/libc/exit/assert.c create mode 100644 kernel/libc/include/assert.h create mode 100644 kernel/libc/include/errno.h create mode 100644 kernel/libc/include/limits.h create mode 100644 kernel/libc/include/stdio.h create mode 100644 kernel/libc/include/stdlib.h create mode 100644 kernel/libc/include/string.h create mode 100644 kernel/libc/include/time.h create mode 100644 kernel/libc/include/types.h create mode 100644 kernel/libc/stdio/print.c create mode 100644 kernel/libc/string/copy.c create mode 100644 kernel/libc/string/isequal.c create mode 100644 kernel/libc/string/memcmp.c create mode 100644 kernel/libc/string/memcpy.c create mode 100644 kernel/libc/string/memset.c create mode 100644 kernel/libc/string/strcat.c create mode 100644 kernel/libc/string/strcmp.c create mode 100644 kernel/libc/string/strcpy.c create mode 100644 kernel/libc/string/strlcpy.c create mode 100644 kernel/libc/string/strlen.c create mode 100644 kernel/libc/string/strncpy.c (limited to 'kernel/libc') diff --git a/kernel/libc/exit/assert.c b/kernel/libc/exit/assert.c new file mode 100644 index 0000000..b48773a --- /dev/null +++ b/kernel/libc/exit/assert.c @@ -0,0 +1,12 @@ +#include +#include +#include +#include + +void aFailed(char *f, int l) { + kprintf("Assert failed\n"); + kprintf("%s : %d\n", f, l); + dump_backtrace(10); + for (;;) + ; +} diff --git a/kernel/libc/include/assert.h b/kernel/libc/include/assert.h new file mode 100644 index 0000000..90a0be4 --- /dev/null +++ b/kernel/libc/include/assert.h @@ -0,0 +1,19 @@ +#include +#include + +#define assert(expr) \ + { \ + if (!(expr)) \ + aFailed(__FILE__, __LINE__); \ + } + +#define ASSERT_BUT_FIXME_PROPOGATE(expr) \ + { \ + if (!(expr)) \ + kprintf("Performing assert that should have been a propogated error."); \ + assert(expr); \ + } + +void aFailed(char *f, int l); +#define ASSERT_NOT_REACHED \ + { assert(0) } diff --git a/kernel/libc/include/errno.h b/kernel/libc/include/errno.h new file mode 100644 index 0000000..1ad1004 --- /dev/null +++ b/kernel/libc/include/errno.h @@ -0,0 +1,85 @@ +#ifndef ERRNO_H +#define ERRNO_H +// https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/errno.h.html +#define E2BIG 1 // Argument list too long. +#define EACCES 2 // Permission denied. +#define EADDRINUSE 3 // Address in use. +#define EADDRNOTAVAIL 4 // Address not available. +#define EAFNOSUPPORT 5 // Address family not supported. +#define EAGAIN 6 // Resource unavailable, try again. +#define EALREADY 7 // Connection already in progress. +#define EBADF 8 // Bad file descriptor. +#define EBADMSG 9 // Bad message. +#define EBUSY 10 // Device or resource busy. +#define ECANCELED 11 // Operation canceled. +#define ECHILD 12 // No child processes. +#define ECONNABORTED 13 // Connection aborted. +#define ECONNREFUSED 14 // Connection refused. +#define ECONNRESET 15 // Connection reset. +#define EDEADLK 16 // Resource deadlock would occur. +#define EDESTADDRREQ 17 // Destination address required. +#define EDOM 18 // Mathematics argument out of domain of function. +#define EDQUOT 19 // Reserved. +#define EEXIST 20 // File exists. +#define EFAULT 21 // Bad address. +#define EFBIG 22 // File too large. +#define EHOSTUNREACH 23 // Host is unreachable. +#define EIDRM 24 // Identifier removed. +#define EILSEQ 25 // Illegal byte sequence. +#define EINPROGRESS 26 // Operation in progress. +#define EINTR 27 // Interrupted function. +#define EINVAL 28 // Invalid argument. +#define EIO 29 // I/O error. +#define EISCONN 30 // Socket is connected. +#define EISDIR 31 // Is a directory. +#define ELOOP 32 // Too many levels of symbolic links. +#define EMFILE 33 // File descriptor value too large. +#define EMLINK 34 // Too many links. +#define EMSGSIZE 35 // Message too large. +#define EMULTIHOP 36 // Reserved. +#define ENAMETOOLONG 37 // Filename too long. +#define ENETDOWN 38 // Network is down. +#define ENETRESET 39 // Connection aborted by network. +#define ENETUNREACH 40 // Network unreachable. +#define ENFILE 41 // Too many files open in system. +#define ENOBUFS 42 // No buffer space available. +#define ENODATA 43 // No message is available on the STREAM head read queue. +#define ENODEV 44 // No such device. +#define ENOENT 45 // No such file or directory. +#define ENOEXEC 46 // Executable file format error. +#define ENOLCK 47 // No locks available. +#define ENOLINK 48 // Reserved. +#define ENOMEM 49 // Not enough space. +#define ENOMSG 50 // No message of the desired type. +#define ENOPROTOOPT 51 // Protocol not available. +#define ENOSPC 52 // No space left on device. +#define ENOSR 53 // No STREAM resources. +#define ENOSTR 54 // Not a STREAM. +#define ENOSYS 55 // Functionality not supported. +#define ENOTCONN 56 // The socket is not connected. +#define ENOTDIR 57 // Not a directory or a symbolic link to a directory. +#define ENOTEMPTY 58 // Directory not empty. +#define ENOTRECOVERABLE 59 // State not recoverable. +#define ENOTSOCK 60 // Not a socket. +#define ENOTSUP 61 // Not supported (may be the same value as. +#define ENOTTY 62 // Inappropriate I/O control operation. +#define ENXIO 63 // No such device or address. +#define EOPNOTSUPP ENOTSUP // Operation not supported on socket. +#define EOVERFLOW 65 // Value too large to be stored in data type. +#define EOWNERDEAD 66 // Previous owner died. +#define EPERM 67 // Operation not permitted. +#define EPIPE 68 // Broken pipe. +#define EPROTO 69 // Protocol error. +#define EPROTONOSUPPORT 70 // Protocol not supported. +#define EPROTOTYPE 71 // Protocol wrong type for socket. +#define ERANGE 72 // Result too large. +#define EROFS 73 // Read-only file system. +#define ESPIPE 74 // Invalid seek. +#define ESRCH 75 // No such process. +#define ESTALE 76 // Reserved. +#define ETIME 77 // Stream ioctl() timeout. +#define ETIMEDOUT 78 // Connection timed out. +#define ETXTBSY 79 // Text file busy. +#define EWOULDBLOCK EAGAIN // Operation would block. +#define EXDEV 81 // Cross-device link. +#endif diff --git a/kernel/libc/include/limits.h b/kernel/libc/include/limits.h new file mode 100644 index 0000000..05022ec --- /dev/null +++ b/kernel/libc/include/limits.h @@ -0,0 +1 @@ +#define PATH_MAX 256 diff --git a/kernel/libc/include/stdio.h b/kernel/libc/include/stdio.h new file mode 100644 index 0000000..f2bbb32 --- /dev/null +++ b/kernel/libc/include/stdio.h @@ -0,0 +1,9 @@ +#ifndef STDIO_H +#define STDIO_H + +void putc(const char c); +int puts(char *str); +void delete_characther(void); +int kprintf(const char *format, ...); + +#endif diff --git a/kernel/libc/include/stdlib.h b/kernel/libc/include/stdlib.h new file mode 100644 index 0000000..e69de29 diff --git a/kernel/libc/include/string.h b/kernel/libc/include/string.h new file mode 100644 index 0000000..7cee4b2 --- /dev/null +++ b/kernel/libc/include/string.h @@ -0,0 +1,19 @@ +#ifndef STRING_H +#define STRING_H +#include +#include + +unsigned long strlen(const char *s); +void *memcpy(void *dest, const void *src, uint32_t n); +void *memset(void *dst, const unsigned char c, uint32_t n); +int memcmp(const void *s1, const void *s2, uint32_t n); +char *strcpy(char *d, const char *s); +int strcmp(const char *s1, const char *s2); +int isequal(const char *s1, const char *s2); +int isequal_n(const char *s1, const char *s2, uint32_t n); +char *copy_and_allocate_string(const char *s); +char *copy_and_allocate_user_string(const char *s); +char *strncpy(char *dest, const char *src, size_t n); +size_t strlcpy(char *dst, const char *src, size_t dsize); +char *strcat(char *s1, const char *s2); +#endif diff --git a/kernel/libc/include/time.h b/kernel/libc/include/time.h new file mode 100644 index 0000000..4e356d1 --- /dev/null +++ b/kernel/libc/include/time.h @@ -0,0 +1,6 @@ +#include + +struct timespec { + time_t tv_sec; // Seconds. + long tv_nsec; // Nanoseconds. +}; diff --git a/kernel/libc/include/types.h b/kernel/libc/include/types.h new file mode 100644 index 0000000..ffcf281 --- /dev/null +++ b/kernel/libc/include/types.h @@ -0,0 +1,27 @@ +#ifndef TYPES_H +#define TYPES_H +typedef unsigned int ino_t; + +typedef int mode_t; + +typedef int nlink_t; +typedef int uid_t; +typedef int gid_t; +typedef int id_t; + +typedef int blkcnt_t; +typedef int off_t; + +typedef int dev_t; +typedef unsigned int fsblkcnt_t; +typedef unsigned int fsfilcnt_t; +typedef unsigned int ino_t; +//typedef unsigned int size_t; + +typedef int blksize_t; +typedef int pid_t; +typedef int ssize_t; + +//typedef int clock_t; +typedef int time_t; +#endif diff --git a/kernel/libc/stdio/print.c b/kernel/libc/stdio/print.c new file mode 100644 index 0000000..8174983 --- /dev/null +++ b/kernel/libc/stdio/print.c @@ -0,0 +1,97 @@ +#include "../../drivers/serial.h" +#include "../include/assert.h" +#include "../include/stdio.h" +#include + +#define TAB_SIZE 8 + +const char HEX_SET[0x10] = {'0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'}; + +inline void putc(const char c) { write_serial(c); } + +int kprint_hex(uint64_t num) { + int c = 2; + + if (num == 0) { + putc('0'); + c++; + return c; + } + + char str[16] = {0}; + int i = 0; + for (; num != 0 && i < 16; i++, num /= 16) + str[i] = HEX_SET[(num % 16)]; + + c += i; + for (i--; i >= 0; i--) + putc(str[i]); + + return c; +} + +int kprint_int(int num) { + int c = 0; + if (0 == num) { + putc('0'); + c++; + return c; + } + char str[10]; + int i = 0; + for (; num != 0 && i < 10; i++, num /= 10) + str[i] = (num % 10) + '0'; + + c += i; + for (i--; i >= 0; i--) + putc(str[i]); + return c; +} + +int kprintf(const char *format, ...) { + int c = 0; + va_list list; + va_start(list, format); + + const char *s = format; + for (; *s; s++) { + if ('%' != *s) { + putc(*s); + c++; + continue; + } + + char flag = *(s + 1); + if ('\0' == flag) + break; + + switch (flag) { + case 'c': + putc((char)va_arg(list, int)); + c++; + break; + case 'd': + c += kprint_int(va_arg(list, int)); + break; + case 's': + for (char *string = va_arg(list, char *); *string; putc(*string++), c++) + ; + break; + case 'x': + c += kprint_hex(va_arg(list, const uint32_t)); + break; + case '%': + putc('%'); + c++; + break; + default: + ASSERT_NOT_REACHED; + break; + } + s++; + } + return c; +} + +int puts(char *str) { return kprintf("%s\n", str); } diff --git a/kernel/libc/string/copy.c b/kernel/libc/string/copy.c new file mode 100644 index 0000000..277c808 --- /dev/null +++ b/kernel/libc/string/copy.c @@ -0,0 +1,26 @@ +#include +#include +#include +#include + +char *copy_and_allocate_string(const char *s) { + size_t l = strlen(s); + char *r = kmalloc(l + 1); + if (!r) + return NULL; + return strncpy(r, s, l); +} + +char *copy_and_allocate_user_string(const char *s) { + size_t len; + if (!is_valid_user_c_string(s, &len)) + return NULL; + size_t real_len = strlen(s); + assert(real_len == len); + len = real_len; + char *r = kmalloc(len + 1); + if (!r) + return NULL; + strlcpy(r, s, len); + return r; +} diff --git a/kernel/libc/string/isequal.c b/kernel/libc/string/isequal.c new file mode 100644 index 0000000..cdbd3cc --- /dev/null +++ b/kernel/libc/string/isequal.c @@ -0,0 +1,15 @@ +#include "../include/string.h" + +int isequal(const char *s1, const char *s2) { + for(;*s1;s1++,s2++) + if(*s1 != *s2) + return 0; + return 1; +} + +int isequal_n(const char *s1, const char *s2, uint32_t n) { + for(;*s1 && n;s1++,s2++,n--) + if(*s1 != *s2) + return 0; + return 1; +} diff --git a/kernel/libc/string/memcmp.c b/kernel/libc/string/memcmp.c new file mode 100644 index 0000000..72c680a --- /dev/null +++ b/kernel/libc/string/memcmp.c @@ -0,0 +1,12 @@ +#include "../include/string.h" + +int memcmp(const void *s1, const void *s2, uint32_t n) +{ + int return_value = 0; + + for(uint32_t i = 0;i < n;i++) + if(((unsigned char *)(s1))[i] != ((unsigned char *)(s2))[i]) + return_value++; + + return return_value; +} diff --git a/kernel/libc/string/memcpy.c b/kernel/libc/string/memcpy.c new file mode 100644 index 0000000..5c04407 --- /dev/null +++ b/kernel/libc/string/memcpy.c @@ -0,0 +1,20 @@ +#include "../include/string.h" + +void * +memcpy(void *dest, const void *src, uint32_t n) { + unsigned char *d = dest; + const unsigned char *s = src; + + for (; n >= 8; n -= 8, d += 8, s += 8) + *(uint64_t *)d = *(uint64_t *)s; + + for (; n >= 4; n -= 4, d += 4, s += 4) + *(uint32_t *)d = *(uint32_t *)s; + + for (; n >= 2; n -= 2, d += 2, s += 2) + *(uint16_t *)d = *(uint16_t *)s; + + for (; n; n--) + *d++ = *s++; + return dest; +} diff --git a/kernel/libc/string/memset.c b/kernel/libc/string/memset.c new file mode 100644 index 0000000..a446eb4 --- /dev/null +++ b/kernel/libc/string/memset.c @@ -0,0 +1,9 @@ +#include + +void *memset(void *dst, const unsigned char c, uint32_t n) { + uintptr_t d = (uintptr_t)dst; + for (uint32_t i = 0; i < n; i++, d++) + *(unsigned char *)d = c; + + return (void *)d; +} diff --git a/kernel/libc/string/strcat.c b/kernel/libc/string/strcat.c new file mode 100644 index 0000000..78a9ec6 --- /dev/null +++ b/kernel/libc/string/strcat.c @@ -0,0 +1,6 @@ +#include + +char *strcat(char *s1, const char *s2) { + strcpy(s1 + strlen(s1), s2); + return s1; +} diff --git a/kernel/libc/string/strcmp.c b/kernel/libc/string/strcmp.c new file mode 100644 index 0000000..d7039e2 --- /dev/null +++ b/kernel/libc/string/strcmp.c @@ -0,0 +1,8 @@ +#include "../include/string.h" + +int strcmp(const char *s1, const char *s2) +{ + for(;*s1 == *s2 && *s1; s1++, s2++) + ; + return *s1 - *s2; +} diff --git a/kernel/libc/string/strcpy.c b/kernel/libc/string/strcpy.c new file mode 100644 index 0000000..fa1e336 --- /dev/null +++ b/kernel/libc/string/strcpy.c @@ -0,0 +1,8 @@ +#include + +char *strcpy(char *d, const char *s) { + char *s1 = d; + for (; (*d++ = *s++);) + ; + return s1; +} diff --git a/kernel/libc/string/strlcpy.c b/kernel/libc/string/strlcpy.c new file mode 100644 index 0000000..43d0e58 --- /dev/null +++ b/kernel/libc/string/strlcpy.c @@ -0,0 +1,21 @@ +#include +#include + +// Copy string src to buffer dst of size dsize. At most dsize-1 +// chars will be copied. Always NUL terminates (unless dsize == 0). +// Returns strlen(src); if retval >= dsize, truncation occurred. +size_t strlcpy(char *dst, const char *src, size_t dsize) { + size_t n = dsize; + const char *osrc = src; + for (; n; n--) { + if ((*dst++ = *src++) == '\0') + break; + } + if (n == 0) { + if (dsize != 0) + *dst = '\0'; /* NUL-terminate dst */ + while (*src++) + ; + } + return src - osrc - 1; +} diff --git a/kernel/libc/string/strlen.c b/kernel/libc/string/strlen.c new file mode 100644 index 0000000..4346383 --- /dev/null +++ b/kernel/libc/string/strlen.c @@ -0,0 +1,8 @@ +#include "../include/string.h" + +unsigned long strlen(const char *s) +{ + const char * tmp = s; + for(;*tmp++;); + return (tmp - s)-1; +} diff --git a/kernel/libc/string/strncpy.c b/kernel/libc/string/strncpy.c new file mode 100644 index 0000000..a886895 --- /dev/null +++ b/kernel/libc/string/strncpy.c @@ -0,0 +1,11 @@ +#include +#include + +// FIXME: Something is weird with this function +char *strncpy(char *dest, const char *src, size_t n) { + char *r = dest; + for (; n && (*dest = *src); n--, src++, dest++) + ; + *dest = '\0'; + return r; +} -- cgit v1.2.3