diff --git a/.gitignore b/.gitignore index c759f33d..1a09d8ef 100644 --- a/.gitignore +++ b/.gitignore @@ -1,15 +1,5 @@ Luna.iso toolchain/ .vscode/ -**/*.o -initrd/boot/moon -kernel/bin/moon -initrd/sys/moon.sym -initrd/bin/** -apps/bin/** -tests/**/bin/** -base/usr/** -**/*.a -ports/**/workdir/** -ports/ports.list -**/*.pkg.tar.xz \ No newline at end of file +build/ +initrd/boot/moon \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 00000000..97cc6d2b --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,18 @@ +cmake_minimum_required(VERSION 3.8..3.22) + +set(CMAKE_C_COMPILER_WORKS 1) +set(CMAKE_CXX_COMPILER_WORKS 1) + +set(CMAKE_SYSTEM_NAME Luna) +set(CMAKE_CROSSCOMPILING true) + +project(Luna LANGUAGES C CXX ASM) + +set(LUNA_ROOT ${CMAKE_CURRENT_LIST_DIR}) + +set(CMAKE_C_COMPILER x86_64-luna-gcc) +set(CMAKE_CXX_COMPILER x86_64-luna-g++) + +set(CMAKE_FIND_ROOT_PATH ${LUNA_ROOT}/toolchain/x86-64-luna) + +add_subdirectory(kernel) \ No newline at end of file diff --git a/apps/Makefile b/apps/Makefile deleted file mode 100644 index 3ae58d7e..00000000 --- a/apps/Makefile +++ /dev/null @@ -1,33 +0,0 @@ -C_APPS := init sh uname uptime hello ps ls args cat stat su session date mkdir screen touch write -CXX_APPS := hello-cpp - -APPS_DIR := $(LUNA_ROOT)/apps -APPS_SRC := $(APPS_DIR)/src -APPS_BIN := $(APPS_DIR)/bin - -C_APPS_PATH := $(patsubst %, $(APPS_BIN)/%, $(C_APPS)) -CXX_APPS_PATH := $(patsubst %, $(APPS_BIN)/%, $(CXX_APPS)) - -CFLAGS := -Wall -Wextra -Werror -Os -fno-asynchronous-unwind-tables -ffunction-sections -fdata-sections -Wl,--gc-sections -CXXFLAGS := -fno-exceptions - -$(APPS_BIN)/%: $(APPS_SRC)/%.c - @mkdir -p $(@D) - @$(CC) $(CFLAGS) -o $@ $^ - @echo " CC $^" - -$(APPS_BIN)/%: $(APPS_SRC)/%.cpp - @mkdir -p $(@D) - @$(CXX) $(CFLAGS) $(CXXFLAGS) -o $@ $^ - @echo " CXX $^" - -build: $(C_APPS_PATH) $(CXX_APPS_PATH) - -install: $(C_APPS_PATH) $(CXX_APPS_PATH) - @mkdir -p $(LUNA_ROOT)/initrd/bin - @cp $(C_APPS_PATH) $(CXX_APPS_PATH) $(LUNA_ROOT)/initrd/bin - @echo " INSTALL $(C_APPS) $(CXX_APPS)" - @chmod a+s $(LUNA_ROOT)/initrd/bin/su - -clean: - rm -f $(APPS_BIN)/* \ No newline at end of file diff --git a/apps/src/args.c b/apps/src/args.c deleted file mode 100644 index aa3bf2f3..00000000 --- a/apps/src/args.c +++ /dev/null @@ -1,7 +0,0 @@ -#include -#include - -int main(int argc, char** argv) -{ - for (int i = 0; i < argc; i++) puts(argv[i]); -} \ No newline at end of file diff --git a/apps/src/cat.c b/apps/src/cat.c deleted file mode 100644 index 7c744913..00000000 --- a/apps/src/cat.c +++ /dev/null @@ -1,45 +0,0 @@ -#define _GNU_SOURCE // for program_invocation_name -#include - -#include -#include -#include - -void cat(FILE* stream) -{ - char buf[BUFSIZ]; - do { - fgets(buf, BUFSIZ, stream); - if (ferror(stream)) - { - perror(program_invocation_name); - exit(EXIT_FAILURE); - } - fputs(buf, stdout); - } while (!feof(stream)); -} - -int main(int argc, char** argv) -{ - if (argc == 1) cat(stdin); - else - { - for (int i = 1; i < argc; i++) - { - if (strcmp(argv[i], "-") == 0) cat(stdin); - else if (strcmp(argv[i], "-n") == 0 || strcmp(argv[i], "--newline") == 0) - putchar('\n'); - else - { - FILE* stream = fopen(argv[i], "r"); - if (!stream) - { - perror(program_invocation_name); - return EXIT_FAILURE; - } - cat(stream); - fclose(stream); - } - } - } -} \ No newline at end of file diff --git a/apps/src/date.c b/apps/src/date.c deleted file mode 100644 index b8243899..00000000 --- a/apps/src/date.c +++ /dev/null @@ -1,9 +0,0 @@ -#include -#include - -int main() -{ - time_t date = time(NULL); - - fputs(ctime(&date), stdout); -} \ No newline at end of file diff --git a/apps/src/hello-cpp.cpp b/apps/src/hello-cpp.cpp deleted file mode 100644 index a6eda67f..00000000 --- a/apps/src/hello-cpp.cpp +++ /dev/null @@ -1,19 +0,0 @@ -#include -#include -#include - -int main() -{ - std::printf("Well hello world!\n"); - - std::string str = "this is a c++ string"; - - str.append(" yay"); - - std::printf("%s\n", str.c_str()); - - std::vector vec = {3, 2, 8}; - - for (int i : vec) { std::printf("%d ", i); } - std::putchar('\n'); -} \ No newline at end of file diff --git a/apps/src/hello.c b/apps/src/hello.c deleted file mode 100644 index 50106f10..00000000 --- a/apps/src/hello.c +++ /dev/null @@ -1,6 +0,0 @@ -#include - -int main() -{ - puts("Hello, world!"); -} \ No newline at end of file diff --git a/apps/src/init.c b/apps/src/init.c deleted file mode 100644 index 9a97a46b..00000000 --- a/apps/src/init.c +++ /dev/null @@ -1,77 +0,0 @@ -#include -#include -#include -#include -#include -#include - -void show_motd() -{ - int fd = open("/etc/motd", O_RDONLY | O_CLOEXEC); - if (fd < 0) - { - if (errno != ENOENT) { perror("open"); } - return; - } - FILE* fp = fdopen(fd, "r"); - if (!fp) - { - perror("fopen"); - return; - } - - char buf[4096]; - size_t nread = fread(buf, 1, sizeof(buf) - 1, fp); - if (ferror(fp)) - { - perror("fread"); - fclose(fp); - return; - } - buf[nread] = 0; - - puts(buf); - - fclose(fp); - - putchar('\n'); -} - -int main() -{ - if (getpid() != 1) - { - fprintf(stderr, "init must be started as PID 1\n"); - return 1; - } - - if (getuid() != 0) - { - fprintf(stderr, "init must be started as root\n"); - return 1; - } - - show_motd(); - - pid_t child = fork(); - if (child < 0) - { - perror("fork"); - return 1; - } - if (child == 0) - { - char* argv[] = {"/bin/session", NULL}; - execv(argv[0], argv); - perror("execv"); - return 1; - } - - pid_t result; - - for (;;) - { - result = wait(NULL); - if (result == child) return 0; - } -} diff --git a/apps/src/ls.c b/apps/src/ls.c deleted file mode 100644 index aa81fb2f..00000000 --- a/apps/src/ls.c +++ /dev/null @@ -1,31 +0,0 @@ -#include -#include -#include -#include -#include - -int main(int argc, char** argv) -{ - const char* pathname; - if (argc == 1) pathname = "/"; - else - pathname = argv[1]; - DIR* dp = opendir(pathname); - if (!dp) - { - perror("opendir"); - return 1; - } - bool first_ent = true; - do { - struct dirent* ent = readdir(dp); - if (!ent) break; - printf(first_ent ? "%s" : " %s", ent->d_name); - first_ent = false; - } while (1); - - printf("\n"); - - closedir(dp); - return 0; -} \ No newline at end of file diff --git a/apps/src/mkdir.c b/apps/src/mkdir.c deleted file mode 100644 index 60a00b86..00000000 --- a/apps/src/mkdir.c +++ /dev/null @@ -1,17 +0,0 @@ -#include -#include - -int main(int argc, char** argv) -{ - if (argc == 1) - { - fprintf(stderr, "Usage: %s [directory]\n", argv[0]); - return 1; - } - - if (mkdir(argv[1], 0755) < 0) - { - perror("mkdir"); - return 1; - } -} \ No newline at end of file diff --git a/apps/src/ps.c b/apps/src/ps.c deleted file mode 100644 index 1a58c8e2..00000000 --- a/apps/src/ps.c +++ /dev/null @@ -1,48 +0,0 @@ -#include -#include -#include -#include -#include -#include - -pid_t get_current_max_threads() -{ - pid_t result = pstat(-1, NULL); - if (result < 0) - { - perror("pstat(-1)"); - exit(1); - } - return result; -} - -void display_process(struct pstat* pstatbuf) -{ - struct passwd* pwd = getpwuid(pstatbuf->pt_uid); - if (!pwd && errno) perror("getpwuid"); - printf("%s %ld %ld %s %s (%ld ms)\n", pwd ? pwd->pw_name : "???", pstatbuf->pt_pid, pstatbuf->pt_ppid, - pstatbuf->pt_name, pstatname(pstatbuf), pstatbuf->pt_time); -} - -int try_pstat(pid_t pid, struct pstat* pstatbuf) -{ - pid_t result = pstat(pid, pstatbuf); - if (result < 0) - { - if (errno == ESRCH) return 0; - perror("pstat"); - exit(1); - } - return 1; -} - -int main() -{ - struct pstat pst; - pid_t max = get_current_max_threads(); - for (pid_t pid = 0; pid <= max; pid++) - { - if (try_pstat(pid, &pst)) { display_process(&pst); } - } - endpwent(); -} \ No newline at end of file diff --git a/apps/src/screen.c b/apps/src/screen.c deleted file mode 100644 index 7b26ba33..00000000 --- a/apps/src/screen.c +++ /dev/null @@ -1,32 +0,0 @@ -#include -#include -#include -#include - -int main() -{ - int fd = open("/dev/fb0", O_WRONLY | O_CLOEXEC); - if (fd < 0) - { - perror("open"); - return 1; - } - - int fb_width = ioctl(fd, FB_GET_WIDTH); - if (fb_width < 0) - { - perror("ioctl(FB_GET_WIDTH)"); - return 1; - } - - int fb_height = ioctl(fd, FB_GET_HEIGHT); - if (fb_height < 0) - { - perror("ioctl(FB_GET_HEIGHT)"); - return 1; - } - - printf("Your screen is %dx%d\n", fb_width, fb_height); - - close(fd); -} \ No newline at end of file diff --git a/apps/src/session.c b/apps/src/session.c deleted file mode 100644 index 7faf8df0..00000000 --- a/apps/src/session.c +++ /dev/null @@ -1,145 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include - -static char* echoing_fgets(char* buf, size_t size, FILE* stream) -{ - char* s = buf; - memset(buf, 0, size); - size_t oldsize = size; - while (size) - { - int c = fgetc(stream); - if (c == EOF) - { - if (ferror(stream)) return NULL; - if (feof(stream)) - { - if (s != buf) return s; - else - return NULL; - }; - } - if ((char)c == '\b') - { - if (size != oldsize) - { - buf--; - size++; - putchar('\b'); - } - } - else - { - size--; - *buf = (char)c; - buf++; - putchar((char)c); - if ((char)c == '\n') return s; - } - *buf = 0; - } - return s; -} - -static void strip_newline(char* str) -{ - size_t len = strlen(str); - if (str[len - 1] == '\n') str[len - 1] = 0; -} - -static char* collect_password() -{ - static char buf[BUFSIZ]; - - printf("Password: "); - fgets(buf, BUFSIZ, stdin); - - strip_newline(buf); - putchar('\n'); - - char* copy = strdup( - buf); // The password only stays in a caller-controlled heap-allocated buffer, where it can be freed at will. - - memset(buf, 0, BUFSIZ); - - return copy; -} - -static void login_as(struct passwd* user) -{ - pid_t child = fork(); - if (child < 0) - { - perror("fork"); - return; - } - if (child == 0) - { - setgid(user->pw_gid); - setuid(user->pw_uid); - char* argv[] = {user->pw_shell, NULL}; - execv(argv[0], argv); - perror("execv"); - exit(EXIT_FAILURE); - } - wait(NULL); -} - -static int login() -{ - printf("Username: "); - char username[BUFSIZ]; - echoing_fgets(username, BUFSIZ, stdin); - strip_newline(username); - if (strcmp("exit", username) == 0) return 1; - struct passwd* user = getpwnam(username); - if (!user) - { - if (errno) perror("getpwnam"); - else - printf("Unknown user %s\n", username); - return 0; - } - char* password = collect_password(); - putchar('\n'); - if (strcmp(user->pw_passwd, password) == 0) - { - free(password); - login_as(user); - puts("logout\n"); - } - else - { - free(password); - puts("Invalid password.\n"); - } - return 0; -} - -int main(int argc, char** argv) -{ - (void)argc; - - if (getuid() != 0) - { - fprintf(stderr, - "%s must be run as root.\nYou are probably looking for the 'su' command, which lets you switch users " - "once logged in.\n", - argv[0]); - return EXIT_FAILURE; - } - - for (;;) - { - if (login()) break; - } - - endpwent(); - - return EXIT_SUCCESS; -} \ No newline at end of file diff --git a/apps/src/sh.c b/apps/src/sh.c deleted file mode 100644 index 8545f485..00000000 --- a/apps/src/sh.c +++ /dev/null @@ -1,364 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static int status = 0; -static char* username = NULL; - -typedef struct -{ - char* buffer; - size_t size; - size_t capacity; - int interactive; -} command_t; - -char** split_command_into_argv(const char* cmd) -{ - size_t argc = 1; - char* ptr = strdup(cmd); - char* endptr; - char** arr = calloc(sizeof(char*), argc); - for (;;) - { - endptr = strchr(ptr, ' '); - arr[argc - 1] = ptr; - if (endptr == NULL) break; - *endptr = 0; - ptr = endptr + 1; - if (*ptr) - { - argc++; - arr = realloc(arr, sizeof(char*) * argc); - } - else - break; - } - argc++; - arr = realloc(arr, sizeof(char*) * argc); - arr[argc - 1] = NULL; - return arr; -} - -char* shell_concat_path(const char* dirname, const char* basename) -{ - char* buf = malloc(strlen(basename) + strlen(dirname) + 6); - strlcpy(buf, dirname, strlen(dirname) + 1); - strncat(buf, basename, strlen(basename)); - return buf; -} - -void shell_execvp(char* pathname, char* const argv[]) -{ - char* new_path; - if (access(pathname, F_OK) == 0) - { - execv(pathname, argv); - return; - } - if (pathname[0] == '/') return; // We do not want to lookup absolute paths - new_path = shell_concat_path("/bin/", pathname); - if (access(new_path, F_OK) == 0) - { - execv(new_path, argv); - return; - } - free(new_path); - new_path = shell_concat_path("/usr/bin/", pathname); - execv(new_path, argv); - int saved = errno; - free(new_path); - errno = saved; -} - -void show_prompt() -{ - if (WEXITSTATUS(status)) { printf("%d [%s]> ", WEXITSTATUS(status), username); } - else - printf("[%s]> ", username); -} - -int command_matches(command_t* cmd, const char* string) -{ - if (cmd->size <= strlen(string)) // cmd->size includes null terminator - return 0; - return strncmp(cmd->buffer, string, strlen(string)) == 0; -} - -int command_matches_exactly(command_t* cmd, const char* string) -{ - if (cmd->size <= strlen(string)) // cmd->size includes null terminator - return 0; - if (cmd->size > (strlen(string) + 1)) return 0; - return strncmp(cmd->buffer, string, strlen(string)) == 0; -} - -int command_match_builtins(command_t* cmd) -{ - if (command_matches(cmd, "exit ")) { exit(atoi(cmd->buffer + 5)); } - if (command_matches_exactly(cmd, "exit")) { exit(0); } - if (command_matches_exactly(cmd, "id")) - { - printf("pid %ld, ppid %ld, uid %d (%s), gid %d\n", getpid(), getppid(), getuid(), username, getgid()); - return 1; - } - if (command_matches(cmd, "sleep")) - { - sleep(atoi(cmd->buffer + 6)); - return 1; - } - if (command_matches_exactly(cmd, "clear")) - { - fputs("\033@", stdout); // clear screen. for now, escape sequences in luna are non-standard. - return 1; - } - return 0; -} - -void command_expand(command_t* cmd, long new_capacity) -{ - char* buffer = realloc(cmd->buffer, new_capacity); - if (!buffer) - { - perror("realloc"); - exit(1); - } - cmd->buffer = buffer; - cmd->capacity = new_capacity; -} - -void command_push(command_t* cmd, char c) -{ - if (cmd->size == cmd->capacity) command_expand(cmd, cmd->capacity + 8); - cmd->buffer[cmd->size] = c; - cmd->size++; -} - -void command_pop(command_t* cmd) -{ - cmd->size--; -} - -void command_init(command_t* cmd) -{ - cmd->buffer = malloc(5); - cmd->capacity = 5; - cmd->size = 0; -} - -void command_clear(command_t* cmd) -{ - free(cmd->buffer); - return command_init(cmd); -} - -void process_execute_command(const char* command) -{ - char** argv = split_command_into_argv(command); - shell_execvp(argv[0], argv); - perror(argv[0]); - exit(127); -} - -void command_execute(command_t* cmd) -{ - command_push(cmd, '\0'); - if (command_match_builtins(cmd)) - { - command_clear(cmd); - if (cmd->interactive) show_prompt(); - return; - } - pid_t child = fork(); - if (child < 0) - { - perror("fork"); - command_clear(cmd); - if (cmd->interactive) show_prompt(); - return; - } - if (child == 0) process_execute_command(cmd->buffer); - pid_t result = waitpid(child, &status, 0); - if (result < 0) - { - perror("waitpid"); - command_clear(cmd); - if (cmd->interactive) show_prompt(); - return; - } - int exit_status = WEXITSTATUS(status); - if (exit_status == -2 || exit_status == -3) printf("(PID %ld) Segmentation fault\n", result); - if (exit_status == -1) printf("(PID %ld) Aborted\n", result); - command_clear(cmd); - if (cmd->interactive) show_prompt(); -} - -void command_concat_char(command_t* cmd, char c) -{ - if (c == '\b') - { - if (cmd->size != 0) - { - if (cmd->interactive) putchar(c); - command_pop(cmd); - } - } - else if (c == '\n') - { - if (cmd->interactive) putchar(c); - if (cmd->size == 0) - { - status = 0; - if (cmd->interactive) show_prompt(); - } - else - command_execute(cmd); - } - else - { - if (cmd->interactive) putchar(c); - command_push(cmd, c); - } -} - -void command_concat(command_t* cmd, const char* str) -{ - while (*str) - { - command_concat_char(cmd, *str); - str++; - } -} - -void shell_interactive() -{ - show_prompt(); - - command_t shell_command; - command_init(&shell_command); - - shell_command.interactive = 1; - - while (1) - { - int c = getchar(); - if (c == EOF) - { - if (ferror(stdin)) - { - perror("getchar"); - exit(EXIT_FAILURE); - } - if (feof(stdin)) exit(EXIT_SUCCESS); - assert(false); // we should never get here - } - command_concat_char(&shell_command, (char)c); - } -} - -void shell_read_from_file(const char* pathname) -{ - FILE* fp = fopen(pathname, "r"); - if (!fp) - { - perror("sh"); - exit(EXIT_FAILURE); - } - - command_t file_command; - command_init(&file_command); - - file_command.interactive = 0; - - char buffer[BUFSIZ]; - while (fgets(buffer, BUFSIZ, fp)) - { - command_concat(&file_command, buffer); - if (feof(fp)) break; - } - - if (file_command.size > 0) // last line of file, does not end with newline - { - command_execute(&file_command); - } - - fclose(fp); -} - -void shell_execute_command(const char* command) -{ - command_t cmd; - cmd.buffer = strdup(command); - cmd.size = strlen(command) + 1; - if (command_match_builtins(&cmd)) return; - command_clear(&cmd); - process_execute_command(command); -} - -void fetch_username() -{ - struct passwd* user = getpwuid(getuid()); - if (!user) - { - perror("getpwuid"); - exit(EXIT_FAILURE); - } - username = user->pw_name; - endpwent(); -} - -int main(int argc, char** argv) -{ - fetch_username(); - - if (argc == 1) shell_interactive(); - else if (argc == 2) - { - if (!strcmp(argv[1], "-v") || !strcmp(argv[1], "--version")) - { - puts("Luna sh version 0.1"); // FIXME: Store the version somewhere, or use the kernel's version. - return 0; - } - - if (!strcmp(argv[1], "-h") || !strcmp(argv[1], "--help")) - { - printf("To use interactively: %s\n", argv[0]); - printf("To run a script: %s [script-name]\n", argv[0]); - printf("To get help: %s --help\n", argv[0]); - printf("To show the version: %s --version\n", argv[0]); - printf("To run a command: %s -c [command]\n", argv[0]); - return 0; - } - - if (!strcmp(argv[1], "-c") || !strcmp(argv[1], "--command")) - { - fprintf(stderr, "Usage: %s %s [command]\n", argv[0], argv[1]); - fprintf(stderr, "Use the --help flag for more help.\n"); - return 1; - } - - shell_read_from_file(argv[1]); - } - else if (argc == 3) - { - if (!strcmp(argv[1], "-c") || !strcmp(argv[1], "--command")) shell_execute_command(argv[2]); - else - { - fprintf(stderr, "%s: too many arguments\n", argv[0]); - fprintf(stderr, "Use the --help flag for more help.\n"); - return 1; - } - } - else - { - fprintf(stderr, "%s: too many arguments\n", argv[0]); - fprintf(stderr, "Use the --help flag for more help.\n"); - return 1; - } -} \ No newline at end of file diff --git a/apps/src/stat.c b/apps/src/stat.c deleted file mode 100644 index 7e158bea..00000000 --- a/apps/src/stat.c +++ /dev/null @@ -1,66 +0,0 @@ -#include -#include -#include -#include -#include - -const char* mode_to_string(mode_t mode) -{ - static char mode_string[12]; - - char mode_set[12] = {'s', 'g', 'r', 'w', 'x', 'r', 'w', 'x', 'r', 'w', 'x', 0}; - mode_t mode_val[12] = {S_ISUID, S_ISGID, S_IRUSR, S_IWUSR, S_IXUSR, S_IRGRP, - S_IWGRP, S_IXGRP, S_IROTH, S_IWOTH, S_IXOTH, S_IFMT}; - - for (int i = 0; i < 12; i++) - { - if (mode & mode_val[i]) mode_string[i] = mode_set[i]; - else - mode_string[i] = '-'; - } - - return mode_string; -} - -int main(int argc, char** argv) -{ - if (argc == 1) - { - fprintf(stderr, "Usage: stat [file]\n"); - return EXIT_FAILURE; - } - - struct stat st; - if (stat(argv[1], &st) < 0) - { - perror("stat"); - return EXIT_FAILURE; - } - - printf("Type: "); - - switch (st.st_mode & S_IFMT) - { - case S_IFREG: puts("Regular file"); break; - case S_IFDIR: puts("Directory"); break; - case S_IFCHR: puts("Character device"); break; - default: puts("Unknown"); break; - } - - struct passwd* own = getpwuid(st.st_uid); - - printf("Length: %ld\n", st.st_size); - printf("Inode: %ld\n", st.st_ino); - if (!own) printf("Owned by: UID %d\n", st.st_uid); - else - printf("Owned by: %s\n", own->pw_name); - printf("Mode: %s\n", mode_to_string(st.st_mode)); - - printf("Accessed on: %s", ctime(&st.st_atime)); - printf("Modified on: %s", ctime(&st.st_mtime)); - printf("Changed on: %s", ctime(&st.st_ctime)); - - endpwent(); - - return EXIT_SUCCESS; -} \ No newline at end of file diff --git a/apps/src/su.c b/apps/src/su.c deleted file mode 100644 index 4c9c2a02..00000000 --- a/apps/src/su.c +++ /dev/null @@ -1,88 +0,0 @@ -#include -#include -#include -#include -#include -#include - -void run_program(char** argv) -{ - execv(argv[0], argv); - - perror("execv"); - exit(EXIT_FAILURE); -} - -void strip_newline(char* str) -{ - size_t len = strlen(str); - if (str[len - 1] == '\n') str[len - 1] = 0; -} - -static const char* collect_password() -{ - static char buf[BUFSIZ]; - - printf("Password: "); - fgets(buf, BUFSIZ, stdin); - - strip_newline(buf); - putchar('\n'); - - return buf; -} - -int main(int argc, char** argv) -{ - const char* username; - - if (argc == 1) username = "root"; - else - username = argv[1]; - - if (geteuid() != 0) - { - fprintf(stderr, "%s must be setuid root", argv[0]); - return EXIT_FAILURE; - } - - struct passwd* user = getpwnam(username); - - endpwent(); - - if (!user) - { - if (errno) perror("getpwnam"); - else - fprintf(stderr, "Unknown user %s\n", username); - return EXIT_FAILURE; - } - - if (getuid() != geteuid()) // we were started from a non-root user - { - const char* pw = collect_password(); - if (strcmp(pw, user->pw_passwd) != 0) - { - fprintf(stderr, "Invalid password\n"); - return EXIT_FAILURE; - } - } - - if (setgid(user->pw_gid) < 0) - { - perror("setgid"); - return EXIT_FAILURE; - } - - if (setuid(user->pw_uid) < 0) - { - perror("setuid"); - return EXIT_FAILURE; - } - - char* default_argv[] = {user->pw_shell, NULL}; - - if (argc < 3) run_program(default_argv); - else - run_program(argv + 2); -} \ No newline at end of file diff --git a/apps/src/touch.c b/apps/src/touch.c deleted file mode 100644 index b2b0a218..00000000 --- a/apps/src/touch.c +++ /dev/null @@ -1,22 +0,0 @@ -#include -#include -#include - -int main(int argc, char** argv) -{ - if (argc == 1) - { - fprintf(stderr, "Usage: %s [directory]\n", argv[0]); - return 1; - } - - int fd = creat(argv[1], 0755); - - if (fd < 0) - { - perror("creat"); - return 1; - } - - close(fd); -} \ No newline at end of file diff --git a/apps/src/uname.c b/apps/src/uname.c deleted file mode 100644 index 380e00ff..00000000 --- a/apps/src/uname.c +++ /dev/null @@ -1,18 +0,0 @@ -#include - -int main() -{ - FILE* fp = fopen("/dev/version", "r"); - if (!fp) - { - perror("fopen"); - return 1; - } - - char buf[BUFSIZ]; - fgets(buf, sizeof(buf), fp); - - printf("%s\n", buf); - - fclose(fp); -} \ No newline at end of file diff --git a/apps/src/uptime.c b/apps/src/uptime.c deleted file mode 100644 index 673ff47c..00000000 --- a/apps/src/uptime.c +++ /dev/null @@ -1,38 +0,0 @@ -#include -#include - -#define VALUE_SINGULAR_AT_ONE(v) v, v == 1 ? "" : "s" - -int main() -{ - struct timespec tp; - clock_gettime(CLOCK_MONOTONIC, &tp); // On Luna, CLOCK_MONOTONIC starts at boot. - - struct tm* time = gmtime( - &tp.tv_sec); // just splitting the value into seconds, minutes, hours, days... not the best way to do it but ok. - time->tm_year -= 70; - - if (time->tm_year) - { - printf("up for %d year%s, %d day%s, %d hour%s, %d minute%s, %d second%s\n", - VALUE_SINGULAR_AT_ONE(time->tm_year), VALUE_SINGULAR_AT_ONE(time->tm_yday), - VALUE_SINGULAR_AT_ONE(time->tm_hour), VALUE_SINGULAR_AT_ONE(time->tm_min), - VALUE_SINGULAR_AT_ONE(time->tm_sec)); - } - else if (time->tm_yday) - { - printf("up for %d day%s, %d hour%s, %d minute%s, %d second%s\n", VALUE_SINGULAR_AT_ONE(time->tm_yday), - VALUE_SINGULAR_AT_ONE(time->tm_hour), VALUE_SINGULAR_AT_ONE(time->tm_min), - VALUE_SINGULAR_AT_ONE(time->tm_sec)); - } - else if (time->tm_hour) - { - printf("up for %d hour%s, %d minute%s, %d second%s\n", VALUE_SINGULAR_AT_ONE(time->tm_hour), - VALUE_SINGULAR_AT_ONE(time->tm_min), VALUE_SINGULAR_AT_ONE(time->tm_sec)); - } - else if (time->tm_min) - printf("up for %d minute%s, %d second%s\n", VALUE_SINGULAR_AT_ONE(time->tm_min), - VALUE_SINGULAR_AT_ONE(time->tm_sec)); - else - printf("up for %d second%s\n", VALUE_SINGULAR_AT_ONE(time->tm_sec)); -} \ No newline at end of file diff --git a/apps/src/write.c b/apps/src/write.c deleted file mode 100644 index 1b541da9..00000000 --- a/apps/src/write.c +++ /dev/null @@ -1,75 +0,0 @@ -#include -#include -#include -#include - -static char* echoing_fgets(char* buf, size_t size, FILE* stream) -{ - char* s = buf; - memset(buf, 0, size); - size_t oldsize = size; - while (size) - { - int c = fgetc(stream); - if (c == EOF) - { - if (ferror(stream)) return NULL; - if (feof(stream)) - { - if (s != buf) return s; - else - return NULL; - }; - } - if ((char)c == '\b') - { - if (size != oldsize) - { - buf--; - size++; - putchar('\b'); - } - } - else - { - size--; - *buf = (char)c; - buf++; - putchar((char)c); - if ((char)c == '\n') return s; - } - *buf = 0; - } - return s; -} - -int main(int argc, char** argv) -{ - if (argc == 1) - { - fprintf(stderr, "Usage: %s [directory]\n", argv[0]); - return 1; - } - - int fd = open(argv[1], O_WRONLY | O_CREAT | O_APPEND, 0755); - - if (fd < 0) - { - perror("open"); - return 1; - } - - FILE* fp = fdopen(fd, "a"); - - char buf[BUFSIZ]; - echoing_fgets(buf, BUFSIZ, stdin); - - fputs(buf, fp); - if (ferror(fp)) - { - perror("fputs"); - return 1; - } - - fclose(fp); -} \ No newline at end of file diff --git a/initrd/etc/motd b/initrd/etc/motd deleted file mode 100644 index 08cac88a..00000000 --- a/initrd/etc/motd +++ /dev/null @@ -1,3 +0,0 @@ -Welcome to Luna! - -Tip of the day: Log in as user 'selene' and password 'moon' :) \ No newline at end of file diff --git a/initrd/etc/passwd b/initrd/etc/passwd deleted file mode 100644 index 3a1d10e2..00000000 --- a/initrd/etc/passwd +++ /dev/null @@ -1,2 +0,0 @@ -root:secure:0:0:Administrator:/:/bin/sh -selene:moon:1:1:Default User:/:/bin/sh \ No newline at end of file diff --git a/initrd/make-folders.sh b/initrd/make-folders.sh deleted file mode 100644 index f2fdd17f..00000000 --- a/initrd/make-folders.sh +++ /dev/null @@ -1,9 +0,0 @@ -mkdir /tmp/1 -sleep 1 -mkdir /tmp/1/2 -sleep 1 -mkdir /tmp/1/2/3 -sleep 1 -mkdir /tmp/1/2/3/4 -sleep 1 -mkdir /tmp/1/2/3/4/5 \ No newline at end of file diff --git a/initrd/sys/config b/initrd/sys/config index 926fdc83..e7a9cff1 100644 --- a/initrd/sys/config +++ b/initrd/sys/config @@ -1,3 +1,2 @@ screen=1024x768 -kernel=boot/moon -verbose=1 \ No newline at end of file +kernel=boot/moon \ No newline at end of file diff --git a/kernel/CMakeLists.txt b/kernel/CMakeLists.txt new file mode 100644 index 00000000..70bf59ca --- /dev/null +++ b/kernel/CMakeLists.txt @@ -0,0 +1,26 @@ +set(SOURCES + src/main.cpp +) + +add_compile_options(-Os) + +add_compile_options(-pedantic -Wall -Wextra -Werror -Wvla) +add_compile_options(-Wdisabled-optimization -Wformat=2 -Winit-self) +add_compile_options(-Wmissing-include-dirs -Wswitch-default -Wcast-qual -Wundef) +add_compile_options(-Wcast-align -Wwrite-strings -Wlogical-op -Wredundant-decls -Wshadow -Wconversion) +add_compile_options(-fno-rtti -ffreestanding -fno-exceptions) +add_compile_options(-fno-asynchronous-unwind-tables -fno-omit-frame-pointer) +add_compile_options(-nostdlib -mcmodel=kernel) +add_compile_options(-mno-red-zone) + +add_compile_options(-mno-80387 -mno-mmx -mno-sse -mno-sse2) + +add_link_options(-lgcc -Wl,--build-id=none -z max-page-size=0x1000 -mno-red-zone -mcmodel=kernel) + +add_executable(moon ${SOURCES}) + +target_include_directories(moon PUBLIC ${LUNA_ROOT}/luna) + +target_link_options(moon PRIVATE LINKER:-T ${CMAKE_CURRENT_LIST_DIR}/moon.ld -nostdlib -nodefaultlibs) + +install(FILES "${CMAKE_CURRENT_BINARY_DIR}/moon" DESTINATION ${LUNA_ROOT}/initrd/boot) \ No newline at end of file diff --git a/kernel/Makefile b/kernel/Makefile deleted file mode 100644 index 14d800c5..00000000 --- a/kernel/Makefile +++ /dev/null @@ -1,85 +0,0 @@ -MOON_DIR := $(realpath $(dir $(abspath $(lastword $(MAKEFILE_LIST))))) -MOON_SRC := $(MOON_DIR)/src -MOON_OBJ := $(MOON_DIR)/lib -MOON_BIN := $(MOON_DIR)/bin - -CFLAGS ?= -Os -CFLAGS := ${CFLAGS} -pedantic -Wall -Wextra -Werror -Wvla -Wfloat-equal -Wdisabled-optimization -Wformat=2 -Winit-self -Wmissing-include-dirs -Wswitch-default -Wcast-qual -Wundef -Wcast-align -Wwrite-strings -Wlogical-op -Wredundant-decls -Wshadow -Wconversion -ffreestanding -fstack-protector-strong -fno-omit-frame-pointer -mno-red-zone -mno-mmx -mno-sse -mno-sse2 -fshort-wchar -mcmodel=kernel -I$(MOON_DIR)/include -isystem $(MOON_DIR)/include/std -CXXFLAGS := -fno-rtti -fno-exceptions -Wsign-promo -Wstrict-null-sentinel -Wctor-dtor-privacy -ASMFLAGS := -felf64 -LDFLAGS := -T$(MOON_DIR)/moon.ld -nostdlib -lgcc -Wl,--build-id=none -z max-page-size=0x1000 -mno-red-zone -mcmodel=kernel - -ifneq ($(MOON_BUILD_STABLE), 1) -CFLAGS := ${CFLAGS} -D_MOON_SUFFIX=-$(shell git rev-parse --short HEAD) -endif - -ifeq ($(MOON_BUILD_DEBUG), 1) -CFLAGS := -ggdb -fsanitize=undefined ${CFLAGS} -endif - -rwildcard=$(foreach d,$(wildcard $(1:=/*)),$(call rwildcard,$d,$2) $(filter $(subst *,%,$2),$d)) - -CXX_SRC = $(call rwildcard,$(MOON_SRC),*.cpp) -C_SRC = $(call rwildcard,$(MOON_SRC),*.c) -NASM_SRC = $(call rwildcard,$(MOON_SRC),*.asm) - -OBJS = $(patsubst $(MOON_SRC)/%.cpp, $(MOON_OBJ)/%.cpp.o, $(CXX_SRC)) -OBJS += $(patsubst $(MOON_SRC)/%.c, $(MOON_OBJ)/%.c.o, $(C_SRC)) -OBJS += $(patsubst $(MOON_SRC)/%.asm, $(MOON_OBJ)/%.asm.o, $(NASM_SRC)) - -default: $(MOON_BIN)/moon - -$(MOON_OBJ)/main.cpp.o: $(MOON_SRC)/main.cpp - @mkdir -p $(@D) - @$(CXX) $(CFLAGS) -fno-stack-protector $(CXXFLAGS) -o $@ -c $^ - @echo " CXX $^" - -$(MOON_OBJ)/misc/config.cpp.o: $(MOON_SRC)/misc/config.cpp FORCE - @mkdir -p $(@D) - @$(CXX) $(CFLAGS) $(CXXFLAGS) -o $@ -c $(MOON_SRC)/misc/config.cpp - @echo " CXX $^" - -$(MOON_OBJ)/init/Init.cpp.o: $(MOON_SRC)/init/Init.cpp - @mkdir -p $(@D) - @$(CXX) $(CFLAGS) -fno-stack-protector $(CXXFLAGS) -o $@ -c $^ - @echo " CXX $^" - -$(MOON_OBJ)/%.cpp.o: $(MOON_SRC)/%.cpp - @mkdir -p $(@D) - @$(CXX) $(CFLAGS) $(CXXFLAGS) -o $@ -c $^ - @echo " CXX $^" - -$(MOON_OBJ)/memory/liballoc/liballoc.c.o: $(MOON_SRC)/memory/liballoc/liballoc.c - @mkdir -p $(@D) - @$(CC) $(CFLAGS) -fno-sanitize=undefined -o $@ -c $^ - @echo " CC $^" - -$(MOON_OBJ)/%.c.o: $(MOON_SRC)/%.c - @mkdir -p $(@D) - @$(CC) $(CFLAGS) -o $@ -c $^ - @echo " CC $^" - -$(MOON_OBJ)/%.asm.o: $(MOON_SRC)/%.asm - @mkdir -p $(@D) - @$(ASM) $(ASMFLAGS) -o $@ $^ - @echo " ASM $^" - -build: $(OBJS) - @mkdir -p $(MOON_BIN) - @$(CC) $(OBJS) $(LDFLAGS) -o $(MOON_BIN)/moon - @echo " CCLD $(MOON_BIN)/moon" - -clean: - rm -rf $(MOON_OBJ)/* - rm -rf $(MOON_BIN)/* - -install: $(MOON_BIN)/moon - @mkdir -p $(LUNA_ROOT)/initrd/boot - @cp $^ $(LUNA_ROOT)/initrd/boot/moon - @echo " INSTALL $^" - @$(LUNA_ROOT)/tools/generate-symbols.sh - @$(STRIP) $(LUNA_ROOT)/initrd/boot/moon - @echo " STRIP $(LUNA_ROOT)/initrd/boot/moon" - -.PHONY: build clean install FORCE -FORCE: \ No newline at end of file diff --git a/kernel/include/acpi/FADT.h b/kernel/include/acpi/FADT.h deleted file mode 100644 index 553bb43c..00000000 --- a/kernel/include/acpi/FADT.h +++ /dev/null @@ -1,93 +0,0 @@ -#pragma once -#include "acpi/SDT.h" - -namespace ACPI -{ - enum AddressSpace - { - SystemMemory = 0, - SystemIO = 1, - PCI = 2, - EmbeddedController = 3, - SystemManagementBus = 4, - SystemCMOS = 5, - PCIBarTarget = 6, - IPMI = 7, - GeneralPurposeIO = 8, - GenericSerialBus = 9, - PlatformCommunicationChannel = 10 - }; - - struct GenericAddressStructure - { - uint8_t AddressSpace; - uint8_t BitWidth; - uint8_t BitOffset; - uint8_t AccessSize; - uint64_t Address; - }; - - struct FADT - { - SDTHeader header; - uint32_t FirmwareCtrl; - uint32_t Dsdt; - - uint8_t Reserved; - - uint8_t PreferredPowerManagementProfile; - uint16_t SCI_Interrupt; - uint32_t SMI_CommandPort; - uint8_t AcpiEnable; - uint8_t AcpiDisable; - uint8_t S4BIOS_REQ; - uint8_t PSTATE_Control; - uint32_t PM1aEventBlock; - uint32_t PM1bEventBlock; - uint32_t PM1aControlBlock; - uint32_t PM1bControlBlock; - uint32_t PM2ControlBlock; - uint32_t PMTimerBlock; - uint32_t GPE0Block; - uint32_t GPE1Block; - uint8_t PM1EventLength; - uint8_t PM1ControlLength; - uint8_t PM2ControlLength; - uint8_t PMTimerLength; - uint8_t GPE0Length; - uint8_t GPE1Length; - uint8_t GPE1Base; - uint8_t CStateControl; - uint16_t WorstC2Latency; - uint16_t WorstC3Latency; - uint16_t FlushSize; - uint16_t FlushStride; - uint8_t DutyOffset; - uint8_t DutyWidth; - uint8_t DayAlarm; - uint8_t MonthAlarm; - uint8_t Century; - - uint16_t BootArchitectureFlags; - - uint8_t Reserved2; - uint32_t Flags; - - GenericAddressStructure ResetReg; - - uint8_t ResetValue; - uint8_t Reserved3[3]; - - uint64_t X_FirmwareControl; - uint64_t X_Dsdt; - - GenericAddressStructure X_PM1aEventBlock; - GenericAddressStructure X_PM1bEventBlock; - GenericAddressStructure X_PM1aControlBlock; - GenericAddressStructure X_PM1bControlBlock; - GenericAddressStructure X_PM2ControlBlock; - GenericAddressStructure X_PMTimerBlock; - GenericAddressStructure X_GPE0Block; - GenericAddressStructure X_GPE1Block; - }; -} \ No newline at end of file diff --git a/kernel/include/acpi/RSDT.h b/kernel/include/acpi/RSDT.h deleted file mode 100644 index 9e136cb7..00000000 --- a/kernel/include/acpi/RSDT.h +++ /dev/null @@ -1,25 +0,0 @@ -#pragma once -#include "acpi/SDT.h" - -namespace ACPI -{ - struct XSDT - { - SDTHeader header; - uint64_t other_sdt[1]; - }; - - struct RSDT - { - SDTHeader header; - uint32_t other_sdt[1]; - }; - - SDTHeader* get_rsdt_or_xsdt(); - - bool validate_rsdt_or_xsdt(SDTHeader* root_sdt); - - bool is_xsdt(); - - void* find_table(SDTHeader* root_sdt, const char* signature); -} \ No newline at end of file diff --git a/kernel/include/acpi/SDT.h b/kernel/include/acpi/SDT.h deleted file mode 100644 index b757203c..00000000 --- a/kernel/include/acpi/SDT.h +++ /dev/null @@ -1,20 +0,0 @@ -#pragma once -#include - -namespace ACPI -{ - struct SDTHeader - { - char Signature[4]; - uint32_t Length; - uint8_t Revision; - uint8_t Checksum; - char OEMID[6]; - char OEMTableID[8]; - uint32_t OEMRevision; - uint32_t CreatorID; - uint32_t CreatorRevision; - }; - - bool validate_sdt_header(SDTHeader* header); -} \ No newline at end of file diff --git a/kernel/include/bootboot.h b/kernel/include/bootboot.h deleted file mode 100644 index 8ac1207e..00000000 --- a/kernel/include/bootboot.h +++ /dev/null @@ -1,162 +0,0 @@ -/* - * bootboot.h - * https://gitlab.com/bztsrc/bootboot - * - * Copyright (C) 2017 - 2021 bzt (bztsrc@gitlab) - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * This file is part of the BOOTBOOT Protocol package. - * @brief The BOOTBOOT structure - * - */ - -#ifndef _BOOTBOOT_H_ -#define _BOOTBOOT_H_ - -#include - -#ifdef __cplusplus -extern "C" -{ -#endif -#ifndef _MSC_VER -#define _pack __attribute__((packed)) -#else -#define _pack -#pragma pack(push) -#pragma pack(1) -#endif - -#define BOOTBOOT_MAGIC "BOOT" - -/* default virtual addresses for level 0 and 1 static loaders */ -#define BOOTBOOT_MMIO 0xfffffffff8000000 /* memory mapped IO virtual address */ -#define BOOTBOOT_FB 0xfffffffffc000000 /* frame buffer virtual address */ -#define BOOTBOOT_INFO 0xffffffffffe00000 /* bootboot struct virtual address */ -#define BOOTBOOT_ENV 0xffffffffffe01000 /* environment string virtual address */ -#define BOOTBOOT_CORE 0xffffffffffe02000 /* core loadable segment start */ - -/* minimum protocol level: - * hardcoded kernel name, static kernel memory addresses */ -#define PROTOCOL_MINIMAL 0 -/* static protocol level: - * kernel name parsed from environment, static kernel memory addresses */ -#define PROTOCOL_STATIC 1 -/* dynamic protocol level: - * kernel name parsed, kernel memory addresses from ELF or PE symbols */ -#define PROTOCOL_DYNAMIC 2 -/* big-endian flag */ -#define PROTOCOL_BIGENDIAN 0x80 - -/* loader types, just informational */ -#define LOADER_BIOS (0 << 2) -#define LOADER_UEFI (1 << 2) -#define LOADER_RPI (2 << 2) -#define LOADER_COREBOOT (3 << 2) - -/* framebuffer pixel format, only 32 bits supported */ -#define FB_ARGB 0 -#define FB_RGBA 1 -#define FB_ABGR 2 -#define FB_BGRA 3 - - /* mmap entry, type is stored in least significant tetrad (half byte) of size - * this means size described in 16 byte units (not a problem, most modern - * firmware report memory in pages, 4096 byte units anyway). */ - typedef struct - { - uint64_t ptr; - uint64_t size; - } _pack MMapEnt; -#define MMapEnt_Ptr(a) ((a)->ptr) -#define MMapEnt_Size(a) ((a)->size & 0xFFFFFFFFFFFFFFF0) -#define MMapEnt_Type(a) ((a)->size & 0xF) -#define MMapEnt_IsFree(a) (((a)->size & 0xF) == 1) - -#define MMAP_USED 0 /* don't use. Reserved or unknown regions */ -#define MMAP_FREE 1 /* usable memory */ -#define MMAP_ACPI 2 /* acpi memory, volatile and non-volatile as well */ -#define MMAP_MMIO 3 /* memory mapped IO region */ - -#define INITRD_MAXSIZE 16 /* Mb */ - - typedef struct - { - /* first 64 bytes is platform independent */ - uint8_t magic[4]; /* 'BOOT' magic */ - uint32_t size; /* length of bootboot structure, minimum 128 */ - uint8_t protocol; /* 1, static addresses, see PROTOCOL_* and LOADER_* above */ - uint8_t fb_type; /* framebuffer type, see FB_* above */ - uint16_t numcores; /* number of processor cores */ - uint16_t bspid; /* Bootsrap processor ID (Local APIC Id on x86_64) */ - int16_t timezone; /* in minutes -1440..1440 */ - uint8_t datetime[8]; /* in BCD yyyymmddhhiiss UTC (independent to timezone) */ - uint64_t initrd_ptr; /* ramdisk image position and size */ - uint64_t initrd_size; - uint64_t fb_ptr; /* framebuffer pointer and dimensions */ - uint32_t fb_size; - uint32_t fb_width; - uint32_t fb_height; - uint32_t fb_scanline; - - /* the rest (64 bytes) is platform specific */ - union { - struct - { - uint64_t acpi_ptr; - uint64_t smbi_ptr; - uint64_t efi_ptr; - uint64_t mp_ptr; - uint64_t unused0; - uint64_t unused1; - uint64_t unused2; - uint64_t unused3; - } x86_64; - struct - { - uint64_t acpi_ptr; - uint64_t mmio_ptr; - uint64_t efi_ptr; - uint64_t unused0; - uint64_t unused1; - uint64_t unused2; - uint64_t unused3; - uint64_t unused4; - } aarch64; - } arch; - - /* from 128th byte, MMapEnt[], more records may follow */ - MMapEnt mmap; - /* use like this: - * MMapEnt *mmap_ent = &bootboot.mmap; mmap_ent++; - * until you reach bootboot->size, while(mmap_ent < bootboot + bootboot->size) */ - } _pack BOOTBOOT; - -#ifdef _MSC_VER -#pragma pack(pop) -#endif - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/kernel/include/config.h b/kernel/include/config.h deleted file mode 100644 index f59a47e0..00000000 --- a/kernel/include/config.h +++ /dev/null @@ -1,7 +0,0 @@ -#pragma once - -int __moon_version_major(); -int __moon_version_minor(); -const char* __moon_version_suffix(); - -const char* moon_version(); \ No newline at end of file diff --git a/kernel/include/cpu/CPU.h b/kernel/include/cpu/CPU.h deleted file mode 100644 index 81b0ef83..00000000 --- a/kernel/include/cpu/CPU.h +++ /dev/null @@ -1,14 +0,0 @@ -#pragma once -#include "cpu/Features.h" -#include - -namespace CPU -{ - const char* get_vendor_string(); - const char* get_brand_string(); - void log_cpu_information(); - uint64_t get_feature_bitmask(); - uint64_t get_initial_apic_id(); - bool has_feature(CPU::Features); - bool has_nx(); -} \ No newline at end of file diff --git a/kernel/include/cpu/Features.h b/kernel/include/cpu/Features.h deleted file mode 100644 index c5e99053..00000000 --- a/kernel/include/cpu/Features.h +++ /dev/null @@ -1,72 +0,0 @@ -#pragma once - -namespace CPU -{ - enum class Features - { - FPU, - VME, - DE, - PSE, - TSC, - MSR, - PAE, - MCE, - CX8, - APIC, - UNUSED1, - SEP, - MTRR, - PGE, - MCA, - CMOV, - PAT, - PSE36, - PSN, - CLFLUSH, - UNUSED2, - DS, - ACPI, - MMX, - FXSR, - SSE, - SSE2, - SS, - HTT, - TM, - IA64, - PBE, - SSE3, - PCLMUL, - DTES64, - MONITOR, - DS_CPL, - VMX, - SMX, - EST, - TM2, - SSSE3, - CID, - SDBG, - FMA, - CX16, - XTPR, - PDCM, - UNUSED3, - PCID, - DCA, - SSE4_1, - SSE4_2, - X2APIC, - MOVBE, - POPCNT, - TSC_2, - AES, - XSAVE, - OSXSAVE, - AVX, - F16C, - RDRAND, - HYPERVISOR, - }; -} \ No newline at end of file diff --git a/kernel/include/font.h b/kernel/include/font.h deleted file mode 100644 index 1122471f..00000000 --- a/kernel/include/font.h +++ /dev/null @@ -1,260 +0,0 @@ -#pragma once - -unsigned char font[] = { - 0x00, 0x00, 0x00, 0x00, 0x7e, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x7e, 0x00, 0x00, 0x00, 0x00, /* 0 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 1 */ - 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, /* 2 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 3 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 4 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 5 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 6 */ - 0x00, 0x00, 0x00, 0x38, 0x44, 0x44, 0x44, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 7 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 8 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 9 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 10 */ - 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 11 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, /* 12 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, /* 13 */ - 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 14 */ - 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0xff, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, /* 15 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 16 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 17 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 18 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 19 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 20 */ - 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x0f, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, /* 21 */ - 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0xf8, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, /* 22 */ - 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 23 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, /* 24 */ - 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, /* 25 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 26 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 27 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 28 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 29 */ - 0x00, 0x00, 0x00, 0x1c, 0x22, 0x20, 0x20, 0xf8, 0x20, 0x20, 0x72, 0x8c, 0x00, 0x00, 0x00, 0x00, /* 30 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 31 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 32 */ - 0x00, 0x00, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, /* 33 */ - 0x00, 0x24, 0x24, 0x24, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 34 */ - 0x00, 0x00, 0x00, 0x24, 0x24, 0x7e, 0x24, 0x24, 0x24, 0x7e, 0x24, 0x24, 0x00, 0x00, 0x00, 0x00, /* 35 */ - 0x00, 0x00, 0x08, 0x08, 0x1e, 0x20, 0x20, 0x1c, 0x02, 0x02, 0x3c, 0x08, 0x08, 0x00, 0x00, 0x00, /* 36 */ - 0x00, 0x00, 0x00, 0x30, 0x49, 0x4a, 0x34, 0x08, 0x16, 0x29, 0x49, 0x06, 0x00, 0x00, 0x00, 0x00, /* 37 */ - 0x00, 0x00, 0x30, 0x48, 0x48, 0x48, 0x30, 0x31, 0x49, 0x46, 0x46, 0x39, 0x00, 0x00, 0x00, 0x00, /* 38 */ - 0x00, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 39 */ - 0x00, 0x00, 0x04, 0x08, 0x08, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x08, 0x08, 0x04, 0x00, 0x00, /* 40 */ - 0x00, 0x00, 0x20, 0x10, 0x10, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x10, 0x10, 0x20, 0x00, 0x00, /* 41 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x18, 0x7e, 0x18, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 42 */ - 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0x7f, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, /* 43 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x08, 0x08, 0x10, 0x00, /* 44 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 45 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, /* 46 */ - 0x00, 0x00, 0x02, 0x02, 0x04, 0x04, 0x08, 0x08, 0x10, 0x10, 0x20, 0x20, 0x40, 0x40, 0x00, 0x00, /* 47 */ - 0x00, 0x00, 0x00, 0x3c, 0x42, 0x46, 0x4a, 0x52, 0x62, 0x42, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, /* 48 */ - 0x00, 0x00, 0x00, 0x08, 0x18, 0x28, 0x08, 0x08, 0x08, 0x08, 0x08, 0x3e, 0x00, 0x00, 0x00, 0x00, /* 49 */ - 0x00, 0x00, 0x00, 0x3c, 0x42, 0x02, 0x02, 0x04, 0x08, 0x10, 0x20, 0x7e, 0x00, 0x00, 0x00, 0x00, /* 50 */ - 0x00, 0x00, 0x00, 0x7e, 0x04, 0x08, 0x1c, 0x02, 0x02, 0x02, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, /* 51 */ - 0x00, 0x00, 0x00, 0x04, 0x0c, 0x14, 0x24, 0x44, 0x7e, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, /* 52 */ - 0x00, 0x00, 0x00, 0x7e, 0x40, 0x40, 0x7c, 0x02, 0x02, 0x02, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, /* 53 */ - 0x00, 0x00, 0x00, 0x1c, 0x20, 0x40, 0x40, 0x7c, 0x42, 0x42, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, /* 54 */ - 0x00, 0x00, 0x00, 0x7e, 0x02, 0x04, 0x04, 0x08, 0x08, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, /* 55 */ - 0x00, 0x00, 0x00, 0x3c, 0x42, 0x42, 0x42, 0x3c, 0x42, 0x42, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, /* 56 */ - 0x00, 0x00, 0x00, 0x3c, 0x42, 0x42, 0x42, 0x3e, 0x02, 0x02, 0x04, 0x38, 0x00, 0x00, 0x00, 0x00, /* 57 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, /* 58 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x08, 0x08, 0x10, 0x00, /* 59 */ - 0x00, 0x00, 0x00, 0x04, 0x08, 0x10, 0x20, 0x40, 0x20, 0x10, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, /* 60 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 61 */ - 0x00, 0x00, 0x00, 0x20, 0x10, 0x08, 0x04, 0x02, 0x04, 0x08, 0x10, 0x20, 0x00, 0x00, 0x00, 0x00, /* 62 */ - 0x00, 0x00, 0x3c, 0x42, 0x02, 0x04, 0x08, 0x10, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, /* 63 */ - 0x00, 0x00, 0x1c, 0x22, 0x41, 0x4f, 0x51, 0x51, 0x51, 0x53, 0x4d, 0x40, 0x20, 0x1f, 0x00, 0x00, /* 64 */ - 0x00, 0x00, 0x00, 0x18, 0x24, 0x42, 0x42, 0x42, 0x7e, 0x42, 0x42, 0x42, 0x00, 0x00, 0x00, 0x00, /* 65 */ - 0x00, 0x00, 0x00, 0x7c, 0x42, 0x42, 0x42, 0x7c, 0x42, 0x42, 0x42, 0x7c, 0x00, 0x00, 0x00, 0x00, /* 66 */ - 0x00, 0x00, 0x00, 0x1e, 0x20, 0x40, 0x40, 0x40, 0x40, 0x40, 0x20, 0x1e, 0x00, 0x00, 0x00, 0x00, /* 67 */ - 0x00, 0x00, 0x00, 0x78, 0x44, 0x42, 0x42, 0x42, 0x42, 0x42, 0x44, 0x78, 0x00, 0x00, 0x00, 0x00, /* 68 */ - 0x00, 0x00, 0x00, 0x7e, 0x40, 0x40, 0x40, 0x7c, 0x40, 0x40, 0x40, 0x7e, 0x00, 0x00, 0x00, 0x00, /* 69 */ - 0x00, 0x00, 0x00, 0x7e, 0x40, 0x40, 0x40, 0x7c, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, /* 70 */ - 0x00, 0x00, 0x00, 0x1e, 0x20, 0x40, 0x40, 0x46, 0x42, 0x42, 0x22, 0x1e, 0x00, 0x00, 0x00, 0x00, /* 71 */ - 0x00, 0x00, 0x00, 0x42, 0x42, 0x42, 0x42, 0x7e, 0x42, 0x42, 0x42, 0x42, 0x00, 0x00, 0x00, 0x00, /* 72 */ - 0x00, 0x00, 0x00, 0x3e, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x3e, 0x00, 0x00, 0x00, 0x00, /* 73 */ - 0x00, 0x00, 0x00, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x42, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, /* 74 */ - 0x00, 0x00, 0x00, 0x42, 0x44, 0x48, 0x50, 0x60, 0x50, 0x48, 0x44, 0x42, 0x00, 0x00, 0x00, 0x00, /* 75 */ - 0x00, 0x00, 0x00, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x7e, 0x00, 0x00, 0x00, 0x00, /* 76 */ - 0x00, 0x00, 0x00, 0x41, 0x63, 0x55, 0x49, 0x49, 0x41, 0x41, 0x41, 0x41, 0x00, 0x00, 0x00, 0x00, /* 77 */ - 0x00, 0x00, 0x00, 0x42, 0x62, 0x52, 0x4a, 0x46, 0x42, 0x42, 0x42, 0x42, 0x00, 0x00, 0x00, 0x00, /* 78 */ - 0x00, 0x00, 0x00, 0x3c, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, /* 79 */ - 0x00, 0x00, 0x00, 0x7c, 0x42, 0x42, 0x42, 0x7c, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, /* 80 */ - 0x00, 0x00, 0x00, 0x3c, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3c, 0x04, 0x02, 0x00, 0x00, /* 81 */ - 0x00, 0x00, 0x00, 0x7c, 0x42, 0x42, 0x42, 0x7c, 0x48, 0x44, 0x42, 0x42, 0x00, 0x00, 0x00, 0x00, /* 82 */ - 0x00, 0x00, 0x00, 0x3e, 0x40, 0x40, 0x20, 0x18, 0x04, 0x02, 0x02, 0x7c, 0x00, 0x00, 0x00, 0x00, /* 83 */ - 0x00, 0x00, 0x00, 0x7f, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, /* 84 */ - 0x00, 0x00, 0x00, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, /* 85 */ - 0x00, 0x00, 0x00, 0x42, 0x42, 0x42, 0x42, 0x42, 0x24, 0x24, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, /* 86 */ - 0x00, 0x00, 0x00, 0x41, 0x41, 0x41, 0x41, 0x49, 0x49, 0x49, 0x55, 0x63, 0x00, 0x00, 0x00, 0x00, /* 87 */ - 0x00, 0x00, 0x00, 0x41, 0x41, 0x22, 0x14, 0x08, 0x14, 0x22, 0x41, 0x41, 0x00, 0x00, 0x00, 0x00, /* 88 */ - 0x00, 0x00, 0x00, 0x41, 0x41, 0x22, 0x14, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, /* 89 */ - 0x00, 0x00, 0x00, 0x7e, 0x04, 0x08, 0x08, 0x10, 0x10, 0x20, 0x20, 0x7e, 0x00, 0x00, 0x00, 0x00, /* 90 */ - 0x00, 0x00, 0x1e, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x1e, 0x00, 0x00, /* 91 */ - 0x00, 0x00, 0x40, 0x40, 0x20, 0x20, 0x10, 0x10, 0x08, 0x08, 0x04, 0x04, 0x02, 0x02, 0x00, 0x00, /* 92 */ - 0x00, 0x00, 0x78, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x78, 0x00, 0x00, /* 93 */ - 0x00, 0x00, 0x10, 0x28, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 94 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, /* 95 */ - 0x00, 0x20, 0x10, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 96 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x02, 0x02, 0x3e, 0x42, 0x42, 0x3e, 0x00, 0x00, 0x00, 0x00, /* 97 */ - 0x00, 0x00, 0x40, 0x40, 0x40, 0x7c, 0x42, 0x42, 0x42, 0x42, 0x42, 0x7c, 0x00, 0x00, 0x00, 0x00, /* 98 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x42, 0x40, 0x40, 0x40, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, /* 99 */ - 0x00, 0x00, 0x02, 0x02, 0x02, 0x3e, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3e, 0x00, 0x00, 0x00, 0x00, /* 100 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x42, 0x42, 0x7e, 0x40, 0x40, 0x3e, 0x00, 0x00, 0x00, 0x00, /* 101 */ - 0x00, 0x00, 0x0e, 0x10, 0x10, 0x7e, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, /* 102 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3e, 0x02, 0x02, 0x3c, 0x00, /* 103 */ - 0x00, 0x00, 0x40, 0x40, 0x40, 0x7c, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x00, 0x00, 0x00, 0x00, /* 104 */ - 0x00, 0x00, 0x08, 0x08, 0x00, 0x38, 0x08, 0x08, 0x08, 0x08, 0x08, 0x3e, 0x00, 0x00, 0x00, 0x00, /* 105 */ - 0x00, 0x00, 0x04, 0x04, 0x00, 0x1c, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x38, 0x00, /* 106 */ - 0x00, 0x00, 0x40, 0x40, 0x40, 0x44, 0x48, 0x50, 0x70, 0x48, 0x44, 0x42, 0x00, 0x00, 0x00, 0x00, /* 107 */ - 0x00, 0x00, 0x38, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x3e, 0x00, 0x00, 0x00, 0x00, /* 108 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x00, 0x00, 0x00, 0x00, /* 109 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x00, 0x00, 0x00, 0x00, /* 110 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, /* 111 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x42, 0x42, 0x42, 0x42, 0x42, 0x7c, 0x40, 0x40, 0x40, 0x00, /* 112 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3e, 0x02, 0x02, 0x02, 0x00, /* 113 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x2e, 0x30, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0x00, /* 114 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x40, 0x20, 0x18, 0x04, 0x02, 0x7c, 0x00, 0x00, 0x00, 0x00, /* 115 */ - 0x00, 0x00, 0x00, 0x10, 0x10, 0x7e, 0x10, 0x10, 0x10, 0x10, 0x10, 0x0e, 0x00, 0x00, 0x00, 0x00, /* 116 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3e, 0x00, 0x00, 0x00, 0x00, /* 117 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x42, 0x42, 0x24, 0x24, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, /* 118 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x41, 0x41, 0x49, 0x49, 0x55, 0x63, 0x00, 0x00, 0x00, 0x00, /* 119 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x22, 0x14, 0x08, 0x14, 0x22, 0x41, 0x00, 0x00, 0x00, 0x00, /* 120 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3e, 0x02, 0x02, 0x3c, 0x00, /* 121 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x04, 0x08, 0x10, 0x20, 0x40, 0x7e, 0x00, 0x00, 0x00, 0x00, /* 122 */ - 0x00, 0x0e, 0x10, 0x10, 0x10, 0x10, 0x10, 0xe0, 0x10, 0x10, 0x10, 0x10, 0x10, 0x0e, 0x00, 0x00, /* 123 */ - 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, /* 124 */ - 0x00, 0x70, 0x08, 0x08, 0x08, 0x08, 0x08, 0x07, 0x08, 0x08, 0x08, 0x08, 0x08, 0x70, 0x00, 0x00, /* 125 */ - 0x00, 0x00, 0x31, 0x49, 0x46, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 126 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 127 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 128 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 129 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 130 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 131 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 132 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 133 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 134 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 135 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 136 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 137 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 138 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 139 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 140 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 141 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 142 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 143 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 144 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 145 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 146 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 147 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 148 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 149 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 150 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 151 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 152 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 153 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 154 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 155 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 156 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 157 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 158 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 159 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 160 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, /* 161 */ - 0x00, 0x00, 0x08, 0x08, 0x1c, 0x22, 0x40, 0x40, 0x40, 0x22, 0x1c, 0x08, 0x08, 0x00, 0x00, 0x00, /* 162 */ - 0x00, 0x00, 0x00, 0x1c, 0x22, 0x20, 0x20, 0xf8, 0x20, 0x20, 0x72, 0x8c, 0x00, 0x00, 0x00, 0x00, /* 163 */ - 0x00, 0x00, 0x00, 0x00, 0x42, 0x3c, 0x24, 0x24, 0x24, 0x3c, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, /* 164 */ - 0x00, 0x00, 0x00, 0x41, 0x22, 0x14, 0x08, 0x3e, 0x08, 0x3e, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, /* 165 */ - 0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, /* 166 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 167 */ - 0x22, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 168 */ - 0x00, 0x00, 0x00, 0x1c, 0x22, 0x41, 0x4d, 0x51, 0x51, 0x4d, 0x41, 0x22, 0x1c, 0x00, 0x00, 0x00, /* 169 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 170 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x12, 0x24, 0x48, 0x24, 0x12, 0x09, 0x00, 0x00, 0x00, 0x00, /* 171 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 172 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 173 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 174 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 175 */ - 0x00, 0x00, 0x00, 0x38, 0x44, 0x44, 0x44, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 176 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 177 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 178 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 179 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 180 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 181 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 182 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 183 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x30, 0x00, /* 184 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 185 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 186 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x24, 0x12, 0x09, 0x12, 0x24, 0x48, 0x00, 0x00, 0x00, 0x00, /* 187 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 188 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 189 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 190 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x08, 0x10, 0x20, 0x40, 0x42, 0x3c, 0x00, /* 191 */ - 0x20, 0x10, 0x00, 0x18, 0x18, 0x24, 0x24, 0x24, 0x7e, 0x42, 0x42, 0x42, 0x00, 0x00, 0x00, 0x00, /* 192 */ - 0x04, 0x08, 0x00, 0x18, 0x18, 0x24, 0x24, 0x24, 0x7e, 0x42, 0x42, 0x42, 0x00, 0x00, 0x00, 0x00, /* 193 */ - 0x18, 0x24, 0x00, 0x18, 0x18, 0x24, 0x24, 0x24, 0x7e, 0x42, 0x42, 0x42, 0x00, 0x00, 0x00, 0x00, /* 194 */ - 0x32, 0x4c, 0x00, 0x18, 0x18, 0x24, 0x24, 0x24, 0x7e, 0x42, 0x42, 0x42, 0x00, 0x00, 0x00, 0x00, /* 195 */ - 0x24, 0x24, 0x00, 0x18, 0x18, 0x24, 0x24, 0x24, 0x7e, 0x42, 0x42, 0x42, 0x00, 0x00, 0x00, 0x00, /* 196 */ - 0x18, 0x24, 0x24, 0x18, 0x18, 0x24, 0x24, 0x24, 0x7e, 0x42, 0x42, 0x42, 0x00, 0x00, 0x00, 0x00, /* 197 */ - 0x00, 0x00, 0x00, 0x0f, 0x14, 0x14, 0x24, 0x27, 0x3c, 0x44, 0x44, 0x47, 0x00, 0x00, 0x00, 0x00, /* 198 */ - 0x00, 0x00, 0x00, 0x1e, 0x20, 0x40, 0x40, 0x40, 0x40, 0x40, 0x20, 0x1e, 0x08, 0x08, 0x30, 0x00, /* 199 */ - 0x20, 0x10, 0x00, 0x7e, 0x40, 0x40, 0x40, 0x7c, 0x40, 0x40, 0x40, 0x7e, 0x00, 0x00, 0x00, 0x00, /* 200 */ - 0x04, 0x08, 0x00, 0x7e, 0x40, 0x40, 0x40, 0x7c, 0x40, 0x40, 0x40, 0x7e, 0x00, 0x00, 0x00, 0x00, /* 201 */ - 0x18, 0x24, 0x00, 0x7e, 0x40, 0x40, 0x40, 0x7c, 0x40, 0x40, 0x40, 0x7e, 0x00, 0x00, 0x00, 0x00, /* 202 */ - 0x24, 0x24, 0x00, 0x7e, 0x40, 0x40, 0x40, 0x7c, 0x40, 0x40, 0x40, 0x7e, 0x00, 0x00, 0x00, 0x00, /* 203 */ - 0x10, 0x08, 0x00, 0x3e, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x3e, 0x00, 0x00, 0x00, 0x00, /* 204 */ - 0x04, 0x08, 0x00, 0x3e, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x3e, 0x00, 0x00, 0x00, 0x00, /* 205 */ - 0x18, 0x24, 0x00, 0x3e, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x3e, 0x00, 0x00, 0x00, 0x00, /* 206 */ - 0x22, 0x22, 0x00, 0x3e, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x3e, 0x00, 0x00, 0x00, 0x00, /* 207 */ - 0x00, 0x00, 0x00, 0x3c, 0x22, 0x21, 0x21, 0x79, 0x21, 0x21, 0x22, 0x3c, 0x00, 0x00, 0x00, 0x00, /* 208 */ - 0x32, 0x4c, 0x00, 0x42, 0x62, 0x52, 0x4a, 0x46, 0x42, 0x42, 0x42, 0x42, 0x00, 0x00, 0x00, 0x00, /* 209 */ - 0x10, 0x08, 0x00, 0x1c, 0x22, 0x41, 0x41, 0x41, 0x41, 0x41, 0x22, 0x1c, 0x00, 0x00, 0x00, 0x00, /* 210 */ - 0x04, 0x08, 0x00, 0x1c, 0x22, 0x41, 0x41, 0x41, 0x41, 0x41, 0x22, 0x1c, 0x00, 0x00, 0x00, 0x00, /* 211 */ - 0x18, 0x24, 0x00, 0x1c, 0x22, 0x41, 0x41, 0x41, 0x41, 0x41, 0x22, 0x1c, 0x00, 0x00, 0x00, 0x00, /* 212 */ - 0x32, 0x4c, 0x00, 0x1c, 0x22, 0x41, 0x41, 0x41, 0x41, 0x41, 0x22, 0x1c, 0x00, 0x00, 0x00, 0x00, /* 213 */ - 0x24, 0x24, 0x00, 0x1c, 0x22, 0x41, 0x41, 0x41, 0x41, 0x41, 0x22, 0x1c, 0x00, 0x00, 0x00, 0x00, /* 214 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x14, 0x08, 0x14, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, /* 215 */ - 0x00, 0x00, 0x02, 0x3c, 0x42, 0x46, 0x4a, 0x52, 0x62, 0x42, 0x42, 0x3c, 0x40, 0x00, 0x00, 0x00, /* 216 */ - 0x20, 0x10, 0x00, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, /* 217 */ - 0x04, 0x08, 0x00, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, /* 218 */ - 0x18, 0x24, 0x00, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, /* 219 */ - 0x24, 0x24, 0x00, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, /* 220 */ - 0x04, 0x08, 0x00, 0x41, 0x41, 0x22, 0x14, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, /* 221 */ - 0x00, 0x00, 0x00, 0x40, 0x40, 0x7c, 0x42, 0x42, 0x42, 0x7c, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, /* 222 */ - 0x00, 0x00, 0x00, 0x3c, 0x42, 0x44, 0x4c, 0x42, 0x42, 0x42, 0x44, 0x58, 0x00, 0x00, 0x00, 0x00, /* 223 */ - 0x00, 0x00, 0x20, 0x10, 0x00, 0x3c, 0x02, 0x02, 0x3e, 0x42, 0x42, 0x3e, 0x00, 0x00, 0x00, 0x00, /* 224 */ - 0x00, 0x00, 0x04, 0x08, 0x00, 0x3c, 0x02, 0x02, 0x3e, 0x42, 0x42, 0x3e, 0x00, 0x00, 0x00, 0x00, /* 225 */ - 0x00, 0x18, 0x24, 0x00, 0x00, 0x3c, 0x02, 0x02, 0x3e, 0x42, 0x42, 0x3e, 0x00, 0x00, 0x00, 0x00, /* 226 */ - 0x00, 0x32, 0x4c, 0x00, 0x00, 0x3c, 0x02, 0x02, 0x3e, 0x42, 0x42, 0x3e, 0x00, 0x00, 0x00, 0x00, /* 227 */ - 0x00, 0x00, 0x24, 0x24, 0x00, 0x3c, 0x02, 0x02, 0x3e, 0x42, 0x42, 0x3e, 0x00, 0x00, 0x00, 0x00, /* 228 */ - 0x18, 0x24, 0x24, 0x18, 0x00, 0x3c, 0x02, 0x02, 0x3e, 0x42, 0x42, 0x3e, 0x00, 0x00, 0x00, 0x00, /* 229 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x09, 0x39, 0x4f, 0x48, 0x48, 0x37, 0x00, 0x00, 0x00, 0x00, /* 230 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x42, 0x40, 0x40, 0x40, 0x42, 0x3c, 0x08, 0x08, 0x30, 0x00, /* 231 */ - 0x00, 0x00, 0x20, 0x10, 0x00, 0x3c, 0x42, 0x42, 0x7e, 0x40, 0x40, 0x3e, 0x00, 0x00, 0x00, 0x00, /* 232 */ - 0x00, 0x00, 0x04, 0x08, 0x00, 0x3c, 0x42, 0x42, 0x7e, 0x40, 0x40, 0x3e, 0x00, 0x00, 0x00, 0x00, /* 233 */ - 0x00, 0x18, 0x24, 0x00, 0x00, 0x3c, 0x42, 0x42, 0x7e, 0x40, 0x40, 0x3e, 0x00, 0x00, 0x00, 0x00, /* 234 */ - 0x00, 0x00, 0x24, 0x24, 0x00, 0x3c, 0x42, 0x42, 0x7e, 0x40, 0x40, 0x3e, 0x00, 0x00, 0x00, 0x00, /* 235 */ - 0x00, 0x00, 0x10, 0x08, 0x00, 0x38, 0x08, 0x08, 0x08, 0x08, 0x08, 0x3e, 0x00, 0x00, 0x00, 0x00, /* 236 */ - 0x00, 0x00, 0x04, 0x08, 0x00, 0x38, 0x08, 0x08, 0x08, 0x08, 0x08, 0x3e, 0x00, 0x00, 0x00, 0x00, /* 237 */ - 0x00, 0x18, 0x24, 0x00, 0x00, 0x38, 0x08, 0x08, 0x08, 0x08, 0x08, 0x3e, 0x00, 0x00, 0x00, 0x00, /* 238 */ - 0x00, 0x00, 0x24, 0x24, 0x00, 0x38, 0x08, 0x08, 0x08, 0x08, 0x08, 0x3e, 0x00, 0x00, 0x00, 0x00, /* 239 */ - 0x00, 0x09, 0x06, 0x1a, 0x01, 0x1d, 0x23, 0x41, 0x41, 0x41, 0x22, 0x1c, 0x00, 0x00, 0x00, 0x00, /* 240 */ - 0x00, 0x32, 0x4c, 0x00, 0x00, 0x7c, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x00, 0x00, 0x00, 0x00, /* 241 */ - 0x00, 0x00, 0x10, 0x08, 0x00, 0x3c, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, /* 242 */ - 0x00, 0x00, 0x04, 0x08, 0x00, 0x3c, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, /* 243 */ - 0x00, 0x18, 0x24, 0x00, 0x00, 0x3c, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, /* 244 */ - 0x00, 0x32, 0x4c, 0x00, 0x00, 0x3c, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, /* 245 */ - 0x00, 0x00, 0x24, 0x24, 0x00, 0x3c, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, /* 246 */ - 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, /* 247 */ - 0x00, 0x00, 0x00, 0x00, 0x02, 0x3c, 0x46, 0x4a, 0x52, 0x62, 0x42, 0x3c, 0x40, 0x00, 0x00, 0x00, /* 248 */ - 0x00, 0x00, 0x20, 0x10, 0x00, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3e, 0x00, 0x00, 0x00, 0x00, /* 249 */ - 0x00, 0x00, 0x04, 0x08, 0x00, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3e, 0x00, 0x00, 0x00, 0x00, /* 250 */ - 0x00, 0x18, 0x24, 0x00, 0x00, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3e, 0x00, 0x00, 0x00, 0x00, /* 251 */ - 0x00, 0x00, 0x24, 0x24, 0x00, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3e, 0x00, 0x00, 0x00, 0x00, /* 252 */ - 0x00, 0x00, 0x04, 0x08, 0x00, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3e, 0x02, 0x02, 0x3c, 0x00, /* 253 */ - 0x00, 0x00, 0x40, 0x40, 0x40, 0x5c, 0x62, 0x41, 0x41, 0x41, 0x62, 0x5c, 0x40, 0x40, 0x40, 0x00, /* 254 */ - 0x00, 0x00, 0x24, 0x24, 0x00, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3e, 0x02, 0x02, 0x3c, 0x00, - /* 255 */}; \ No newline at end of file diff --git a/kernel/include/fs/FileDescriptor.h b/kernel/include/fs/FileDescriptor.h deleted file mode 100644 index 9e34df83..00000000 --- a/kernel/include/fs/FileDescriptor.h +++ /dev/null @@ -1,83 +0,0 @@ -#pragma once -#include "fs/VFS.h" -#include - -struct Descriptor -{ - bool is_open() - { - return m_is_open; - } - - bool can_read() - { - return m_can_read && m_is_open; - } - - bool can_write() - { - return m_can_write && m_is_open; - } - - void close() - { - m_is_open = false; - } - - VFS::Node* node() - { - return m_node; - } - - ssize_t read(size_t size, char* buffer); - ssize_t write(size_t size, const char* buffer); - - ssize_t user_read(size_t size, char* buffer); - ssize_t user_write(size_t size, const char* buffer); - - uintptr_t mmap(uintptr_t addr, size_t size, int prot, off_t offset); - - long ioctl(int cmd, uintptr_t arg); - - void open(VFS::Node* node, bool can_read, bool can_write, bool able_to_block, bool close_on_exec); - - int seek(long offset); - long offset() - { - return (long)m_offset; - } - - unsigned long length() - { - return m_node->length; - } - - bool able_to_block() - { - return m_able_to_block; - } - - bool close_on_exec() - { - return m_close_on_exec; - } - - void set_close_on_exec(bool value) - { - m_close_on_exec = value; - } - - Descriptor(const Descriptor& other); - Descriptor(); - - const Descriptor& operator=(const Descriptor& other); - - private: - bool m_is_open; - bool m_can_read; - bool m_can_write; - bool m_able_to_block; - bool m_close_on_exec; - VFS::Node* m_node; - uint64_t m_offset; -}; \ No newline at end of file diff --git a/kernel/include/fs/InitRD.h b/kernel/include/fs/InitRD.h deleted file mode 100644 index d0ce7b42..00000000 --- a/kernel/include/fs/InitRD.h +++ /dev/null @@ -1,54 +0,0 @@ -#pragma once -#include -#include - -#define TAR_MAGIC "ustar" -#define TAR_BLOCKSIZE 512 - -namespace InitRD -{ - struct TarHeader - { /* byte offset */ - char name[100]; /* 0 */ - char mode[8]; /* 100 */ - char uid[8]; /* 108 */ - char gid[8]; /* 116 */ - char size[12]; /* 124 */ - char mtime[12]; /* 136 */ - char chksum[8]; /* 148 */ - char typeflag; /* 156 */ - char linkname[100]; /* 157 */ - char magic[6]; /* 257 */ - char version[2]; /* 263 */ - char uname[32]; /* 265 */ - char gname[32]; /* 297 */ - char devmajor[8]; /* 329 */ - char devminor[8]; /* 337 */ - char prefix[155]; /* 345 */ - /* 500 */ - } __attribute__((packed)); - - struct File - { - char name[100]; - uint64_t size; - uint64_t size_in_blocks; - void* addr; - mode_t mode; - }; - - uint64_t get_total_blocks(); - File get_file(TarHeader* header); - void free_file(File& file); - TarHeader* get_block(uint64_t block_index); - bool is_valid_header(TarHeader* header); - - uint64_t get_file_physical_address(File& file); - - File open(const char* filename); - void for_each(void (*callback)(File& file)); - - bool is_initialized(); - - void init(); -} \ No newline at end of file diff --git a/kernel/include/fs/TmpFS.h b/kernel/include/fs/TmpFS.h deleted file mode 100644 index cb79f37a..00000000 --- a/kernel/include/fs/TmpFS.h +++ /dev/null @@ -1,18 +0,0 @@ -#pragma once - -#include "fs/VFS.h" - -namespace TmpFS -{ - VFS::Node* get(); - - VFS::Node* finddir(VFS::Node* node, const char* filename); - VFS::Node* readdir(VFS::Node* node, long offset); - - int mkdir(VFS::Node* node, const char* name, mode_t mode); - - ssize_t read(VFS::Node* node, size_t offset, size_t length, char* buffer); - ssize_t write(VFS::Node* node, size_t offset, size_t length, const char* buffer); - - VFS::Node* create(VFS::Node* node, const char* name, mode_t mode, uid_t uid, gid_t gid); -} \ No newline at end of file diff --git a/kernel/include/fs/VFS.h b/kernel/include/fs/VFS.h deleted file mode 100644 index 410c9ec7..00000000 --- a/kernel/include/fs/VFS.h +++ /dev/null @@ -1,92 +0,0 @@ -#pragma once -#include "utils/Result.h" -#include -#include -#include - -typedef long ssize_t; - -#define VFS_FILE 0x0 -#define VFS_DIRECTORY 0x1 -#define VFS_DEVICE 0x2 - -#define VFS_MOUNTPOINT 0x1 - -#define NAME_MAX 64 - -namespace VFS -{ - struct Node; - - typedef ssize_t (*node_read)(Node*, size_t, size_t, char*); - typedef ssize_t (*node_write)(Node*, size_t, size_t, const char*); - typedef Node* (*node_finddir)(Node*, const char*); - typedef int (*node_mkdir)(Node*, const char*, mode_t); - typedef int (*node_block)(Node*); - typedef Node* (*node_readdir)(Node*, long); - typedef uintptr_t (*node_mmap)(Node*, uintptr_t, size_t, int, off_t); - typedef long (*node_ioctl)(Node*, int, uintptr_t); - typedef Node* (*node_create)(Node*, const char*, mode_t, uid_t, gid_t); - - struct Node - { - char name[NAME_MAX]; - int type; - int flags; - int tty = 0; - int uid; - int gid; - mode_t mode; - uint64_t impl; - uint64_t atime; - uint64_t ctime; - uint64_t mtime; - uint64_t inode; - uint64_t length; - node_read read_func; - node_finddir find_func; - node_readdir readdir_func; - node_mkdir mkdir_func; - node_write write_func; - node_block block_func; - node_mmap mmap_func; - node_ioctl ioctl_func; - node_create create_func; - Node* link; - }; - - ssize_t read(Node* node, size_t offset, size_t length, char* buffer); - ssize_t write(Node* node, size_t offset, size_t length, const char* buffer); - int mkdir(const char* path, const char* name); - int mkdir(const char* pathname); - - int do_mkdir(const char* path, const char* name, int uid, int gid, mode_t mode); - int do_mkdir(const char* pathname, int uid, int gid, mode_t mode); - - Result create(const char* pathname, mode_t mode, uid_t uid, gid_t gid); - - int would_block(Node* node); - - void mount_root(Node* root); - - Node* resolve_path(const char* filename, Node* root = nullptr); - Node* resolve_parent(const char* filename, Node* root = nullptr); - - bool exists(const char* pathname); - - void mount(Node* mountpoint, Node* mounted); - void mount(const char* pathname, Node* mounted); - - void unmount(Node* mountpoint); - - Node* root(); - - Node* readdir(Node* dir, long offset); - - bool can_execute(Node* node, int uid, int gid); - bool can_read(Node* node, int uid, int gid); - bool can_write(Node* node, int uid, int gid); - - bool is_setuid(Node* node); - bool is_setgid(Node* node); -} \ No newline at end of file diff --git a/kernel/include/fs/devices/Console.h b/kernel/include/fs/devices/Console.h deleted file mode 100644 index aef42b14..00000000 --- a/kernel/include/fs/devices/Console.h +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once -#include "fs/VFS.h" - -namespace ConsoleDevice -{ - VFS::Node* create_new(const char* devname); - - ssize_t write(VFS::Node* node, size_t offset, size_t size, const char* buffer); - - ssize_t read(VFS::Node* node, size_t offset, size_t size, char* buffer); - - int would_block(VFS::Node* node); - - void append(char c); -} \ No newline at end of file diff --git a/kernel/include/fs/devices/DeviceFS.h b/kernel/include/fs/devices/DeviceFS.h deleted file mode 100644 index d6a37998..00000000 --- a/kernel/include/fs/devices/DeviceFS.h +++ /dev/null @@ -1,10 +0,0 @@ -#pragma once -#include "fs/VFS.h" - -namespace DeviceFS -{ - VFS::Node* get(); - - VFS::Node* finddir(VFS::Node* node, const char* filename); - VFS::Node* readdir(VFS::Node* node, long offset); -} \ No newline at end of file diff --git a/kernel/include/fs/devices/Framebuffer.h b/kernel/include/fs/devices/Framebuffer.h deleted file mode 100644 index 32b2a04f..00000000 --- a/kernel/include/fs/devices/Framebuffer.h +++ /dev/null @@ -1,13 +0,0 @@ -#pragma once -#include "fs/VFS.h" - -namespace FramebufferDevice -{ - VFS::Node* create_new(const char* devname); - - ssize_t write(VFS::Node* node, size_t offset, size_t size, const char* buffer); - - uintptr_t mmap(VFS::Node* node, uintptr_t addr, size_t size, int prot, off_t offset); - - long ioctl(VFS::Node* node, int cmd, uintptr_t arg); -} \ No newline at end of file diff --git a/kernel/include/fs/devices/Keyboard.h b/kernel/include/fs/devices/Keyboard.h deleted file mode 100644 index 3dc30575..00000000 --- a/kernel/include/fs/devices/Keyboard.h +++ /dev/null @@ -1,13 +0,0 @@ -#pragma once -#include "fs/VFS.h" - -namespace KeyboardDevice -{ - VFS::Node* create_new(const char* devname); - - ssize_t read(VFS::Node* node, size_t offset, size_t size, char* buffer); - - int would_block(VFS::Node* node); - - void append(char c); -} \ No newline at end of file diff --git a/kernel/include/fs/devices/NullDevice.h b/kernel/include/fs/devices/NullDevice.h deleted file mode 100644 index 5c264fcd..00000000 --- a/kernel/include/fs/devices/NullDevice.h +++ /dev/null @@ -1,10 +0,0 @@ -#pragma once -#include "fs/VFS.h" - -namespace NullDevice -{ - VFS::Node* create_new(const char* devname); - - ssize_t write(VFS::Node* node, size_t offset, size_t size, const char* buffer); - ssize_t read(VFS::Node* node, size_t offset, size_t size, char* buffer); -} \ No newline at end of file diff --git a/kernel/include/fs/devices/Random.h b/kernel/include/fs/devices/Random.h deleted file mode 100644 index 916ba0c4..00000000 --- a/kernel/include/fs/devices/Random.h +++ /dev/null @@ -1,9 +0,0 @@ -#pragma once -#include "fs/VFS.h" - -namespace RandomDevice -{ - VFS::Node* create_new(const char* devname); - - ssize_t read(VFS::Node* node, size_t offset, size_t size, char* buffer); -} \ No newline at end of file diff --git a/kernel/include/fs/devices/Serial.h b/kernel/include/fs/devices/Serial.h deleted file mode 100644 index 2f9728ca..00000000 --- a/kernel/include/fs/devices/Serial.h +++ /dev/null @@ -1,9 +0,0 @@ -#pragma once -#include "fs/VFS.h" - -namespace SerialDevice -{ - VFS::Node* create_new(const char* devname); - - ssize_t write(VFS::Node* node, size_t offset, size_t size, const char* buffer); -} \ No newline at end of file diff --git a/kernel/include/fs/devices/Version.h b/kernel/include/fs/devices/Version.h deleted file mode 100644 index 72590515..00000000 --- a/kernel/include/fs/devices/Version.h +++ /dev/null @@ -1,9 +0,0 @@ -#pragma once -#include "fs/VFS.h" - -namespace VersionDevice -{ - VFS::Node* create_new(const char* devname); - - ssize_t read(VFS::Node* node, size_t offset, size_t size, char* buffer); -} \ No newline at end of file diff --git a/kernel/include/gdt/GDT.h b/kernel/include/gdt/GDT.h deleted file mode 100644 index 297199ad..00000000 --- a/kernel/include/gdt/GDT.h +++ /dev/null @@ -1,6 +0,0 @@ -#pragma once - -namespace GDT -{ - void load(); -} \ No newline at end of file diff --git a/kernel/include/init/Init.h b/kernel/include/init/Init.h deleted file mode 100644 index 0870c600..00000000 --- a/kernel/include/init/Init.h +++ /dev/null @@ -1,9 +0,0 @@ -#pragma once - -namespace Init -{ - void check_magic(); - void disable_smp(); - void early_init(); - void finish_kernel_boot(); -} \ No newline at end of file diff --git a/kernel/include/interrupts/Context.h b/kernel/include/interrupts/Context.h deleted file mode 100644 index 41f60847..00000000 --- a/kernel/include/interrupts/Context.h +++ /dev/null @@ -1,14 +0,0 @@ -#pragma once -#include - -struct Context -{ - uint64_t cr2, ds; - uint64_t r15, r14, r13, r12, r11, r10, r9, r8, rsi, rdi, rbp, rdx, rcx, rbx, rax; - uint64_t number; - union { - uint64_t error_code; - uint64_t irq_number; - }; - uint64_t rip, cs, rflags, rsp, ss; -}; \ No newline at end of file diff --git a/kernel/include/interrupts/IDT.h b/kernel/include/interrupts/IDT.h deleted file mode 100644 index edded58e..00000000 --- a/kernel/include/interrupts/IDT.h +++ /dev/null @@ -1,18 +0,0 @@ -#pragma once -#include - -#define IDT_TA_InterruptGate 0b10001110 -#define IDT_TA_InterruptGateUser 0b11101110 -#define IDT_TA_TrapGate 0b10001111 - -struct IDTR -{ - uint16_t limit; - uint64_t offset; -} __attribute__((packed)); - -namespace IDT -{ - void add_handler(short interrupt_number, void* handler, uint8_t type_attr); - void load(); -} \ No newline at end of file diff --git a/kernel/include/interrupts/IRQ.h b/kernel/include/interrupts/IRQ.h deleted file mode 100644 index a61540ce..00000000 --- a/kernel/include/interrupts/IRQ.h +++ /dev/null @@ -1,7 +0,0 @@ -#pragma once -#include "Context.h" - -namespace IRQ -{ - void interrupt_handler(Context* context); -} \ No newline at end of file diff --git a/kernel/include/interrupts/Install.h b/kernel/include/interrupts/Install.h deleted file mode 100644 index 18d985b2..00000000 --- a/kernel/include/interrupts/Install.h +++ /dev/null @@ -1,7 +0,0 @@ -#pragma once -#include - -namespace Interrupts -{ - void install(); -} \ No newline at end of file diff --git a/kernel/include/interrupts/Interrupts.h b/kernel/include/interrupts/Interrupts.h deleted file mode 100644 index e5e5b26f..00000000 --- a/kernel/include/interrupts/Interrupts.h +++ /dev/null @@ -1,17 +0,0 @@ -#pragma once -#include "interrupts/Context.h" - -namespace Interrupts -{ - void enable(); - void disable(); - - bool is_in_handler(); - void return_from_handler(Context* context); - - bool are_enabled(); - bool were_enabled(); - void push_and_disable(); - void push_and_enable(); - void pop(); -} \ No newline at end of file diff --git a/kernel/include/io/IO.h b/kernel/include/io/IO.h deleted file mode 100644 index 883983ad..00000000 --- a/kernel/include/io/IO.h +++ /dev/null @@ -1,13 +0,0 @@ -#pragma once -#include - -namespace IO -{ - uint8_t inb(uint16_t); - void outb(uint16_t, uint8_t); - uint16_t inw(uint16_t); - void outw(uint16_t, uint16_t); - uint32_t inl(uint16_t); - void outl(uint16_t, uint32_t); - void delay(); -} \ No newline at end of file diff --git a/kernel/include/io/PCI.h b/kernel/include/io/PCI.h deleted file mode 100644 index e5bea2e6..00000000 --- a/kernel/include/io/PCI.h +++ /dev/null @@ -1,98 +0,0 @@ -#pragma once -#include - -#define PCI_VENDOR_FIELD 0x0 -#define PCI_DEVICE_FIELD 0x2 -#define PCI_SUBCLASS_FIELD 0xa -#define PCI_CLASS_FIELD 0xb -#define PCI_REVISION_ID_FIELD 0x8 -#define PCI_PROG_IF_FIELD 0x9 -#define PCI_HEADER_TYPE_FIELD 0xe -#define PCI_SECONDARY_BUS_NUMBER_FIELD 0x19 -#define PCI_BAR0_FIELD 0x10 -#define PCI_BAR1_FIELD 0x14 -#define PCI_BAR2_FIELD 0x18 -#define PCI_BAR3_FIELD 0x1C -#define PCI_BAR4_FIELD 0x20 -#define PCI_BAR5_FIELD 0x24 - -namespace PCI -{ - struct DeviceID - { - uint16_t vendor; - uint16_t device; - }; - - struct DeviceType - { - uint8_t dev_class; - uint8_t dev_subclass; - uint8_t prog_if; - uint8_t revision; - }; - - struct Device - { - void write8(int32_t offset, uint8_t value); - void write16(int32_t offset, uint16_t value); - void write32(int32_t offset, uint32_t value); - uint8_t read8(int32_t offset); - uint16_t read16(int32_t offset); - uint32_t read32(int32_t offset); - - uint32_t getBAR0(); - uint32_t getBAR1(); - uint32_t getBAR2(); - uint32_t getBAR3(); - uint32_t getBAR4(); - uint32_t getBAR5(); - - uint8_t bus() - { - return m_bus; - } - - uint8_t slot() - { - return m_slot; - } - - uint8_t function() - { - return m_function; - } - - DeviceID id() - { - return m_id; - } - - DeviceType type() - { - return m_type; - } - - Device(DeviceID id, DeviceType type, uint8_t bus, uint8_t slot, uint8_t function); - Device(uint8_t bus, uint8_t slot, uint8_t function); - Device(const Device& other); - - private: - DeviceID m_id; - DeviceType m_type; - uint8_t m_bus; - uint8_t m_slot; - uint8_t m_function; - }; - - uint32_t raw_address(uint32_t bus, uint32_t slot, uint32_t function, int32_t offset); - void raw_write8(uint32_t bus, uint32_t slot, uint32_t function, int32_t offset, uint8_t value); - void raw_write16(uint32_t bus, uint32_t slot, uint32_t function, int32_t offset, uint16_t value); - void raw_write32(uint32_t bus, uint32_t slot, uint32_t function, int32_t offset, uint32_t value); - uint8_t raw_read8(uint32_t bus, uint32_t slot, uint32_t function, int32_t offset); - uint16_t raw_read16(uint32_t bus, uint32_t slot, uint32_t function, int32_t offset); - uint32_t raw_read32(uint32_t bus, uint32_t slot, uint32_t function, int32_t offset); - DeviceID get_device_id(uint32_t bus, uint32_t slot, uint32_t function); - DeviceType get_device_type(uint32_t bus, uint32_t slot, uint32_t function); - void scan(void (*callback)(PCI::Device&)); -} \ No newline at end of file diff --git a/kernel/include/io/PIC.h b/kernel/include/io/PIC.h deleted file mode 100644 index 1aaf6079..00000000 --- a/kernel/include/io/PIC.h +++ /dev/null @@ -1,12 +0,0 @@ -#pragma once -#include - -namespace PIC -{ - void remap(); - void end_slave(); - void end_master(); - void enable_master(uint8_t mask); - void enable_slave(uint8_t mask); - void send_eoi(unsigned char irq); -} \ No newline at end of file diff --git a/kernel/include/io/Serial.h b/kernel/include/io/Serial.h deleted file mode 100644 index 9d371563..00000000 --- a/kernel/include/io/Serial.h +++ /dev/null @@ -1,13 +0,0 @@ -#pragma once -#include "render/Color.h" -#include - -namespace Serial -{ - void wait(); - void write(const char* string, size_t size); - void print(const char* string); - void println(const char* string); - void set_color(Color& color); - void reset_color(); -} \ No newline at end of file diff --git a/kernel/include/log/CLog.h b/kernel/include/log/CLog.h deleted file mode 100644 index 0c02696a..00000000 --- a/kernel/include/log/CLog.h +++ /dev/null @@ -1,41 +0,0 @@ -#ifndef _MOON_CLOG_H -#define _MOON_CLOG_H - -enum log_level -{ - LOG_DEBUG, - LOG_INFO, - LOG_WARN, - LOG_ERROR -}; - -#define PRINTF_LIKE(n, m) __attribute__((format(printf, n, m))) - -#ifdef __cplusplus -extern "C" -{ -#endif - - void clog_log(const char* function, enum log_level level, const char* message, ...) PRINTF_LIKE(3, 4); - void clog_logln(const char* function, enum log_level level, const char* message, ...) PRINTF_LIKE(3, 4); - -#ifdef __cplusplus -} -#endif - -#ifndef MODULE -#define kcommonlog(function, level, ...) clog_##function(__FUNCTION__, level, __VA_ARGS__) -#else -#define kcommonlog(function, level, ...) clog_##function(MODULE, level, __VA_ARGS__) -#endif - -#define kdbg(...) kcommonlog(log, LOG_DEBUG, __VA_ARGS__) -#define kdbgln(...) kcommonlog(logln, LOG_DEBUG, __VA_ARGS__) -#define kinfo(...) kcommonlog(log, LOG_INFO, __VA_ARGS__) -#define kinfoln(...) kcommonlog(logln, LOG_INFO, __VA_ARGS__) -#define kwarn(...) kcommonlog(log, LOG_WARN, __VA_ARGS__) -#define kwarnln(...) kcommonlog(logln, LOG_WARN, __VA_ARGS__) -#define kerror(...) kcommonlog(log, LOG_ERROR, __VA_ARGS__) -#define kerrorln(...) kcommonlog(logln, LOG_ERROR, __VA_ARGS__) - -#endif \ No newline at end of file diff --git a/kernel/include/log/Log.h b/kernel/include/log/Log.h deleted file mode 100644 index f27dcb80..00000000 --- a/kernel/include/log/Log.h +++ /dev/null @@ -1,41 +0,0 @@ -#pragma once - -enum class LogLevel -{ - DEBUG, - INFO, - WARN, - ERROR -}; - -enum class Backend -{ - Serial, - Console -}; - -#define PRINTF_LIKE(n, m) __attribute__((format(printf, n, m))) - -namespace KernelLog -{ - void log(const char* function, LogLevel level, const char* message, ...) PRINTF_LIKE(3, 4); - void logln(const char* function, LogLevel level, const char* message, ...) PRINTF_LIKE(3, 4); - void toggle_log_level(LogLevel level); - void toggle_log_backend(Backend backend); - void enable_log_backend(Backend backend); -} - -#ifndef MODULE -#define kcommonlog(function, level, ...) KernelLog::function(__FUNCTION__, level, __VA_ARGS__) -#else -#define kcommonlog(function, level, ...) KernelLog::function(MODULE, level, __VA_ARGS__) -#endif - -#define kdbg(...) kcommonlog(log, LogLevel::DEBUG, __VA_ARGS__) -#define kdbgln(...) kcommonlog(logln, LogLevel::DEBUG, __VA_ARGS__) -#define kinfo(...) kcommonlog(log, LogLevel::INFO, __VA_ARGS__) -#define kinfoln(...) kcommonlog(logln, LogLevel::INFO, __VA_ARGS__) -#define kwarn(...) kcommonlog(log, LogLevel::WARN, __VA_ARGS__) -#define kwarnln(...) kcommonlog(logln, LogLevel::WARN, __VA_ARGS__) -#define kerror(...) kcommonlog(log, LogLevel::ERROR, __VA_ARGS__) -#define kerrorln(...) kcommonlog(logln, LogLevel::ERROR, __VA_ARGS__) \ No newline at end of file diff --git a/kernel/include/memory/AddressSpace.h b/kernel/include/memory/AddressSpace.h deleted file mode 100644 index c125b0a0..00000000 --- a/kernel/include/memory/AddressSpace.h +++ /dev/null @@ -1,22 +0,0 @@ -#pragma once -#include "memory/Paging.h" -#include "utils/Result.h" - -struct AddressSpace -{ - static Result create(); - - void destroy(); - - void clear(); - - AddressSpace clone(); - - PageTable* get_pml4() - { - return m_pml4; - } - - private: - PageTable* m_pml4; -}; \ No newline at end of file diff --git a/kernel/include/memory/KernelHeap.h b/kernel/include/memory/KernelHeap.h deleted file mode 100644 index 5dc14d64..00000000 --- a/kernel/include/memory/KernelHeap.h +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once -#include - -namespace KernelHeap -{ // Virtual memory allocator for the kernel, goes from -128MB to -64MB - uint64_t request_virtual_page(); - uint64_t request_virtual_pages(uint64_t count); - - void free_virtual_page(uint64_t address); - void free_virtual_pages(uint64_t address, uint64_t count); - - void clear(); - - void dump_usage(); -} \ No newline at end of file diff --git a/kernel/include/memory/Memory.h b/kernel/include/memory/Memory.h deleted file mode 100644 index aa5aebf3..00000000 --- a/kernel/include/memory/Memory.h +++ /dev/null @@ -1,11 +0,0 @@ -#pragma once -#include - -namespace Memory -{ - uint64_t get_system(); - uint64_t get_usable(); - - bool is_user_address(uintptr_t address); - bool is_kernel_address(uintptr_t address); -} \ No newline at end of file diff --git a/kernel/include/memory/MemoryManager.h b/kernel/include/memory/MemoryManager.h deleted file mode 100644 index 3cecf2ae..00000000 --- a/kernel/include/memory/MemoryManager.h +++ /dev/null @@ -1,41 +0,0 @@ -#pragma once -#include "utils/Result.h" -#include - -#ifndef PAGE_SIZE -#define PAGE_SIZE 4096 -#endif - -#define MAP_READ_WRITE 1 << 0 -#define MAP_USER 1 << 1 -#define MAP_EXEC 1 << 2 -#define MAP_AS_OWNED_BY_TASK 1 << 3 - -namespace MemoryManager -{ - void init(); - - void protect_kernel_sections(); - - Result get_mapping(void* physicalAddress, int flags = MAP_READ_WRITE); - void release_mapping(void* mapping); - - Result get_unaligned_mapping(void* physicalAddress, int flags = MAP_READ_WRITE); - Result get_unaligned_mappings(void* physicalAddress, uint64_t count, int flags = MAP_READ_WRITE); - void release_unaligned_mapping(void* mapping); - void release_unaligned_mappings(void* mapping, uint64_t count); - - Result get_page(int flags = MAP_READ_WRITE); - Result get_pages(uint64_t count, int flags = MAP_READ_WRITE); - - Result get_page_at(uint64_t addr, int flags = MAP_READ_WRITE); - Result get_pages_at(uint64_t addr, uint64_t count, int flags = MAP_READ_WRITE); - - void release_page(void* page); - void release_pages(void* pages, uint64_t count); - - void protect(void* page, uint64_t count, int flags); - - void map_several_pages(uint64_t physicalAddress, uint64_t virtualAddress, uint64_t count, - int flags = MAP_READ_WRITE); -} \ No newline at end of file diff --git a/kernel/include/memory/MemoryMap.h b/kernel/include/memory/MemoryMap.h deleted file mode 100644 index c2714dc1..00000000 --- a/kernel/include/memory/MemoryMap.h +++ /dev/null @@ -1,6 +0,0 @@ -#pragma once - -namespace Memory -{ - void walk_memory_map(); -} \ No newline at end of file diff --git a/kernel/include/memory/PMM.h b/kernel/include/memory/PMM.h deleted file mode 100644 index 83d4482b..00000000 --- a/kernel/include/memory/PMM.h +++ /dev/null @@ -1,25 +0,0 @@ -#pragma once -#include "utils/Result.h" -#include - -namespace PMM -{ - void init(); - - Result request_page(); - Result request_pages(uint64_t count); - - void free_page(void* address); - void free_pages(void* address, uint64_t count); - - void lock_page(void* address); - void lock_pages(void* address, uint64_t count); - - uint64_t get_free(); - uint64_t get_used(); - uint64_t get_reserved(); - - uint64_t get_bitmap_size(); - - void map_bitmap_to_virtual(); -}; diff --git a/kernel/include/memory/Paging.h b/kernel/include/memory/Paging.h deleted file mode 100644 index baedd9a3..00000000 --- a/kernel/include/memory/Paging.h +++ /dev/null @@ -1,34 +0,0 @@ -#pragma once -#include - -#ifndef PAGE_SIZE -#define PAGE_SIZE 4096 -#endif - -struct PageDirectoryEntry -{ - bool present : 1; - bool read_write : 1; - bool user : 1; - bool write_through : 1; - bool cache_disabled : 1; - bool accessed : 1; - bool ignore0 : 1; - bool larger_pages : 1; - bool ignore1 : 1; - uint8_t available : 3; - uint64_t address : 48; - bool owned_by_task : 1; // Part of the available for OS use bits. - uint8_t available2 : 2; - bool no_execute : 1; - - void set_address(uint64_t addr); - uint64_t get_address(); -} __attribute__((packed)); - -struct PageTable -{ - PageDirectoryEntry entries[512]; -} __attribute__((aligned(PAGE_SIZE))); - -static_assert(sizeof(PageDirectoryEntry) == 8UL); \ No newline at end of file diff --git a/kernel/include/memory/UserHeap.h b/kernel/include/memory/UserHeap.h deleted file mode 100644 index 166c6a5c..00000000 --- a/kernel/include/memory/UserHeap.h +++ /dev/null @@ -1,27 +0,0 @@ -#pragma once -#include - -struct UserHeap -{ - bool init(); - - uint64_t request_virtual_page(); - uint64_t request_virtual_pages(uint64_t count); - - void free_virtual_page(uint64_t address); - void free_virtual_pages(uint64_t address, uint64_t count); - - void free(); - - bool inherit(UserHeap& other); - - private: - uint8_t* bitmap = nullptr; - uint64_t bitmap_size = 0; - uint64_t start_index = 0; - bool bitmap_read(uint64_t index); - void bitmap_set(uint64_t index, bool value); - - bool try_expand(); - bool try_expand_size(uint64_t size); -}; \ No newline at end of file diff --git a/kernel/include/memory/VMM.h b/kernel/include/memory/VMM.h deleted file mode 100644 index ceb44ea2..00000000 --- a/kernel/include/memory/VMM.h +++ /dev/null @@ -1,48 +0,0 @@ -#pragma once -#include "memory/AddressSpace.h" -#include "memory/Paging.h" - -enum Flags -{ - ReadWrite = 1 << 0, - User = 1 << 1, - Execute = 1 << 2, - OwnedByTask = 1 << 3, -}; -namespace VMM -{ - void init(); // Fetch page table from cr3 - - void switch_to_user_address_space(AddressSpace& space); - void switch_to_previous_user_address_space(); - void switch_back_to_kernel_address_space(); - - void enter_syscall_context(); - void exit_syscall_context(); - - void apply_address_space(); - - bool is_using_kernel_address_space(); - - void map(uint64_t vaddr, uint64_t paddr, int flags); - void remap(uint64_t vaddr, int flags); - void unmap(uint64_t vaddr); - uint64_t get_physical(uint64_t vaddr); - uint64_t get_flags(uint64_t vaddr); - - PageDirectoryEntry* find_pde(PageTable* root, uint64_t vaddr); - PageDirectoryEntry* create_pde_if_not_exists(PageTable* root, uint64_t vaddr); - - void propagate_read_write(PageTable* root, uint64_t vaddr); - void propagate_no_execute(PageTable* root, uint64_t vaddr); - void propagate_user(PageTable* root, uint64_t vaddr); - - void flush_tlb(uint64_t addr); - void flush_tlb_full(); - - void decompose_vaddr(uint64_t vaddr, uint64_t& page_index, uint64_t& pt_index, uint64_t& pd_index, - uint64_t& pdp_index); - uint64_t recompose_vaddr(uint64_t page_index, uint64_t pt_index, uint64_t pd_index, uint64_t pdp_index); - - void install_kernel_page_directory_into_address_space(AddressSpace& space); -}; \ No newline at end of file diff --git a/kernel/include/memory/liballoc/liballoc.h b/kernel/include/memory/liballoc/liballoc.h deleted file mode 100644 index 0ad6274d..00000000 --- a/kernel/include/memory/liballoc/liballoc.h +++ /dev/null @@ -1,75 +0,0 @@ -#ifndef _LIBALLOC_H -#define _LIBALLOC_H - -#include - -/** \defgroup ALLOCHOOKS liballoc hooks - * - * These are the OS specific functions which need to - * be implemented on any platform that the library - * is expected to work on. - */ - -/** @{ */ - -// If we are told to not define our own size_t, then we skip the define. -//#define _HAVE_UINTPTR_T -// typedef unsigned long uintptr_t; - -// This lets you prefix malloc and friends -#define PREFIX(func) k##func - -#ifdef __cplusplus -extern "C" -{ -#endif -#ifndef __skip_bindings - /** This function is supposed to lock the memory data structures. It - * could be as simple as disabling interrupts or acquiring a spinlock. - * It's up to you to decide. - * - * \return 0 if the lock was acquired successfully. Anything else is - * failure. - */ - extern int liballoc_lock(); - - /** This function unlocks what was previously locked by the liballoc_lock - * function. If it disabled interrupts, it enables interrupts. If it - * had acquiried a spinlock, it releases the spinlock. etc. - * - * \return 0 if the lock was successfully released. - */ - extern int liballoc_unlock(); - - /** This is the hook into the local system which allocates pages. It - * accepts an integer parameter which is the number of pages - * required. The page size was set up in the liballoc_init function. - * - * \return NULL if the pages were not allocated. - * \return A pointer to the allocated memory. - */ - extern void* liballoc_alloc(size_t); - - /** This frees previously allocated memory. The void* parameter passed - * to the function is the exact same value returned from a previous - * liballoc_alloc call. - * - * The integer value is the number of pages to free. - * - * \return 0 if the memory was successfully freed. - */ - extern int liballoc_free(void*, size_t); -#endif - - extern void* PREFIX(malloc)(size_t); ///< The standard function. - extern void* PREFIX(realloc)(void*, size_t); ///< The standard function. - extern void* PREFIX(calloc)(size_t, size_t); ///< The standard function. - extern void PREFIX(free)(void*); ///< The standard function. - -#ifdef __cplusplus -} -#endif - -/** @} */ - -#endif \ No newline at end of file diff --git a/kernel/include/misc/MSR.h b/kernel/include/misc/MSR.h deleted file mode 100644 index 1c7ae4db..00000000 --- a/kernel/include/misc/MSR.h +++ /dev/null @@ -1,21 +0,0 @@ -#pragma once -#include - -#define IA32_EFER_MSR 0xC0000080 - -struct MSR -{ - void write(uint64_t value); - uint64_t read(); - - MSR(uint32_t msr_num); - - static void write_to(uint32_t msr_num, uint64_t value); - static uint64_t read_from(uint32_t msr_num); - - static void with_value_of(uint32_t msr_num, void (*callback)(uint64_t&)); - void with_value(void (*callback)(uint64_t&)); - - private: - uint32_t m_msr_num; -}; \ No newline at end of file diff --git a/kernel/include/misc/PCITypes.h b/kernel/include/misc/PCITypes.h deleted file mode 100644 index 4a537bf6..00000000 --- a/kernel/include/misc/PCITypes.h +++ /dev/null @@ -1,4 +0,0 @@ -#pragma once -#include "io/PCI.h" - -const char* pci_type_name(PCI::DeviceType type); \ No newline at end of file diff --git a/kernel/include/misc/Scancodes.h b/kernel/include/misc/Scancodes.h deleted file mode 100644 index 439b2678..00000000 --- a/kernel/include/misc/Scancodes.h +++ /dev/null @@ -1,6 +0,0 @@ -#pragma once - -// This should only be used for a keyboard TTY interface. Userspace should translate keyboard scancodes by themselves. -char translate_scancode(unsigned char scancode, bool* ignore); - -bool scancode_filter_released(unsigned char* scancode); \ No newline at end of file diff --git a/kernel/include/misc/hang.h b/kernel/include/misc/hang.h deleted file mode 100644 index 105c03a6..00000000 --- a/kernel/include/misc/hang.h +++ /dev/null @@ -1,4 +0,0 @@ -#pragma once - -[[noreturn]] void hang(); -void halt(); \ No newline at end of file diff --git a/kernel/include/misc/reboot.h b/kernel/include/misc/reboot.h deleted file mode 100644 index e7de0de8..00000000 --- a/kernel/include/misc/reboot.h +++ /dev/null @@ -1,3 +0,0 @@ -#pragma once - -[[noreturn]] void reboot(); \ No newline at end of file diff --git a/kernel/include/misc/shutdown.h b/kernel/include/misc/shutdown.h deleted file mode 100644 index 4c620652..00000000 --- a/kernel/include/misc/shutdown.h +++ /dev/null @@ -1,3 +0,0 @@ -#pragma once - -[[noreturn]] void shutdown(); \ No newline at end of file diff --git a/kernel/include/misc/utils.h b/kernel/include/misc/utils.h deleted file mode 100644 index cc8974e5..00000000 --- a/kernel/include/misc/utils.h +++ /dev/null @@ -1,10 +0,0 @@ -#pragma once -#include - -namespace Utilities -{ - inline uint64_t get_blocks_from_size(uint64_t blocksize, uint64_t size) - { - return (size + (blocksize - 1)) / blocksize; - } -} \ No newline at end of file diff --git a/kernel/include/panic/Panic.h b/kernel/include/panic/Panic.h deleted file mode 100644 index 5c66799d..00000000 --- a/kernel/include/panic/Panic.h +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once -#include "interrupts/Context.h" - -#ifdef __cplusplus -extern "C" -{ -#endif - [[noreturn]] bool __do_int_panic(Context* context, const char* file, int line, const char* message); - [[noreturn]] bool __do_panic(const char* file, int line, const char* message); -#ifdef __cplusplus -} -#endif - -#define panic(message) __do_panic(__FILE__, __LINE__, message) -#define int_panic(context, message) __do_int_panic(context, __FILE__, __LINE__, message) \ No newline at end of file diff --git a/kernel/include/rand/Init.h b/kernel/include/rand/Init.h deleted file mode 100644 index d0b91c70..00000000 --- a/kernel/include/rand/Init.h +++ /dev/null @@ -1,7 +0,0 @@ -#pragma once - -namespace Mersenne -{ - void init(); - void reseed(); -} \ No newline at end of file diff --git a/kernel/include/rand/Mersenne.h b/kernel/include/rand/Mersenne.h deleted file mode 100644 index 791b4500..00000000 --- a/kernel/include/rand/Mersenne.h +++ /dev/null @@ -1,8 +0,0 @@ -#pragma once -#include - -namespace Mersenne -{ - void seed(uint64_t); - uint64_t get(); -} \ No newline at end of file diff --git a/kernel/include/render/Color.h b/kernel/include/render/Color.h deleted file mode 100644 index 93b2bf76..00000000 --- a/kernel/include/render/Color.h +++ /dev/null @@ -1,22 +0,0 @@ -#pragma once -#include - -struct Color -{ - uint8_t blue; - uint8_t green; - uint8_t red; - uint8_t alpha; - - static Color White; - static Color Black; - static Color Red; - static Color Green; - static Color Blue; - static Color Yellow; - static Color Cyan; - static Color Magenta; - static Color Gray; - - static Color from_integer(uint32_t source); -} __attribute__((packed)); // to reinterpret this as a uint32_t AARRGGBB (in reversed order here because endianness) \ No newline at end of file diff --git a/kernel/include/render/Framebuffer.h b/kernel/include/render/Framebuffer.h deleted file mode 100644 index c8b53fe2..00000000 --- a/kernel/include/render/Framebuffer.h +++ /dev/null @@ -1,30 +0,0 @@ -#pragma once -#include "render/Color.h" - -class Framebuffer -{ - public: - void init(void* fb_address, int fb_type, int fb_scanline, int fb_width, int fb_height); - void set_pixel(uint32_t x, uint32_t y, Color color); - Color get_pixel(uint32_t x, uint32_t y); - void paint_rect(uint32_t x, uint32_t y, uint32_t w, uint32_t h, Color color); - void paint_rect(uint32_t x, uint32_t y, uint32_t w, uint32_t h, Color* colors); - void clear(Color color); - int width() - { - return m_fb_width; - } - int height() - { - return m_fb_height; - } - - private: - void* m_fb_address; - int m_fb_type; - int m_fb_scanline; - int m_fb_width; - int m_fb_height; -}; - -extern Framebuffer framebuffer0; \ No newline at end of file diff --git a/kernel/include/render/TextRenderer.h b/kernel/include/render/TextRenderer.h deleted file mode 100644 index cc7db7d0..00000000 --- a/kernel/include/render/TextRenderer.h +++ /dev/null @@ -1,10 +0,0 @@ -#pragma once -#include "render/Color.h" -#include - -namespace TextRenderer -{ - void putchar(char chr); - void write(const char* str, size_t size); - void reset(); -} \ No newline at end of file diff --git a/kernel/include/std/ensure.h b/kernel/include/std/ensure.h deleted file mode 100644 index 8e90db85..00000000 --- a/kernel/include/std/ensure.h +++ /dev/null @@ -1,9 +0,0 @@ -#pragma once -#include "panic/Panic.h" - -#define STRINGIZE(x) #x -#define STRINGIZE_VALUE_OF(x) STRINGIZE(x) - -// clang-format off -#define ensure(expr) (bool)(expr) || panic("Check failed at " __FILE__ ", line " STRINGIZE_VALUE_OF(__LINE__) ": " #expr) -// clang-format on \ No newline at end of file diff --git a/kernel/include/std/errno.h b/kernel/include/std/errno.h deleted file mode 100644 index be1713a3..00000000 --- a/kernel/include/std/errno.h +++ /dev/null @@ -1,24 +0,0 @@ -#pragma once - -#define EPERM 1 -#define ENOENT 2 -#define ESRCH 3 -#define EINTR 4 -#define E2BIG 7 -#define ENOEXEC 8 -#define EBADF 9 -#define ECHILD 10 -#define EAGAIN 11 -#define ENOMEM 12 -#define EACCES 13 -#define EFAULT 14 -#define EEXIST 17 -#define ENOTDIR 20 -#define EISDIR 21 -#define EINVAL 22 -#define EMFILE 24 -#define ENOTTY 25 -#define ENOSPC 28 -#define ERANGE 36 -#define ENOSYS 38 -#define ENOTSUP 95 \ No newline at end of file diff --git a/kernel/include/std/libgen.h b/kernel/include/std/libgen.h deleted file mode 100644 index 1a3a0e4d..00000000 --- a/kernel/include/std/libgen.h +++ /dev/null @@ -1,7 +0,0 @@ -#pragma once - -char* basename(char* path); -char* dirname(char* path); - -char* better_basename(const char* path); -char* better_dirname(const char* path); \ No newline at end of file diff --git a/kernel/include/std/stdio.h b/kernel/include/std/stdio.h deleted file mode 100644 index ffe7e14e..00000000 --- a/kernel/include/std/stdio.h +++ /dev/null @@ -1,14 +0,0 @@ -#pragma once -#include -#include - -#define PRINTF_LIKE(n, m) __attribute__((format(printf, n, m))) - -int printf(const char* fmt, ...) PRINTF_LIKE(1, 2); // Outputs to serial. -int sprintf(char* __s, const char* fmt, ...) PRINTF_LIKE(2, 3); -int snprintf(char* __s, size_t max, const char* fmt, ...) PRINTF_LIKE(3, 4); -int vprintf(const char* fmt, va_list ap); -int vsprintf(char* __s, const char* fmt, va_list ap); -int vsnprintf(char* __s, size_t max, const char* fmt, va_list ap); -int kprintf(const char* fmt, ...) PRINTF_LIKE(1, 2); // Outputs to text console. -int vkprintf(const char* fmt, va_list ap); \ No newline at end of file diff --git a/kernel/include/std/stdlib.h b/kernel/include/std/stdlib.h deleted file mode 100644 index e11f9469..00000000 --- a/kernel/include/std/stdlib.h +++ /dev/null @@ -1,14 +0,0 @@ -#pragma once -#include - -char* itoa(int32_t number, char* arr, int base); -char* utoa(uint32_t number, char* arr, int base); - -char* ltoa(int64_t number, char* arr, int base); -char* ultoa(uint64_t number, char* arr, int base); - -void sleep(uint64_t ms); - -#define __skip_bindings -#include "memory/liballoc/liballoc.h" -#undef __skip_bindings \ No newline at end of file diff --git a/kernel/include/std/string.h b/kernel/include/std/string.h deleted file mode 100644 index 8725a94e..00000000 --- a/kernel/include/std/string.h +++ /dev/null @@ -1,23 +0,0 @@ -#pragma once -#include - -size_t strlen(const char* __s); - -__attribute__((deprecated)) char* strcpy(char* dest, const char* src); -__attribute__((deprecated)) int strcmp(const char* a, const char* b); -__attribute__((deprecated)) char* strcat(char* dest, const char* src); - -char* strncpy(char* dest, const char* src, size_t n); -size_t strlcpy(char* dest, const char* src, size_t size); -int strncmp(const char* a, const char* b, size_t n); -char* strncat(char* dest, const char* src, size_t n); - -char* strstr(char* haystack, const char* needle); - -void* memcpy(void* dest, const void* src, size_t n); -void* memset(void* dest, int c, size_t n); -int memcmp(const void* a, const void* b, size_t n); -void* memmove(void* dest, const void* src, size_t n); - -char* strdup(const char* src); -char* strrchr(const char* str, int c); \ No newline at end of file diff --git a/kernel/include/sys/Syscall.h b/kernel/include/sys/Syscall.h deleted file mode 100644 index 8a929696..00000000 --- a/kernel/include/sys/Syscall.h +++ /dev/null @@ -1,76 +0,0 @@ -#pragma once -#include "interrupts/Context.h" -#include -#include - -#define SYS_exit 0 -#define SYS_yield 1 -#define SYS_sleep 2 -#define SYS_write 3 -#define SYS_getprocid 4 -#define SYS_mmap 5 -#define SYS_munmap 6 -#define SYS_open 7 -#define SYS_read 8 -#define SYS_close 9 -#define SYS_seek 10 -#define SYS_execv 11 -#define SYS_fcntl 12 -#define SYS_mprotect 13 -#define SYS_clock_gettime 14 -#define SYS_mkdir 15 -#define SYS_fork 16 -#define SYS_waitpid 17 -#define SYS_access 18 -#define SYS_fstat 19 -#define SYS_pstat 20 -#define SYS_getdents 21 -#define SYS_stat 22 -#define SYS_dup2 23 -#define SYS_setuid 24 -#define SYS_setgid 25 -#define SYS_umask 26 -#define SYS_ioctl 27 -#define SYS_seteuid 28 -#define SYS_setegid 29 - -struct stat; -struct pstat; -struct luna_dirent; -struct timespec; - -namespace Syscall -{ - void entry(Context* context); -} - -void sys_exit(Context* context, int status); -void sys_yield(Context* context); -void sys_sleep(Context* context, uint64_t ms); -void sys_write(Context* context, int fd, size_t size, const char* addr); -void sys_getprocid(Context* context, int field); -void sys_mmap(Context* context, void* address, size_t size, int prot, int fd, off_t offset); -void sys_munmap(Context* context, void* address, size_t size); -void sys_open(Context* context, const char* filename, int flags, mode_t mode); -void sys_read(Context* context, int fd, size_t size, char* buffer); -void sys_close(Context* context, int fd); -void sys_seek(Context* context, int fd, long offset, int whence); -void sys_execv(Context* context, const char* pathname, char** argv); -void sys_fcntl(Context* context, int fd, int command, uintptr_t arg); -void sys_mprotect(Context* context, void* address, size_t size, int prot); -void sys_clock_gettime(Context* context, int clock_id, struct timespec* tp); -void sys_mkdir(Context* context, const char* filename, mode_t mode); -void sys_fork(Context* context); -void sys_waitpid(Context* context, long pid, int* wstatus, int options); -void sys_access(Context* context, const char* path, int amode); -void sys_fstat(Context* context, int fd, struct stat* buf); -void sys_pstat(Context* context, long pid, struct pstat* buf); -void sys_getdents(Context* context, int fd, struct luna_dirent* buf, size_t count); -void sys_stat(Context* context, const char* path, struct stat* buf); -void sys_dup2(Context* context, int fd, int fd2); -void sys_setuid(Context* context, uid_t uid); -void sys_setgid(Context* context, gid_t gid); -void sys_umask(Context* context, mode_t cmask); -void sys_ioctl(Context* context, int fd, int request, uintptr_t arg); -void sys_seteuid(Context* context, uid_t euid); -void sys_setegid(Context* context, gid_t egid); \ No newline at end of file diff --git a/kernel/include/sys/UserMemory.h b/kernel/include/sys/UserMemory.h deleted file mode 100644 index fca1c034..00000000 --- a/kernel/include/sys/UserMemory.h +++ /dev/null @@ -1,30 +0,0 @@ -#pragma once - -#ifndef MODULE -#define MODULE "mem" -#endif - -#include "log/Log.h" -#include "memory/MemoryManager.h" -#include "memory/VMM.h" -#include "misc/utils.h" -#include - -Result strdup_from_user(const char* user_string); -bool validate_user_readable_page(uintptr_t address); -bool validate_user_writable_page(uintptr_t address); -bool validate_user_read(uintptr_t address, size_t size); -bool validate_user_write(uintptr_t address, size_t size); - -bool copy_from_user(const void* user_ptr, void* ptr, size_t size); -bool copy_to_user(void* user_ptr, const void* ptr, size_t size); - -template bool copy_typed_from_user(const T* user_ptr, T* ptr) -{ - return copy_from_user(user_ptr, ptr, sizeof(T)); -} - -template bool copy_typed_to_user(T* user_ptr, const T* ptr) -{ - return copy_to_user(user_ptr, ptr, sizeof(T)); -} \ No newline at end of file diff --git a/kernel/include/sys/elf/ELF.h b/kernel/include/sys/elf/ELF.h deleted file mode 100644 index 711bd3bd..00000000 --- a/kernel/include/sys/elf/ELF.h +++ /dev/null @@ -1,48 +0,0 @@ -#pragma once - -#define ELFMAG "\177ELF" -#define SELFMAG 4 -#define EI_CLASS 4 /* File class byte index */ -#define ELFCLASS64 2 /* 64-bit objects */ -#define EI_DATA 5 /* Data encoding byte index */ -#define ELFDATA2LSB 1 /* 2's complement, little endian */ -#define ET_EXEC 2 /* Executable file */ -#define PT_LOAD 1 /* Loadable program segment */ -#ifdef __x86_64__ -#define EM_MACH 62 /* AMD x86-64 architecture */ -#endif -#ifdef __aarch64__ -#define EM_MACH 183 /* ARM aarch64 architecture */ -#endif - -#include - -typedef struct -{ - uint8_t e_ident[16]; /* Magic number and other info */ - uint16_t e_type; /* Object file type */ - uint16_t e_machine; /* Architecture */ - uint32_t e_version; /* Object file version */ - uint64_t e_entry; /* Entry point virtual address */ - uint64_t e_phoff; /* Program header table file offset */ - uint64_t e_shoff; /* Section header table file offset */ - uint32_t e_flags; /* Processor-specific flags */ - uint16_t e_ehsize; /* ELF header size in bytes */ - uint16_t e_phentsize; /* Program header table entry size */ - uint16_t e_phnum; /* Program header table entry count */ - uint16_t e_shentsize; /* Section header table entry size */ - uint16_t e_shnum; /* Section header table entry count */ - uint16_t e_shstrndx; /* Section header string table index */ -} Elf64_Ehdr; - -typedef struct -{ - uint32_t p_type; /* Segment type */ - uint32_t p_flags; /* Segment flags */ - uint64_t p_offset; /* Segment file offset */ - uint64_t p_vaddr; /* Segment virtual address */ - uint64_t p_paddr; /* Segment physical address */ - uint64_t p_filesz; /* Segment size in file */ - uint64_t p_memsz; /* Segment size in memory */ - uint64_t p_align; /* Segment alignment */ -} Elf64_Phdr; \ No newline at end of file diff --git a/kernel/include/sys/elf/ELFLoader.h b/kernel/include/sys/elf/ELFLoader.h deleted file mode 100644 index 26b869e0..00000000 --- a/kernel/include/sys/elf/ELFLoader.h +++ /dev/null @@ -1,13 +0,0 @@ -#pragma once -#include "fs/VFS.h" -#include "sys/elf/Image.h" -#include - -namespace ELFLoader -{ - ELFImage* load_elf_from_vfs(VFS::Node* node); // This function assumes check_elf_image has been called first. - ELFImage* load_elf_from_filesystem(const char* filename); - void release_elf_image(ELFImage* image); - long check_elf_image(VFS::Node* node); - long check_elf_image_from_filesystem(const char* filename); -} \ No newline at end of file diff --git a/kernel/include/sys/elf/Image.h b/kernel/include/sys/elf/Image.h deleted file mode 100644 index 552b00e4..00000000 --- a/kernel/include/sys/elf/Image.h +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once -#include - -struct ELFSection -{ - uintptr_t base; - uint64_t pages; -}; - -struct ELFImage -{ - uintptr_t entry; - uint64_t section_count; - ELFSection sections[1]; -}; \ No newline at end of file diff --git a/kernel/include/thread/PIT.h b/kernel/include/thread/PIT.h deleted file mode 100644 index 9151508f..00000000 --- a/kernel/include/thread/PIT.h +++ /dev/null @@ -1,11 +0,0 @@ -#pragma once -#include - -namespace PIT -{ - extern volatile uint64_t ms_since_boot; - const uint64_t base_frequency = 1193182; - void initialize(uint64_t frequency); - uint64_t frequency(); - void tick(); -} diff --git a/kernel/include/thread/Scheduler.h b/kernel/include/thread/Scheduler.h deleted file mode 100644 index 24ab7789..00000000 --- a/kernel/include/thread/Scheduler.h +++ /dev/null @@ -1,34 +0,0 @@ -#pragma once -#include "thread/Task.h" - -#define TASK_PAGES_IN_STACK 4 - -namespace Scheduler -{ - void init(); - void yield(); - void exit(int status); - void sleep(unsigned long ms); - void add_kernel_task(const char* taskname, void (*task)(void)); - - Task* create_user_task(); - - long load_user_task(const char* filename); - - void task_exit(Context* context, int64_t status); - void task_misbehave(Context* context, int64_t status); - - Task* current_task(); - - void task_yield(Context* context); - void task_tick(Context* context); - - void reap_task(Task* task); - void reap_tasks(); - - void reset_task(Task* task, ELFImage* new_image); - - void append_task(Task* task); - - Task* find_by_pid(uint64_t pid); -} \ No newline at end of file diff --git a/kernel/include/thread/Spinlock.h b/kernel/include/thread/Spinlock.h deleted file mode 100644 index 8678e69a..00000000 --- a/kernel/include/thread/Spinlock.h +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once -#include - -struct Spinlock -{ - public: - void acquire(); - void release(); - bool locked(); - - private: - volatile uint64_t m_lock = 0; -}; - -void lock(Spinlock& lock, void (*action)(void)); \ No newline at end of file diff --git a/kernel/include/thread/Task.h b/kernel/include/thread/Task.h deleted file mode 100644 index 2238343a..00000000 --- a/kernel/include/thread/Task.h +++ /dev/null @@ -1,123 +0,0 @@ -#pragma once -#include "fs/FileDescriptor.h" -#include "interrupts/Context.h" -#include "memory/AddressSpace.h" -#include "memory/UserHeap.h" -#include "sys/elf/Image.h" -#include - -#define TASK_MAX_FDS 32 - -enum class BlockReason -{ - None, - Reading, - Waiting, -}; - -// FIXME: To make this struct more C++-styled, maybe we could make a lot of these variables private and add -// getters/setters? - -struct Task -{ - enum TaskState - { - Idle, - Running, - Sleeping, - Dying, - Blocking, - Exited - }; - - uint64_t id; - uint64_t ppid; - Context regs; - - int64_t task_sleep = 0; - - int64_t exit_status; - - int64_t task_time = 0; - - uid_t uid; - uid_t euid; - gid_t gid; - gid_t egid; - - Task* next_task = nullptr; - Task* prev_task = nullptr; - - uint64_t allocated_stack = 0; - - TaskState state; - - uint64_t cpu_time = 0; - - char floating_region[512] __attribute__((aligned(16))); - bool floating_saved = false; - - bool user_task = true; - - bool is_user_task(); - - ELFImage* image = nullptr; // FIXME: we probably don't need to keep track of this anymore since the ELF sections are - // freed automatically when calling destroy() or clear() on the address space. - - Descriptor files[TASK_MAX_FDS]; - - AddressSpace address_space; - - UserHeap allocator; - - int alloc_fd(); - - int alloc_fd_greater_than_or_equal(int base_fd); - - void save_context(Context* context); - void restore_context(Context* context); - - void save_floating(); - void restore_floating(); - - void switch_to_address_space(); - - bool has_died(); - - char name[128]; - - mode_t umask; - - BlockReason block_reason; - - union { - struct - { - size_t size; - int fd; - char* buf; - } blocking_read_info; - struct - { - int64_t pid; - int* wstatus; - } blocking_wait_info; - }; - - void resume(); - - bool is_still_blocking(); - - // FIXME: These two functions are a bit clunky. - Descriptor* open_descriptor_from_fd(int fd, int& error); - Descriptor* descriptor_from_fd(int fd, int& error); - - bool is_superuser(); - - private: - void resume_read(); - void resume_wait(); - - bool is_read_still_blocking(); - bool is_wait_still_blocking(); -}; \ No newline at end of file diff --git a/kernel/include/trace/Resolve.h b/kernel/include/trace/Resolve.h deleted file mode 100644 index f54f0b29..00000000 --- a/kernel/include/trace/Resolve.h +++ /dev/null @@ -1,5 +0,0 @@ -#pragma once -#include -#include - -void get_symbol_name(uintptr_t address, char* buffer, size_t size); \ No newline at end of file diff --git a/kernel/include/trace/StackTracer.h b/kernel/include/trace/StackTracer.h deleted file mode 100644 index b82234f2..00000000 --- a/kernel/include/trace/StackTracer.h +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once -#include - -struct StackTracer -{ - StackTracer(); - StackTracer(uintptr_t base_pointer); - void trace(); - void trace_with_ip(uintptr_t ip); - - private: - uintptr_t m_base_pointer; -}; - -bool stack_trace_contains(uintptr_t address); \ No newline at end of file diff --git a/kernel/include/utils/Addresses.h b/kernel/include/utils/Addresses.h deleted file mode 100644 index 23752357..00000000 --- a/kernel/include/utils/Addresses.h +++ /dev/null @@ -1,24 +0,0 @@ -#pragma once - -#include -#include - -#ifndef PAGE_SIZE -#define PAGE_SIZE 4096 -#endif - -inline uintptr_t get_top_of_stack(uintptr_t bottom, size_t stack_pages) -{ - return bottom + (stack_pages * PAGE_SIZE) - sizeof(uintptr_t); -} - -inline uintptr_t round_down_to_nearest_page(uintptr_t addr) -{ - return addr - (addr % PAGE_SIZE); -} - -inline uintptr_t round_up_to_nearest_page(uintptr_t addr) -{ - if (addr % PAGE_SIZE) return addr + (PAGE_SIZE - (addr % PAGE_SIZE)); - return addr; -} \ No newline at end of file diff --git a/kernel/include/utils/Dynamic.h b/kernel/include/utils/Dynamic.h deleted file mode 100644 index 6a2fd496..00000000 --- a/kernel/include/utils/Dynamic.h +++ /dev/null @@ -1,167 +0,0 @@ -#pragma once -#include "log/Log.h" -#include "std/ensure.h" -#include "std/stdlib.h" -#include "std/string.h" -#include "utils/new.h" - -#define __noinline __attribute__((noinline)) - -template struct Dynamic -{ - Dynamic() - { - set_expand_rate(16); - ensure(expand_fixed()); - } - - Dynamic(size_t capacity) - { - set_expand_rate(16); - ensure(expand_fixed()); - } - - Dynamic(const Dynamic& other) - { - set_expand_rate(other.m_expand_rate); - ensure_capacity(other.capacity()); - m_size = other.size(); - memcpy(m_buf, other.data(), m_capacity * sizeof(T)); - } - - Dynamic(Dynamic&& other) - { - set_expand_rate(other.m_expand_rate); - m_buf = other.release_data(); - m_capacity = other.capacity(); - m_size = other.size(); - } - - Dynamic& operator=(const Dynamic& other) - { - if (this == &other) return *this; - - if (m_buf) - { - while (m_size) pop(); // destroy all objects - kfree(m_buf); - } - - set_expand_rate(other.m_expand_rate); - ensure_capacity(other.capacity()); - m_size = other.size(); - memcpy(m_buf, other.data(), m_capacity * sizeof(T)); - - return *this; - } - - ~Dynamic() - { - if (m_buf) - { - while (m_size) pop(); // destroy all objects - kfree(m_buf); - } - } - - T& at(size_t index) - { - ensure(index < m_size); - return m_buf[index]; - } - - const T& at(size_t index) const - { - ensure(index < m_size); - return m_buf[index]; - } - - T& operator[](size_t index) - { - return at(index); - } - - const T& operator[](size_t index) const - { - return at(index); - } - - bool expand_capacity(size_t capacity) - { - return expand(capacity); - } - - void ensure_capacity(size_t capacity) - { - ensure(expand(capacity)); - } - - void set_expand_rate(size_t rate) - { - if (!rate) return; - m_expand_rate = rate; - } - - __noinline bool push(const T& item) - { - if (m_size == m_capacity) - if (!expand_fixed()) return false; - m_size++; - T* loc = ptr_at(m_size - 1); - new (loc) T(item); - return true; - } - - void pop() - { - at(m_size - 1).~T(); - m_size--; - } - - size_t capacity() const - { - return m_capacity; - } - - size_t size() const - { - return m_size; - } - - const T* data() const - { - return m_buf; - } - - T* release_data() - { - T* result = m_buf; - m_buf = nullptr; - return result; - } - - private: - T* m_buf = nullptr; - size_t m_capacity = 0; - size_t m_size = 0; - size_t m_expand_rate = 16; - - bool expand(size_t new_capacity) - { - m_buf = (T*)krealloc(m_buf, new_capacity * sizeof(T)); - if (!m_buf) return false; - m_capacity = new_capacity; - return true; - } - - bool expand_fixed() - { - ensure(m_expand_rate != 0); - return expand(m_capacity + m_expand_rate); - } - - T* ptr_at(size_t index) - { - return (T*)((char*)m_buf + index * sizeof(T)); - } -}; \ No newline at end of file diff --git a/kernel/include/utils/PageFaultReason.h b/kernel/include/utils/PageFaultReason.h deleted file mode 100644 index 7f9d88da..00000000 --- a/kernel/include/utils/PageFaultReason.h +++ /dev/null @@ -1,4 +0,0 @@ -#pragma once -#include - -void determine_user_page_fault_reason(uintptr_t faulting_address); \ No newline at end of file diff --git a/kernel/include/utils/Registers.h b/kernel/include/utils/Registers.h deleted file mode 100644 index 944a0ea0..00000000 --- a/kernel/include/utils/Registers.h +++ /dev/null @@ -1,52 +0,0 @@ -#pragma once - -#include - -extern "C" uintptr_t asm_get_rflags(); -extern "C" void asm_set_rflags(uintptr_t); - -inline uintptr_t read_rflags() -{ - return asm_get_rflags(); -} - -inline void write_rflags(uintptr_t value) -{ - asm_set_rflags(value); -} - -inline uintptr_t read_cr0() -{ - uintptr_t value; - asm volatile("mov %%cr0, %0" : "=r"(value)); - return value; -} - -inline uintptr_t read_cr3() -{ - uintptr_t value; - asm volatile("mov %%cr3, %0" : "=r"(value)); - return value; -} - -inline uintptr_t read_cr4() -{ - uintptr_t value; - asm volatile("mov %%cr4, %0" : "=r"(value)); - return value; -} - -template inline void write_cr0(T value) -{ - asm volatile("mov %0, %%cr0" : : "r"(value)); -} - -template inline void write_cr3(T value) -{ - asm volatile("mov %0, %%cr3" : : "r"(value)); -} - -template inline void write_cr4(T value) -{ - asm volatile("mov %0, %%cr4" : : "r"(value)); -} \ No newline at end of file diff --git a/kernel/include/utils/Result.h b/kernel/include/utils/Result.h deleted file mode 100644 index 6abb0f8a..00000000 --- a/kernel/include/utils/Result.h +++ /dev/null @@ -1,153 +0,0 @@ -#pragma once -#include "std/ensure.h" -#include "std/errno.h" -#include "std/string.h" -#include "utils/move.h" -#include "utils/new.h" - -struct Error -{ - Error(int err) - { - error = err; - } - - int error; -}; - -template class Result -{ - public: - Result(const T& value) - { - m_storage.store_reference(value); - m_has_value = true; - m_has_error = false; - } - - Result(T&& value) - { - m_storage.store_movable_reference(move(value)); - m_has_value = true; - m_has_error = false; - } - - Result(const Result& other) - { - m_storage.store_reference(other.m_storage.fetch_reference()); - m_has_value = true; - m_has_error = false; - } - - Result(Result&& other) - { - m_storage.store_movable_reference(move(other.m_storage.fetch_reference())); - m_has_value = true; - m_has_error = false; - } - - Result(const Error& err) - { - m_error = err.error; - m_has_error = true; - m_has_value = false; - } - - bool has_error() - { - return m_has_error; - } - - bool has_value() - { - return m_has_value; - } - - int error() - { - ensure(has_error()); - return m_error; - } - - Error release_error() - { - ensure(has_error()); - return {m_error}; - } - - T value() - { - ensure(has_value()); - return m_storage.fetch_reference(); - } - - T value_or(T other) - { - if (has_value()) return m_storage.fetch_reference(); - return other; - } - - T release_value() - { - ensure(has_value()); - T item = m_storage.fetch_reference(); - m_has_value = false; - m_storage.destroy(); - return move(item); - } - - ~Result() - { - if (has_value()) m_storage.destroy(); - } - - private: - struct Storage - { - unsigned char buffer[sizeof(T)]; - - T* fetch_ptr() - { - return (T*)buffer; - } - - T& fetch_reference() - { - return *fetch_ptr(); - } - - const T* fetch_ptr() const - { - return (const T*)buffer; - } - - const T& fetch_reference() const - { - return *fetch_ptr(); - } - - void store_ptr(T* ptr) - { - new (buffer) T(*ptr); - } - - void store_reference(const T& ref) - { - new (buffer) T(ref); - } - - void store_movable_reference(T&& ref) - { - new (buffer) T(ref); - } - - void destroy() - { - fetch_reference().~T(); - } - }; - Storage m_storage; - int m_error; - bool m_has_error; - bool m_has_value; -}; \ No newline at end of file diff --git a/kernel/include/utils/StringParsing.h b/kernel/include/utils/StringParsing.h deleted file mode 100644 index 264644f6..00000000 --- a/kernel/include/utils/StringParsing.h +++ /dev/null @@ -1,4 +0,0 @@ -#pragma once - -long parse_decimal(const char* str); -long parse_octal(const char* str); \ No newline at end of file diff --git a/kernel/include/utils/Time.h b/kernel/include/utils/Time.h deleted file mode 100644 index 3e06716f..00000000 --- a/kernel/include/utils/Time.h +++ /dev/null @@ -1,8 +0,0 @@ -#pragma once -#include - -int make_yday(int year, int month); - -uint64_t broken_down_to_unix(uint64_t year, uint64_t yday, uint64_t hour, uint64_t min, uint64_t sec); - -uint64_t unix_boottime(uint8_t boottime[8]); \ No newline at end of file diff --git a/kernel/include/utils/move.h b/kernel/include/utils/move.h deleted file mode 100644 index 9006d68a..00000000 --- a/kernel/include/utils/move.h +++ /dev/null @@ -1,6 +0,0 @@ -#pragma once - -template inline T&& move(T& lvalue) -{ - return (T &&) lvalue; -} \ No newline at end of file diff --git a/kernel/include/utils/new.h b/kernel/include/utils/new.h deleted file mode 100644 index 1e6afcd1..00000000 --- a/kernel/include/utils/new.h +++ /dev/null @@ -1,13 +0,0 @@ -#pragma once -#include - -inline void* operator new(size_t, void* p) noexcept -{ - return p; -} -inline void* operator new[](size_t, void* p) noexcept -{ - return p; -} -inline void operator delete(void*, void*) noexcept {}; -inline void operator delete[](void*, void*) noexcept {}; \ No newline at end of file diff --git a/kernel/moon.ld b/kernel/moon.ld index e2dd402a..8445665d 100644 --- a/kernel/moon.ld +++ b/kernel/moon.ld @@ -1,4 +1,4 @@ -ENTRY(_main) +ENTRY(_start) OUTPUT_FORMAT(elf64-x86-64) mmio = 0xfffffffff8000000; /* these are configurable for level 2 loaders */ @@ -32,5 +32,4 @@ SECTIONS kernel_end = .; /DISCARD/ : { *(.eh_frame) *(.comment) } -} - +} \ No newline at end of file diff --git a/kernel/src/acpi/RSDT.cpp b/kernel/src/acpi/RSDT.cpp deleted file mode 100644 index 98f78afc..00000000 --- a/kernel/src/acpi/RSDT.cpp +++ /dev/null @@ -1,109 +0,0 @@ -#define MODULE "acpi" - -#include "acpi/RSDT.h" -#include "bootboot.h" -#include "log/Log.h" -#include "memory/MemoryManager.h" -#include "misc/utils.h" -#include "std/stdio.h" -#include "std/string.h" - -extern BOOTBOOT bootboot; - -// FIXME: Propagate errors. - -ACPI::SDTHeader* ACPI::get_rsdt_or_xsdt() -{ - static SDTHeader* cache = nullptr; - if (cache) return cache; - - kdbgln("First time accessing the RSDT/XSDT, mapping it into memory"); - void* physical = (void*)bootboot.arch.x86_64.acpi_ptr; - kdbgln("RSDT/XSDT physical address: %p", physical); - - SDTHeader* rsdt = (SDTHeader*)MemoryManager::get_unaligned_mapping(physical).release_value(); - - uint64_t offset = (uint64_t)physical % PAGE_SIZE; - uint64_t rsdt_pages = Utilities::get_blocks_from_size(PAGE_SIZE, (offset + rsdt->Length)); - - if (rsdt_pages > 1) - { - MemoryManager::release_unaligned_mapping(rsdt); - rsdt = (SDTHeader*)MemoryManager::get_unaligned_mappings(cache, rsdt_pages).release_value(); - } - - kdbgln("Mapped RSDT/XSDT to virtual address %p, uses %ld pages", (void*)rsdt, rsdt_pages); - cache = rsdt; - return rsdt; -} - -bool ACPI::validate_rsdt_or_xsdt(ACPI::SDTHeader* root_sdt) -{ - if (!validate_sdt_header(root_sdt)) return false; - if (strncmp(root_sdt->Signature, "XSDT", 4) == 0) return true; - if (strncmp(root_sdt->Signature, "RSDT", 4) == 0) return true; - return false; -} - -bool ACPI::is_xsdt() -{ - static bool cached = false; - static bool cache = false; - if (cached) return cache; - SDTHeader* rootSDT = get_rsdt_or_xsdt(); - cache = (strncmp(rootSDT->Signature, "XSDT", 4) == 0); - cached = true; - return cache; -} - -void* ACPI::find_table(ACPI::SDTHeader* root_sdt, const char* signature) -{ - bool isXSDT = is_xsdt(); - uint64_t entries = (root_sdt->Length - sizeof(SDTHeader)) / (isXSDT ? 8 : 4); - kdbgln("Searching for table %s in the %s at %p (table contains %ld entries)", signature, isXSDT ? "XSDT" : "RSDT", - (void*)root_sdt, entries); - - for (uint64_t i = 0; i < entries; i++) - { - kdbgln("Testing for table %s in entry %ld", signature, i); - SDTHeader* h; - if (isXSDT) - { - uint64_t reversedAddress = (uint64_t)((XSDT*)root_sdt)->other_sdt[i]; - uint64_t correctAddress = reversedAddress >> 32 | reversedAddress << 32; - h = (SDTHeader*)correctAddress; - } - else - { - uint32_t entry = ((RSDT*)root_sdt)->other_sdt[i]; - h = (SDTHeader*)(uint64_t)entry; - } - if (!h) - { - kwarnln("Entry %ld in the %s points to null", i, isXSDT ? "XSDT" : "RSDT"); - continue; - } - kdbgln("Physical address of entry: %p", (void*)h); - SDTHeader* realHeader = (SDTHeader*)MemoryManager::get_unaligned_mapping(h).release_value(); - kdbgln("Mapped entry to virtual address %p", (void*)realHeader); - if (!validate_sdt_header(realHeader)) - { - kwarnln("Header of entry %ld is not valid, skipping this entry", i); - MemoryManager::release_unaligned_mapping(realHeader); - continue; - } - char tableSignature[5]; - memcpy(tableSignature, h->Signature, 4); - tableSignature[4] = 0; - kdbgln("Comparing target signature (%s) to signature of entry (%s)", signature, tableSignature); - if (strncmp(h->Signature, signature, 4) == 0) - { - kdbgln("Found table %s", signature); - return (void*)realHeader; - } - kdbgln("Signatures do not match, unmapping entry and continuing"); - MemoryManager::release_unaligned_mapping(realHeader); - } - - return NULL; -} \ No newline at end of file diff --git a/kernel/src/acpi/SDT.cpp b/kernel/src/acpi/SDT.cpp deleted file mode 100644 index 9b861ab6..00000000 --- a/kernel/src/acpi/SDT.cpp +++ /dev/null @@ -1,15 +0,0 @@ -#include "acpi/SDT.h" - -#pragma GCC push_options -#pragma GCC diagnostic ignored "-Wconversion" - -bool ACPI::validate_sdt_header(ACPI::SDTHeader* header) -{ - uint8_t sum = 0; - - for (uint32_t i = 0; i < header->Length; i++) { sum += ((char*)header)[i]; } - - return sum == 0; -} - -#pragma GCC pop_options \ No newline at end of file diff --git a/kernel/src/cpu/CPU.cpp b/kernel/src/cpu/CPU.cpp deleted file mode 100644 index f686a009..00000000 --- a/kernel/src/cpu/CPU.cpp +++ /dev/null @@ -1,99 +0,0 @@ -#define MODULE "cpuid" - -#include "cpu/CPU.h" -#include "log/Log.h" -#include -#include - -const char* CPU::get_vendor_string() -{ - static bool cached = false; - static char vendor[13]; - if (cached) { return vendor; } - else - { - unsigned int unused, ebx, ecx, edx; - __get_cpuid(0, &unused, &ebx, &ecx, &edx); - memcpy(vendor, &ebx, 4); - memcpy(&vendor[4], &edx, 4); - memcpy(&vendor[8], &ecx, 4); - vendor[12] = 0; - cached = true; - return vendor; - } -} - -const char* CPU::get_brand_string() -{ - static bool cached = false; - static char brand[49]; - if (cached) { return brand; } - else - { - unsigned int eax, ebx, ecx, edx; - __get_cpuid(0x80000002, &eax, &ebx, &ecx, &edx); - memcpy(brand, &eax, 4); - memcpy(&brand[4], &ebx, 4); - memcpy(&brand[8], &ecx, 4); - memcpy(&brand[12], &edx, 4); - __get_cpuid(0x80000003, &eax, &ebx, &ecx, &edx); - memcpy(&brand[16], &eax, 4); - memcpy(&brand[16 + 4], &ebx, 4); - memcpy(&brand[16 + 8], &ecx, 4); - memcpy(&brand[16 + 12], &edx, 4); - __get_cpuid(0x80000004, &eax, &ebx, &ecx, &edx); - memcpy(&brand[32], &eax, 4); - memcpy(&brand[32 + 4], &ebx, 4); - memcpy(&brand[32 + 8], &ecx, 4); - memcpy(&brand[32 + 12], &edx, 4); - brand[48] = 0; - cached = true; - return brand; - } -} - -uint64_t CPU::get_feature_bitmask() -{ - static uint64_t bitmask = 0; - static bool cached = false; - if (cached) return bitmask; - unsigned int unused; - unsigned int ecx = 0; - unsigned int edx = 0; - __get_cpuid(1, &unused, &unused, &ecx, &edx); - bitmask = ((uint64_t)ecx << 32) | (uint64_t)edx; - cached = true; - return bitmask; -} - -bool CPU::has_nx() -{ - unsigned int unused; - unsigned int edx; - __get_cpuid(0x80000001, &unused, &unused, &unused, &edx); - return edx & (1 << 20); -} - -static bool _has_feature(int feature) -{ - return (CPU::get_feature_bitmask() & (uint64_t)(1UL << feature)) > 0; -} - -bool CPU::has_feature(CPU::Features feature) -{ - return _has_feature((int)feature); -} - -uint64_t CPU::get_initial_apic_id() -{ - unsigned int unused; - unsigned int ebx = 0; - __get_cpuid(1, &unused, &ebx, &unused, &unused); - return ebx >> 24; -} - -void CPU::log_cpu_information() -{ - kinfoln("CPU vendor: %s", get_vendor_string()); - kinfoln("CPU brand: %s", get_brand_string()); -} diff --git a/kernel/src/fs/FileDescriptor.cpp b/kernel/src/fs/FileDescriptor.cpp deleted file mode 100644 index 26dee2bc..00000000 --- a/kernel/src/fs/FileDescriptor.cpp +++ /dev/null @@ -1,96 +0,0 @@ -#include "fs/FileDescriptor.h" -#include "std/errno.h" -#include "std/stdlib.h" -#include "sys/UserMemory.h" - -Descriptor::Descriptor() : m_is_open(false) -{ -} - -Descriptor::Descriptor(const Descriptor& other) - : m_is_open(other.m_is_open), m_can_read(other.m_can_read), m_can_write(other.m_can_write), - m_able_to_block(other.m_able_to_block), m_close_on_exec(other.m_close_on_exec), m_node(other.m_node), - m_offset(other.m_offset) -{ -} - -void Descriptor::open(VFS::Node* node, bool can_read, bool can_write, bool able_to_block, bool close_on_exec) -{ - m_can_read = can_read; - m_can_write = can_write; - m_able_to_block = able_to_block; - m_close_on_exec = close_on_exec; - m_node = node; - m_offset = 0; - m_is_open = true; -} - -ssize_t Descriptor::read(size_t size, char* buffer) -{ - ssize_t result = VFS::read(m_node, m_offset, size, buffer); - m_offset += result; - return result; -} - -ssize_t Descriptor::write(size_t size, const char* buffer) -{ - ssize_t result = VFS::write(m_node, m_offset, size, buffer); - m_offset += result; - return result; -} - -ssize_t Descriptor::user_read(size_t size, char* buffer) -{ - char* buf = (char*)kmalloc(size); - if (!buf) return -ENOMEM; - ssize_t result = read(size, buf); - if (!copy_to_user(buffer, buf, size)) result = -EFAULT; - kfree(buf); - return result; -} - -ssize_t Descriptor::user_write(size_t size, const char* buffer) -{ - char* buf = (char*)kmalloc(size); - if (!buf) return -ENOMEM; - ssize_t result; - if (!copy_from_user(buffer, buf, size)) result = -EFAULT; - else - result = write(size, buf); - kfree(buf); - return result; -} - -#define MAP_FAIL(errno) 0xffffffffffffff00 | (unsigned char)(errno) - -uintptr_t Descriptor::mmap(uintptr_t addr, size_t size, int prot, off_t offset) -{ - if (!m_node->mmap_func) return MAP_FAIL(ENOTSUP); - return m_node->mmap_func(m_node, addr, size, prot, offset); -} - -long Descriptor::ioctl(int cmd, uintptr_t arg) -{ - if (!m_node->ioctl_func) return MAP_FAIL(ENOTSUP); - return m_node->ioctl_func(m_node, cmd, arg); -} - -int Descriptor::seek(long offset) -{ - if (m_node->type == VFS_FILE && (uint64_t)offset > m_node->length) - return -EINVAL; // FIXME: Support seeking beyond the current file's length. - m_offset = (uint64_t)offset; - return 0; -} - -const Descriptor& Descriptor::operator=(const Descriptor& other) -{ - m_is_open = other.m_is_open; - m_can_read = other.m_can_read; - m_can_write = other.m_can_write; - m_offset = other.m_offset; - m_node = other.m_node; - m_able_to_block = other.m_able_to_block; - m_close_on_exec = other.m_close_on_exec; - return other; -} \ No newline at end of file diff --git a/kernel/src/fs/InitRD.cpp b/kernel/src/fs/InitRD.cpp deleted file mode 100644 index bb664610..00000000 --- a/kernel/src/fs/InitRD.cpp +++ /dev/null @@ -1,424 +0,0 @@ -#define MODULE "initrd" - -#include "fs/InitRD.h" -#include "bootboot.h" -#include "fs/VFS.h" -#include "io/Serial.h" -#include "log/Log.h" -#include "memory/MemoryManager.h" -#include "misc/utils.h" -#include "std/errno.h" -#include "std/stdlib.h" -#include "std/string.h" -#include "utils/StringParsing.h" - -// FIXME: A lot of this code was written before the VFS was created and thus is quite messy and assumes other stuff. - -extern BOOTBOOT bootboot; - -static void* initrd_base; -static bool initrd_initialized = false; - -static VFS::Node initrd_root; - -extern uint64_t clock_boot(); // defined in sys/clock.cpp -extern uint64_t clock_now(); - -bool InitRD::is_initialized() -{ - return initrd_initialized; -} - -static inline uint64_t get_file_size_in_blocks(InitRD::File f) -{ - return f.size_in_blocks; -} - -inline uint64_t InitRD::get_total_blocks() -{ - return bootboot.initrd_size / TAR_BLOCKSIZE; -} - -inline InitRD::TarHeader* InitRD::get_block(uint64_t block_index) -{ - return (TarHeader*)((uintptr_t)initrd_base + block_index * TAR_BLOCKSIZE); -} - -inline bool InitRD::is_valid_header(TarHeader* header) -{ - return strncmp(header->magic, TAR_MAGIC, 5) == 0; -} - -uint64_t InitRD::get_file_physical_address(InitRD::File& file) -{ - return (uint64_t)file.addr - (uint64_t)initrd_base + (uint64_t)bootboot.initrd_ptr; -} - -InitRD::File InitRD::get_file(TarHeader* header) -{ - File result; - char null_terminated_size[13]; - memcpy(null_terminated_size, header->size, 12); - null_terminated_size[12] = 0; - result.size = parse_octal(null_terminated_size); - memcpy(result.name, header->name, 100); - result.addr = (void*)((uint64_t)header + TAR_BLOCKSIZE); - result.size_in_blocks = Utilities::get_blocks_from_size(TAR_BLOCKSIZE, result.size); - result.mode = (mode_t)parse_octal(header->mode); - return result; -} - -InitRD::File InitRD::open(const char* filename) -{ - uint64_t block = 0; - uint64_t total_blocks = get_total_blocks(); - while (block < total_blocks) - { - TarHeader* hdr = (TarHeader*)get_block(block); - if (hdr->typeflag == 53) - { - block++; - continue; - } - if (!is_valid_header(hdr)) - { - block++; - continue; - } - auto f = get_file(hdr); - if (strncmp(hdr->name, filename, strlen(filename)) == 0) { return f; } - block += get_file_size_in_blocks(f) + 1; - } - File nullFile; - nullFile.addr = 0; - nullFile.size = 0; - memcpy(nullFile.name, "NULL", 5); - return nullFile; -} - -void InitRD::for_each(void (*callback)(File& f)) -{ - uint64_t block = 0; - uint64_t total_blocks = get_total_blocks(); - while (block < total_blocks) - { - TarHeader* hdr = (TarHeader*)get_block(block); - if (hdr->typeflag == 53) - { - block++; - continue; - } - if (!is_valid_header(hdr)) - { - block++; - continue; - } - auto f = get_file(hdr); - block += get_file_size_in_blocks(f) + 1; - callback(f); - } -} - -#define INITRD_MAX_FILES_IN_DIR 32 -#define INITRD_MAX_FILES 64 - -namespace InitRD -{ - struct Directory - { - char name[64]; - int entries = 0; - VFS::Node* files[INITRD_MAX_FILES_IN_DIR]; - }; -} - -void initrd_for_each_dir(void (*callback)(InitRD::Directory& f)) -{ - uint64_t block = 0; - uint64_t total_blocks = InitRD::get_total_blocks(); - while (block < total_blocks) - { - InitRD::TarHeader* hdr = (InitRD::TarHeader*)InitRD::get_block(block); - if (!InitRD::is_valid_header(hdr)) - { - block++; - continue; - } - if (hdr->typeflag == 53) - { - InitRD::Directory dir; - strncpy(dir.name, hdr->name, sizeof(dir.name)); - callback(dir); - block++; - continue; - } - auto f = get_file(hdr); - block += get_file_size_in_blocks(f) + 1; - } -} - -static InitRD::File files[INITRD_MAX_FILES]; -static uint32_t total_files = 0; - -static InitRD::Directory dirs[INITRD_MAX_FILES]; -static uint32_t total_dirs = 0; - -static VFS::Node nodes[INITRD_MAX_FILES + (INITRD_MAX_FILES - 1)]; // One of the dirs is the initrd_root -static uint32_t total_nodes = 0; - -ssize_t initrd_read(VFS::Node* node, size_t offset, size_t length, char* buffer) -{ - if (!node) return -1; - if (node->inode >= total_files) return -1; - InitRD::File& file = files[node->inode]; - if (offset > file.size) return -1; - if (offset + length > file.size) { length = file.size - offset; } - memcpy(buffer, (void*)((uintptr_t)file.addr + offset), length); - return length; -} - -VFS::Node* initrd_scan_dir(VFS::Node* node, const char* filename) -{ - if (!node) return 0; - if (node->inode >= total_dirs) return 0; - InitRD::Directory dir = dirs[node->inode]; - for (int i = 0; i < dir.entries; i++) - { - if (strncmp(dir.files[i]->name, filename, sizeof(VFS::Node::name)) == 0) { return dir.files[i]; } - } - return 0; -} - -VFS::Node* initrd_read_dir(VFS::Node* node, long offset) -{ - if (!node) return 0; - if (node->inode >= total_dirs) return 0; - InitRD::Directory dir = dirs[node->inode]; - if (offset >= dir.entries) return 0; - return dir.files[offset]; -} - -int initrd_mkdir(VFS::Node* node, const char* name, mode_t mode) // FIXME: Return proper error numbers. -{ - if (total_dirs >= 32) - { - kwarnln("mkdir() failed: too many directories"); - return -ENOSPC; - } - if (node->inode > total_dirs) - { - kwarnln("mkdir() failed: invalid node"); - return -EINVAL; - } - if (!(node->type & VFS_DIRECTORY)) - { - kwarnln("mkdir() failed: not a directory"); - return -ENOTDIR; - } - InitRD::Directory& parent = dirs[node->inode]; - if (parent.entries == INITRD_MAX_FILES_IN_DIR) - { - kwarnln("mkdir() failed: parent is full"); - return -ENOSPC; - } - uint64_t inode = total_dirs; - VFS::Node& new_node = nodes[total_nodes++]; - new_node.inode = inode; - new_node.find_func = initrd_scan_dir; - new_node.mkdir_func = initrd_mkdir; - new_node.readdir_func = initrd_read_dir; - new_node.length = 0; - new_node.type = VFS_DIRECTORY; - new_node.mode = mode; - new_node.uid = new_node.gid = 0; - new_node.atime = new_node.ctime = new_node.mtime = clock_now(); - strncpy(new_node.name, name, sizeof(new_node.name)); - InitRD::Directory dir; - strncpy(dir.name, name, sizeof(dir.name)); - dir.entries = 0; - dirs[total_dirs++] = dir; // FIXME: Right now this isn't of worry, but there is a possibility for a TOCTOU bug here. - // Should use a spinlock or something. - node->length++; - parent.files[parent.entries++] = &new_node; - return 0; -} - -static bool initrd_register_dir(InitRD::Directory& dir, uint64_t inode) -{ - const char* filename = dir.name; - VFS::Node* current_node = &initrd_root; - while (true) - { - while (*filename == '/') { filename++; } - if (*filename == 0) { return false; } - - size_t path_section_size = 0; - while (filename[path_section_size] && filename[path_section_size] != '/') { path_section_size++; } - - if (filename[path_section_size]) // We are in a '/' - { - char* buffer = (char*)kmalloc(path_section_size + 1); - memcpy(buffer, filename, path_section_size); - buffer[path_section_size] = 0; - if (!current_node->find_func) { return false; } - VFS::Node* child = current_node->find_func(current_node, buffer); - if (!child) { return false; } - current_node = child; - kfree(buffer); - } - else - { - if (strncmp(filename, ".", path_section_size) != 0) // The current path section is not '.' - { - if (strncmp(filename, "..", path_section_size) == 0) { return false; } - - if (!current_node->find_func) { return false; } - - InitRD::Directory& parent = dirs[current_node->inode]; - if (parent.entries == INITRD_MAX_FILES_IN_DIR) { return false; } - - char* buffer = (char*)kmalloc(path_section_size + 1); - memcpy(buffer, filename, path_section_size); - buffer[path_section_size] = 0; - - VFS::Node& node = nodes[total_nodes++]; - node.inode = inode; - node.find_func = initrd_scan_dir; - node.length = 0; - node.type = VFS_DIRECTORY; - node.mkdir_func = initrd_mkdir; - node.readdir_func = initrd_read_dir; - node.length = 0; - node.mode = 0755; - node.uid = node.gid = 0; - node.atime = node.ctime = node.mtime = clock_boot(); - strncpy(node.name, buffer, sizeof(node.name)); - strncpy(dir.name, buffer, sizeof(dir.name)); - - parent.files[parent.entries++] = &node; - current_node->length++; - - kfree(buffer); - return true; - } - else { return false; } - } - - filename += path_section_size; - } -} - -static bool initrd_register_file(InitRD::File& f, uint64_t inode) -{ - const char* filename = f.name; - VFS::Node* current_node = &initrd_root; - while (true) - { - while (*filename == '/') { filename++; } - if (*filename == 0) { return false; } - - size_t path_section_size = 0; - while (filename[path_section_size] && filename[path_section_size] != '/') { path_section_size++; } - - if (filename[path_section_size]) // We are in a '/' - { - char* buffer = (char*)kmalloc(path_section_size + 1); - memcpy(buffer, filename, path_section_size); - buffer[path_section_size] = 0; - if (!current_node->find_func) { return false; } - VFS::Node* child = current_node->find_func(current_node, buffer); - if (!child) { return false; } - current_node = child; - kfree(buffer); - } - else - { - if (strncmp(filename, ".", path_section_size) != 0) // The current path section is not '.' - { - if (strncmp(filename, "..", path_section_size) == 0) { return false; } - - if (!current_node->find_func) { return false; } - - InitRD::Directory& parent = dirs[current_node->inode]; - if (parent.entries == INITRD_MAX_FILES_IN_DIR) { return false; } - - char* buffer = (char*)kmalloc(path_section_size + 1); - memcpy(buffer, filename, path_section_size); - buffer[path_section_size] = 0; - - VFS::Node& node = nodes[total_nodes++]; - node.inode = inode; - node.read_func = initrd_read; - node.length = f.size; - node.type = VFS_FILE; - node.mode = f.mode & 07555; // don't allow writing - node.uid = node.gid = 0; - node.atime = node.ctime = node.mtime = clock_boot(); - strncpy(node.name, buffer, sizeof(node.name)); - strncpy(f.name, buffer, sizeof(f.name)); - - parent.files[parent.entries++] = &node; - current_node->length++; - kfree(buffer); - return true; - } - else { return false; } - } - - filename += path_section_size; - } -} - -static void initrd_scan() -{ - initrd_for_each_dir([](InitRD::Directory& dir) { - if (total_dirs >= INITRD_MAX_FILES) - { - kwarnln("Failed to register directory %s: Too many directories in initrd", dir.name); - return; - } - uint64_t inode = total_dirs; - if (initrd_register_dir(dir, inode)) dirs[total_dirs++] = dir; - }); - InitRD::for_each([](InitRD::File& f) { - if (total_files >= INITRD_MAX_FILES) - { - kwarnln("Failed to register file %s: Too many files in initrd", f.name); - return; - } - uint64_t inode = total_files; - if (initrd_register_file(f, inode)) files[total_files++] = f; - }); -} - -static void initrd_initialize_root() -{ - initrd_root.length = 0; - initrd_root.inode = 0; - initrd_root.type |= VFS_DIRECTORY; - initrd_root.mode = 0755; - initrd_root.uid = initrd_root.gid = 0; - initrd_root.atime = initrd_root.ctime = initrd_root.mtime = clock_boot(); - InitRD::Directory& root = dirs[0]; - total_dirs++; - strncpy(initrd_root.name, "initrd", sizeof(initrd_root.name)); - strncpy(root.name, "initrd", sizeof(root.name)); - initrd_root.find_func = initrd_scan_dir; - initrd_root.mkdir_func = initrd_mkdir; - initrd_root.readdir_func = initrd_read_dir; -} - -void InitRD::init() -{ - initrd_base = MemoryManager::get_unaligned_mappings( - (void*)bootboot.initrd_ptr, Utilities::get_blocks_from_size(PAGE_SIZE, bootboot.initrd_size)) - .release_value(); // FIXME: Propagate errors. - kdbgln("physical base at %lx, size %lx, mapped to %p", bootboot.initrd_ptr, bootboot.initrd_size, initrd_base); - kdbgln("total blocks: %ld", get_total_blocks()); - void* leak = kmalloc(4); // leak some memory so that kmalloc doesn't continously allocate and free pages - initrd_initialize_root(); - initrd_scan(); - VFS::mount_root(&initrd_root); - initrd_initialized = true; - kfree(leak); -} \ No newline at end of file diff --git a/kernel/src/fs/TmpFS.cpp b/kernel/src/fs/TmpFS.cpp deleted file mode 100644 index e4e5fccb..00000000 --- a/kernel/src/fs/TmpFS.cpp +++ /dev/null @@ -1,186 +0,0 @@ -#define MODULE "tmpfs" - -#include "fs/TmpFS.h" -#include "log/Log.h" -#include "memory/MemoryManager.h" -#include "misc/utils.h" -#include "std/errno.h" -#include "std/string.h" -#include "utils/Dynamic.h" -#include "utils/move.h" - -namespace TmpFS -{ - struct File - { - void* ptr; - uint64_t pages; - uint64_t length; - }; - - struct Directory - { - Dynamic files; - }; -} - -VFS::Node* tmpfs_root = nullptr; - -Dynamic tmpfs_dirs; -Dynamic tmpfs_files; - -extern uint64_t clock_now(); - -static bool resize_file(TmpFS::File& file, size_t new_size) -{ - size_t pages = Utilities::get_blocks_from_size(PAGE_SIZE, new_size); - if (pages > file.pages) // resize only if we need a bigger chunk of memory - { - auto rc = MemoryManager::get_pages(pages, MAP_READ_WRITE); - if (rc.has_error()) return false; - void* new_ptr = rc.release_value(); - if (file.ptr) - { - memcpy(new_ptr, file.ptr, file.length); - MemoryManager::release_pages(file.ptr, file.pages); - } - file.pages = pages; - file.ptr = new_ptr; - } - file.length = new_size; - return true; -} - -VFS::Node* TmpFS::get() -{ - if (tmpfs_root) return tmpfs_root; - kinfoln("initializing tmpfs instance"); - tmpfs_root = new VFS::Node; - tmpfs_root->length = 0; - tmpfs_root->inode = 0; - tmpfs_root->type = VFS_DIRECTORY; - tmpfs_root->find_func = TmpFS::finddir; - tmpfs_root->readdir_func = TmpFS::readdir; - tmpfs_root->mkdir_func = TmpFS::mkdir; - tmpfs_root->create_func = TmpFS::create; - tmpfs_root->mode = 0777; - tmpfs_root->uid = tmpfs_root->gid = 0; - tmpfs_root->atime = tmpfs_root->ctime = tmpfs_root->mtime = clock_now(); - strncpy(tmpfs_root->name, "tmpfs", sizeof(tmpfs_root->name)); - tmpfs_dirs.ensure_capacity(16); - tmpfs_files.ensure_capacity(16); - tmpfs_dirs.set_expand_rate(16); - tmpfs_files.set_expand_rate(16); - ensure(tmpfs_dirs.push({{}})); - return tmpfs_root; -} - -VFS::Node* TmpFS::finddir(VFS::Node* node, const char* filename) -{ - if (!node) return nullptr; - if (node->inode >= tmpfs_dirs.size()) return nullptr; - auto& dir = tmpfs_dirs[node->inode]; - kdbgln("searching for '%s' in '%s'", filename, node->name); - for (size_t i = 0; i < dir.files.size(); i++) - { - if (!strncmp(dir.files[i]->name, filename, sizeof(dir.files[i]->name))) return dir.files[i]; - } - return nullptr; -} - -VFS::Node* TmpFS::readdir(VFS::Node* node, long offset) -{ - if (!node) return nullptr; - if (node->inode >= tmpfs_dirs.size()) return nullptr; - auto& dir = tmpfs_dirs[node->inode]; - if (offset < 0) return nullptr; - if ((size_t)offset >= dir.files.size()) return nullptr; - kdbgln("reading offset %ld in '%s'", offset, node->name); - return dir.files[offset]; -} - -int TmpFS::mkdir(VFS::Node* node, const char* name, mode_t mode) -{ - if (node->inode >= tmpfs_dirs.size()) return -EINVAL; - if (!(node->type & VFS_DIRECTORY)) return -ENOTDIR; - auto& parent = tmpfs_dirs[node->inode]; - VFS::Node* new_node = new VFS::Node; - new_node->inode = tmpfs_dirs.size(); - new_node->find_func = TmpFS::finddir; - new_node->readdir_func = TmpFS::readdir; - new_node->mkdir_func = TmpFS::mkdir; - new_node->create_func = TmpFS::create; - new_node->length = 0; - new_node->type = VFS_DIRECTORY; - new_node->mode = mode; - new_node->uid = new_node->gid = 0; - new_node->atime = new_node->ctime = new_node->mtime = clock_now(); - strncpy(new_node->name, name, sizeof(new_node->name)); - ensure(parent.files.push( - new_node)); // We have to push the new node to the parent BEFORE we push the directory object to the list of - // tmpfs directories. This is crucial, since pushing to the list of tmpfs directories could relocate - // said list, where the parent object is stored, while we would still be using the old parent - // object. Thus our changes to the parent would be erased as soon as we exit this function. - ensure(tmpfs_dirs.push({{}})); // FIXME: Handle OOM instead of panicking - node->length++; - kdbgln("created directory '%s' in '%s' (which now has %lu entries), mode %o", name, node->name, node->length, mode); - return 0; -} - -VFS::Node* TmpFS::create(VFS::Node* node, const char* name, mode_t mode, uid_t uid, gid_t gid) -{ - if (node->inode >= tmpfs_dirs.size()) return nullptr; - if (!(node->type & VFS_DIRECTORY)) return nullptr; - auto& parent = tmpfs_dirs[node->inode]; - VFS::Node* new_node = new VFS::Node; - new_node->inode = tmpfs_files.size(); - new_node->length = 0; - new_node->read_func = TmpFS::read; - new_node->write_func = TmpFS::write; - new_node->type = VFS_FILE; - new_node->mode = mode; - new_node->uid = uid; - new_node->gid = gid; - new_node->atime = new_node->ctime = new_node->mtime = clock_now(); - strncpy(new_node->name, name, sizeof(new_node->name)); - ensure(parent.files.push( - new_node)); // We have to push the new node to the parent BEFORE we push the directory object to the list of - // tmpfs directories. This is crucial, since pushing to the list of tmpfs directories could relocate - // said list, where the parent object is stored, while we would still be using the old parent - // object. Thus our changes to the parent would be erased as soon as we exit this function. - ensure(tmpfs_files.push({nullptr, 0, 0})); // FIXME: Handle OOM instead of panicking - node->length++; - kdbgln("created file '%s' in '%s' (which now has %lu entries), mode %o", name, node->name, node->length, mode); - return 0; -} - -ssize_t TmpFS::read(VFS::Node* node, size_t offset, size_t length, char* buffer) -{ - kdbgln("got to read()"); - if (!node) return -1; - if (node->inode >= tmpfs_files.size()) return -1; - File& file = tmpfs_files[node->inode]; - size_t old_len = length; - if (offset > file.length) return -1; - if (offset + length > file.length) { length = file.length - offset; } - kdbgln("reading %zu bytes from '%s' at offset %zu (requested length was %zu)", length, node->name, offset, old_len); - memcpy(buffer, (void*)((uintptr_t)file.ptr + offset), length); - return length; -} - -ssize_t TmpFS::write(VFS::Node* node, size_t offset, size_t length, const char* buffer) -{ - if (!node) return -1; - if (node->inode >= tmpfs_files.size()) return -1; - File& file = tmpfs_files[node->inode]; - size_t new_length = file.length; - if (offset + length > file.length) new_length = offset + length; - if (new_length != file.length) - { - if (!resize_file(file, new_length)) return -ENOMEM; - node->length = new_length; - } - kdbgln("writing %zu bytes to '%s' at offset %zu", length, node->name, offset); - memcpy((void*)((uintptr_t)file.ptr + offset), buffer, length); - return length; -} \ No newline at end of file diff --git a/kernel/src/fs/VFS.cpp b/kernel/src/fs/VFS.cpp deleted file mode 100644 index 0d186efa..00000000 --- a/kernel/src/fs/VFS.cpp +++ /dev/null @@ -1,340 +0,0 @@ -#define MODULE "vfs" - -#include "fs/VFS.h" -#include "log/Log.h" -#include "std/errno.h" -#include "std/libgen.h" -#include "std/stdlib.h" -#include "std/string.h" - -static VFS::Node* vfs_root; - -int VFS::would_block(Node* node) -{ - if (!node) { return 0; } - if (!node->block_func) { return 0; } - return node->block_func(node); -} - -ssize_t VFS::read(Node* node, size_t offset, size_t length, char* buffer) -{ - if (!node) - { - kwarnln("read() failed: trying to read from nullptr"); - return -1; - } - if (node->type == VFS_DIRECTORY) - { - kwarnln("read() failed: is a directory"); - return -EISDIR; - } - if (!node->read_func) - { - kwarnln("read() failed: the chosen node doesn't support reading"); - return -1; - } - - return node->read_func(node, offset, length, buffer); -} - -ssize_t VFS::write(Node* node, size_t offset, size_t length, const char* buffer) -{ - if (!node) - { - kwarnln("write() failed: trying to write to nullptr"); - return -1; - } - if (node->type == VFS_DIRECTORY) - { - kwarnln("write() failed: is a directory"); - return -EISDIR; - } - if (!node->write_func) - { - kwarnln("write() failed: the chosen node doesn't support writing"); - return -1; - } - - return node->write_func(node, offset, length, buffer); -} - -void VFS::mount_root(Node* root) -{ - if (!root) - { - kwarnln("mount_root() failed: attempted to mount nullptr"); - return; - } - if (vfs_root) - { - kwarnln("mount_root() failed: root filesystem already mounted"); - return; - } - kinfoln("mounting node '%s' as vfs root", root->name); - vfs_root = root; -} - -VFS::Node* VFS::root() -{ - return vfs_root; -} - -VFS::Node* VFS::resolve_path(const char* filename, Node* root) -{ - if (!root) root = vfs_root; - - if (strlen(filename) == 0) return 0; - if (*filename == '/') // Absolute path. - { - filename++; - root = vfs_root; - } - - Node* current_node = root; - - while (true) - { - while (*filename == '/') { filename++; } - if (*filename == 0) { return current_node; } - - size_t path_section_size = 0; - while (filename[path_section_size] && filename[path_section_size] != '/') { path_section_size++; } - - if (strncmp(filename, ".", path_section_size) != 0) // The current path section is not '.' - { - char* buffer = (char*)kmalloc(path_section_size + 1); - memcpy(buffer, filename, path_section_size); - buffer[path_section_size] = 0; - if (!current_node->find_func) - { - kwarnln("Current node has no way to find child nodes"); - return 0; - } - Node* child = current_node->find_func(current_node, buffer); - if (!child) { return 0; } - if (child->flags & VFS_MOUNTPOINT) - { - if (!child->link) - { - kwarnln("Current node's link is null"); - return 0; - } - child = child->link; - } - current_node = child; - kfree(buffer); - } - - filename += path_section_size; - } -} - -VFS::Node* VFS::resolve_parent(const char* filename, Node* root) -{ - char* dir = better_dirname(filename); - auto* result = resolve_path(dir, root); - kfree(dir); - return result; -} - -int VFS::mkdir(const char* path, const char* name) -{ - Node* node = resolve_path(path, vfs_root); - if (!node) - { - kwarnln("Attempting to mkdir in %s, which does not exist", path); - return -ENOENT; - } - if (node->type != VFS_DIRECTORY) - { - kwarnln("Attempting to mkdir in %s, which is not a directory!!", path); - return -ENOTDIR; - } - if (!node->mkdir_func) - { - kwarnln("Chosen node does not support mkdir()"); - return -ENOTSUP; - } - if (!node->find_func) - { - kwarnln("Chosen node does not support finddir()"); - return -ENOTSUP; - } - if (!strncmp(name, ".", strlen(name)) || !strncmp(name, "..", strlen(name))) - { - kwarnln("Attempted to mkdir . or .., which already exist"); - return -EEXIST; - } - if (node->find_func(node, name) != nullptr) - { - kwarnln("Already exists"); - return -EEXIST; - } - return node->mkdir_func(node, name, 0755); -} - -int VFS::do_mkdir(const char* path, const char* name, int uid, int gid, mode_t mode) -{ - Node* node = resolve_path(path, vfs_root); - if (!node) - { - kwarnln("Attempting to mkdir in %s, which does not exist", path); - return -ENOENT; - } - if (node->type != VFS_DIRECTORY) - { - kwarnln("Attempting to mkdir in %s, which is not a directory!!", path); - return -ENOTDIR; - } - if (!node->mkdir_func) - { - kwarnln("Chosen node does not support mkdir()"); - return -ENOTSUP; - } - if (!node->find_func) - { - kwarnln("Chosen node does not support finddir()"); - return -ENOTSUP; - } - if (!strncmp(name, ".", strlen(name)) || !strncmp(name, "..", strlen(name))) - { - kwarnln("Attempted to mkdir . or .., which already exist"); - return -EEXIST; - } - if (node->find_func(node, name) != nullptr) - { - kwarnln("Already exists"); - return -EEXIST; - } - if (!can_write(node, uid, gid)) - { - kwarnln("Not enough permissions"); - return -EACCES; - } - return node->mkdir_func(node, name, mode); -} - -int VFS::mkdir(const char* pathname) -{ - char* base = better_basename(pathname); - char* dir = better_dirname(pathname); - - kdbgln("mkdir(): creating %s in directory %s", base, dir); - - int result = mkdir(dir, base); - - kfree(base); - kfree(dir); - - return result; -} - -int VFS::do_mkdir(const char* pathname, int uid, int gid, mode_t mode) -{ - char* base = better_basename(pathname); - char* dir = better_dirname(pathname); - - kdbgln("mkdir(): creating %s in directory %s", base, dir); - - int result = do_mkdir(dir, base, uid, gid, mode); - - kfree(base); - kfree(dir); - - return result; -} - -Result VFS::create(const char* pathname, mode_t mode, uid_t uid, gid_t gid) -{ - VFS::Node* parent = VFS::resolve_parent(pathname); - if (!parent) return {ENOENT}; - if (parent->type != VFS_DIRECTORY) - { - kwarnln("Attempting to create %s, parent is not a directory", pathname); - return {ENOTDIR}; - } - if (!parent->create_func) - { - kwarnln("Chosen node does not support create()"); - return {ENOTSUP}; // FIXME: Probably EROFS. - } - if (!parent->find_func) - { - kwarnln("Chosen node does not support finddir()"); - return {ENOTSUP}; - } - if (!can_write(parent, uid, gid)) return {EACCES}; - char* child = better_basename(pathname); - if (parent->find_func(parent, child)) - { - kwarnln("Already exists"); - kfree(child); - return {EEXIST}; - } - VFS::Node* child_node = parent->create_func(parent, child, mode, uid, gid); - kfree(child); - return child_node; -} - -bool VFS::exists(const char* pathname) -{ - return resolve_path(pathname) != nullptr; -} - -void VFS::mount(Node* mountpoint, Node* mounted) -{ - if (!mountpoint || !mounted) return; - if (mountpoint->flags & VFS_MOUNTPOINT || mounted->flags & VFS_MOUNTPOINT) return; - mountpoint->link = mounted; - mountpoint->flags |= VFS_MOUNTPOINT; -} - -void VFS::mount(const char* pathname, Node* mounted) -{ - return mount(resolve_path(pathname), mounted); -} - -void VFS::unmount(Node* mountpoint) -{ - if (!mountpoint) return; - if (!(mountpoint->flags & VFS_MOUNTPOINT)) return; - mountpoint->flags &= ~VFS_MOUNTPOINT; -} - -VFS::Node* VFS::readdir(VFS::Node* dir, long offset) -{ - if (!dir) return 0; - if (!dir->readdir_func) return 0; - return dir->readdir_func(dir, offset); -} - -bool VFS::can_execute(VFS::Node* node, int uid, int gid) -{ - if (uid == node->uid) return node->mode & 0100; - if (gid == node->gid) return node->mode & 0010; - return node->mode & 0001; -} - -bool VFS::can_write(VFS::Node* node, int uid, int gid) -{ - if (uid == node->uid) return node->mode & 0200; - if (gid == node->gid) return node->mode & 0020; - return node->mode & 0002; -} - -bool VFS::can_read(VFS::Node* node, int uid, int gid) -{ - if (uid == node->uid) return node->mode & 0400; - if (gid == node->gid) return node->mode & 0040; - return node->mode & 0004; -} - -bool VFS::is_setuid(VFS::Node* node) -{ - return node->mode & 04000; -} - -bool VFS::is_setgid(VFS::Node* node) -{ - return node->mode & 02000; -} \ No newline at end of file diff --git a/kernel/src/fs/devices/Console.cpp b/kernel/src/fs/devices/Console.cpp deleted file mode 100644 index 2eaeafc2..00000000 --- a/kernel/src/fs/devices/Console.cpp +++ /dev/null @@ -1,61 +0,0 @@ -#include "fs/devices/Console.h" -#include "config.h" -#include "render/TextRenderer.h" -#include "std/stdio.h" -#include "std/stdlib.h" -#include "std/string.h" - -char* conin_buffer = nullptr; -uint64_t conin_bufsize = 0; - -int ConsoleDevice::would_block(VFS::Node*) -{ - return conin_bufsize == 0; -} - -extern uint64_t clock_now(); - -VFS::Node* ConsoleDevice::create_new(const char* devname) -{ - VFS::Node* dev = new VFS::Node; - dev->write_func = ConsoleDevice::write; - dev->read_func = ConsoleDevice::read; - dev->block_func = ConsoleDevice::would_block; - dev->inode = 0; - dev->length = 0; - dev->type = VFS_DEVICE; - dev->flags = 0; - dev->tty = 1; - dev->uid = dev->gid = 0; - dev->mode = 0666; - dev->atime = dev->ctime = dev->mtime = clock_now(); - strncpy(dev->name, devname, sizeof(dev->name)); - return dev; -} - -ssize_t ConsoleDevice::write(VFS::Node* node, size_t, size_t size, const char* buffer) -{ - if (!node) return -1; - TextRenderer::write(buffer, size); - return (ssize_t)size; -} - -ssize_t ConsoleDevice::read(VFS::Node* node, size_t, size_t size, char* buffer) -{ - if (!node) return -1; - if (!conin_buffer) return 0; - if (size > conin_bufsize) size = conin_bufsize; - memcpy(buffer, conin_buffer, size); - memmove(conin_buffer, conin_buffer + size, conin_bufsize - size); - conin_bufsize -= size; - conin_buffer = (char*)krealloc(conin_buffer, conin_bufsize); - return (ssize_t)size; -} - -void ConsoleDevice::append(char c) -{ - conin_bufsize++; - conin_buffer = (char*)krealloc( - conin_buffer, conin_bufsize); // FIXME: We should probably not be calling realloc every time a key is pressed. - conin_buffer[conin_bufsize - 1] = c; -} \ No newline at end of file diff --git a/kernel/src/fs/devices/DeviceFS.cpp b/kernel/src/fs/devices/DeviceFS.cpp deleted file mode 100644 index d98cb00f..00000000 --- a/kernel/src/fs/devices/DeviceFS.cpp +++ /dev/null @@ -1,61 +0,0 @@ -#include "fs/devices/DeviceFS.h" -#include "fs/devices/Console.h" -#include "fs/devices/Framebuffer.h" -#include "fs/devices/Keyboard.h" -#include "fs/devices/NullDevice.h" -#include "fs/devices/Random.h" -#include "fs/devices/Serial.h" -#include "fs/devices/Version.h" -#include "std/stdlib.h" -#include "std/string.h" - -#define DEVFS_MAX_FILES 32 - -VFS::Node* devfs_root = nullptr; - -VFS::Node* devfs_files[DEVFS_MAX_FILES]; -int devfs_file_count = 0; - -extern uint64_t clock_boot(); - -VFS::Node* DeviceFS::get() -{ - if (devfs_root) return devfs_root; - devfs_root = new VFS::Node; - devfs_root->length = 0; - devfs_root->inode = 0; - devfs_root->type = VFS_DIRECTORY; - devfs_root->find_func = DeviceFS::finddir; - devfs_root->readdir_func = DeviceFS::readdir; - devfs_root->mode = 0755; - devfs_root->uid = devfs_root->gid = 0; - devfs_root->atime = devfs_root->ctime = devfs_root->mtime = clock_boot(); - strncpy(devfs_root->name, "dev", sizeof(devfs_root->name)); - - devfs_files[devfs_file_count++] = VersionDevice::create_new("version"); - devfs_files[devfs_file_count++] = ConsoleDevice::create_new("console"); - devfs_files[devfs_file_count++] = SerialDevice::create_new("serial"); - devfs_files[devfs_file_count++] = RandomDevice::create_new("random"); - devfs_files[devfs_file_count++] = KeyboardDevice::create_new("kbd"); - devfs_files[devfs_file_count++] = NullDevice::create_new("null"); - devfs_files[devfs_file_count++] = FramebufferDevice::create_new("fb0"); - devfs_root->length = devfs_file_count; - return devfs_root; -} - -VFS::Node* DeviceFS::finddir(VFS::Node* node, const char* filename) -{ - if (!node) return 0; - for (int i = 0; i < devfs_file_count; i++) - { - if (strncmp(devfs_files[i]->name, filename, sizeof(VFS::Node::name)) == 0) { return devfs_files[i]; } - } - return 0; -} - -VFS::Node* DeviceFS::readdir(VFS::Node* node, long offset) -{ - if (!node) return 0; - if (offset >= devfs_file_count) return 0; - return devfs_files[offset]; -} \ No newline at end of file diff --git a/kernel/src/fs/devices/Framebuffer.cpp b/kernel/src/fs/devices/Framebuffer.cpp deleted file mode 100644 index b6175650..00000000 --- a/kernel/src/fs/devices/Framebuffer.cpp +++ /dev/null @@ -1,71 +0,0 @@ -#include "fs/devices/Framebuffer.h" -#include "bootboot.h" -#include "memory/MemoryManager.h" -#include "misc/utils.h" -#include "std/errno.h" -#include "std/stdio.h" -#include "std/stdlib.h" -#include "std/string.h" -#include "utils/Addresses.h" - -extern BOOTBOOT bootboot; -extern char fb[1]; - -#define MAP_FAIL(errno) 0xffffffffffffff00 | (unsigned char)(errno) - -extern uint64_t clock_now(); - -VFS::Node* FramebufferDevice::create_new(const char* devname) -{ - VFS::Node* dev = new VFS::Node; - dev->write_func = FramebufferDevice::write; - dev->mmap_func = FramebufferDevice::mmap; - dev->ioctl_func = FramebufferDevice::ioctl; - dev->inode = 0; - dev->length = 0; - dev->type = VFS_DEVICE; - dev->flags = 0; - dev->uid = dev->gid = 0; - dev->mode = 0222; - dev->atime = dev->ctime = dev->mtime = clock_now(); - strncpy(dev->name, devname, sizeof(dev->name)); - return dev; -} - -uintptr_t FramebufferDevice::mmap(VFS::Node* node, uintptr_t addr, size_t size, int prot, off_t offset) -{ - if (!node) return -1; - int real_prot = prot & ~(MAP_AS_OWNED_BY_TASK); - if (round_down_to_nearest_page(offset) != (uintptr_t)offset) { return MAP_FAIL(EINVAL); } - if ((size + offset) > bootboot.fb_size) - { - return MAP_FAIL(ERANGE); // FIXME: Should probably be EOVERFLOW. - } - MemoryManager::map_several_pages(bootboot.fb_ptr + offset, addr, Utilities::get_blocks_from_size(PAGE_SIZE, size), - real_prot); - return addr; -} - -ssize_t FramebufferDevice::write(VFS::Node* node, size_t offset, size_t size, const char* buffer) -{ - if (!node) return -1; - if ((size + offset) > (uint64_t)bootboot.fb_size) { size = (uint64_t)bootboot.fb_size - offset; } - memcpy(fb + offset, buffer, size); - return (ssize_t)size; -} - -#define FB_GET_WIDTH 0 -#define FB_GET_HEIGHT 1 -#define FB_GET_SCANLINE 2 - -long FramebufferDevice::ioctl(VFS::Node* node, int cmd, uintptr_t) -{ - if (!node) return -1; - switch (cmd) - { - case FB_GET_WIDTH: return (long)bootboot.fb_width; - case FB_GET_HEIGHT: return (long)bootboot.fb_height; - case FB_GET_SCANLINE: return (long)bootboot.fb_scanline; - default: return -EINVAL; - } -} \ No newline at end of file diff --git a/kernel/src/fs/devices/Keyboard.cpp b/kernel/src/fs/devices/Keyboard.cpp deleted file mode 100644 index 8a1813d4..00000000 --- a/kernel/src/fs/devices/Keyboard.cpp +++ /dev/null @@ -1,56 +0,0 @@ -#define MODULE "kbd" - -#include "fs/devices/Keyboard.h" -#include "config.h" -#include "log/Log.h" -#include "render/TextRenderer.h" -#include "std/stdio.h" -#include "std/stdlib.h" -#include "std/string.h" - -char* kbd_buffer = nullptr; -uint64_t kbd_bufsize = 0; - -int KeyboardDevice::would_block(VFS::Node*) -{ - return kbd_bufsize == 0; -} - -extern uint64_t clock_boot(); - -VFS::Node* KeyboardDevice::create_new(const char* devname) -{ - VFS::Node* dev = new VFS::Node; - dev->read_func = KeyboardDevice::read; - dev->block_func = KeyboardDevice::would_block; - dev->inode = 0; - dev->length = 0; - dev->type = VFS_DEVICE; - dev->flags = 0; - dev->tty = 1; - dev->uid = dev->gid = 0; - dev->mode = 0444; - dev->atime = dev->ctime = dev->mtime = clock_boot(); - strncpy(dev->name, devname, sizeof(dev->name)); - return dev; -} - -ssize_t KeyboardDevice::read(VFS::Node* node, size_t, size_t size, char* buffer) -{ - if (!node) return -1; - if (!kbd_buffer) return 0; - if (size > kbd_bufsize) size = kbd_bufsize; - memcpy(buffer, kbd_buffer, size); - memmove(kbd_buffer, kbd_buffer + size, kbd_bufsize - size); - kbd_bufsize -= size; - kbd_buffer = (char*)krealloc(kbd_buffer, kbd_bufsize); - return (ssize_t)size; -} - -void KeyboardDevice::append(char c) -{ - kbd_bufsize++; - kbd_buffer = (char*)krealloc( - kbd_buffer, kbd_bufsize); // FIXME: We should probably not be calling realloc every time a key is pressed. - kbd_buffer[kbd_bufsize - 1] = c; -} \ No newline at end of file diff --git a/kernel/src/fs/devices/NullDevice.cpp b/kernel/src/fs/devices/NullDevice.cpp deleted file mode 100644 index b49b578c..00000000 --- a/kernel/src/fs/devices/NullDevice.cpp +++ /dev/null @@ -1,34 +0,0 @@ -#include "fs/devices/NullDevice.h" -#include "std/stdio.h" -#include "std/stdlib.h" -#include "std/string.h" - -extern uint64_t clock_boot(); - -VFS::Node* NullDevice::create_new(const char* devname) -{ - VFS::Node* dev = new VFS::Node; - dev->write_func = NullDevice::write; - dev->read_func = NullDevice::read; - dev->inode = 0; - dev->length = 0; - dev->type = VFS_DEVICE; - dev->flags = 0; - dev->uid = dev->gid = 0; - dev->mode = 0666; - dev->atime = dev->ctime = dev->mtime = clock_boot(); - strncpy(dev->name, devname, sizeof(dev->name)); - return dev; -} - -ssize_t NullDevice::write(VFS::Node* node, size_t, size_t size, const char*) -{ - if (!node) return -1; - return (ssize_t)size; -} - -ssize_t NullDevice::read(VFS::Node* node, size_t, size_t, char*) -{ - if (!node) return -1; - return 0; -} \ No newline at end of file diff --git a/kernel/src/fs/devices/Random.cpp b/kernel/src/fs/devices/Random.cpp deleted file mode 100644 index 0cc8c27b..00000000 --- a/kernel/src/fs/devices/Random.cpp +++ /dev/null @@ -1,43 +0,0 @@ -#include "fs/devices/Random.h" -#include "config.h" -#include "rand/Mersenne.h" -#include "render/TextRenderer.h" -#include "std/stdio.h" -#include "std/stdlib.h" -#include "std/string.h" - -extern uint64_t clock_boot(); - -VFS::Node* RandomDevice::create_new(const char* devname) -{ - VFS::Node* dev = new VFS::Node; - dev->read_func = RandomDevice::read; - dev->inode = 0; - dev->length = 0; - dev->type = VFS_DEVICE; - dev->flags = 0; - dev->uid = dev->gid = 0; - dev->mode = 0444; - dev->atime = dev->ctime = dev->mtime = clock_boot(); - strncpy(dev->name, devname, sizeof(dev->name)); - return dev; -} - -ssize_t RandomDevice::read(VFS::Node* node, size_t, size_t size, char* buffer) -{ - if (!node) return -1; - size_t nread = size; - while (size >= sizeof(uint64_t)) - { - *(uint64_t*)buffer = Mersenne::get(); - size -= sizeof(uint64_t); - buffer += sizeof(uint64_t); - } - while (size) - { - *buffer = (char)(Mersenne::get() & 0xFF); - size--; - buffer++; - } - return (ssize_t)nread; -} \ No newline at end of file diff --git a/kernel/src/fs/devices/Serial.cpp b/kernel/src/fs/devices/Serial.cpp deleted file mode 100644 index b8675fff..00000000 --- a/kernel/src/fs/devices/Serial.cpp +++ /dev/null @@ -1,30 +0,0 @@ -#include "io/Serial.h" -#include "config.h" -#include "fs/devices/Serial.h" -#include "std/stdio.h" -#include "std/stdlib.h" -#include "std/string.h" - -extern uint64_t clock_boot(); - -VFS::Node* SerialDevice::create_new(const char* devname) -{ - VFS::Node* dev = new VFS::Node; - dev->write_func = SerialDevice::write; - dev->inode = 0; - dev->length = 0; - dev->type = VFS_DEVICE; - dev->flags = 0; - dev->uid = dev->gid = 0; - dev->mode = 0222; - dev->atime = dev->ctime = dev->mtime = clock_boot(); - strncpy(dev->name, devname, sizeof(dev->name)); - return dev; -} - -ssize_t SerialDevice::write(VFS::Node* node, size_t, size_t size, const char* buffer) -{ - if (!node) return -1; - Serial::write(buffer, size); - return (ssize_t)size; -} \ No newline at end of file diff --git a/kernel/src/fs/devices/Version.cpp b/kernel/src/fs/devices/Version.cpp deleted file mode 100644 index 0a1ac394..00000000 --- a/kernel/src/fs/devices/Version.cpp +++ /dev/null @@ -1,30 +0,0 @@ -#include "fs/devices/Version.h" -#include "config.h" -#include "std/stdio.h" -#include "std/stdlib.h" -#include "std/string.h" - -extern uint64_t clock_boot(); - -VFS::Node* VersionDevice::create_new(const char* devname) -{ - VFS::Node* dev = new VFS::Node; - dev->read_func = VersionDevice::read; - dev->inode = 0; - dev->length = strlen(moon_version()) + 5; - dev->type = VFS_DEVICE; - dev->flags = 0; - dev->uid = dev->gid = 0; - dev->mode = 0444; - dev->atime = dev->ctime = dev->mtime = clock_boot(); - strncpy(dev->name, devname, sizeof(dev->name)); - return dev; -} - -ssize_t VersionDevice::read(VFS::Node* node, size_t offset, size_t size, char* buffer) -{ - if (!node) return -1; - if (offset > 0) return 0; // EOF after first read (FIXME: Should be only if everything was read) - snprintf(buffer, size + 1, "moon %s", moon_version()); // FIXME: Support offseting this read - return (ssize_t)size; -} \ No newline at end of file diff --git a/kernel/src/gdt/GDT.asm b/kernel/src/gdt/GDT.asm deleted file mode 100644 index 171debdb..00000000 --- a/kernel/src/gdt/GDT.asm +++ /dev/null @@ -1,21 +0,0 @@ -global load_gdt -load_gdt: - cli - lgdt [rdi] - mov ax, 0x10 - mov ds, ax - mov es, ax - mov fs, ax - mov gs, ax - mov ss, ax - push 0x08 - lea rax, [rel .reload_CS] - push rax - retfq -.reload_CS: - ret -global load_tr -load_tr: - mov rax, rdi - ltr ax - ret \ No newline at end of file diff --git a/kernel/src/gdt/GDT.cpp b/kernel/src/gdt/GDT.cpp deleted file mode 100644 index 0c2ecca4..00000000 --- a/kernel/src/gdt/GDT.cpp +++ /dev/null @@ -1,114 +0,0 @@ -#define MODULE "gdt" - -#include "gdt/GDT.h" -#include "log/Log.h" -#include "memory/MemoryManager.h" -#include "std/ensure.h" -#include "std/string.h" -#include "utils/Addresses.h" -#include - -struct GDTR -{ - uint16_t size; - uint64_t offset; -} __attribute__((packed)); - -struct GDTEntry -{ - uint16_t limit0; - uint16_t base0; - uint8_t base1; - uint8_t access; - uint8_t limit1_flags; - uint8_t base2; -} __attribute__((packed)); - -struct HighGDTEntry -{ - uint32_t base_high; - uint32_t reserved; -} __attribute__((packed)); - -struct TSS -{ - uint32_t reserved0; - uint64_t rsp[3]; - uint64_t reserved1; - uint64_t ist[7]; - uint64_t reserved2; - uint16_t reserved3; - uint16_t iomap_base; -} __attribute__((packed)); - -struct InternalGDT -{ - GDTEntry null; - GDTEntry kernel_code; - GDTEntry kernel_data; - GDTEntry user_code; - GDTEntry user_data; - GDTEntry tss; - HighGDTEntry tss2; -} __attribute__((packed)) __attribute((aligned(PAGE_SIZE))); - -__attribute__((aligned(PAGE_SIZE))) static InternalGDT internal_gdt = {{0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00}, - {0xffff, 0x0000, 0x00, 0x9a, 0xaf, 0x00}, - {0xffff, 0x0000, 0x00, 0x92, 0xcf, 0x00}, - {0xffff, 0x0000, 0x00, 0xfa, 0xaf, 0x00}, - {0xffff, 0x0000, 0x00, 0xf2, 0xcf, 0x00}, - {0x0000, 0x0000, 0x00, 0xe9, 0x0f, 0x00}, - {0x00000000, 0x00000000}}; - -static TSS main_tss; - -extern "C" void load_gdt(GDTR* gdtr); -extern "C" void load_tr(int segment); - -static void set_base(GDTEntry* entry, uint32_t base) -{ - entry->base0 = (base & 0xFFFF); - entry->base1 = (base >> 16) & 0xFF; - entry->base2 = (uint8_t)((base >> 24) & 0xFF); -} - -static void set_limit(GDTEntry* entry, uint32_t limit) -{ - ensure(limit <= 0xFFFFF); - entry->limit0 = limit & 0xFFFF; - entry->limit1_flags = (entry->limit1_flags & 0xF0) | ((limit >> 16) & 0xF); -} - -static void set_tss_base(GDTEntry* tss1, HighGDTEntry* tss2, uint64_t addr) -{ - set_base(tss1, addr & 0xffffffff); - tss2->base_high = (uint32_t)(addr >> 32); -} - -static void setup_tss() -{ - memset(&main_tss, 0, sizeof(TSS)); - main_tss.rsp[0] = get_top_of_stack((uint64_t)MemoryManager::get_pages(4).release_value(), - 4); // FIXME: Propagate errors, we should use 1 kernel stack - // per task, and it probably shouldn't be so big. - main_tss.iomap_base = sizeof(TSS); - set_tss_base(&internal_gdt.tss, &internal_gdt.tss2, (uint64_t)&main_tss); - set_limit(&internal_gdt.tss, sizeof(TSS) - 1); -} - -static void load_tss() -{ - kdbgln("Loading TR (GDT entry 0x2b)"); - load_tr(0x2b); -} - -void GDT::load() -{ - static GDTR gdtr; - gdtr.offset = (uint64_t)&internal_gdt; - gdtr.size = sizeof(InternalGDT); - setup_tss(); - kdbgln("Loading GDT at offset %lx, size %d", gdtr.offset, gdtr.size); - load_gdt(&gdtr); - load_tss(); -} \ No newline at end of file diff --git a/kernel/src/init/Init.cpp b/kernel/src/init/Init.cpp deleted file mode 100644 index 15ba82c1..00000000 --- a/kernel/src/init/Init.cpp +++ /dev/null @@ -1,116 +0,0 @@ -#define MODULE "init" - -#include "init/Init.h" -#include "bootboot.h" -#include "cpu/CPU.h" -#include "fs/InitRD.h" -#include "interrupts/Interrupts.h" -#include "io/Serial.h" -#include "log/Log.h" -#include "memory/MemoryManager.h" -#include "memory/PMM.h" -#include "memory/VMM.h" -#include "misc/MSR.h" -#include "misc/hang.h" -#include "rand/Init.h" -#include "rand/Mersenne.h" -#include "render/Framebuffer.h" -#include "render/TextRenderer.h" -#include "std/ensure.h" -#include "std/string.h" -#include "utils/Time.h" - -extern BOOTBOOT bootboot; -extern "C" char environment[4096]; -extern uintptr_t fb; - -uintptr_t __stack_chk_guard = 0xfeff34; - -void Init::check_magic() -{ - if (strncmp((char*)bootboot.magic, BOOTBOOT_MAGIC, 4) != 0) hang(); -} - -void Init::disable_smp() -{ - if (CPU::get_initial_apic_id() != bootboot.bspid) { hang(); } - return; -} - -extern "C" void asm_enable_sse(); -extern void clock_init(); - -extern void panic_prepare_keyboard_triple_fault(); - -#define NO_EXECUTE_ENABLED (1 << 11) - -static void check_and_enable_nx() -{ - if (!CPU::has_nx()) - { - kerrorln("This machine does not support the NX feature, which is required to continue booting."); - kerrorln("On most cases, this means your machine is too old and not supported."); - - kinfoln("Press any key to restart and select an OS that is suitable for your CPU."); - - panic_prepare_keyboard_triple_fault(); - - while (1) halt(); - } - - kdbgln("nx supported"); - - MSR efer(IA32_EFER_MSR); - - uint64_t value = efer.read(); - - if (value & NO_EXECUTE_ENABLED) - { - kdbgln("nx already enabled"); - return; - } - - kdbgln("nx not enabled, enabling it"); - - efer.write(value | NO_EXECUTE_ENABLED); -} - -void Init::early_init() -{ - Interrupts::disable(); - asm volatile("cld"); - - asm_enable_sse(); - - framebuffer0.init((void*)&fb, bootboot.fb_type, bootboot.fb_scanline, bootboot.fb_width, bootboot.fb_height); - - check_and_enable_nx(); - - MemoryManager::init(); - - MemoryManager::protect_kernel_sections(); - - if (strstr(environment, "quiet=1")) - { - KernelLog::toggle_log_level(LogLevel::DEBUG); - KernelLog::toggle_log_level(LogLevel::INFO); - } - else if (!strstr(environment, "verbose=1")) { KernelLog::toggle_log_level(LogLevel::DEBUG); } - - clock_init(); - - InitRD::init(); - - Mersenne::init(); - - kdbgln("Page bitmap uses %ld bytes of memory", PMM::get_bitmap_size()); - - __stack_chk_guard = Mersenne::get(); -} - -void Init::finish_kernel_boot() -{ - KernelLog::toggle_log_backend(Backend::Console); - framebuffer0.clear(Color::Black); - TextRenderer::reset(); -} \ No newline at end of file diff --git a/kernel/src/interrupts/Entry.cpp b/kernel/src/interrupts/Entry.cpp deleted file mode 100644 index d69750e6..00000000 --- a/kernel/src/interrupts/Entry.cpp +++ /dev/null @@ -1,69 +0,0 @@ -#define MODULE "isr" - -#include "interrupts/Context.h" -#include "interrupts/IRQ.h" -#include "interrupts/Interrupts.h" -#include "io/Serial.h" -#include "log/Log.h" -#include "memory/VMM.h" -#include "misc/hang.h" -#include "panic/Panic.h" -#include "std/ensure.h" -#include "std/stdio.h" -#include "sys/Syscall.h" -#include "thread/Scheduler.h" -#include "trace/StackTracer.h" -#include "utils/PageFaultReason.h" - -extern "C" void common_handler(Context* context) -{ - ensure(Interrupts::is_in_handler()); - if (context->number >= 0x20 && context->number < 0x30) - { - IRQ::interrupt_handler(context); - return; - } - if (context->number == 13) - { - Interrupts::disable(); - - if (context->cs == 0x8) { int_panic(context, "GPF in kernel task"); } - else - { - VMM::enter_syscall_context(); - - kerrorln("General protection fault at RIP %lx, cs %ld, ss %ld, RSP %lx, error code %ld", context->rip, - context->cs, context->ss, context->rsp, context->error_code); - kinfoln("Stack trace:"); - - StackTracer tracer(context->rbp); - tracer.trace_with_ip(context->rip); - Scheduler::task_misbehave(context, -2); - } - } - if (context->number == 14) - { - Interrupts::disable(); - - if (context->cs == 0x8) { int_panic(context, "Page fault in kernel task"); } - else - { - VMM::enter_syscall_context(); - - kerrorln("Page fault in ring 3 (RIP %lx), while trying to access %lx, error code %ld", context->rip, - context->cr2, context->error_code); - kinfoln("Stack trace:"); - - StackTracer tracer(context->rbp); - tracer.trace_with_ip(context->rip); - - determine_user_page_fault_reason(context->cr2); - - Scheduler::task_misbehave(context, -3); - } - } - if (context->number == 8) { int_panic(context, "Double fault, halting"); } - if (context->number == 66) { Syscall::entry(context); } - if (context->number == 256) { kwarnln("Unused interrupt"); } - return; -} \ No newline at end of file diff --git a/kernel/src/interrupts/IDT.cpp b/kernel/src/interrupts/IDT.cpp deleted file mode 100644 index 4fba0569..00000000 --- a/kernel/src/interrupts/IDT.cpp +++ /dev/null @@ -1,55 +0,0 @@ -#define MODULE "idt" - -#include "interrupts/IDT.h" -#include "log/Log.h" -#include "std/ensure.h" - -struct IDTEntry -{ - uint16_t offset0; - uint16_t selector; - uint8_t ist; - uint8_t type_attr; - uint16_t offset1; - uint32_t offset2; - uint32_t ignore; - void set_offset(uint64_t offset); - uint64_t get_offset(); -}; - -static IDTEntry entries[256]; - -void IDTEntry::set_offset(uint64_t offset) -{ - offset0 = (uint16_t)(offset & 0x000000000000ffff); - offset1 = (uint16_t)((offset & 0x00000000ffff0000) >> 16); - offset2 = (uint32_t)((offset & 0xffffffff00000000) >> 32); -} - -uint64_t IDTEntry::get_offset() -{ - uint64_t offset = 0; - offset |= (uint64_t)offset0; - offset |= (uint64_t)offset1 << 16; - offset |= (uint64_t)offset2 << 32; - return offset; -} - -void IDT::add_handler(short interrupt_number, void* handler, uint8_t type_attr) -{ - ensure(handler != nullptr); - ensure(interrupt_number < 256); - IDTEntry* entry_for_handler = &entries[interrupt_number]; - entry_for_handler->selector = 0x08; - entry_for_handler->type_attr = type_attr; - entry_for_handler->set_offset((uint64_t)handler); -} - -IDTR idtr; -void IDT::load() -{ - idtr.limit = 0x0FFF; - idtr.offset = (uint64_t)entries; - kdbgln("Loading IDT at offset %lx, limit %d", idtr.offset, idtr.limit); - asm("lidt %0" : : "m"(idtr)); -} \ No newline at end of file diff --git a/kernel/src/interrupts/IRQ.cpp b/kernel/src/interrupts/IRQ.cpp deleted file mode 100644 index 5dcf7d21..00000000 --- a/kernel/src/interrupts/IRQ.cpp +++ /dev/null @@ -1,37 +0,0 @@ -#define MODULE "irq" - -#include "interrupts/IRQ.h" -#include "fs/devices/Console.h" -#include "fs/devices/Keyboard.h" -#include "io/IO.h" -#include "io/PIC.h" -#include "log/Log.h" -#include "misc/Scancodes.h" -#include "rand/Init.h" -#include "std/stdio.h" -#include "thread/PIT.h" -#include "thread/Scheduler.h" - -void IRQ::interrupt_handler(Context* context) -{ - switch (context->irq_number) - { - case 0: - PIT::tick(); - Scheduler::task_tick(context); - break; - case 1: { - unsigned char scancode = IO::inb(0x60); - KeyboardDevice::append((char)scancode); - bool ignore = false; - char key = translate_scancode(scancode, &ignore); - if (ignore) break; - ConsoleDevice::append(key); - break; - } - default: kwarnln("Unhandled IRQ: %ld", context->irq_number); break; - } - Mersenne::reseed(); - PIC::send_eoi((unsigned char)(context->irq_number & 0xFF)); - return; -} \ No newline at end of file diff --git a/kernel/src/interrupts/Install.cpp b/kernel/src/interrupts/Install.cpp deleted file mode 100644 index 2025af3a..00000000 --- a/kernel/src/interrupts/Install.cpp +++ /dev/null @@ -1,112 +0,0 @@ -#include "interrupts/Install.h" -#include "interrupts/IDT.h" -#include "log/Log.h" - -extern "C" -{ - void unused(); - void isr0(); - void isr1(); - void isr2(); - void isr3(); - void isr4(); - void isr5(); - void isr6(); - void isr7(); - void isr8(); - void isr10(); - void isr11(); - void isr12(); - void isr13(); - void isr14(); - void isr16(); - void isr17(); - void isr18(); - void isr19(); - void isr20(); - void isr21(); - void isr28(); - void isr29(); - void isr30(); - void isr31(); - void isr32(); - void isr33(); - void isr34(); - void isr35(); - void isr36(); - void isr37(); - void isr38(); - void isr39(); - void isr40(); - void isr41(); - void isr42(); - void isr43(); - void isr44(); - void isr45(); - void isr46(); - void isr47(); - void isr66(); -} - -#define INSTALL_TRAP(x) IDT::add_handler(x, (void*)&isr##x, IDT_TA_TrapGate) -#define INSTALL_UNUSED(x) IDT::add_handler(x, (void*)&unused, IDT_TA_InterruptGate) -#define INSTALL_ISR(x) IDT::add_handler(x, (void*)&isr##x, IDT_TA_InterruptGate) -#define INSTALL_USER_ISR(x) IDT::add_handler(x, (void*)&isr##x, IDT_TA_InterruptGateUser) - -void Interrupts::install() -{ - kdbgln("Installing handler stubs for exceptions (ISRs 0-31)"); - INSTALL_TRAP(0); - INSTALL_TRAP(1); - INSTALL_TRAP(2); - INSTALL_TRAP(3); - INSTALL_TRAP(4); - INSTALL_TRAP(5); - INSTALL_TRAP(6); - INSTALL_TRAP(7); - INSTALL_TRAP(8); - INSTALL_UNUSED(9); - INSTALL_TRAP(10); - INSTALL_TRAP(11); - INSTALL_TRAP(12); - INSTALL_TRAP(13); - INSTALL_TRAP(14); - INSTALL_UNUSED(15); - INSTALL_TRAP(16); - INSTALL_TRAP(17); - INSTALL_TRAP(18); - INSTALL_TRAP(19); - INSTALL_TRAP(20); - INSTALL_TRAP(21); - INSTALL_UNUSED(22); - INSTALL_UNUSED(23); - INSTALL_UNUSED(24); - INSTALL_UNUSED(25); - INSTALL_UNUSED(26); - INSTALL_UNUSED(27); - INSTALL_TRAP(28); - INSTALL_TRAP(29); - INSTALL_TRAP(30); - INSTALL_UNUSED(31); - kdbgln("Installing handler stubs for IRQs (ISRs 32-47)"); - INSTALL_ISR(32); - INSTALL_ISR(33); - INSTALL_ISR(34); - INSTALL_ISR(35); - INSTALL_ISR(36); - INSTALL_ISR(37); - INSTALL_ISR(38); - INSTALL_ISR(39); - INSTALL_ISR(40); - INSTALL_ISR(41); - INSTALL_ISR(42); - INSTALL_ISR(43); - INSTALL_ISR(44); - INSTALL_ISR(45); - INSTALL_ISR(46); - INSTALL_ISR(47); - kdbgln("Installing unused handler stubs for the rest of the IDT"); - for (short i = 48; i < 256; i++) { INSTALL_UNUSED(i); } - kdbgln("Installing syscall handler stub"); - INSTALL_USER_ISR(66); -} \ No newline at end of file diff --git a/kernel/src/interrupts/InterruptEntry.asm b/kernel/src/interrupts/InterruptEntry.asm deleted file mode 100644 index 7ee280e0..00000000 --- a/kernel/src/interrupts/InterruptEntry.asm +++ /dev/null @@ -1,136 +0,0 @@ -%macro ISR 1 - global isr%1 - isr%1: - push byte 0 - push byte %1 - jmp asm_common -%endmacro - -%macro ISR_ERROR 1 - global isr%1 - isr%1: - push byte %1 - jmp asm_common -%endmacro - -%macro IRQ 2 - global isr%1 - isr%1: - push byte %2 - push byte %1 - jmp asm_common -%endmacro - -%macro SOFT 1 - global isr%1 - isr%1: - push byte 0 - push byte %1 - jmp asm_common -%endmacro - -global unused -unused: - push byte 0 - push 256 - jmp asm_common - -extern common_handler - -section .text -global asm_common -asm_common: - cld - push rax - push rbx - push rcx - push rdx - push rbp - push rdi - push rsi - push r8 - push r9 - push r10 - push r11 - push r12 - push r13 - push r14 - push r15 - - mov ax, ds - push rax - - mov r8, cr2 - push r8 - - mov rdi, rsp - - call common_handler - -global _asm_interrupt_exit -_asm_interrupt_exit: - - add rsp, 8 - - pop rax - mov ds, ax - mov es, ax - - pop r15 - pop r14 - pop r13 - pop r12 - pop r11 - pop r10 - pop r9 - pop r8 - pop rsi - pop rdi - pop rbp - pop rdx - pop rcx - pop rbx - pop rax - add rsp, 16 - iretq - -ISR 0 -ISR 1 -ISR 2 -ISR 3 -ISR 4 -ISR 5 -ISR 6 -ISR 7 -ISR_ERROR 8 -ISR_ERROR 10 -ISR_ERROR 11 -ISR_ERROR 12 -ISR_ERROR 13 -ISR_ERROR 14 -ISR 16 -ISR_ERROR 17 -ISR 18 -ISR 19 -ISR 20 -ISR_ERROR 21 -ISR 28 -ISR_ERROR 29 -ISR_ERROR 30 -IRQ 32, 0 -IRQ 33, 1 -IRQ 34, 2 -IRQ 35, 3 -IRQ 36, 4 -IRQ 37, 5 -IRQ 38, 6 -IRQ 39, 7 -IRQ 40, 8 -IRQ 41, 9 -IRQ 42, 10 -IRQ 43, 11 -IRQ 44, 12 -IRQ 45, 13 -IRQ 46, 14 -IRQ 47, 15 -SOFT 66 \ No newline at end of file diff --git a/kernel/src/interrupts/Interrupts.cpp b/kernel/src/interrupts/Interrupts.cpp deleted file mode 100644 index b57420d8..00000000 --- a/kernel/src/interrupts/Interrupts.cpp +++ /dev/null @@ -1,59 +0,0 @@ -#include "interrupts/Interrupts.h" -#include "trace/StackTracer.h" -#include "utils/Registers.h" - -void Interrupts::disable() -{ - asm volatile("cli"); -} - -void Interrupts::enable() -{ - asm volatile("sti"); -} - -extern int _asm_interrupt_exit; - -bool Interrupts::is_in_handler() -{ - return stack_trace_contains((uintptr_t)&_asm_interrupt_exit); -} - -void Interrupts::return_from_handler(Context* context) -{ - asm volatile("mov %0, %%rsp\n" - "jmp _asm_interrupt_exit" - : - : "r"(context)); -} - -bool Interrupts::are_enabled() -{ - return (read_rflags() & 0x200) > 0; -} - -static bool saved_interrupt_state; - -void Interrupts::push_and_disable() -{ - saved_interrupt_state = are_enabled(); - disable(); -} - -void Interrupts::push_and_enable() -{ - saved_interrupt_state = are_enabled(); - enable(); -} - -void Interrupts::pop() -{ - if (saved_interrupt_state && !are_enabled()) enable(); - else if (!saved_interrupt_state && are_enabled()) - disable(); -} - -bool Interrupts::were_enabled() -{ - return saved_interrupt_state; -} \ No newline at end of file diff --git a/kernel/src/io/IO.cpp b/kernel/src/io/IO.cpp deleted file mode 100644 index 5eb75688..00000000 --- a/kernel/src/io/IO.cpp +++ /dev/null @@ -1,42 +0,0 @@ -#include "io/IO.h" - -uint8_t IO::inb(uint16_t port) -{ - uint8_t result; - asm volatile("inb %1, %0" : "=a"(result) : "Nd"(port)); - return result; -} - -void IO::outb(uint16_t port, uint8_t value) -{ - asm volatile("outb %0, %1" : : "a"(value), "Nd"(port)); -} - -uint16_t IO::inw(uint16_t port) -{ - uint16_t result; - asm volatile("inw %1, %0" : "=a"(result) : "Nd"(port)); - return result; -} - -void IO::outw(uint16_t port, uint16_t value) -{ - asm volatile("outw %0, %1" : : "a"(value), "Nd"(port)); -} - -uint32_t IO::inl(uint16_t port) -{ - uint32_t result; - asm volatile("inl %1, %0" : "=a"(result) : "Nd"(port)); - return result; -} - -void IO::outl(uint16_t port, uint32_t value) -{ - asm volatile("outl %0, %1" : : "a"(value), "Nd"(port)); -} - -void IO::delay() -{ - asm volatile("outb %%al, $0x80" : : "a"(0)); -} \ No newline at end of file diff --git a/kernel/src/io/PCI.cpp b/kernel/src/io/PCI.cpp deleted file mode 100644 index f53ee653..00000000 --- a/kernel/src/io/PCI.cpp +++ /dev/null @@ -1,197 +0,0 @@ -#define MODULE "pci" - -#include "io/PCI.h" -#include "io/IO.h" -#include "log/Log.h" -#include "thread/Spinlock.h" - -#define PCI_ADDRESS 0xCF8 -#define PCI_VALUE 0xCFC - -Spinlock pci_lock; - -uint32_t PCI::raw_address(uint32_t bus, uint32_t slot, uint32_t function, int32_t offset) -{ - return 0x80000000 | (bus << 16) | (slot << 11) | (function << 8) | ((offset)&0xFC); -} - -void PCI::raw_write8(uint32_t bus, uint32_t slot, uint32_t function, int32_t offset, uint8_t value) -{ - IO::outl(PCI_ADDRESS, raw_address(bus, slot, function, offset)); - IO::outl(PCI_VALUE, (uint32_t)value); -} - -void PCI::raw_write16(uint32_t bus, uint32_t slot, uint32_t function, int32_t offset, uint16_t value) -{ - IO::outl(PCI_ADDRESS, raw_address(bus, slot, function, offset)); - IO::outl(PCI_VALUE, (uint32_t)value); -} - -void PCI::raw_write32(uint32_t bus, uint32_t slot, uint32_t function, int32_t offset, uint32_t value) -{ - IO::outl(PCI_ADDRESS, raw_address(bus, slot, function, offset)); - IO::outl(PCI_VALUE, value); -} - -uint8_t PCI::raw_read8(uint32_t bus, uint32_t slot, uint32_t function, int32_t offset) -{ - IO::outl(PCI_ADDRESS, raw_address(bus, slot, function, offset)); - return (uint8_t)(IO::inl(PCI_VALUE + (offset & 3)) & 0xFF); -} - -uint16_t PCI::raw_read16(uint32_t bus, uint32_t slot, uint32_t function, int32_t offset) -{ - IO::outl(PCI_ADDRESS, raw_address(bus, slot, function, offset)); - return (uint16_t)(IO::inl(PCI_VALUE + (offset & 2)) & 0xFFFF); -} - -uint32_t PCI::raw_read32(uint32_t bus, uint32_t slot, uint32_t function, int32_t offset) -{ - IO::outl(PCI_ADDRESS, raw_address(bus, slot, function, offset)); - return IO::inl(PCI_VALUE); -} - -PCI::DeviceID PCI::get_device_id(uint32_t bus, uint32_t slot, uint32_t function) -{ - uint16_t vendor = PCI::raw_read16(bus, slot, function, PCI_VENDOR_FIELD); - uint16_t device = PCI::raw_read16(bus, slot, function, PCI_DEVICE_FIELD); - return {vendor, device}; -} - -PCI::DeviceType PCI::get_device_type(uint32_t bus, uint32_t slot, uint32_t function) -{ - uint8_t dev_subclass = PCI::raw_read8(bus, slot, function, PCI_SUBCLASS_FIELD); - uint8_t dev_class = PCI::raw_read8(bus, slot, function, PCI_CLASS_FIELD); - uint8_t prog_if = PCI::raw_read8(bus, slot, function, PCI_PROG_IF_FIELD); - uint8_t revision = PCI::raw_read8(bus, slot, function, PCI_REVISION_ID_FIELD); - return {dev_class, dev_subclass, prog_if, revision}; -} - -static void pci_scan_bus(uint8_t bus, void (*callback)(PCI::Device&)) -{ - for (uint8_t slot = 0; slot < 32; slot++) - { - uint8_t num_functions = 1; - for (uint8_t function = 0; function < num_functions; function++) - { - PCI::DeviceID device_id = PCI::get_device_id(bus, slot, function); - if (device_id.vendor == 0xFFFF || device_id.device == 0xFFFF) continue; - PCI::DeviceType device_type = PCI::get_device_type(bus, slot, function); - uint8_t header = PCI::raw_read8(bus, slot, function, PCI_HEADER_TYPE_FIELD); - if (header & 0x80) // multi function device - { - num_functions = 8; - } - if ((header & 0x7F) == 1) - { - uint8_t sub_bus = PCI::raw_read8(bus, slot, function, PCI_SECONDARY_BUS_NUMBER_FIELD); - pci_scan_bus(sub_bus, callback); - } - PCI::Device device{device_id, device_type, bus, slot, function}; - pci_lock.release(); - callback(device); - pci_lock.acquire(); - } - } -} - -void PCI::scan(void (*callback)(PCI::Device&)) -{ - pci_lock.acquire(); - uint8_t function; - uint8_t bus; - - uint8_t header_type = PCI::raw_read8(0, 0, 0, PCI_HEADER_TYPE_FIELD); - if ((header_type & 0x80) == 0) - { - // Single PCI host controller - pci_scan_bus(0, callback); - } - else - { - // Multiple PCI host controllers - for (function = 0; function < 8; function++) - { - if (get_device_id(0, 0, function).vendor == 0xFFFF) break; - bus = function; - pci_scan_bus(bus, callback); - } - } - pci_lock.release(); -} - -PCI::Device::Device(const Device& other) - : m_id(other.m_id), m_type(other.m_type), m_bus(other.m_bus), m_slot(other.m_slot), m_function(other.m_function) -{ -} - -PCI::Device::Device(uint8_t bus, uint8_t slot, uint8_t function) : m_bus(bus), m_slot(slot), m_function(function) -{ - m_id = get_device_id(m_bus, m_slot, m_function); - m_type = get_device_type(m_bus, m_slot, m_function); -} - -PCI::Device::Device(DeviceID id, DeviceType type, uint8_t bus, uint8_t slot, uint8_t function) - : m_id(id), m_type(type), m_bus(bus), m_slot(slot), m_function(function) -{ -} - -void PCI::Device::write8(int32_t offset, uint8_t value) -{ - PCI::raw_write8(m_bus, m_slot, m_function, offset, value); -} - -void PCI::Device::write16(int32_t offset, uint16_t value) -{ - PCI::raw_write16(m_bus, m_slot, m_function, offset, value); -} - -void PCI::Device::write32(int32_t offset, uint32_t value) -{ - PCI::raw_write32(m_bus, m_slot, m_function, offset, value); -} - -uint8_t PCI::Device::read8(int32_t offset) -{ - return PCI::raw_read8(m_bus, m_slot, m_function, offset); -} - -uint16_t PCI::Device::read16(int32_t offset) -{ - return PCI::raw_read16(m_bus, m_slot, m_function, offset); -} - -uint32_t PCI::Device::read32(int32_t offset) -{ - return PCI::raw_read32(m_bus, m_slot, m_function, offset); -} - -uint32_t PCI::Device::getBAR0() -{ - return read32(PCI_BAR0_FIELD); -} - -uint32_t PCI::Device::getBAR1() -{ - return read32(PCI_BAR1_FIELD); -} - -uint32_t PCI::Device::getBAR2() -{ - return read32(PCI_BAR2_FIELD); -} - -uint32_t PCI::Device::getBAR3() -{ - return read32(PCI_BAR3_FIELD); -} - -uint32_t PCI::Device::getBAR4() -{ - return read32(PCI_BAR4_FIELD); -} - -uint32_t PCI::Device::getBAR5() -{ - return read32(PCI_BAR5_FIELD); -} \ No newline at end of file diff --git a/kernel/src/io/PIC.cpp b/kernel/src/io/PIC.cpp deleted file mode 100644 index 2aa553c6..00000000 --- a/kernel/src/io/PIC.cpp +++ /dev/null @@ -1,82 +0,0 @@ -#define MODULE "pic" - -#include "io/PIC.h" -#include "io/IO.h" -#include "log/Log.h" - -#define PIC1_COMMAND 0x20 -#define PIC1_DATA 0x21 -#define PIC2_COMMAND 0xA0 -#define PIC2_DATA 0xA1 -#define PIC_EOI 0x20 - -#define ICW1_INIT 0x10 -#define ICW1_ICW4 0x01 -#define ICW4_8086 0x01 - -void PIC::remap() -{ - kdbgln("Remapping PIC"); - uint8_t a1, a2; - - a1 = IO::inb(PIC1_DATA); - IO::delay(); - a2 = IO::inb(PIC2_DATA); - IO::delay(); - - IO::outb(PIC1_COMMAND, ICW1_INIT | ICW1_ICW4); - IO::delay(); - IO::outb(PIC2_COMMAND, ICW1_INIT | ICW1_ICW4); - IO::delay(); - - kdbgln("Remapping master PIC to ISRs 32-39"); - IO::outb(PIC1_DATA, 0x20); - IO::delay(); - kdbgln("Remapping slave PIC to ISRs 40-47"); - IO::outb(PIC2_DATA, 0x28); - IO::delay(); - - IO::outb(PIC1_DATA, 4); - IO::delay(); - IO::outb(PIC2_DATA, 2); - IO::delay(); - - IO::outb(PIC1_DATA, ICW4_8086); - IO::delay(); - IO::outb(PIC2_DATA, ICW4_8086); - IO::delay(); - - IO::outb(PIC1_DATA, a1); - IO::delay(); - IO::outb(PIC2_DATA, a2); -} - -void PIC::enable_master(uint8_t mask) -{ - kdbgln("Setting mask of master PIC to 0x%x", mask); - IO::outb(PIC1_DATA, mask); -} - -void PIC::enable_slave(uint8_t mask) -{ - kdbgln("Setting mask of slave PIC to 0x%x", mask); - IO::outb(PIC2_DATA, mask); -} - -void PIC::end_master() -{ - IO::outb(PIC1_COMMAND, PIC_EOI); -} - -void PIC::end_slave() -{ - IO::outb(PIC2_COMMAND, PIC_EOI); - IO::outb(PIC1_COMMAND, PIC_EOI); -} - -void PIC::send_eoi(unsigned char irq) -{ - if (irq >= 8) end_slave(); - else - end_master(); -} \ No newline at end of file diff --git a/kernel/src/io/Serial.cpp b/kernel/src/io/Serial.cpp deleted file mode 100644 index 753d368a..00000000 --- a/kernel/src/io/Serial.cpp +++ /dev/null @@ -1,49 +0,0 @@ -#include "io/Serial.h" -#include "io/IO.h" -#include -#include - -#define COM1 0x3f8 - -void Serial::wait() -{ - while (!(IO::inb(COM1 + 5) & 0x20)) { asm volatile("pause"); } -} - -void Serial::write(const char* string, size_t size) -{ - for (size_t i = 0; i < size; i++) - { - wait(); - IO::outb(COM1, *(string + i)); - } -} - -void Serial::print(const char* string) -{ - Serial::write(string, strlen(string)); -} - -void Serial::println(const char* string) -{ - Serial::write(string, strlen(string)); - wait(); - IO::outb(COM1, '\n'); -} - -static const char* format_color(Color& color) -{ - static char output[20]; - snprintf(output, sizeof(output), "\x1b[38;2;%d;%d;%dm", color.red, color.green, color.blue); - return output; -} - -void Serial::set_color(Color& color) -{ - Serial::print(format_color(color)); -} - -void Serial::reset_color() -{ - Serial::print("\x1b[0m"); -} \ No newline at end of file diff --git a/kernel/src/log/CLog.cpp b/kernel/src/log/CLog.cpp deleted file mode 100644 index 7c62e565..00000000 --- a/kernel/src/log/CLog.cpp +++ /dev/null @@ -1,56 +0,0 @@ -#include "log/CLog.h" -#include "std/stdio.h" -#include - -enum class LogLevel -{ - DEBUG, - INFO, - WARN, - ERROR -}; - -enum class Backend -{ - Serial, - Console -}; - -namespace KernelLog -{ - void log(const char* function, LogLevel level, const char* message, ...) PRINTF_LIKE(3, 4); - void logln(const char* function, LogLevel level, const char* message, ...) PRINTF_LIKE(3, 4); -} - -void log_backend_serial(const char* function, LogLevel level, const char* message, va_list origin); -void log_backend_console(const char* function, LogLevel level, const char* message, va_list origin); -bool log_level_enabled(LogLevel level); -bool log_backend_enabled(Backend backend); - -extern "C" void clog_log(const char* function, enum log_level level, const char* message, ...) -{ - if (!log_level_enabled((LogLevel)level)) return; - va_list ap; - va_start(ap, message); - if (log_backend_enabled(Backend::Serial)) log_backend_serial(function, (LogLevel)level, message, ap); - if (log_backend_enabled(Backend::Console)) log_backend_console(function, (LogLevel)level, message, ap); - va_end(ap); -} - -extern "C" void clog_logln(const char* function, enum log_level level, const char* message, ...) -{ - if (!log_level_enabled((LogLevel)level)) return; - va_list ap; - va_start(ap, message); - if (log_backend_enabled(Backend::Serial)) - { - log_backend_serial(function, (LogLevel)level, message, ap); - printf("\n"); - } - if (log_backend_enabled(Backend::Console)) - { - log_backend_console(function, (LogLevel)level, message, ap); - kprintf("\n"); - } - va_end(ap); -} \ No newline at end of file diff --git a/kernel/src/log/Log.cpp b/kernel/src/log/Log.cpp deleted file mode 100644 index 13df22ea..00000000 --- a/kernel/src/log/Log.cpp +++ /dev/null @@ -1,94 +0,0 @@ -#include "log/Log.h" -#include "io/Serial.h" -#include "std/stdio.h" -#include "thread/PIT.h" -#include "thread/Scheduler.h" -#include - -static int level_mask = 15; -static int backend_mask = 3; - -bool log_level_enabled(LogLevel level) -{ - return level_mask & (1 << (int)level); -} - -bool log_backend_enabled(Backend backend) -{ - return backend_mask & (1 << (int)backend); -} - -void log_backend_serial(const char* function, LogLevel level, const char* message, va_list origin) -{ - va_list ap; - va_copy(ap, origin); - Serial::reset_color(); - if (Scheduler::current_task() && Scheduler::current_task()->id) - { - Task* current_task = Scheduler::current_task(); - printf("[%ld.%ld] (%s %ld) %s: ", PIT::ms_since_boot / 1000, PIT::ms_since_boot % 1000, current_task->name, - current_task->id, function); - } - else { printf("[%ld.%ld] (kernel) %s: ", PIT::ms_since_boot / 1000, PIT::ms_since_boot % 1000, function); } - switch (level) - { - case LogLevel::WARN: Serial::set_color(Color::Yellow); break; - case LogLevel::ERROR: Serial::set_color(Color::Red); break; - default: break; - } - vprintf(message, ap); - Serial::reset_color(); - va_end(ap); -} - -void log_backend_console(const char* function, [[maybe_unused]] LogLevel level, const char* message, va_list origin) -{ - va_list ap; - va_copy(ap, origin); - kprintf("%s: ", function); - vkprintf(message, ap); - va_end(ap); -} - -void KernelLog::log(const char* function, LogLevel level, const char* message, ...) -{ - if (!log_level_enabled(level)) return; - va_list ap; - va_start(ap, message); - if (log_backend_enabled(Backend::Serial)) log_backend_serial(function, level, message, ap); - if (log_backend_enabled(Backend::Console)) log_backend_console(function, level, message, ap); - va_end(ap); -} - -void KernelLog::logln(const char* function, LogLevel level, const char* message, ...) -{ - if (!log_level_enabled(level)) return; - va_list ap; - va_start(ap, message); - if (log_backend_enabled(Backend::Serial)) - { - log_backend_serial(function, level, message, ap); - printf("\n"); - } - if (log_backend_enabled(Backend::Console)) - { - log_backend_console(function, level, message, ap); - kprintf("\n"); - } - va_end(ap); -} - -void KernelLog::toggle_log_level(LogLevel level) -{ - level_mask ^= (1 << (int)level); -} - -void KernelLog::toggle_log_backend(Backend backend) -{ - backend_mask ^= (1 << (int)backend); -} - -void KernelLog::enable_log_backend(Backend backend) -{ - backend_mask |= (1 << (int)backend); -} \ No newline at end of file diff --git a/kernel/src/main.asm b/kernel/src/main.asm deleted file mode 100644 index 4593a076..00000000 --- a/kernel/src/main.asm +++ /dev/null @@ -1,40 +0,0 @@ -global _main -extern _start - -_main: - xor rbp, rbp - call _start - cli -.hang: - hlt - jmp .hang - -global idle_task_function -idle_task_function: - sti -.idle: - hlt - jmp .idle - -global asm_enable_sse -asm_enable_sse: - mov rax, cr0 - and ax, 0xFFFB - or ax, 0x2 - mov cr0, rax - mov rax, cr4 - or ax, 3 << 9 - mov cr4, rax - ret - -global asm_get_rflags -asm_get_rflags: - pushfq - pop rax - ret - -global asm_set_rflags -asm_set_rflags: - push rdi - popfq - ret \ No newline at end of file diff --git a/kernel/src/main.cpp b/kernel/src/main.cpp index f12e9e7c..abf41426 100644 --- a/kernel/src/main.cpp +++ b/kernel/src/main.cpp @@ -1,80 +1,7 @@ -#define MODULE "main" - -#include "config.h" -#include "cpu/CPU.h" -#include "fs/TmpFS.h" -#include "fs/devices/DeviceFS.h" -#include "gdt/GDT.h" -#include "init/Init.h" -#include "interrupts/IDT.h" -#include "interrupts/Install.h" -#include "interrupts/Interrupts.h" -#include "io/PIC.h" -#include "log/Log.h" -#include "memory/Memory.h" -#include "memory/MemoryMap.h" -#include "misc/hang.h" -#include "std/ensure.h" -#include "std/stdlib.h" -#include "thread/PIT.h" -#include "thread/Scheduler.h" - -#define STRINGIZE(x) #x -#define STRINGIZE_VALUE_OF(x) STRINGIZE(x) +#include extern "C" void _start() { - Init::disable_smp(); // Put all other cores except the bootstrap one in an infinite loop - Init::check_magic(); - Init::early_init(); - - kinfoln("Starting Moon %s", moon_version()); - - CPU::log_cpu_information(); - - Memory::walk_memory_map(); - - GDT::load(); - - Interrupts::install(); - - IDT::load(); - - PIT::initialize(1000); // 1000 times per second - - Scheduler::init(); - -#ifdef RUN_TEST_AS_INIT - ensure(Scheduler::load_user_task(STRINGIZE_VALUE_OF(RUN_TEST_AS_INIT)) > 0); -#else - ensure(Scheduler::load_user_task("/bin/init") > 0); -#endif - - Scheduler::add_kernel_task("[reaper]", []() { - while (1) - { - sleep(400); - Scheduler::reap_tasks(); - } - }); - - ensure(VFS::mkdir("/dev") == 0); - ensure(VFS::mkdir("/tmp") == 0); - VFS::mount("/dev", DeviceFS::get()); - VFS::mount("/tmp", TmpFS::get()); - - Init::finish_kernel_boot(); - - PIC::remap(); - PIC::enable_master(0b11111100); - PIC::enable_slave(0b11111111); - - Interrupts::enable(); - - while (1) - halt(); // As soon as the first timer interrupt arrives, this idle loop is gone, since the main function is not - // registered as a task and thus the scheduler will never schedule this again. We still have to do - // something while waiting for a timer interrupt to arrive, though. In fact, in most cases, calling - // halt() once would be enough, since that function halts the CPU until the next interrupt (most likely - // the timer one) arrives. But we have to guarantee this function never returns. + for (;;) + ; } \ No newline at end of file diff --git a/kernel/src/memory/AddressSpace.cpp b/kernel/src/memory/AddressSpace.cpp deleted file mode 100644 index 7a0e7473..00000000 --- a/kernel/src/memory/AddressSpace.cpp +++ /dev/null @@ -1,284 +0,0 @@ -#define MODULE "vmm" - -#include "memory/AddressSpace.h" -#include "log/Log.h" -#include "memory/PMM.h" -#include "memory/VMM.h" -#include "std/errno.h" -#include "std/stdlib.h" -#include "std/string.h" -#include "utils/move.h" - -Result AddressSpace::create() -{ - AddressSpace result; - auto page = PMM::request_page(); - if (page.has_error()) return page.release_error(); - result.m_pml4 = (PageTable*)page.release_value(); - memset(result.m_pml4, 0, PAGE_SIZE); - VMM::install_kernel_page_directory_into_address_space(result); - return move(result); -} - -void AddressSpace::destroy() -{ - uint64_t pages_freed = 0; - for (int i = 0; i < 512; i++) - { - PageDirectoryEntry& pdp_pde = m_pml4->entries[i]; - if (!pdp_pde.present) continue; - if (pdp_pde.larger_pages) - { - if (pdp_pde.owned_by_task) - { - pages_freed++; - PMM::free_page((void*)pdp_pde.get_address()); - } - continue; - } - PageTable* pdp = (PageTable*)pdp_pde.get_address(); - for (int j = 0; j < 511; j++) // skip the last page directory, it's the kernel one - { - PageDirectoryEntry& pd_pde = pdp->entries[j]; - if (!pd_pde.present) continue; - if (pd_pde.larger_pages) - { - if (pd_pde.owned_by_task) - { - pages_freed++; - PMM::free_page((void*)pd_pde.get_address()); - } - continue; - } - PageTable* pd = (PageTable*)pd_pde.get_address(); - for (int k = 0; k < 512; k++) - { - PageDirectoryEntry& pt_pde = pd->entries[k]; - if (!pt_pde.present) continue; - if (pt_pde.larger_pages) - { - if (pt_pde.owned_by_task) - { - pages_freed++; - PMM::free_page((void*)pt_pde.get_address()); - } - continue; - } - PageTable* pt = (PageTable*)pt_pde.get_address(); - for (int l = 0; l < 512; l++) - { - PageDirectoryEntry& pde = pt->entries[l]; - if (!pde.present) continue; - if (!pde.owned_by_task) continue; - pages_freed++; - PMM::free_page((void*)pde.get_address()); - } - pages_freed++; - PMM::free_page(pt); - } - pages_freed++; - PMM::free_page(pd); - } - pages_freed++; - PMM::free_page(pdp); - } - pages_freed++; - PMM::free_page(m_pml4); - - kdbgln("Reclaimed %ld pages from address space!", pages_freed); -} - -void AddressSpace::clear() -{ - uint64_t pages_freed = 0; - for (int i = 0; i < 512; i++) - { - PageDirectoryEntry& pdp_pde = m_pml4->entries[i]; - if (!pdp_pde.present) continue; - if (pdp_pde.larger_pages) - { - if (pdp_pde.owned_by_task) - { - pages_freed++; - PMM::free_page((void*)pdp_pde.get_address()); - } - continue; - } - PageTable* pdp = (PageTable*)pdp_pde.get_address(); - for (int j = 0; j < 511; j++) // skip the last page directory, it's the kernel one - { - PageDirectoryEntry& pd_pde = pdp->entries[j]; - if (!pd_pde.present) continue; - if (pd_pde.larger_pages) - { - if (pd_pde.owned_by_task) - { - pages_freed++; - PMM::free_page((void*)pd_pde.get_address()); - } - continue; - } - PageTable* pd = (PageTable*)pd_pde.get_address(); - for (int k = 0; k < 512; k++) - { - PageDirectoryEntry& pt_pde = pd->entries[k]; - if (!pt_pde.present) continue; - if (pt_pde.larger_pages) - { - if (pt_pde.owned_by_task) - { - pages_freed++; - PMM::free_page((void*)pt_pde.get_address()); - } - continue; - } - PageTable* pt = (PageTable*)pt_pde.get_address(); - for (int l = 0; l < 512; l++) - { - PageDirectoryEntry& pde = pt->entries[l]; - if (!pde.present) continue; - if (!pde.owned_by_task) continue; - pages_freed++; - PMM::free_page((void*)pde.get_address()); - } - pages_freed++; - PMM::free_page(pt); - } - pages_freed++; - PMM::free_page(pd); - } - pages_freed++; - PMM::free_page(pdp); - } - memset(m_pml4, 0, PAGE_SIZE); - - VMM::install_kernel_page_directory_into_address_space(*this); - - kdbgln("Reclaimed %ld pages from address space!", pages_freed); -} - -static PageTable* try_clone_page_table(PageTable* source) -{ - auto page = PMM::request_page(); - if (page.has_error()) { return 0; } - PageTable* dst = (PageTable*)page.release_value(); - memcpy(dst, source, sizeof(PageTable)); - return dst; -} - -AddressSpace AddressSpace::clone() // FIXME: Add out-of-memory checks to this function. -{ - AddressSpace result; - result.m_pml4 = try_clone_page_table(m_pml4); - if (!result.m_pml4) return result; - for (int i = 0; i < 512; i++) - { - PageDirectoryEntry& pdp_pde = m_pml4->entries[i]; - PageDirectoryEntry& cloned_pdp_pde = result.m_pml4->entries[i]; - if (!pdp_pde.present) continue; - if (pdp_pde.larger_pages) - { - if (!pdp_pde.owned_by_task) - { - memcpy(&cloned_pdp_pde, &pdp_pde, sizeof(PageDirectoryEntry)); - continue; - } - void* cloned = try_clone_page_table((PageTable*)pdp_pde.get_address()); - if (!cloned) - { - cloned_pdp_pde.present = false; - continue; - } - cloned_pdp_pde.set_address((uint64_t)cloned); - continue; - } - PageTable* pdp = (PageTable*)pdp_pde.get_address(); - PageTable* cloned_pdp = try_clone_page_table(pdp); - if (!cloned_pdp) - { - cloned_pdp_pde.present = false; - continue; - } - cloned_pdp_pde.set_address((uint64_t)cloned_pdp); - for (int j = 0; j < 511; j++) // skip the last page directory, it's the kernel one - { - PageDirectoryEntry& pd_pde = pdp->entries[j]; - PageDirectoryEntry& cloned_pd_pde = cloned_pdp->entries[j]; - if (!pd_pde.present) continue; - if (pd_pde.larger_pages) - { - if (!pd_pde.owned_by_task) - { - memcpy(&cloned_pd_pde, &pd_pde, sizeof(PageDirectoryEntry)); - continue; - } - void* cloned = try_clone_page_table((PageTable*)pd_pde.get_address()); - if (!cloned) - { - cloned_pd_pde.present = false; - continue; - } - cloned_pd_pde.set_address((uint64_t)cloned); - continue; - } - PageTable* pd = (PageTable*)pd_pde.get_address(); - PageTable* cloned_pd = try_clone_page_table(pd); - if (!cloned_pd) - { - cloned_pd_pde.present = false; - continue; - } - cloned_pd_pde.set_address((uint64_t)cloned_pd); - for (int k = 0; k < 512; k++) - { - PageDirectoryEntry& pt_pde = pd->entries[k]; - PageDirectoryEntry& cloned_pt_pde = cloned_pd->entries[k]; - if (!pt_pde.present) continue; - if (pt_pde.larger_pages) - { - if (!pt_pde.owned_by_task) - { - memcpy(&cloned_pt_pde, &pt_pde, sizeof(PageDirectoryEntry)); - continue; - } - void* cloned = try_clone_page_table((PageTable*)pt_pde.get_address()); - if (!cloned) - { - cloned_pt_pde.present = false; - continue; - } - cloned_pt_pde.set_address((uint64_t)cloned); - continue; - } - PageTable* pt = (PageTable*)pt_pde.get_address(); - PageTable* cloned_pt = try_clone_page_table(pt); - if (!cloned_pt) - { - cloned_pt_pde.present = false; - continue; - } - cloned_pt_pde.set_address((uint64_t)cloned_pt); - for (int l = 0; l < 512; l++) - { - PageDirectoryEntry& pde = pt->entries[l]; - PageDirectoryEntry& cloned_pde = cloned_pt->entries[l]; - if (!pde.owned_by_task) - { - memcpy(&cloned_pde, &pde, sizeof(PageDirectoryEntry)); - continue; - } - if (!pde.present) continue; - void* cloned = try_clone_page_table((PageTable*)pde.get_address()); - if (!cloned) - { - cloned_pde.present = false; - continue; - } - cloned_pde.set_address((uint64_t)cloned); - continue; - } - } - } - } - return result; -} \ No newline at end of file diff --git a/kernel/src/memory/KernelHeap.cpp b/kernel/src/memory/KernelHeap.cpp deleted file mode 100644 index d42c520e..00000000 --- a/kernel/src/memory/KernelHeap.cpp +++ /dev/null @@ -1,135 +0,0 @@ -#define MODULE "kheap" - -#include "memory/KernelHeap.h" -#include "assert.h" -#include "log/Log.h" -#include "std/string.h" - -#ifndef PAGE_SIZE -#define PAGE_SIZE 4096 -#endif - -static uint8_t page_bitmap[2048]; - -static int64_t kheap_free = sizeof(page_bitmap) * 8 * PAGE_SIZE; -static int64_t kheap_used = 0; - -#define ALLOC_BASE 0xfffffffff8000000 -#define ALLOC_END 0xfffffffffc000000 - -// static uint64_t start_index = 0; - -static bool bitmap_read(uint64_t index) -{ - return (page_bitmap[index / 8] & (0b10000000 >> (index % 8))) > 0; -} - -static void bitmap_set(uint64_t index, bool value) -{ - uint64_t byteIndex = index / 8; - uint8_t bitIndexer = 0b10000000 >> (index % 8); - page_bitmap[byteIndex] &= ~bitIndexer; - if (value) { page_bitmap[byteIndex] |= bitIndexer; } -} - -void KernelHeap::clear() -{ - memset(page_bitmap, 0, sizeof(page_bitmap)); -} - -uint64_t KernelHeap::request_virtual_page() -{ - for (uint64_t index = 0; index < sizeof(page_bitmap) * 8; index++) - { - if (bitmap_read(index)) continue; - bitmap_set(index, true); - // start_index = index + 1; -#ifdef KHEAP_DEBUG - kinfoln("allocating one page for caller %p, returning %lx", __builtin_return_address(0), - ALLOC_BASE + (index * PAGE_SIZE)); -#endif - kheap_free -= PAGE_SIZE; - kheap_used += PAGE_SIZE; -#ifdef KHEAP_DEBUG - dump_usage(); -#endif - return ALLOC_BASE + (index * PAGE_SIZE); - } - - return 0; -} - -uint64_t KernelHeap::request_virtual_pages(uint64_t count) -{ - uint64_t contiguous = 0; - uint64_t contiguous_start = 0; - for (uint64_t index = 0; index < sizeof(page_bitmap) * 8; index++) - { - if (bitmap_read(index)) - { - contiguous = 0; - continue; - } - if (contiguous == 0) - { - contiguous_start = index; - contiguous++; - } - else - contiguous++; - if (contiguous == count) - { - for (uint64_t i = 0; i < count; i++) bitmap_set(contiguous_start + i, true); -#ifdef KHEAP_DEBUG - kinfoln("allocating %lu pages for caller %p, returning %lx", count, __builtin_return_address(0), - ALLOC_BASE + (contiguous_start * PAGE_SIZE)); -#endif - kheap_free -= (count * PAGE_SIZE); - kheap_used += (count * PAGE_SIZE); -#ifdef KHEAP_DEBUG - dump_usage(); -#endif - return ALLOC_BASE + (contiguous_start * PAGE_SIZE); - } - } - - return 0; -} - -void KernelHeap::free_virtual_page(uint64_t address) -{ - if (address < ALLOC_BASE || address >= ALLOC_END) return; - uint64_t index = (address - ALLOC_BASE) / PAGE_SIZE; - bitmap_set(index, false); -#ifdef KHEAP_DEBUG - kinfoln("releasing one page for caller %p, %lx", __builtin_return_address(0), address); -#endif - kheap_free += PAGE_SIZE; - kheap_used -= PAGE_SIZE; -#ifdef KHEAP_DEBUG - dump_usage(); -#endif - // if (start_index > index) start_index = index; -} - -void KernelHeap::free_virtual_pages(uint64_t address, uint64_t count) -{ - if (address < ALLOC_BASE || address >= ALLOC_END) return; - uint64_t index = (address - ALLOC_BASE) / PAGE_SIZE; - for (uint64_t i = 0; i < count; i++) { bitmap_set(index + i, false); } -#ifdef KHEAP_DEBUG - kinfoln("releasing %lu pages for caller %p, %lx", count, __builtin_return_address(0), address); -#endif - kheap_free += (count * PAGE_SIZE); - kheap_used -= (count * PAGE_SIZE); -#ifdef KHEAP_DEBUG - dump_usage(); -#endif - // if (start_index > index) start_index = index; -} - -void KernelHeap::dump_usage() -{ - kinfoln("Used: %ld KB", kheap_used / 1024); - kinfoln("Free: %ld KB", kheap_free / 1024); -} \ No newline at end of file diff --git a/kernel/src/memory/Memory.cpp b/kernel/src/memory/Memory.cpp deleted file mode 100644 index 6ff02898..00000000 --- a/kernel/src/memory/Memory.cpp +++ /dev/null @@ -1,54 +0,0 @@ -#include "memory/Memory.h" -#include "bootboot.h" - -extern BOOTBOOT bootboot; - -uint64_t Memory::get_system() -{ - static uint64_t result = 0; - static bool cached = false; - - if (cached) return result; - - MMapEnt* ptr = &bootboot.mmap; - uint64_t mmap_entries = (bootboot.size - 128) / 16; - for (uint64_t i = 0; i < mmap_entries; i++) - { - result += MMapEnt_Size(ptr); - ptr++; - } - - cached = true; - - return result; -} - -uint64_t Memory::get_usable() -{ - static uint64_t result = 0; - static bool cached = false; - - if (cached) return result; - - MMapEnt* ptr = &bootboot.mmap; - uint64_t mmap_entries = (bootboot.size - 128) / 16; - for (uint64_t i = 0; i < mmap_entries; i++) - { - if (MMapEnt_IsFree(ptr)) result += MMapEnt_Size(ptr); - ptr++; - } - - cached = true; - - return result; -} - -bool Memory::is_kernel_address(uintptr_t address) -{ - return address >= 0xfffffffff8000000; -} - -bool Memory::is_user_address(uintptr_t address) -{ - return address && address < 0xfffffffff8000000; -} \ No newline at end of file diff --git a/kernel/src/memory/MemoryManager.cpp b/kernel/src/memory/MemoryManager.cpp deleted file mode 100644 index b8bee795..00000000 --- a/kernel/src/memory/MemoryManager.cpp +++ /dev/null @@ -1,223 +0,0 @@ -#ifdef MM_DEBUG -#define MODULE "mm" -#include "log/Log.h" -#endif - -#include "memory/KernelHeap.h" -#include "memory/MemoryManager.h" -#include "memory/PMM.h" -#include "memory/VMM.h" -#include "misc/utils.h" -#include "std/ensure.h" - -// FIXME: Use Result in here. - -void MemoryManager::init() -{ - KernelHeap::clear(); - PMM::init(); - VMM::init(); - PMM::map_bitmap_to_virtual(); -} - -extern char start_of_kernel_rodata[1]; -extern char end_of_kernel_rodata[1]; -extern char start_of_kernel_data[1]; -extern char end_of_kernel_data[1]; - -void MemoryManager::protect_kernel_sections() -{ - protect(start_of_kernel_rodata, - Utilities::get_blocks_from_size(PAGE_SIZE, end_of_kernel_rodata - start_of_kernel_rodata), 0); - protect(start_of_kernel_data, Utilities::get_blocks_from_size(PAGE_SIZE, end_of_kernel_data - start_of_kernel_data), - MAP_READ_WRITE); -} - -Result MemoryManager::get_mapping(void* physicalAddress, int flags) -{ - uint64_t virtualAddress = KernelHeap::request_virtual_page(); - if (!virtualAddress) - { -#ifdef MM_DEBUG - kwarnln("No kernel heap space (virtual address space from -128M to -64M) left"); -#endif - KernelHeap::dump_usage(); - return {ENOMEM}; - } - VMM::map(virtualAddress, (uint64_t)physicalAddress, flags); - return (void*)virtualAddress; -} - -Result MemoryManager::get_unaligned_mapping(void* physicalAddress, int flags) -{ - uint64_t offset = (uint64_t)physicalAddress % PAGE_SIZE; - uint64_t virtualAddress = KernelHeap::request_virtual_page(); - if (!virtualAddress) - { -#ifdef MM_DEBUG - kwarnln("No kernel heap space (virtual address space from -128M to -64M) left"); -#endif - KernelHeap::dump_usage(); - return {ENOMEM}; - } - VMM::map(virtualAddress, (uint64_t)physicalAddress - offset, flags); - return (void*)(virtualAddress + offset); -} - -Result MemoryManager::get_unaligned_mappings(void* physicalAddress, uint64_t count, int flags) -{ - if (!count) return 0; - if (count == 1) return get_unaligned_mapping(physicalAddress, flags); - uint64_t offset = (uint64_t)physicalAddress % PAGE_SIZE; - uint64_t virtualAddress = KernelHeap::request_virtual_pages(count); - if (!virtualAddress) - { -#ifdef MM_DEBUG - kwarnln("Not enough contiguous pages (%ld) left in the kernel heap space (virtual address space from -128M to " - "-64M)", - count); -#endif - KernelHeap::dump_usage(); - return {ENOMEM}; - } - for (uint64_t i = 0; i < count; i++) - { - VMM::map(virtualAddress + (i * PAGE_SIZE), ((uint64_t)physicalAddress - offset) + (i * PAGE_SIZE), flags); - } - return (void*)(virtualAddress + offset); -} - -void MemoryManager::release_unaligned_mapping(void* mapping) -{ - uint64_t offset = (uint64_t)mapping % PAGE_SIZE; - VMM::unmap((uint64_t)mapping - offset); - KernelHeap::free_virtual_page((uint64_t)mapping - offset); -} - -void MemoryManager::release_unaligned_mappings(void* mapping, uint64_t count) -{ - if (!count) return; - if (count == 1) return release_unaligned_mapping(mapping); - uint64_t offset = (uint64_t)mapping % PAGE_SIZE; - KernelHeap::free_virtual_pages((uint64_t)mapping - offset, count); - for (uint64_t i = 0; i < count; i++) { VMM::unmap(((uint64_t)mapping - offset) + (i * PAGE_SIZE)); } -} - -void MemoryManager::release_mapping(void* mapping) -{ - VMM::unmap((uint64_t)mapping); - KernelHeap::free_virtual_page((uint64_t)mapping); -} - -Result MemoryManager::get_page(int flags) -{ - uint64_t virtualAddress = KernelHeap::request_virtual_page(); - if (!virtualAddress) - { -#ifdef MM_DEBUG - kwarnln("No kernel heap space (virtual address space from -128M to -64M) left"); -#endif - KernelHeap::dump_usage(); - return {ENOMEM}; - } - return get_page_at(virtualAddress, flags); -} - -Result MemoryManager::get_page_at(uint64_t addr, int flags) -{ - auto paddr = PMM::request_page(); - if (paddr.has_error()) - { -#ifdef MM_DEBUG - kwarnln("OOM while allocating one page of memory. this is not good..."); -#endif - return {ENOMEM}; - } - VMM::map(addr, (uint64_t)paddr.release_value(), flags); - return (void*)addr; -} - -void MemoryManager::release_page(void* page) -{ - uint64_t physicalAddress = VMM::get_physical((uint64_t)page); - ensure(physicalAddress != UINT64_MAX); // this address is not mapped in the virtual address space... - VMM::unmap((uint64_t)page); - PMM::free_page((void*)physicalAddress); -} - -Result MemoryManager::get_pages(uint64_t count, int flags) -{ - if (!count) return 0; - if (count == 1) return get_page(flags); -#ifdef MM_DEBUG - kdbgln("allocating several pages (%ld)", count); -#endif - uint64_t virtualAddress = KernelHeap::request_virtual_pages(count); - if (!virtualAddress) - { -#ifdef MM_DEBUG - kwarnln("No kernel heap space (virtual address space from -128M to -64M) left"); -#endif - KernelHeap::dump_usage(); - return {ENOMEM}; // Out of virtual address in the kernel heap range (-128M to -64M). This should be difficult to - // achieve... - } - return get_pages_at(virtualAddress, count, flags); -} - -Result MemoryManager::get_pages_at(uint64_t addr, uint64_t count, int flags) -{ - if (!count) return 0; - if (count == 1) return get_page_at(addr, flags); -#ifdef MM_DEBUG - kdbgln("allocating several pages (%ld), at address %lx", count, addr); -#endif - for (uint64_t i = 0; i < count; i++) - { - auto paddr = PMM::request_page(); - if (paddr.has_error()) // OOM: No physical memory available! Since this might be at the end of a - // long allocation, we should be able to recover most of it and allocate a - // smaller range, so this might not be fatal. - { -#ifdef MM_DEBUG - kwarnln("OOM while allocating page %ld of memory. this might be recoverable...", i); -#endif - // FIXME: Weren't we supposed to free all previously allocated pages, to avoid leaks when failing large - // allocations? - return {ENOMEM}; - } - VMM::map(addr + (i * PAGE_SIZE), (uint64_t)paddr.release_value(), flags); - } - return (void*)addr; -} - -void MemoryManager::release_pages(void* pages, uint64_t count) -{ - if (!count) return; - if (count == 1) return release_page(pages); -#ifdef MM_DEBUG - kdbgln("releasing several pages (%ld)", count); -#endif - for (uint64_t i = 0; i < count; i++) - { - void* page = (void*)((uint64_t)pages + (i * PAGE_SIZE)); - uint64_t physicalAddress = VMM::get_physical((uint64_t)page); - ensure(physicalAddress != UINT64_MAX); - VMM::unmap((uint64_t)page); - PMM::free_page((void*)physicalAddress); - } - KernelHeap::free_virtual_pages((uint64_t)pages, count); -} - -void MemoryManager::protect(void* page, uint64_t count, int flags) -{ - for (uint64_t i = 0; i < count; i++) { VMM::remap((uint64_t)page + (i * PAGE_SIZE), flags); } -} - -void MemoryManager::map_several_pages(uint64_t physicalAddress, uint64_t virtualAddress, uint64_t count, int flags) -{ - for (uint64_t i = 0; i < count; i++) - { - VMM::map(virtualAddress + (i * PAGE_SIZE), physicalAddress + (i * PAGE_SIZE), flags); - } -} \ No newline at end of file diff --git a/kernel/src/memory/MemoryMap.cpp b/kernel/src/memory/MemoryMap.cpp deleted file mode 100644 index 9ae89bbe..00000000 --- a/kernel/src/memory/MemoryMap.cpp +++ /dev/null @@ -1,37 +0,0 @@ -#define MODULE "mmap" - -#include "memory/MemoryMap.h" -#include "bootboot.h" -#include "log/Log.h" - -extern BOOTBOOT bootboot; - -void Memory::walk_memory_map() -{ - MMapEnt* ptr = &bootboot.mmap; - uint64_t mmap_entries = (bootboot.size - 128) / 16; - for (uint64_t i = 0; i < mmap_entries; i++) - { - switch (MMapEnt_Type(ptr)) - { - case MMAP_USED: - kinfoln("Used memory region starting at %lx, ends at %lx, size %lx", MMapEnt_Ptr(ptr), - MMapEnt_Ptr(ptr) + MMapEnt_Size(ptr) - 1, MMapEnt_Size(ptr)); - break; - case MMAP_ACPI: - kinfoln("ACPI memory region starting at %lx, ends at %lx, size %lx", MMapEnt_Ptr(ptr), - MMapEnt_Ptr(ptr) + MMapEnt_Size(ptr) - 1, MMapEnt_Size(ptr)); - break; - case MMAP_MMIO: - kinfoln("MMIO memory region starting at %lx, ends at %lx, size %lx", MMapEnt_Ptr(ptr), - MMapEnt_Ptr(ptr) + MMapEnt_Size(ptr) - 1, MMapEnt_Size(ptr)); - break; - case MMAP_FREE: - kinfoln("Free memory region starting at %lx, ends at %lx, size %lx", MMapEnt_Ptr(ptr), - MMapEnt_Ptr(ptr) + MMapEnt_Size(ptr) - 1, MMapEnt_Size(ptr)); - break; - default: kinfoln("Invalid memory map entry"); break; - } - ptr++; - } -} \ No newline at end of file diff --git a/kernel/src/memory/PMM.cpp b/kernel/src/memory/PMM.cpp deleted file mode 100644 index ec62deb0..00000000 --- a/kernel/src/memory/PMM.cpp +++ /dev/null @@ -1,191 +0,0 @@ -#define MODULE "mem" - -#include "memory/PMM.h" -#include "bootboot.h" -#include "log/Log.h" -#include "memory/Memory.h" -#include "memory/MemoryManager.h" -#include "misc/utils.h" -#include "std/ensure.h" -#include "std/errno.h" -#include "std/string.h" - -extern BOOTBOOT bootboot; - -static bool bitmap_read(uint64_t index); -static void bitmap_set(uint64_t index, bool value); - -static uint64_t free_mem = 0; -static uint64_t used_mem = 0; -static uint64_t reserved_mem = 0; - -static char* bitmap_addr; -static char* virtual_bitmap_addr; -static uint64_t bitmap_size; - -static uint64_t start_index = 0; - -void PMM::init() -{ - uint64_t total_mem = Memory::get_system(); - - void* biggest_chunk = nullptr; - uint64_t biggest_chunk_size = 0; - - MMapEnt* ptr = &bootboot.mmap; - uint64_t mmap_entries = (bootboot.size - 128) / 16; - for (uint64_t i = 0; i < mmap_entries; i++) - { - if (!MMapEnt_IsFree(ptr)) - { - ptr++; - continue; - } - if (MMapEnt_Size(ptr) > biggest_chunk_size) - { - biggest_chunk = (void*)MMapEnt_Ptr(ptr); - biggest_chunk_size = MMapEnt_Size(ptr); - } - ptr++; - } - - bitmap_addr = (char*)biggest_chunk; - virtual_bitmap_addr = bitmap_addr; - ensure((total_mem / PAGE_SIZE / 8) < biggest_chunk_size); - bitmap_size = total_mem / PAGE_SIZE / 8 + 1; - memset(bitmap_addr, 0xFF, bitmap_size); - - ptr = &bootboot.mmap; - for (uint64_t i = 0; i < mmap_entries; i++) - { - uint64_t index = MMapEnt_Ptr(ptr) / PAGE_SIZE; - if (!MMapEnt_IsFree(ptr)) { reserved_mem += MMapEnt_Size(ptr); } - else - { - free_mem += MMapEnt_Size(ptr); - for (uint64_t j = 0; j < (MMapEnt_Size(ptr) / PAGE_SIZE); j++) { bitmap_set(index + j, false); } - } - ptr++; - } - - lock_pages(bitmap_addr, bitmap_size / PAGE_SIZE + 1); -} - -static bool bitmap_read(uint64_t index) -{ - return (virtual_bitmap_addr[index / 8] & (0b10000000 >> (index % 8))) > 0; -} - -static void bitmap_set(uint64_t index, bool value) -{ - uint64_t byteIndex = index / 8; - uint8_t bitIndexer = 0b10000000 >> (index % 8); - virtual_bitmap_addr[byteIndex] &= (uint8_t)(~bitIndexer); - if (value) { virtual_bitmap_addr[byteIndex] |= bitIndexer; } -} - -Result PMM::request_page() -{ - for (uint64_t index = start_index; index < (bitmap_size * 8); index++) - { - if (bitmap_read(index)) continue; - bitmap_set(index, true); - start_index = index + 1; - free_mem -= PAGE_SIZE; - used_mem += PAGE_SIZE; - return (void*)(index * PAGE_SIZE); - } - - return {ENOMEM}; -} - -Result PMM::request_pages(uint64_t count) -{ - uint64_t contiguous = 0; - uint64_t contiguous_start = 0; - for (uint64_t index = start_index; index < (bitmap_size * 8); index++) - { - if (bitmap_read(index)) - { - contiguous = 0; - continue; - } - if (contiguous == 0) - { - contiguous_start = index; - contiguous++; - } - else - contiguous++; - if (contiguous == count) - { - for (uint64_t i = 0; i < count; i++) bitmap_set(contiguous_start + i, true); - free_mem -= (count * PAGE_SIZE); - used_mem += (count * PAGE_SIZE); - return (void*)(contiguous_start * PAGE_SIZE); - } - } - - return {ENOMEM}; -} - -void PMM::free_page(void* address) -{ - uint64_t index = (uint64_t)address / PAGE_SIZE; - if (index > (bitmap_size * 8)) - { - kinfoln("attempt to free out-of-range address %p", address); - return; - } - if (!bitmap_read(index)) return; - bitmap_set(index, false); - used_mem -= PAGE_SIZE; - free_mem += PAGE_SIZE; - if (start_index > index) start_index = index; -} - -void PMM::free_pages(void* address, uint64_t count) -{ - for (uint64_t index = 0; index < count; index++) { free_page((void*)((uint64_t)address + index)); } -} - -void PMM::lock_page(void* address) -{ - uint64_t index = ((uint64_t)address) / PAGE_SIZE; - if (bitmap_read(index)) return; - bitmap_set(index, true); - used_mem += PAGE_SIZE; - free_mem -= PAGE_SIZE; -} - -void PMM::lock_pages(void* address, uint64_t count) -{ - for (uint64_t index = 0; index < count; index++) { lock_page((void*)((uint64_t)address + index)); } -} - -uint64_t PMM::get_free() -{ - return free_mem; -} - -uint64_t PMM::get_used() -{ - return used_mem; -} - -uint64_t PMM::get_reserved() -{ - return reserved_mem; -} - -uint64_t PMM::get_bitmap_size() -{ - return bitmap_size; -} - -void PMM::map_bitmap_to_virtual() -{ - virtual_bitmap_addr = (char*)MemoryManager::get_unaligned_mappings( - bitmap_addr, Utilities::get_blocks_from_size(PAGE_SIZE, bitmap_size)) - .release_value(); // If we can't do this, something has gone terribly wrong. -} \ No newline at end of file diff --git a/kernel/src/memory/Paging.cpp b/kernel/src/memory/Paging.cpp deleted file mode 100644 index 8bf7a7dc..00000000 --- a/kernel/src/memory/Paging.cpp +++ /dev/null @@ -1,16 +0,0 @@ -#include "memory/Paging.h" - -#pragma GCC push_options -#pragma GCC diagnostic ignored "-Wconversion" - -void PageDirectoryEntry::set_address(uint64_t addr) -{ - this->address = (addr >> 12); -} - -uint64_t PageDirectoryEntry::get_address() -{ - return (uint64_t)this->address << 12; -} - -#pragma GCC pop_options \ No newline at end of file diff --git a/kernel/src/memory/UserHeap.cpp b/kernel/src/memory/UserHeap.cpp deleted file mode 100644 index b9876a8c..00000000 --- a/kernel/src/memory/UserHeap.cpp +++ /dev/null @@ -1,164 +0,0 @@ -#define MODULE "mem" - -#include "memory/UserHeap.h" -#include "log/Log.h" -#include "misc/utils.h" -#include "std/stdlib.h" -#include "std/string.h" - -#ifndef USER_HEAP_DEBUG -#undef kdbgln -#define kdbgln(...) -#endif - -#ifndef PAGE_SIZE -#define PAGE_SIZE 4096 -#endif - -#define ALLOC_BASE 0xa00000 - -#define INITIAL_SIZE 0x2000 -#define EXPAND_SIZE 0x1000 - -bool UserHeap::init() -{ - bitmap = (uint8_t*)kmalloc(INITIAL_SIZE); - if (!bitmap) return false; - bitmap_size = INITIAL_SIZE; - memset(bitmap, 0, bitmap_size); - kdbgln("new user heap, bitmap at %p, size %ld", (void*)bitmap, bitmap_size); - return true; -} - -bool UserHeap::inherit(UserHeap& other) -{ - bitmap = (uint8_t*)kmalloc(other.bitmap_size); - if (!bitmap) return false; - bitmap_size = other.bitmap_size; - memcpy(bitmap, other.bitmap, bitmap_size); - kdbgln("child user heap, bitmap at %p, size %ld", (void*)bitmap, bitmap_size); - return true; -} - -void UserHeap::free() -{ - kdbgln("freeing user heap, bitmap at %p, size %ld", (void*)bitmap, bitmap_size); - kfree(bitmap); -} - -bool UserHeap::try_expand() -{ - kdbgln("attempting to expand user heap"); - void* new_bitmap = krealloc(bitmap, bitmap_size + EXPAND_SIZE); - if (!new_bitmap) - { - kdbgln("expansion failed"); - return false; - } - bitmap = (uint8_t*)new_bitmap; - memset(bitmap + bitmap_size, 0, EXPAND_SIZE); - bitmap_size += EXPAND_SIZE; - kdbgln("expanded user heap, bitmap at %p, size %ld", (void*)bitmap, bitmap_size); - return true; -} - -bool UserHeap::try_expand_size(uint64_t size) -{ - void* new_bitmap = krealloc(bitmap, bitmap_size + size); - if (!new_bitmap) - { - kdbgln("expansion failed"); - return false; - } - bitmap = (uint8_t*)new_bitmap; - memset(bitmap + bitmap_size, 0, size); - bitmap_size += size; - kdbgln("expanded user heap, bitmap at %p, size %ld", (void*)bitmap, bitmap_size); - return true; -} - -bool UserHeap::bitmap_read(uint64_t index) -{ - return (bitmap[index / 8] & (0b10000000 >> (index % 8))) > 0; -} - -void UserHeap::bitmap_set(uint64_t index, bool value) -{ - uint64_t byteIndex = index / 8; - uint8_t bitIndexer = 0b10000000 >> (index % 8); - bitmap[byteIndex] &= ~bitIndexer; - if (value) { bitmap[byteIndex] |= bitIndexer; } -} - -uint64_t UserHeap::request_virtual_page() -{ - uint64_t attempts = 0; -allocate: - for (uint64_t index = start_index; index < bitmap_size * 8; index++) - { - if (bitmap_read(index)) continue; - bitmap_set(index, true); - start_index = index + 1; - return ALLOC_BASE + (index * PAGE_SIZE); - } - - if (attempts == 0 && try_expand()) // We are allocating ONE PAGE, only one attempt should be necessary. - { - attempts++; - goto allocate; - } - - return 0; -} - -uint64_t UserHeap::request_virtual_pages(uint64_t count) -{ - uint64_t attempts = 0; -allocate: - uint64_t contiguous = 0; - uint64_t contiguous_start = 0; - for (uint64_t index = start_index; index < bitmap_size * 8; index++) - { - if (bitmap_read(index)) - { - contiguous = 0; - continue; - } - if (contiguous == 0) - { - contiguous_start = index; - contiguous++; - } - else - contiguous++; - if (contiguous == count) - { - for (uint64_t i = 0; i < count; i++) bitmap_set(contiguous_start + i, true); - return ALLOC_BASE + (contiguous_start * PAGE_SIZE); - } - } - - if (attempts == 0 && try_expand_size(Utilities::get_blocks_from_size(8, count) + 256)) - { - attempts++; - goto allocate; - } - - return 0; -} - -void UserHeap::free_virtual_page(uint64_t address) -{ - if (address < ALLOC_BASE || address >= (ALLOC_BASE + bitmap_size * 8 * PAGE_SIZE)) return; - uint64_t index = (address - ALLOC_BASE) / PAGE_SIZE; - bitmap_set(index, false); - if (start_index > index) start_index = index; -} - -void UserHeap::free_virtual_pages(uint64_t address, uint64_t count) -{ - if (address < ALLOC_BASE || address >= (ALLOC_BASE + bitmap_size * 8 * PAGE_SIZE)) return; - uint64_t index = (address - ALLOC_BASE) / PAGE_SIZE; - for (uint64_t i = 0; i < count; i++) { bitmap_set(index + i, false); } - if (start_index > index) start_index = index; -} \ No newline at end of file diff --git a/kernel/src/memory/VMM.cpp b/kernel/src/memory/VMM.cpp deleted file mode 100644 index b36c3b6a..00000000 --- a/kernel/src/memory/VMM.cpp +++ /dev/null @@ -1,362 +0,0 @@ -#define MODULE "vmm" - -#include "memory/VMM.h" -#include "log/Log.h" -#include "memory/PMM.h" -#include "misc/utils.h" -#include "std/ensure.h" -#include "std/string.h" -#include "utils/Addresses.h" -#include "utils/Registers.h" - -static PageTable* kernel_pml4; -static PageTable* current_pml4; -static AddressSpace* user_address_space; - -// FIXME: Switch to recursive paging instead of naively assuming the physical address space is identity mapped. - -void VMM::switch_back_to_kernel_address_space() -{ - if (current_pml4 != kernel_pml4) { current_pml4 = kernel_pml4; } -} - -void VMM::switch_to_user_address_space(AddressSpace& space) -{ - user_address_space = &space; - current_pml4 = user_address_space->get_pml4(); -} - -void VMM::switch_to_previous_user_address_space() -{ - current_pml4 = user_address_space->get_pml4(); -} - -void VMM::enter_syscall_context() -{ - if (current_pml4 != kernel_pml4) - { - current_pml4 = kernel_pml4; - apply_address_space(); - switch_to_previous_user_address_space(); - } -} - -void VMM::exit_syscall_context() -{ - if (current_pml4 != user_address_space->get_pml4()) { switch_to_previous_user_address_space(); } - apply_address_space(); -} - -void VMM::apply_address_space() -{ - write_cr3(current_pml4); -} - -bool VMM::is_using_kernel_address_space() -{ - return current_pml4 == kernel_pml4; -} - -void VMM::init() -{ - kernel_pml4 = (PageTable*)read_cr3(); - current_pml4 = kernel_pml4; - - // Set up recursive paging - PageDirectoryEntry& recursive_pde = kernel_pml4->entries[510]; - memset(&recursive_pde, 0, sizeof(PageDirectoryEntry)); - recursive_pde.present = true; - recursive_pde.read_write = true; - recursive_pde.larger_pages = false; - recursive_pde.no_execute = true; - recursive_pde.set_address((uint64_t)kernel_pml4); - flush_tlb_full(); -} - -void VMM::unmap(uint64_t vaddr) -{ - vaddr = round_down_to_nearest_page(vaddr); - - PageDirectoryEntry* pde = find_pde(current_pml4, vaddr); - if (!pde) return; // Already unmapped - - memset(pde, 0, sizeof(PageDirectoryEntry)); - flush_tlb(vaddr); -} - -void VMM::remap(uint64_t vaddr, int flags) -{ - vaddr = round_down_to_nearest_page(vaddr); - - PageDirectoryEntry* pde = find_pde(current_pml4, vaddr); - if (!pde) return; // Not mapped - - if (flags & User) propagate_user(current_pml4, vaddr); - else - pde->user = false; - if (flags & ReadWrite) propagate_read_write(current_pml4, vaddr); - else - pde->read_write = false; - if (flags & Execute) pde->no_execute = false; - else - pde->no_execute = true; - if (flags & OwnedByTask) pde->owned_by_task = true; - else - pde->owned_by_task = false; - flush_tlb(vaddr); -} - -uint64_t VMM::get_physical(uint64_t vaddr) -{ - PageDirectoryEntry* pde = find_pde(current_pml4, round_down_to_nearest_page(vaddr)); - if (!pde) return UINT64_MAX; // Not mapped - - return pde->get_address() | (vaddr % PAGE_SIZE); -} - -uint64_t VMM::get_flags(uint64_t vaddr) -{ - PageDirectoryEntry* pde = find_pde(current_pml4, round_down_to_nearest_page(vaddr)); - if (!pde) return (uint64_t)-1; // Not mapped - - uint64_t flags = 0; - if (pde->user) flags |= User; - if (pde->read_write) flags |= ReadWrite; - if (!pde->no_execute) flags |= Execute; - if (pde->owned_by_task) flags |= OwnedByTask; - return flags; -} - -void VMM::map(uint64_t vaddr, uint64_t paddr, int flags) -{ - vaddr = round_down_to_nearest_page(vaddr); - PageDirectoryEntry* pde = find_pde(current_pml4, vaddr); - bool will_flush_tlb = true; - if (!pde) - { - pde = create_pde_if_not_exists(current_pml4, vaddr); - will_flush_tlb = false; - } - else if (pde->larger_pages) - { - unmap(vaddr); - pde = create_pde_if_not_exists(current_pml4, vaddr); - will_flush_tlb = false; // unmap() already flushes the TLB for us - } - - pde->set_address(round_down_to_nearest_page(paddr)); - if (flags & User) propagate_user(current_pml4, vaddr); - else - pde->user = false; - if (flags & ReadWrite) propagate_read_write(current_pml4, vaddr); - else - pde->read_write = false; - if (flags & Execute) pde->no_execute = false; - else - pde->no_execute = true; - if (flags & OwnedByTask) pde->owned_by_task = true; - else - pde->owned_by_task = false; - if (will_flush_tlb) flush_tlb(vaddr); -} - -PageDirectoryEntry* VMM::find_pde(PageTable* root, uint64_t vaddr) -{ - uint64_t page_index; - PageDirectoryEntry* pde; - PageTable* pt = root; - - uint64_t indexes[3]; - - decompose_vaddr(vaddr, page_index, indexes[2], indexes[1], indexes[0]); - - for (int i = 0; i < 3; - i++) // Walk through the page map level 4, page directory pointer, and page directory to find the page table. - { - pde = &pt->entries[indexes[i]]; - if (!pde->present) return nullptr; - else if (pde->larger_pages) - return pde; - else { pt = (PageTable*)pde->get_address(); } - } - - pde = &pt->entries[page_index]; // PT - if (!pde->present) return nullptr; - return pde; -} - -PageDirectoryEntry* VMM::create_pde_if_not_exists(PageTable* root, uint64_t vaddr) -{ - uint64_t page_index; - PageDirectoryEntry* pde; - PageTable* pt = root; - - uint64_t indexes[3]; - - decompose_vaddr(vaddr, page_index, indexes[2], indexes[1], indexes[0]); - - auto pde_create_if_not_present = [&]() { - auto pt_or_error = PMM::request_page(); - ensure(pt_or_error.has_value()); - pt = (PageTable*)pt_or_error.release_value(); - memset(pt, 0, PAGE_SIZE); - pde->set_address((uint64_t)pt); - pde->present = true; - }; - - for (int i = 0; i < 3; i++) - { - pde = &pt->entries[indexes[i]]; - if (!pde->present) { pde_create_if_not_present(); } - else if (pde->larger_pages) - return pde; - else { pt = (PageTable*)pde->get_address(); } - } - - pde = &pt->entries[page_index]; - if (!pde->present) { pde->present = true; } - return pde; -} - -void VMM::propagate_read_write(PageTable* root, uint64_t vaddr) -{ - uint64_t page_index; - PageDirectoryEntry* pde; - PageTable* pt = root; - - uint64_t indexes[3]; - - decompose_vaddr(vaddr, page_index, indexes[2], indexes[1], indexes[0]); - - for (int i = 0; i < 3; i++) - { - pde = &pt->entries[indexes[i]]; - if (!pde->present) return; - else - { - pde->read_write = true; - if (pde->larger_pages) return; - pt = (PageTable*)pde->get_address(); - } - } - - pde = &pt->entries[page_index]; - if (!pde->present) return; - else - pde->read_write = true; -} - -void VMM::propagate_user(PageTable* root, uint64_t vaddr) -{ - uint64_t page_index; - PageDirectoryEntry* pde; - PageTable* pt = root; - - uint64_t indexes[3]; - - decompose_vaddr(vaddr, page_index, indexes[2], indexes[1], indexes[0]); - - for (int i = 0; i < 3; i++) - { - pde = &pt->entries[indexes[i]]; - if (!pde->present) return; - else - { - pde->user = true; - if (pde->larger_pages) return; - pt = (PageTable*)pde->get_address(); - } - } - - pde = &pt->entries[page_index]; - if (!pde->present) return; - else - pde->user = true; -} - -void VMM::propagate_no_execute(PageTable* root, uint64_t vaddr) -{ - uint64_t page_index; - PageDirectoryEntry* pde; - PageTable* pt = root; - - uint64_t indexes[3]; - - decompose_vaddr(vaddr, page_index, indexes[2], indexes[1], indexes[0]); - - for (int i = 0; i < 3; i++) - { - pde = &pt->entries[indexes[i]]; - if (!pde->present) return; - else - { - pde->no_execute = true; - if (pde->larger_pages) return; - pt = (PageTable*)pde->get_address(); - } - } - - pde = &pt->entries[page_index]; - if (!pde->present) return; - else - pde->no_execute = true; -} - -void VMM::flush_tlb(uint64_t addr) -{ - asm volatile("invlpg (%0)" : : "r"(addr) : "memory"); -} - -void VMM::flush_tlb_full() -{ - write_cr3(current_pml4); -} - -void VMM::decompose_vaddr(uint64_t vaddr, uint64_t& page_index, uint64_t& pt_index, uint64_t& pd_index, - uint64_t& pdp_index) -{ - vaddr >>= 12; - page_index = vaddr & 0x1ff; - vaddr >>= 9; - pt_index = vaddr & 0x1ff; - vaddr >>= 9; - pd_index = vaddr & 0x1ff; - vaddr >>= 9; - pdp_index = vaddr & 0x1ff; -} - -uint64_t VMM::recompose_vaddr(uint64_t page_index, uint64_t pt_index, uint64_t pd_index, uint64_t pdp_index) -{ - return pdp_index << 39 | pd_index << 30 | pt_index << 21 | page_index << 12; -} - -void VMM::install_kernel_page_directory_into_address_space(AddressSpace& space) -{ - PageTable* space_pml4 = space.get_pml4(); - PageTable* kernel_last_pdp = (PageTable*)kernel_pml4->entries[511].get_address(); - PageTable* kernel_last_pd = (PageTable*)kernel_last_pdp->entries[511].get_address(); - - PageDirectoryEntry& space_last_pdp_pde = space_pml4->entries[511]; - - PageTable* space_last_pdp; - - if (!space_last_pdp_pde.present) - { - auto result = PMM::request_page(); - ensure(result.has_value()); // FIXME: Propagate this error. - space_last_pdp = (PageTable*)result.release_value(); - - memset(space_last_pdp, 0, PAGE_SIZE); - - space_last_pdp_pde.present = true; - space_last_pdp_pde.read_write = true; - space_last_pdp_pde.set_address((uint64_t)space_last_pdp); - } - else { space_last_pdp = (PageTable*)space_last_pdp_pde.get_address(); } - - PageDirectoryEntry& space_last_pd_pde = space_last_pdp->entries[511]; - - space_last_pd_pde.present = true; - space_last_pd_pde.read_write = true; - space_last_pd_pde.set_address((uint64_t)kernel_last_pd); -} \ No newline at end of file diff --git a/kernel/src/memory/liballoc/bindings.cpp b/kernel/src/memory/liballoc/bindings.cpp deleted file mode 100644 index 91b53e54..00000000 --- a/kernel/src/memory/liballoc/bindings.cpp +++ /dev/null @@ -1,30 +0,0 @@ -#include "memory/MemoryManager.h" -#include "thread/Spinlock.h" - -#include - -Spinlock alloc_lock; - -extern "C" int liballoc_lock() -{ - alloc_lock.acquire(); - return !alloc_lock.locked(); // Sanity check: the spinlock should be locked (return 0) -} - -extern "C" int liballoc_unlock() -{ - alloc_lock.release(); - return 0; // No sanity check this time because another thread could have acquired the lock the instant we let go of - // it. -} - -extern "C" void* liballoc_alloc(size_t count) -{ - return MemoryManager::get_pages(count).value_or(nullptr); -} - -extern "C" int liballoc_free(void* addr, size_t count) -{ - MemoryManager::release_pages(addr, count); - return 0; -} \ No newline at end of file diff --git a/kernel/src/memory/liballoc/liballoc.c b/kernel/src/memory/liballoc/liballoc.c deleted file mode 100644 index 6cc26933..00000000 --- a/kernel/src/memory/liballoc/liballoc.c +++ /dev/null @@ -1,721 +0,0 @@ -#define MODULE "alloc" - -#include "memory/liballoc/liballoc.h" -#include "log/CLog.h" - -#include - -#pragma GCC push_options -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wsign-conversion" // FIXME: Actually solve these warnings. - -/** Durand's Amazing Super Duper Memory functions. */ - -#define VERSION "1.1" -#define ALIGNMENT \ - 16ul // 4ul ///< This is the byte alignment that memory must be allocated on. IMPORTANT for GTK and - // other stuff. - -#define ALIGN_TYPE char /// unsigned char[16] /// unsigned short -#define ALIGN_INFO \ - sizeof(ALIGN_TYPE) * 16 ///< Alignment information is stored right before the pointer. This is the number of bytes - ///< of information stored there. - -#define USE_CASE1 -#define USE_CASE2 -#define USE_CASE3 -#define USE_CASE4 -#define USE_CASE5 - -/** This macro will conveniently align our pointer upwards */ -#define ALIGN(ptr) \ - if (ALIGNMENT > 1) \ - { \ - uintptr_t align_diff; \ - ptr = (void*)((uintptr_t)ptr + ALIGN_INFO); \ - align_diff = (uintptr_t)ptr & (ALIGNMENT - 1); \ - if (align_diff != 0) \ - { \ - align_diff = ALIGNMENT - align_diff; \ - ptr = (void*)((uintptr_t)ptr + align_diff); \ - } \ - *((ALIGN_TYPE*)((uintptr_t)ptr - ALIGN_INFO)) = align_diff + ALIGN_INFO; \ - } - -#define UNALIGN(ptr) \ - if (ALIGNMENT > 1) \ - { \ - uintptr_t align_diff = *((ALIGN_TYPE*)((uintptr_t)ptr - ALIGN_INFO)); \ - if (align_diff < (ALIGNMENT + ALIGN_INFO)) { ptr = (void*)((uintptr_t)ptr - align_diff); } \ - } - -#define LIBALLOC_MAGIC 0xc001c0de -#define LIBALLOC_DEAD 0xdeaddead - -#if defined DEBUG || defined INFO -#include -#include - -#define FLUSH() - -#endif - -/** A structure found at the top of all system allocated - * memory blocks. It details the usage of the memory block. - */ -struct liballoc_major -{ - struct liballoc_major* prev; ///< Linked list information. - struct liballoc_major* next; ///< Linked list information. - unsigned int pages; ///< The number of pages in the block. - unsigned int size; ///< The number of pages in the block. - unsigned int usage; ///< The number of bytes used in the block. - struct liballoc_minor* first; ///< A pointer to the first allocated memory in the block. -}; - -/** This is a structure found at the beginning of all - * sections in a major block which were allocated by a - * malloc, calloc, realloc call. - */ -struct liballoc_minor -{ - struct liballoc_minor* prev; ///< Linked list information. - struct liballoc_minor* next; ///< Linked list information. - struct liballoc_major* block; ///< The owning block. A pointer to the major structure. - unsigned int magic; ///< A magic number to idenfity correctness. - unsigned int size; ///< The size of the memory allocated. Could be 1 byte or more. - unsigned int req_size; ///< The size of memory requested. -}; - -static struct liballoc_major* l_memRoot = NULL; ///< The root memory block acquired from the system. -static struct liballoc_major* l_bestBet = NULL; ///< The major with the most free memory. - -static unsigned int l_pageSize = 4096; ///< The size of an individual page. Set up in liballoc_init. -static unsigned int l_pageCount = 16; ///< The number of pages to request per chunk. Set up in liballoc_init. -static unsigned long long l_allocated = 0; ///< Running total of allocated memory. -static unsigned long long l_inuse = 0; ///< Running total of used memory. - -static long long l_warningCount = 0; ///< Number of warnings encountered -static long long l_errorCount = 0; ///< Number of actual errors -static long long l_possibleOverruns = 0; ///< Number of possible overruns - -// *********** HELPER FUNCTIONS ******************************* - -static void* liballoc_memset(void* s, int c, size_t n) -{ - unsigned int i; - for (i = 0; i < n; i++) ((char*)s)[i] = c; - - return s; -} -static void* liballoc_memcpy(void* s1, const void* s2, size_t n) -{ - char* cdest; - const char* csrc; - unsigned int* ldest = (unsigned int*)s1; - const unsigned int* lsrc = (const unsigned int*)s2; - - while (n >= sizeof(unsigned int)) - { - *ldest++ = *lsrc++; - n -= sizeof(unsigned int); - } - - cdest = (char*)ldest; - csrc = (const char*)lsrc; - - while (n > 0) - { - *cdest++ = *csrc++; - n -= 1; - } - - return s1; -} - -#if defined DEBUG || defined INFO -static void liballoc_dump() -{ -#ifdef DEBUG - struct liballoc_major* maj = l_memRoot; - struct liballoc_minor* min = NULL; -#endif - - printf("liballoc: ------ Memory data ---------------\n"); - printf("liballoc: System memory allocated: %i bytes\n", l_allocated); - printf("liballoc: Memory in used (malloc'ed): %i bytes\n", l_inuse); - printf("liballoc: Warning count: %i\n", l_warningCount); - printf("liballoc: Error count: %i\n", l_errorCount); - printf("liballoc: Possible overruns: %i\n", l_possibleOverruns); - -#ifdef DEBUG - while (maj != NULL) - { - printf("liballoc: %x: total = %i, used = %i\n", maj, maj->size, maj->usage); - - min = maj->first; - while (min != NULL) - { - printf("liballoc: %x: %i bytes\n", min, min->size); - min = min->next; - } - - maj = maj->next; - } -#endif - - FLUSH(); -} -#endif - -// *************************************************************** - -static struct liballoc_major* allocate_new_page(unsigned int size) -{ - unsigned int st; - struct liballoc_major* maj; - - // This is how much space is required. - st = size + sizeof(struct liballoc_major); - st += sizeof(struct liballoc_minor); - - // Perfect amount of space? - if ((st % l_pageSize) == 0) st = st / (l_pageSize); - else - st = st / (l_pageSize) + 1; - // No, add the buffer. - - // Make sure it's >= the minimum size. - if (st < l_pageCount) st = l_pageCount; - - maj = (struct liballoc_major*)liballoc_alloc(st); - - if (maj == NULL) - { - l_warningCount += 1; -#if defined DEBUG || defined INFO - printf("liballoc: WARNING: liballoc_alloc( %i ) return NULL\n", st); - FLUSH(); -#endif - return NULL; // uh oh, we ran out of memory. - } - - maj->prev = NULL; - maj->next = NULL; - maj->pages = st; - maj->size = st * l_pageSize; - maj->usage = sizeof(struct liballoc_major); - maj->first = NULL; - - l_allocated += maj->size; - -#ifdef DEBUG - printf("liballoc: Resource allocated %x of %i pages (%i bytes) for %i size.\n", maj, st, maj->size, size); - - printf("liballoc: Total memory usage = %i KB\n", (int)((l_allocated / (1024)))); - FLUSH(); -#endif - - return maj; -} - -void* PREFIX(malloc)(size_t req_size) -{ - int startedBet = 0; - unsigned long long bestSize = 0; - void* p = NULL; - uintptr_t diff; - struct liballoc_major* maj; - struct liballoc_minor* min; - struct liballoc_minor* new_min; - unsigned long size = req_size; - - // For alignment, we adjust size so there's enough space to align. - if (ALIGNMENT > 1) { size += ALIGNMENT + ALIGN_INFO; } - // So, ideally, we really want an alignment of 0 or 1 in order - // to save space. - - liballoc_lock(); - - if (size == 0) - { - l_warningCount += 1; -#if defined DEBUG || defined INFO - printf("liballoc: WARNING: alloc( 0 ) called from %x\n", __builtin_return_address(0)); - FLUSH(); -#endif - liballoc_unlock(); - return PREFIX(malloc)(1); - } - - if (l_memRoot == NULL) - { -#if defined DEBUG || defined INFO -#ifdef DEBUG - printf("liballoc: initialization of liballoc " VERSION "\n"); -#endif - atexit(liballoc_dump); - FLUSH(); -#endif - - // This is the first time we are being used. - l_memRoot = allocate_new_page(size); - if (l_memRoot == NULL) - { - liballoc_unlock(); -#ifdef DEBUG - printf("liballoc: initial l_memRoot initialization failed\n", p); - FLUSH(); -#endif - return NULL; - } - -#ifdef DEBUG - printf("liballoc: set up first memory major %x\n", l_memRoot); - FLUSH(); -#endif - } - -#ifdef DEBUG - printf("liballoc: %x PREFIX(malloc)( %i ): ", __builtin_return_address(0), size); - FLUSH(); -#endif - - // Now we need to bounce through every major and find enough space.... - - maj = l_memRoot; - startedBet = 0; - - // Start at the best bet.... - if (l_bestBet != NULL) - { - bestSize = l_bestBet->size - l_bestBet->usage; - - if (bestSize > (size + sizeof(struct liballoc_minor))) - { - maj = l_bestBet; - startedBet = 1; - } - } - - while (maj != NULL) - { - diff = maj->size - maj->usage; - // free memory in the block - - if (bestSize < diff) - { - // Hmm.. this one has more memory then our bestBet. Remember! - l_bestBet = maj; - bestSize = diff; - } - -#ifdef USE_CASE1 - - // CASE 1: There is not enough space in this major block. - if (diff < (size + sizeof(struct liballoc_minor))) - { -#ifdef DEBUG - printf("CASE 1: Insufficient space in block %x\n", maj); - FLUSH(); -#endif - - // Another major block next to this one? - if (maj->next != NULL) - { - maj = maj->next; // Hop to that one. - continue; - } - - if (startedBet == 1) // If we started at the best bet, - { // let's start all over again. - maj = l_memRoot; - startedBet = 0; - continue; - } - - // Create a new major block next to this one and... - maj->next = allocate_new_page(size); // next one will be okay. - if (maj->next == NULL) break; // no more memory. - maj->next->prev = maj; - maj = maj->next; - - // .. fall through to CASE 2 .. - } - -#endif - -#ifdef USE_CASE2 - - // CASE 2: It's a brand new block. - if (maj->first == NULL) - { - maj->first = (struct liballoc_minor*)((uintptr_t)maj + sizeof(struct liballoc_major)); - - maj->first->magic = LIBALLOC_MAGIC; - maj->first->prev = NULL; - maj->first->next = NULL; - maj->first->block = maj; - maj->first->size = size; - maj->first->req_size = req_size; - maj->usage += size + sizeof(struct liballoc_minor); - - l_inuse += size; - - p = (void*)((uintptr_t)(maj->first) + sizeof(struct liballoc_minor)); - - ALIGN(p); - -#ifdef DEBUG - printf("CASE 2: returning %x\n", p); - FLUSH(); -#endif - liballoc_unlock(); // release the lock - return p; - } - -#endif - -#ifdef USE_CASE3 - - // CASE 3: Block in use and enough space at the start of the block. - diff = (uintptr_t)(maj->first); - diff -= (uintptr_t)maj; - diff -= sizeof(struct liballoc_major); - - if (diff >= (size + sizeof(struct liballoc_minor))) - { - // Yes, space in front. Squeeze in. - maj->first->prev = (struct liballoc_minor*)((uintptr_t)maj + sizeof(struct liballoc_major)); - maj->first->prev->next = maj->first; - maj->first = maj->first->prev; - - maj->first->magic = LIBALLOC_MAGIC; - maj->first->prev = NULL; - maj->first->block = maj; - maj->first->size = size; - maj->first->req_size = req_size; - maj->usage += size + sizeof(struct liballoc_minor); - - l_inuse += size; - - p = (void*)((uintptr_t)(maj->first) + sizeof(struct liballoc_minor)); - ALIGN(p); - -#ifdef DEBUG - printf("CASE 3: returning %x\n", p); - FLUSH(); -#endif - liballoc_unlock(); // release the lock - return p; - } - -#endif - -#ifdef USE_CASE4 - - // CASE 4: There is enough space in this block. But is it contiguous? - min = maj->first; - - // Looping within the block now... - while (min != NULL) - { - // CASE 4.1: End of minors in a block. Space from last and end? - if (min->next == NULL) - { - // the rest of this block is free... is it big enough? - diff = (uintptr_t)(maj) + maj->size; - diff -= (uintptr_t)min; - diff -= sizeof(struct liballoc_minor); - diff -= min->size; - // minus already existing usage.. - - if (diff >= (size + sizeof(struct liballoc_minor))) - { - // yay.... - min->next = (struct liballoc_minor*)((uintptr_t)min + sizeof(struct liballoc_minor) + min->size); - min->next->prev = min; - min = min->next; - min->next = NULL; - min->magic = LIBALLOC_MAGIC; - min->block = maj; - min->size = size; - min->req_size = req_size; - maj->usage += size + sizeof(struct liballoc_minor); - - l_inuse += size; - - p = (void*)((uintptr_t)min + sizeof(struct liballoc_minor)); - ALIGN(p); - -#ifdef DEBUG - printf("CASE 4.1: returning %x\n", p); - FLUSH(); -#endif - liballoc_unlock(); // release the lock - return p; - } - } - - // CASE 4.2: Is there space between two minors? - if (min->next != NULL) - { - // is the difference between here and next big enough? - diff = (uintptr_t)(min->next); - diff -= (uintptr_t)min; - diff -= sizeof(struct liballoc_minor); - diff -= min->size; - // minus our existing usage. - - if (diff >= (size + sizeof(struct liballoc_minor))) - { - // yay...... - new_min = (struct liballoc_minor*)((uintptr_t)min + sizeof(struct liballoc_minor) + min->size); - - new_min->magic = LIBALLOC_MAGIC; - new_min->next = min->next; - new_min->prev = min; - new_min->size = size; - new_min->req_size = req_size; - new_min->block = maj; - min->next->prev = new_min; - min->next = new_min; - maj->usage += size + sizeof(struct liballoc_minor); - - l_inuse += size; - - p = (void*)((uintptr_t)new_min + sizeof(struct liballoc_minor)); - ALIGN(p); - -#ifdef DEBUG - printf("CASE 4.2: returning %x\n", p); - FLUSH(); -#endif - - liballoc_unlock(); // release the lock - return p; - } - } // min->next != NULL - - min = min->next; - } // while min != NULL ... - -#endif - -#ifdef USE_CASE5 - - // CASE 5: Block full! Ensure next block and loop. - if (maj->next == NULL) - { -#ifdef DEBUG - printf("CASE 5: block full\n"); - FLUSH(); -#endif - - if (startedBet == 1) - { - maj = l_memRoot; - startedBet = 0; - continue; - } - - // we've run out. we need more... - maj->next = allocate_new_page(size); // next one guaranteed to be okay - if (maj->next == NULL) break; // uh oh, no more memory..... - maj->next->prev = maj; - } - -#endif - - maj = maj->next; - } // while (maj != NULL) - - liballoc_unlock(); // release the lock - -#ifdef DEBUG - printf("All cases exhausted. No memory available.\n"); - FLUSH(); -#endif -#if defined DEBUG || defined INFO - printf("liballoc: WARNING: PREFIX(malloc)( %i ) returning NULL.\n", size); - liballoc_dump(); - FLUSH(); -#endif - return NULL; -} - -void PREFIX(free)(void* ptr) -{ - struct liballoc_minor* min; - struct liballoc_major* maj; - - if (ptr == NULL) - { - l_warningCount += 1; - kwarnln("kfree( NULL ) called from %p", __builtin_return_address(0)); - return; - } - - UNALIGN(ptr); - - liballoc_lock(); // lockit - - min = (struct liballoc_minor*)((uintptr_t)ptr - sizeof(struct liballoc_minor)); - - if (min->magic != LIBALLOC_MAGIC) - { - l_errorCount += 1; - - // Check for overrun errors. For all bytes of LIBALLOC_MAGIC - if (((min->magic & 0xFFFFFF) == (LIBALLOC_MAGIC & 0xFFFFFF)) || - ((min->magic & 0xFFFF) == (LIBALLOC_MAGIC & 0xFFFF)) || ((min->magic & 0xFF) == (LIBALLOC_MAGIC & 0xFF))) - { - l_possibleOverruns += 1; - kerrorln("Possible 1-3 byte overrun for magic %x != %x", min->magic, LIBALLOC_MAGIC); - } - - if (min->magic == LIBALLOC_DEAD) - { - kerrorln("double free attempt on %p from %p.", ptr, __builtin_return_address(0)); - } - else { kerrorln("Bad kfree(%p) called from %p\n", ptr, __builtin_return_address(0)); } - - // being lied to... - liballoc_unlock(); // release the lock - return; - } - -#ifdef DEBUG - printf("liballoc: %x PREFIX(free)( %x ): ", __builtin_return_address(0), ptr); - FLUSH(); -#endif - - maj = min->block; - - l_inuse -= min->size; - - maj->usage -= (min->size + sizeof(struct liballoc_minor)); - min->magic = LIBALLOC_DEAD; // No mojo. - - if (min->next != NULL) min->next->prev = min->prev; - if (min->prev != NULL) min->prev->next = min->next; - - if (min->prev == NULL) maj->first = min->next; - // Might empty the block. This was the first - // minor. - - // We need to clean up after the majors now.... - - if (maj->first == NULL) // Block completely unused. - { - if (l_memRoot == maj) l_memRoot = maj->next; - if (l_bestBet == maj) l_bestBet = NULL; - if (maj->prev != NULL) maj->prev->next = maj->next; - if (maj->next != NULL) maj->next->prev = maj->prev; - l_allocated -= maj->size; - - liballoc_free(maj, maj->pages); - } - else - { - if (l_bestBet != NULL) - { - int bestSize = l_bestBet->size - l_bestBet->usage; - int majSize = maj->size - maj->usage; - - if (majSize > bestSize) l_bestBet = maj; - } - } - -#ifdef DEBUG - printf("OK\n"); - FLUSH(); -#endif - - liballoc_unlock(); // release the lock -} - -void* PREFIX(calloc)(size_t nobj, size_t size) -{ - int real_size; - void* p; - - real_size = nobj * size; - - p = PREFIX(malloc)(real_size); - - liballoc_memset(p, 0, real_size); - - return p; -} - -void* PREFIX(realloc)(void* p, size_t size) -{ - void* ptr; - struct liballoc_minor* min; - unsigned int real_size; - - // Honour the case of size == 0 => free old and return NULL - if (size == 0) - { - PREFIX(free)(p); - return NULL; - } - - // In the case of a NULL pointer, return a simple malloc. - if (p == NULL) return PREFIX(malloc)(size); - - // Unalign the pointer if required. - ptr = p; - UNALIGN(ptr); - - liballoc_lock(); // lockit - - min = (struct liballoc_minor*)((uintptr_t)ptr - sizeof(struct liballoc_minor)); - - // Ensure it is a valid structure. - if (min->magic != LIBALLOC_MAGIC) - { - l_errorCount += 1; - - // Check for overrun errors. For all bytes of LIBALLOC_MAGIC - if (((min->magic & 0xFFFFFF) == (LIBALLOC_MAGIC & 0xFFFFFF)) || - ((min->magic & 0xFFFF) == (LIBALLOC_MAGIC & 0xFFFF)) || ((min->magic & 0xFF) == (LIBALLOC_MAGIC & 0xFF))) - { - l_possibleOverruns += 1; - kerrorln("Possible 1-3 byte overrun for magic %x != %x", min->magic, LIBALLOC_MAGIC); - } - - if (min->magic == LIBALLOC_DEAD) - { - kerrorln("realloc after free attempt on %p from %p.", ptr, __builtin_return_address(0)); - } - else { kerrorln("Bad krealloc(%p) called from %p\n", ptr, __builtin_return_address(0)); } - - // being lied to... - liballoc_unlock(); // release the lock - return NULL; - } - - // Definitely a memory block. - - real_size = min->req_size; - - if (real_size >= size) - { - min->req_size = size; - liballoc_unlock(); - return p; - } - - liballoc_unlock(); - - // If we got here then we're reallocating to a block bigger than us. - ptr = PREFIX(malloc)(size); // We need to allocate new memory - liballoc_memcpy(ptr, p, real_size); - PREFIX(free)(p); - - return ptr; -} - -#pragma GCC pop_options diff --git a/kernel/src/misc/MSR.cpp b/kernel/src/misc/MSR.cpp deleted file mode 100644 index d38140bd..00000000 --- a/kernel/src/misc/MSR.cpp +++ /dev/null @@ -1,43 +0,0 @@ -#include "misc/MSR.h" - -void MSR::write_to(uint32_t msr_num, uint64_t value) -{ - uint32_t lo = value & 0xFFFFFFFF; - uint32_t hi = (uint32_t)(value >> 32); - asm volatile("wrmsr" : : "a"(lo), "d"(hi), "c"(msr_num)); -} - -uint64_t MSR::read_from(uint32_t msr_num) -{ - uint32_t lo; - uint32_t hi; - asm volatile("rdmsr" : "=a"(lo), "=d"(hi) : "c"(msr_num)); - return (uint64_t)hi << 32 | (uint64_t)lo; -} - -void MSR::write(uint64_t value) -{ - write_to(m_msr_num, value); -} - -uint64_t MSR::read() -{ - return read_from(m_msr_num); -} - -MSR::MSR(uint32_t msr_num) : m_msr_num(msr_num) -{ -} - -void MSR::with_value_of(uint32_t msr_num, void (*callback)(uint64_t&)) -{ - MSR msr(msr_num); - msr.with_value(callback); -} - -void MSR::with_value(void (*callback)(uint64_t&)) -{ - uint64_t value = read(); - callback(value); - write(value); -} \ No newline at end of file diff --git a/kernel/src/misc/PCITypes.cpp b/kernel/src/misc/PCITypes.cpp deleted file mode 100644 index d8a49c5e..00000000 --- a/kernel/src/misc/PCITypes.cpp +++ /dev/null @@ -1,85 +0,0 @@ -#include "misc/PCITypes.h" - -static const char* unclassified_device(PCI::DeviceType type) -{ - switch (type.dev_subclass) - { - case 0x0: return "Non-VGA-Compatible Unclassified Device"; - case 0x1: return "VGA-Compatible Unclassified Device"; - - default: return "Unclassified"; - } -} - -static const char* display_controller(PCI::DeviceType type) -{ - switch (type.dev_subclass) - { - case 0x0: return type.prog_if == 1 ? "8514-Compatible Controller" : "VGA Controller"; - case 0x1: return "XGA Controller"; - case 0x2: return "3D Controller (Not VGA-Compatible)"; - case 0x80: return "Display Controller"; - - default: return "Unknown Display Controller"; - } -} - -static const char* memory_controller(PCI::DeviceType type) -{ - switch (type.dev_subclass) - { - case 0x0: return "RAM Controller"; - case 0x1: return "Flash Controller"; - case 0x80: return "Memory Controller"; - - default: return "Unknown Memory Controller"; - } -} - -static const char* processor(PCI::DeviceType type) -{ - switch (type.dev_subclass) - { - case 0x0: return "Processor (386)"; - case 0x1: return "Processor (486)"; - case 0x2: return "Processor (Pentium)"; - case 0x3: return "Processor (Pentium Pro)"; - case 0x10: return "Processor (Alpha)"; - case 0x20: return "Processor (PowerPC)"; - case 0x30: return "Processor (MIPS)"; - case 0x40: return "Co-Processor"; - case 0x80: return "Processor"; - - default: return "Unknown Processor"; - } -} - -const char* pci_type_name(PCI::DeviceType type) -{ - switch (type.dev_class) - { - case 0x0: return unclassified_device(type); - case 0x1: return "Mass Storage Controller"; - case 0x2: return "Network Controller"; - case 0x3: return display_controller(type); - case 0x4: return "Multimedia Controller"; - case 0x5: return memory_controller(type); - case 0x6: return "Bridge"; - case 0x7: return "Simple Communication Controller"; - case 0x8: return "Base System Peripheral"; - case 0x9: return "Input Device Controller"; - case 0xA: return "Docking Station"; - case 0xB: return processor(type); - case 0xC: return "Serial Bus Controller"; - case 0xD: return "Wireless Controller"; - case 0xE: return "Intelligent Controller (I20)"; - case 0xF: return "Satellite Communication Controller"; - case 0x10: return "Encryption Controller"; - case 0x11: return "Signal Processing Controller"; - case 0x12: return "Processing Accelerator"; - case 0x13: return "Non-Essential Instrumentation"; - case 0x40: return "Co-Processor"; - - default: return "Unknown"; - } -} \ No newline at end of file diff --git a/kernel/src/misc/Scancodes.cpp b/kernel/src/misc/Scancodes.cpp deleted file mode 100644 index c694a4d5..00000000 --- a/kernel/src/misc/Scancodes.cpp +++ /dev/null @@ -1,168 +0,0 @@ -#include "misc/Scancodes.h" - -#define SCANCODE_EXTENDED 0xE0 - -bool scancode_filter_released(unsigned char* scancode) -{ - if (*scancode > 0x80) - { - *scancode -= 0x80; - return true; - } - return false; -} - -static bool next_key_ignored = false; // FIXME: Do not ignore extended scancodes. - -static bool left_shifted = false; -static bool right_shifted = false; -static bool capslock = false; - -static bool should_shift() -{ - if (capslock) return !(left_shifted || right_shifted); - return left_shifted || right_shifted; -} - -#define SCANCODE_LEFT_SHIFT 0x2A -#define SCANCODE_RIGHT_SHIFT 0x36 -#define SCANCODE_CAPS_LOCK 0x3A - -#define SCANCODE_LEFT_CONTROL 0x1D -#define SCANCODE_TAB 0x0F -#define SCANCODE_LEFT_ALT 0x38 -#define SCANCODE_F11 0x57 -#define SCANCODE_F12 0x58 - -static bool should_ignore_key(char scancode) -{ - return (scancode > 0x3A && scancode < 0x47) || scancode == SCANCODE_LEFT_CONTROL || scancode == SCANCODE_TAB || - scancode == SCANCODE_LEFT_ALT || scancode == SCANCODE_F11 || scancode == SCANCODE_F12; -} - -char keys_normal[] = { - '\0', - '\1', // escape - '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', '\b', - '\0', // tab - 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']', '\n', - '\0', // left ctrl - 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', '\'', '`', - '\0', // left shift - '\\', 'z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '/', - '\0', // right shift - '*', // keypad * - '\0', // left alt - ' ', - '\0', // caps lock - '\0', // f1 - '\0', // f2 - '\0', // f3 - '\0', // f4 - '\0', // f5 - '\0', // f6 - '\0', // f7 - '\0', // f8 - '\0', // f9 - '\0', // f10 - '\0', // num lock - '\0', // scroll lock - '7', // keypad 7 - '8', // keypad 8 - '9', // keypad 9 - '-', // keypad - - '4', // keypad 4 - '5', // keypad 5 - '6', // keypad 6 - '+', // keypad + - '1', // keypad 1 - '2', // keypad 2 - '3', // keypad 3 - '0', // keypad 0 - '.', // keypad . -}; - -char keys_shifted[] = { - '\0', - '\1', // escape - '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_', '+', '\b', - '\0', // tab - 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '{', '}', '\n', - '\0', // left ctrl - 'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', '"', '~', - '\0', // left shift - '|', 'Z', 'X', 'C', 'V', 'B', 'N', 'M', '<', '>', '?', - '\0', // right shift - '*', // keypad * - '\0', // left alt - ' ', - '\0', // caps lock - '\0', // f1 - '\0', // f2 - '\0', // f3 - '\0', // f4 - '\0', // f5 - '\0', // f6 - '\0', // f7 - '\0', // f8 - '\0', // f9 - '\0', // f10 - '\0', // num lock - '\0', // scroll lock - '7', // keypad 7 - '8', // keypad 8 - '9', // keypad 9 - '-', // keypad - - '4', // keypad 4 - '5', // keypad 5 - '6', // keypad 6 - '+', // keypad + - '1', // keypad 1 - '2', // keypad 2 - '3', // keypad 3 - '0', // keypad 0 - '.', // keypad . -}; - -char translate_scancode(unsigned char scancode, bool* ignore) -{ - if (next_key_ignored) - { - next_key_ignored = false; - *ignore = true; - return 0; - } - if (scancode == SCANCODE_EXTENDED) - { - next_key_ignored = true; - *ignore = true; - return 0; - } - bool released = scancode_filter_released(&scancode); - if (scancode == SCANCODE_CAPS_LOCK) - { - if (!released) { capslock = !capslock; } - *ignore = true; - return 0; - } - if (scancode == SCANCODE_LEFT_SHIFT) - { - left_shifted = !released; - *ignore = true; - return 0; - } - if (scancode == SCANCODE_RIGHT_SHIFT) - { - right_shifted = !released; - *ignore = true; - return 0; - } - if (released || should_ignore_key(scancode)) - { - *ignore = true; - return 0; - } - *ignore = false; - if (should_shift()) { return keys_shifted[scancode]; } - return keys_normal[scancode]; -} \ No newline at end of file diff --git a/kernel/src/misc/config.cpp b/kernel/src/misc/config.cpp deleted file mode 100644 index 0e364f8f..00000000 --- a/kernel/src/misc/config.cpp +++ /dev/null @@ -1,38 +0,0 @@ -#include "config.h" - -#define STRINGIZE(x) #x -#define STRINGIZE_VALUE_OF(x) STRINGIZE(x) - -#ifndef MOON_MAJOR -#define MOON_MAJOR 0 -#endif - -#ifndef MOON_MINOR -#define MOON_MINOR 15 -#endif - -#ifndef _MOON_SUFFIX -#define MOON_SUFFIX "" -#else -#define MOON_SUFFIX STRINGIZE_VALUE_OF(_MOON_SUFFIX) -#endif - -int __moon_version_major() -{ - return MOON_MAJOR; -} - -int __moon_version_minor() -{ - return MOON_MINOR; -} - -const char* __moon_version_suffix() -{ - return MOON_SUFFIX; -} - -const char* moon_version() -{ - return STRINGIZE_VALUE_OF(MOON_MAJOR) "." STRINGIZE_VALUE_OF(MOON_MINOR) MOON_SUFFIX; -} diff --git a/kernel/src/misc/cxxabi.cpp b/kernel/src/misc/cxxabi.cpp deleted file mode 100644 index 48898377..00000000 --- a/kernel/src/misc/cxxabi.cpp +++ /dev/null @@ -1,52 +0,0 @@ -typedef void* (*cxa_atexit_func_t)(void*); - -struct cxa_atexit_entry -{ - cxa_atexit_func_t function; - void* argument; - void* dso_handle; -}; - -#define CXA_ATEXIT_MAX 64 - -int cxa_atexit_entry_count = 0; - -cxa_atexit_entry cxa_atexit_entries[CXA_ATEXIT_MAX]; - -__attribute__((visibility("hidden"))) void* __dso_handle = 0; - -extern "C" -{ - int __cxa_atexit(cxa_atexit_func_t func, void* arg, void* dso) - { - if (cxa_atexit_entry_count >= CXA_ATEXIT_MAX) return -1; - cxa_atexit_entries[cxa_atexit_entry_count].function = func; - cxa_atexit_entries[cxa_atexit_entry_count].argument = arg; - cxa_atexit_entries[cxa_atexit_entry_count].dso_handle = dso; - cxa_atexit_entry_count++; - return 0; - } - - void __cxa_finalize(void* f) - { - int i = cxa_atexit_entry_count; - if (!f) - { - while (i--) - { - if (cxa_atexit_entries[i].function) { cxa_atexit_entries[i].function(cxa_atexit_entries[i].argument); } - } - } - else - { - while (i--) - { - if (cxa_atexit_entries[i].function == (cxa_atexit_func_t)f) - { - cxa_atexit_entries[i].function(cxa_atexit_entries[i].argument); - cxa_atexit_entries[i].function = 0; - } - } - } - } -} \ No newline at end of file diff --git a/kernel/src/misc/hang.cpp b/kernel/src/misc/hang.cpp deleted file mode 100644 index e655f0c5..00000000 --- a/kernel/src/misc/hang.cpp +++ /dev/null @@ -1,14 +0,0 @@ -#include "misc/hang.h" - -[[noreturn]] void hang() -{ - asm volatile("cli"); -end: - halt(); - goto end; -} - -void halt() -{ - asm volatile("hlt"); -} \ No newline at end of file diff --git a/kernel/src/misc/new.cpp b/kernel/src/misc/new.cpp deleted file mode 100644 index 8ecd8175..00000000 --- a/kernel/src/misc/new.cpp +++ /dev/null @@ -1,32 +0,0 @@ -#include "std/stdlib.h" -#include - -void* operator new(size_t size) -{ - return kmalloc(size); -} - -void* operator new[](size_t size) -{ - return kmalloc(size); -} - -void operator delete(void* p) -{ - kfree(p); -} - -void operator delete[](void* p) -{ - kfree(p); -} - -void operator delete(void* p, size_t) -{ - kfree(p); -} - -void operator delete[](void* p, size_t) -{ - kfree(p); -} \ No newline at end of file diff --git a/kernel/src/misc/reboot.cpp b/kernel/src/misc/reboot.cpp deleted file mode 100644 index 8f134556..00000000 --- a/kernel/src/misc/reboot.cpp +++ /dev/null @@ -1,102 +0,0 @@ -#define MODULE "power" - -#include "misc/reboot.h" -#include "acpi/FADT.h" -#include "acpi/RSDT.h" -#include "assert.h" -#include "interrupts/IDT.h" -#include "interrupts/Interrupts.h" -#include "io/IO.h" -#include "log/Log.h" -#include "memory/VMM.h" -#include "misc/hang.h" -#include "std/string.h" - -static void try_acpi_reboot() -{ - kdbgln("Fetching pointer to RSDT/XSDT"); - ACPI::SDTHeader* rootSDT = ACPI::get_rsdt_or_xsdt(); - if (!rootSDT) - { - kwarnln("The pointer to the RSDT/XSDT is null"); - return; - } - if (!ACPI::validate_rsdt_or_xsdt(rootSDT)) - { - kwarnln("The RSDT/XSDT is invalid"); - return; - } - kdbgln("Searching for the FADT"); - ACPI::FADT* fadt = (ACPI::FADT*)ACPI::find_table(rootSDT, "FACP"); - if (!fadt) - { - kwarnln("Unable to find the FADT"); - return; - } - if (fadt->header.Revision < 2) - { - kwarnln("ACPI revision is too low (%d), ACPI Reset is only implemented in ACPI 2.0+", fadt->header.Revision); - return; - } - if (!(fadt->Flags & 1 << 10)) - { - kwarnln("This system does not support ACPI Reset"); - return; - } - switch (fadt->ResetReg.AddressSpace) - { - case ACPI::SystemIO: - kdbgln("Attempting ACPI Reset via SystemIO: sending byte %d to port %lx", fadt->ResetValue, - fadt->ResetReg.Address); - IO::outb((uint16_t)fadt->ResetReg.Address, fadt->ResetValue); - break; - case ACPI::GeneralPurposeIO: - kdbgln("Attempting ACPI Reset via GeneralPurposeIO: sending byte %d to port %lx", fadt->ResetValue, - fadt->ResetReg.Address); - IO::outb((uint16_t)fadt->ResetReg.Address, fadt->ResetValue); - break; - default: kwarnln("This method of rebooting via ACPI is not yet implemented"); return; - } - kerrorln("Tried to reboot, but apparently did nothing"); -} - -static void try_kbd_reboot() -{ - Interrupts::disable(); - - uint8_t temp; - do { - temp = IO::inb(0x64); - if (temp & 0b1) IO::inb(0x60); - } while (temp & 0b10); - - IO::outb(0x64, 0xFE); -} - -static void try_idt_triple_fault() -{ - IDTR idtr; - idtr.limit = 0x0000; - idtr.offset = 0x0000; - asm volatile("lidt %0" : : "m"(idtr)); - Interrupts::enable(); - asm volatile("int $0x80"); -} - -[[noreturn]] void reboot() -{ - Interrupts::disable(); - if (!VMM::is_using_kernel_address_space()) - { - VMM::switch_back_to_kernel_address_space(); - VMM::apply_address_space(); - } - kinfoln("Attempting reboot using ACPI"); - try_acpi_reboot(); - kinfoln("Attempting reboot using keyboard RESET pulsing"); - try_kbd_reboot(); - kinfoln("Attempting reboot by triple faulting"); - try_idt_triple_fault(); - kerrorln("Failed to reboot, halting machine"); - hang(); -} \ No newline at end of file diff --git a/kernel/src/misc/shutdown.cpp b/kernel/src/misc/shutdown.cpp deleted file mode 100644 index 3087ab1a..00000000 --- a/kernel/src/misc/shutdown.cpp +++ /dev/null @@ -1,20 +0,0 @@ -#define MODULE "power" - -#include "misc/shutdown.h" -#include "interrupts/Interrupts.h" -#include "io/IO.h" -#include "log/Log.h" -#include "misc/hang.h" - -[[noreturn]] void shutdown() -{ - Interrupts::disable(); - kinfoln("Attempting shutdown using the Bochs method"); - IO::outw(0xB004, 0x2000); - kinfoln("Attempting shutdown using the QEMU method"); - IO::outw(0x604, 0x2000); - kinfoln("Attempting shutdown using the VirtualBox method"); - IO::outw(0x4004, 0x3400); - kerrorln("Failed to shutdown, halting. It is now safe to turn off your computer manually, though."); - hang(); -} \ No newline at end of file diff --git a/kernel/src/misc/stack.cpp b/kernel/src/misc/stack.cpp deleted file mode 100644 index 781b9f29..00000000 --- a/kernel/src/misc/stack.cpp +++ /dev/null @@ -1,14 +0,0 @@ -#define MODULE "stack" - -#include "log/Log.h" -#include "misc/hang.h" -#include "render/TextRenderer.h" -#include - -extern "C" void __stack_chk_fail() -{ - KernelLog::enable_log_backend(Backend::Console); - TextRenderer::reset(); - kerrorln("stack smashing detected"); - hang(); -} \ No newline at end of file diff --git a/kernel/src/misc/ubsan.cpp b/kernel/src/misc/ubsan.cpp deleted file mode 100644 index d9394956..00000000 --- a/kernel/src/misc/ubsan.cpp +++ /dev/null @@ -1,205 +0,0 @@ -#define MODULE "ubsan" - -#include -#include -#include - -#pragma GCC push_options -#pragma GCC diagnostic ignored "-Wpedantic" - -struct source_location -{ - const char* file; - uint32_t line; - uint32_t column; -}; - -struct type_descriptor -{ - uint16_t kind; - uint16_t info; - char name[]; -}; - -struct type_mismatch_info -{ - struct source_location location; - struct type_descriptor* type; - uintptr_t alignment; - uint8_t type_check_kind; -}; - -struct type_mismatch_info_v1 -{ - struct source_location location; - struct type_descriptor* type; - unsigned char log_alignment; - unsigned char type_check_kind; -}; - -struct overflow_info -{ - struct source_location location; - struct type_descriptor* type; -}; - -struct unreachable_info -{ - struct source_location location; -}; - -struct out_of_bounds_info -{ - struct source_location location; - struct type_descriptor* array_type; - struct type_descriptor* index_type; -}; - -struct invalid_value_info -{ - struct source_location location; - struct type_descriptor* type; -}; - -struct shift_out_of_bounds_info -{ - struct source_location location; - struct type_descriptor* lhs_type; - struct type_descriptor* rhs_type; -}; - -struct pointer_overflow_info -{ - struct source_location location; -}; - -#define is_aligned(value, alignment) !(value & (alignment - 1)) - -const char* Type_Check_Kinds[] = { - "load of", - "store to", - "reference binding to", - "member access within", - "member call on", - "constructor call on", - "downcast of", - "downcast of", - "upcast of", - "cast to virtual base of", -}; - -static void log_location(source_location* location) -{ - kinfoln("at %s:%d:%d", location->file, location->line, location->column); -} - -extern "C" void __ubsan_handle_type_mismatch(type_mismatch_info* type_mismatch, uintptr_t pointer) -{ - source_location* location = &type_mismatch->location; - if (pointer == 0) { kinfoln("Null pointer access"); } - else if (type_mismatch->alignment != 0 && is_aligned(pointer, type_mismatch->alignment)) - { - // Most useful on architectures with stricter memory alignment requirements, like ARM. - kinfoln("Unaligned memory access"); - } - else - { - kinfoln("Insufficient size"); - kinfoln("%s address %p with insufficient space for object of type %s\n", - Type_Check_Kinds[type_mismatch->type_check_kind], (void*)pointer, type_mismatch->type->name); - } - log_location(location); - panic("Undefined behaviour detected"); -} - -extern "C" void __ubsan_handle_type_mismatch_v1(type_mismatch_info_v1* type_mismatch, unsigned long pointer) -{ - type_mismatch_info info = {type_mismatch->location, type_mismatch->type, 1UL << type_mismatch->log_alignment, - type_mismatch->type_check_kind}; - - __ubsan_handle_type_mismatch(&info, pointer); -} - -extern "C" void __ubsan_handle_add_overflow(overflow_info* overflow_data, uintptr_t, uintptr_t) -{ - source_location* location = &overflow_data->location; - kinfoln("Addition overflow for two values of type %s", overflow_data->type->name); - log_location(location); - panic("Undefined behaviour detected"); -} - -extern "C" void __ubsan_handle_sub_overflow(overflow_info* overflow_data, uintptr_t, uintptr_t) -{ - source_location* location = &overflow_data->location; - kinfoln("Substraction overflow for two values of type %s", overflow_data->type->name); - log_location(location); - panic("Undefined behaviour detected"); -} - -extern "C" void __ubsan_handle_mul_overflow(overflow_info* overflow_data, uintptr_t, uintptr_t) -{ - source_location* location = &overflow_data->location; - kinfoln("Multiplication overflow for two values of type %s", overflow_data->type->name); - log_location(location); - panic("Undefined behaviour detected"); -} - -extern "C" void __ubsan_handle_negate_overflow(overflow_info* overflow_data, uintptr_t) -{ - source_location* location = &overflow_data->location; - kinfoln("Negation overflow for two values of type %s", overflow_data->type->name); - log_location(location); - panic("Undefined behaviour detected"); -} - -extern "C" void __ubsan_handle_divrem_overflow(overflow_info* overflow_data, uintptr_t, uintptr_t) -{ - source_location* location = &overflow_data->location; - kinfoln("Division overflow for two values of type %s", overflow_data->type->name); - log_location(location); - panic("Undefined behaviour detected"); -} - -extern "C" void __ubsan_handle_builtin_unreachable(unreachable_info* unreachable_data) -{ - source_location* location = &unreachable_data->location; - kinfoln("Reached the unreachable"); - log_location(location); - panic("Undefined behaviour detected"); -} - -extern "C" void __ubsan_handle_out_of_bounds(out_of_bounds_info* out_of_bounds_data, uintptr_t index) -{ - source_location* location = &out_of_bounds_data->location; - kinfoln("Out of bounds access at index %ld of array type %s and index type %s", index, - out_of_bounds_data->array_type->name, out_of_bounds_data->index_type->name); - log_location(location); - panic("Undefined behaviour detected"); -} - -extern "C" void __ubsan_handle_load_invalid_value(invalid_value_info* invalid_value_data, uintptr_t) -{ - source_location* location = &invalid_value_data->location; - kinfoln("Invalid value load of type %s", invalid_value_data->type->name); - log_location(location); - panic("Undefined behaviour detected"); -} - -extern "C" void __ubsan_handle_shift_out_of_bounds(shift_out_of_bounds_info* shift_out_of_bounds_data, uintptr_t, - uintptr_t) -{ - source_location* location = &shift_out_of_bounds_data->location; - kinfoln("Shift out of bounds for type %s", shift_out_of_bounds_data->lhs_type->name); - log_location(location); - panic("Undefined behaviour detected"); -} - -extern "C" void __ubsan_handle_pointer_overflow(pointer_overflow_info* pointer_overflow_data, uintptr_t, uintptr_t) -{ - source_location* location = &pointer_overflow_data->location; - kinfoln("Pointer overflow"); - log_location(location); - panic("Undefined behaviour detected"); -} - -#pragma GCC pop_options \ No newline at end of file diff --git a/kernel/src/panic/Panic.cpp b/kernel/src/panic/Panic.cpp deleted file mode 100644 index 1e6565e0..00000000 --- a/kernel/src/panic/Panic.cpp +++ /dev/null @@ -1,176 +0,0 @@ -#define MODULE "panic" - -#include "panic/Panic.h" -#include "fs/InitRD.h" -#include "interrupts/IDT.h" -#include "io/PIC.h" -#include "log/Log.h" -#include "memory/VMM.h" -#include "misc/MSR.h" -#include "render/Framebuffer.h" -#include "render/TextRenderer.h" -#include "std/stdio.h" -#include "thread/Scheduler.h" -#include "trace/StackTracer.h" - -static bool g_is_in_panic = false; -static bool g_is_in_double_panic = false; - -void panic_prepare_keyboard_triple_fault() -{ - PIC::enable_master(0b11111101); // enable keyboard only - PIC::enable_slave(0b11111111); - - IDTR idtr; - idtr.limit = 0x0000; - idtr.offset = 0x0000; - asm volatile( - "lidt %0" - : - : "m"( - idtr)); // when an interrupt arrives, triple-fault (the only interrupt that should come is the keyboard one) - - asm volatile("sti"); -} - -void dump_registers(Context* context) -{ - kinfoln("-- Registers:"); - kinfoln("rax: %lx, rbx: %lx, rcx: %lx, rdx: %lx", context->rax, context->rbx, context->rcx, context->rdx); - kinfoln("rsi: %lx, rdi: %lx, rsp: %lx, rbp: %lx", context->rsi, context->rdi, context->rsp, context->rbp); - kinfoln("r8: %lx, r9: %lx, r10: %lx, r11: %lx", context->r8, context->r9, context->r10, context->r11); - kinfoln("r12: %lx, r13: %lx, r14: %lx, r15: %lx", context->r12, context->r13, context->r14, context->r15); - kinfoln("rip: %lx, cs: %lx, ss: %lx", context->rip, context->cs, context->ss); - kinfoln("rflags: %lx, cr2: %lx", context->rflags, context->cr2); - kinfoln("ia32_efer: %lx", MSR::read_from(IA32_EFER_MSR)); -} - -void fatal_dump_registers(Context* context) -{ - printf("-- Possibly Relevant Registers:\n"); - printf("rbp: %lx, rsp: %lx, rip: %lx, cs: %lx, ss: %lx, rflags: %lx, cr2: %lx, error code: %lx\n", context->rbp, - context->rsp, context->rip, context->cs, context->ss, context->rflags, context->cr2, context->error_code); -} - -[[noreturn]] void __panic_fatal_stub(Context* context) -{ - if (context) fatal_dump_registers(context); - printf("-- No stack trace available\n"); - - KernelLog::enable_log_backend(Backend::Console); - KernelLog::toggle_log_backend( - Backend::Console); // disable console logging, as we can page fault while writing to the framebuffer. - - Scheduler::current_task()->id = 0; // we're panicking, we don't even care anymore. This is so KernelLog shows - // (kernel) instead of (taskname: PID) in the log. - - panic_prepare_keyboard_triple_fault(); - - printf("Press any key to restart.\n"); - - while (1) asm volatile("hlt"); -} - -[[noreturn]] void __panic_stub(Context* context) -{ - VMM::switch_back_to_kernel_address_space(); - VMM::apply_address_space(); - if (context) dump_registers(context); - - if (InitRD::is_initialized()) - { - kinfoln("-- Stack trace:"); - if (context) - { - StackTracer tracer(context->rbp); - tracer.trace_with_ip(context->rip); - } - else - { - uintptr_t rbp; - - asm volatile("mov %%rbp, %0" : "=r"(rbp)); - StackTracer tracer(rbp); - tracer.trace(); - } - } - else { kinfoln("-- No stack trace available"); } - - panic_prepare_keyboard_triple_fault(); - - while (1) asm volatile("hlt"); -} - -extern "C" [[noreturn]] bool __do_int_panic(Context* context, const char* file, int line, const char* message) -{ - asm volatile("cli"); - - if (g_is_in_double_panic) - { - panic_prepare_keyboard_triple_fault(); - while (1) asm volatile("hlt"); - } - - if (g_is_in_panic) - { - g_is_in_double_panic = true; - printf("Kernel panic while panicking (showing vital information only) at %s, line %d: %s\n", file, line, - message); - __panic_fatal_stub(context); - } - - g_is_in_panic = true; - - KernelLog::enable_log_backend(Backend::Console); - - TextRenderer::reset(); - - framebuffer0.clear(Color::Black); - - if (context->number >= 0x20 && context->number < 0x30) { PIC::send_eoi((uint8_t)(context->irq_number & 0xFF)); } - - Task* task; - if ((task = Scheduler::current_task())) - { - kerrorln("Kernel panic in task %ld, at %s, line %d: %s", task->id, file, line, message); - } - else { kerrorln("Kernel panic at %s, line %d: %s", file, line, message); } - - __panic_stub(context); -} - -extern "C" [[noreturn]] bool __do_panic(const char* file, int line, const char* message) -{ - asm volatile("cli"); - - if (g_is_in_double_panic) - { - panic_prepare_keyboard_triple_fault(); - while (1) asm volatile("hlt"); - } - - if (g_is_in_panic) - { - g_is_in_double_panic = true; - printf("Kernel panic while panicking (showing vital information only) at %s, line %d: %s\n", file, line, - message); - __panic_fatal_stub(nullptr); - } - - g_is_in_panic = true; - - KernelLog::enable_log_backend(Backend::Console); - - TextRenderer::reset(); - - framebuffer0.clear(Color::Black); - - Task* task; - if ((task = Scheduler::current_task())) - { - kerrorln("Kernel panic in task %ld, at %s, line %d: %s", task->id, file, line, message); - } - else { kerrorln("Kernel panic at %s, line %d: %s", file, line, message); } - - __panic_stub(nullptr); -} \ No newline at end of file diff --git a/kernel/src/rand/Init.asm b/kernel/src/rand/Init.asm deleted file mode 100644 index 9dbe3db8..00000000 --- a/kernel/src/rand/Init.asm +++ /dev/null @@ -1,11 +0,0 @@ -global asm_test_rdseed - -asm_test_rdseed: - xor rax, rax - mov eax, 7 - mov ecx, 0 - cpuid - shr ebx, 18 - and ebx, 1 - mov eax, ebx - ret \ No newline at end of file diff --git a/kernel/src/rand/Init.cpp b/kernel/src/rand/Init.cpp deleted file mode 100644 index 79f9569b..00000000 --- a/kernel/src/rand/Init.cpp +++ /dev/null @@ -1,74 +0,0 @@ -#define MODULE "rand" - -#include "rand/Init.h" -#include "config.h" -#include "cpu/CPU.h" -#include "io/IO.h" -#include "log/Log.h" -#include "rand/Mersenne.h" - -static uint64_t state = 0xf5026f5ae96319e9; - -static bool has_rdrand = false; -static bool has_rdseed = false; - -extern "C" int asm_test_rdseed(); - -static uint64_t rdtsc() -{ - uint64_t result1; - uint64_t result2; - asm volatile("rdtsc" : "=a"(result1), "=d"(result2)); - return result2 << 32 | result1; -} - -static uint64_t rdseed() -{ - uint64_t result; - asm volatile("rdseed %0" : "=r"(result)); - return result; -} - -static uint64_t rdrand() -{ - uint64_t result; - asm volatile("rdrand %0" : "=r"(result)); - return result; -} - -void Mersenne::init() -{ - has_rdrand = CPU::has_feature(CPU::Features::RDRAND); - has_rdseed = asm_test_rdseed(); - - if (!has_rdrand && !has_rdseed) kwarnln("CPU does not support either RDRAND or RDSEED"); - - state ^= (0x45fe1024UL + __moon_version_major()) * (__moon_version_minor() ^ 200UL); - - state ^= 0xe0e4f5332ea75b; - - reseed(); - - state ^= Mersenne::get() * 0xffe3; - - state ^= rdtsc(); - - Mersenne::seed(state); -} - -void Mersenne::reseed() -{ - state ^= rdtsc(); - - if (has_rdrand) { state ^= rdrand(); } - - if (has_rdseed) { state ^= rdseed(); } - - state ^= rdtsc(); - - state ^= IO::inb(0x40); - - state ^= rdtsc(); - - Mersenne::seed(state); -} \ No newline at end of file diff --git a/kernel/src/rand/Mersenne.cpp b/kernel/src/rand/Mersenne.cpp deleted file mode 100644 index 9f30d469..00000000 --- a/kernel/src/rand/Mersenne.cpp +++ /dev/null @@ -1,62 +0,0 @@ -#define MODULE "rand" - -#include "rand/Mersenne.h" -#include "std/ensure.h" -#include - -typedef uint64_t word_t; - -static const int STATE_SIZE = 312; -static const int MIDDLE = 156; -static const int INIT_SHIFT = 62; -static const uint64_t TWIST_MASK = 0xb5026f5aa96619e9; -static const uint64_t INIT_FACT = 6364136223846793005; -static const int SHIFT1 = 29; -static const uint64_t MASK1 = 0x5555555555555555; -static const int SHIFT2 = 17; -static const uint64_t MASK2 = 0x71d67fffeda60000; -static const int SHIFT3 = 37; -static const uint64_t MASK3 = 0xfff7eee000000000; -static const int SHIFT4 = 43; - -static const word_t LOWER_MASK = 0x7fffffff; -static const word_t UPPER_MASK = (~(word_t)LOWER_MASK); - -static word_t state[STATE_SIZE]; -static size_t index = STATE_SIZE + 1; - -void Mersenne::seed(uint64_t s) -{ - index = STATE_SIZE; - state[0] = s; - for (size_t i = 1; i < STATE_SIZE; i++) state[i] = (INIT_FACT * (state[i - 1] ^ (state[i - 1] >> INIT_SHIFT))) + i; -} - -static void twist() -{ - for (size_t i = 0; i < STATE_SIZE; i++) - { - word_t x = (state[i] & UPPER_MASK) | (state[(i + 1) % STATE_SIZE] & LOWER_MASK); - x = (x >> 1) ^ (x & 1 ? TWIST_MASK : 0); - state[i] = state[(i + MIDDLE) % STATE_SIZE] ^ x; - } - index = 0; -} - -uint64_t Mersenne::get() -{ - if (index >= STATE_SIZE) - { - ensure(index == STATE_SIZE && "Mersenne generator was never seeded"); - twist(); - } - - word_t y = state[index]; - y ^= (y >> SHIFT1) & MASK1; - y ^= (y << SHIFT2) & MASK2; - y ^= (y << SHIFT3) & MASK3; - y ^= y >> SHIFT4; - - index++; - return y; -} \ No newline at end of file diff --git a/kernel/src/render/Color.cpp b/kernel/src/render/Color.cpp deleted file mode 100644 index 505b8516..00000000 --- a/kernel/src/render/Color.cpp +++ /dev/null @@ -1,21 +0,0 @@ -#include "render/Color.h" - -Color Color::White = {0xFF, 0xFF, 0xFF, 0xFF}; -Color Color::Black = {0x00, 0x00, 0x00, 0xFF}; -Color Color::Red = {0x00, 0x00, 0xFF, 0xFF}; -Color Color::Green = {0x00, 0xFF, 0x00, 0xFF}; -Color Color::Blue = {0xFF, 0x00, 0x00, 0xFF}; -Color Color::Yellow = {0x00, 0xFF, 0xFF, 0xFF}; -Color Color::Cyan = {0xFF, 0xFF, 0x00, 0xFF}; -Color Color::Magenta = {0xFF, 0x00, 0xFF, 0xFF}; -Color Color::Gray = {0x80, 0x80, 0x80, 0xFF}; - -#pragma GCC push_options -#pragma GCC diagnostic ignored "-Wstrict-aliasing" - -Color Color::from_integer(uint32_t source) -{ - return reinterpret_cast(source); -} - -#pragma GCC pop_options \ No newline at end of file diff --git a/kernel/src/render/Framebuffer.cpp b/kernel/src/render/Framebuffer.cpp deleted file mode 100644 index bdde5a73..00000000 --- a/kernel/src/render/Framebuffer.cpp +++ /dev/null @@ -1,59 +0,0 @@ -#define MODULE "fb" - -#include "render/Framebuffer.h" -#include "assert.h" -#include "bootboot.h" -#include "panic/Panic.h" -#include "string.h" - -Framebuffer framebuffer0; - -void Framebuffer::init(void* fb_address, int fb_type, int fb_scanline, int fb_width, int fb_height) -{ - m_fb_address = fb_address; - m_fb_height = fb_height; - m_fb_width = fb_width; - m_fb_scanline = fb_scanline; - m_fb_type = fb_type; - if (m_fb_type != FB_ARGB) - { - memset(m_fb_address, 0xe4, 500); // make it visible - panic("unsupported framebuffer"); - } -} - -void Framebuffer::set_pixel(uint32_t x, uint32_t y, Color color) -{ - *(uint32_t*)((char*)m_fb_address + m_fb_scanline * y + x * 4) = *(uint32_t*)&color; -} - -Color Framebuffer::get_pixel(uint32_t x, uint32_t y) -{ - return *(Color*)((char*)m_fb_address + m_fb_scanline * y + x * 4); -} - -void Framebuffer::clear(Color color) -{ - paint_rect(0, 0, m_fb_width, m_fb_height, color); -} - -void Framebuffer::paint_rect(uint32_t x, uint32_t y, uint32_t w, uint32_t h, Color color) -{ - for (uint32_t i = y; i < (y + h); i++) - { - uint64_t addr = (uint64_t)((char*)m_fb_address + (m_fb_scanline * i) + (x * 4)); - for (uint64_t addr_current = addr; addr_current < (addr + w * 4); addr_current += 4) - { - *(uint32_t*)addr_current = *(uint32_t*)&color; - } - } -} - -void Framebuffer::paint_rect(uint32_t x, uint32_t y, uint32_t w, uint32_t h, Color* colors) -{ - uint32_t j; - for (uint32_t l = j = 0; l < h; l++) - { - for (uint32_t i = 0; i < w; i++, j++) { set_pixel(x + i, y + l, colors[j]); } - } -} diff --git a/kernel/src/render/TextRenderer.cpp b/kernel/src/render/TextRenderer.cpp deleted file mode 100644 index d8e2ad7f..00000000 --- a/kernel/src/render/TextRenderer.cpp +++ /dev/null @@ -1,116 +0,0 @@ -#define MODULE "text" - -#include "render/TextRenderer.h" -#include "bootboot.h" -#include "font.h" -#include "fs/InitRD.h" -#include "io/Serial.h" -#include "log/Log.h" -#include "render/Framebuffer.h" -#include "std/stdio.h" -#include "std/string.h" - -extern BOOTBOOT bootboot; - -static Color bgColor = Color::Black; -static Color fgColor = Color::White; -static uint32_t xpos = 0; -static uint32_t ypos = 0; - -#define FONT_HEIGHT 16 -#define FONT_WIDTH 8 - -void TextRenderer::reset() -{ - xpos = 0; - ypos = 0; -} - -#pragma GCC push_options -#pragma GCC optimize("O0") - -static void putchar_at_offset( - char c, uint32_t cx, uint32_t cy, [[maybe_unused]] Color& fg, - [[maybe_unused]] Color& bg) // FIXME: Rewrite this function to actually work with foreground and background colors. -{ - uint8_t* glyph = &font[c * 16]; - for (uint32_t y = 0; y < FONT_HEIGHT; y++) - { - for (uint32_t x = 0; x < FONT_WIDTH; x++) - { - volatile uint8_t mask = *glyph; - if ((mask & (0b10000000 >> x)) > 0) { framebuffer0.set_pixel(cx + x, cy + y, Color::White); } - else { framebuffer0.set_pixel(cx + x, cy + y, Color::Black); } - } - glyph++; - } -} - -static bool g_escape_sequence = false; - -#pragma GCC pop_options - -void TextRenderer::putchar(char chr) -{ - if (g_escape_sequence) - { - g_escape_sequence = false; - switch (chr) - { - case '@': - reset(); - framebuffer0.clear(Color::Black); - break; - default: break; - } - } - else - { - switch (chr) - { - case '\n': { - ypos += FONT_HEIGHT; - if ((ypos + FONT_HEIGHT) >= bootboot.fb_height) - { - memcpy((void*)bootboot.fb_ptr, (char*)bootboot.fb_ptr + (bootboot.fb_scanline * FONT_HEIGHT), - bootboot.fb_size - (bootboot.fb_scanline * FONT_HEIGHT)); - ypos -= FONT_HEIGHT; - framebuffer0.paint_rect(0, ypos, bootboot.fb_width, FONT_HEIGHT, Color::Black); - } - xpos = 0; - break; - } - case '\r': xpos = 0; break; - case '\b': - if (xpos != 0) - { - xpos -= FONT_WIDTH; - framebuffer0.paint_rect(xpos, ypos, FONT_WIDTH, FONT_HEIGHT, Color::Black); - } - break; - case '\033': g_escape_sequence = true; break; - default: { - putchar_at_offset(chr, xpos, ypos, fgColor, bgColor); - xpos += FONT_WIDTH; - if ((xpos + FONT_WIDTH) > bootboot.fb_width) - { - xpos = 0; - ypos += FONT_HEIGHT; - if ((ypos + FONT_HEIGHT) >= bootboot.fb_height) - { - memcpy((void*)bootboot.fb_ptr, (char*)bootboot.fb_ptr + (bootboot.fb_scanline * FONT_HEIGHT), - bootboot.fb_size - (bootboot.fb_scanline * FONT_HEIGHT)); - ypos -= FONT_HEIGHT; - framebuffer0.paint_rect(0, ypos, bootboot.fb_width, FONT_HEIGHT, Color::Black); - } - } - break; - } - } - } -} - -void TextRenderer::write(const char* str, size_t size) -{ - for (size_t i = 0; i < size; i++) { putchar(str[i]); } -} \ No newline at end of file diff --git a/kernel/src/std/libgen.cpp b/kernel/src/std/libgen.cpp deleted file mode 100644 index b0a46a98..00000000 --- a/kernel/src/std/libgen.cpp +++ /dev/null @@ -1,67 +0,0 @@ -#include "std/libgen.h" -#include "std/stdlib.h" -#include "std/string.h" - -static char dot[] = "."; - -char* basename(char* path) -{ - // If path is NULL, or the string's length is 0, return . - if (!path) return dot; - size_t len = strlen(path); - if (!len) return dot; - - // Strip trailing slashes. - char* it = path + len - 1; - while (*it == '/' && it != path) { it--; } - *(it + 1) = 0; - if (it == path) return path; - - // Return path from the first character if there are no more slashes, or from the first character after the last - // slash. - char* beg = strrchr(path, '/'); - if (!beg) return path; - return beg + 1; -} - -char* dirname(char* path) -{ - // If path is NULL, or the string's length is 0, return . - if (!path) return dot; - size_t len = strlen(path); - if (!len) return dot; - - // Strip trailing slashes. - char* it = path + len - 1; - while (*it == '/' && it != path) { it--; } - *(char*)(it + 1) = 0; - if (it == path) return path; - - // Search for the last slash. If there is none, return . - // Otherwise, we end the string there and return. - char* end = strrchr(path, '/'); - if (!end) return dot; - if (end != path) *end = 0; - else - *(end + 1) = 0; - return path; -} - -char* better_basename(const char* path) -{ - char* mut = strdup(path); // create a mutable copy of path - char* ptr = basename(mut); // get a pointer to the start of the base name - char* result = strdup(ptr); // create a copy of it, so the caller can free the returned pointer directly - kfree(mut); // free the original mutable copy - return result; -} - -char* better_dirname(const char* path) -{ - // same as above - char* mut = strdup(path); - char* ptr = dirname(mut); - char* result = strdup(ptr); - kfree(mut); - return result; -} \ No newline at end of file diff --git a/kernel/src/std/stdio.cpp b/kernel/src/std/stdio.cpp deleted file mode 100644 index d17a70cc..00000000 --- a/kernel/src/std/stdio.cpp +++ /dev/null @@ -1,311 +0,0 @@ -#include "std/stdio.h" -#include "io/Serial.h" -#include "render/TextRenderer.h" -#include "std/stdlib.h" -#include "std/string.h" - -typedef long int ssize_t; - -template -static int internal_printf(const char* format, PutString put_string_callback, ssize_t max, va_list ap) -{ - char buffer[1025]; // 1024 with null terminator - size_t format_size = strlen(format); - size_t format_index = 0; - size_t buffer_insert_index = 0; - ssize_t max_remaining = max; - size_t written = 0; - - auto flush_buffer = [&]() { - size_t buffer_length = buffer_insert_index; - written += buffer_length; - buffer_insert_index = 0; - if (max_remaining < 0) - { - buffer[buffer_length] = 0; - put_string_callback(buffer); - return; - } - if (max_remaining == 0) { return; } - if (buffer_length <= (size_t)max_remaining) - { - max_remaining -= buffer_length; - buffer[buffer_length] = 0; - put_string_callback(buffer); - } - else - { - buffer[max_remaining] = 0; - max_remaining = 0; - put_string_callback(buffer); - } - }; - - bool is_long = false; - bool is_unsigned_long = false; - - bool preserve_format = false; - - while (format_index < format_size) - { - char current_char = format[format_index]; - if (current_char == '%' || preserve_format) - { - if (!preserve_format && format_index + 1 == format_size) // end of format string - { - format_index++; - continue; - } - else - { - if (!preserve_format) format_index++; - preserve_format = false; - current_char = format[format_index]; - switch (current_char) - { - case 'c': { - buffer[buffer_insert_index++] = (char)va_arg(ap, int); - if (buffer_insert_index == 1024) flush_buffer(); - break; - } - case '%': { - buffer[buffer_insert_index++] = '%'; - if (buffer_insert_index == 1024) flush_buffer(); - break; - } - case 'z': { - is_unsigned_long = true; - preserve_format = true; - break; - } - case 'l': { - is_long = true; - preserve_format = true; - break; - } - case 'd': { - if (is_unsigned_long) - { - char result[25]; - ultoa(va_arg(ap, uint64_t), result, 10); - if (buffer_insert_index + strlen(result) > 1024) flush_buffer(); - memcpy(buffer + buffer_insert_index, result, strlen(result)); - buffer_insert_index += strlen(result); - if (buffer_insert_index == 1024) flush_buffer(); - is_unsigned_long = is_long = false; - } - else if (is_long) - { - char result[25]; - ltoa(va_arg(ap, int64_t), result, 10); - if (buffer_insert_index + strlen(result) > 1024) flush_buffer(); - memcpy(buffer + buffer_insert_index, result, strlen(result)); - buffer_insert_index += strlen(result); - if (buffer_insert_index == 1024) flush_buffer(); - is_unsigned_long = is_long = false; - } - else - { - char result[25]; - itoa(va_arg(ap, int32_t), result, 10); - if (buffer_insert_index + strlen(result) > 1024) flush_buffer(); - memcpy(buffer + buffer_insert_index, result, strlen(result)); - buffer_insert_index += strlen(result); - if (buffer_insert_index == 1024) flush_buffer(); - } - break; - } - case 'o': { - if (is_unsigned_long || is_long) - { - char result[25]; - ultoa(va_arg(ap, uint64_t), result, 8); - if (buffer_insert_index + strlen(result) > 1024) flush_buffer(); - memcpy(buffer + buffer_insert_index, result, strlen(result)); - buffer_insert_index += strlen(result); - if (buffer_insert_index == 1024) flush_buffer(); - is_unsigned_long = is_long = false; - } - else - { - char result[25]; - utoa(va_arg(ap, uint32_t), result, 8); - if (buffer_insert_index + strlen(result) > 1024) flush_buffer(); - memcpy(buffer + buffer_insert_index, result, strlen(result)); - buffer_insert_index += strlen(result); - if (buffer_insert_index == 1024) flush_buffer(); - } - break; - } - case 'u': { - if (is_unsigned_long || is_long) - { - char result[25]; - ultoa(va_arg(ap, uint64_t), result, 10); - if (buffer_insert_index + strlen(result) > 1024) flush_buffer(); - memcpy(buffer + buffer_insert_index, result, strlen(result)); - buffer_insert_index += strlen(result); - if (buffer_insert_index == 1024) flush_buffer(); - is_unsigned_long = is_long = false; - } - else - { - char result[25]; - utoa(va_arg(ap, uint32_t), result, 10); - if (buffer_insert_index + strlen(result) > 1024) flush_buffer(); - memcpy(buffer + buffer_insert_index, result, strlen(result)); - buffer_insert_index += strlen(result); - if (buffer_insert_index == 1024) flush_buffer(); - } - break; - } - case 'x': { - if (is_unsigned_long || is_long) - { - char result[25]; - ultoa(va_arg(ap, uint64_t), result, 16); - if (buffer_insert_index + strlen(result) > 1024) flush_buffer(); - memcpy(buffer + buffer_insert_index, result, strlen(result)); - buffer_insert_index += strlen(result); - if (buffer_insert_index == 1024) flush_buffer(); - is_unsigned_long = is_long = false; - } - else - { - char result[25]; - utoa(va_arg(ap, uint32_t), result, 16); - if (buffer_insert_index + strlen(result) > 1024) flush_buffer(); - memcpy(buffer + buffer_insert_index, result, strlen(result)); - buffer_insert_index += strlen(result); - if (buffer_insert_index == 1024) flush_buffer(); - } - break; - } - case 'p': { - char result[25]; - ultoa(va_arg(ap, uint64_t), result, 16); - if (buffer_insert_index + strlen(result) > 1024) flush_buffer(); - memcpy(buffer + buffer_insert_index, result, strlen(result)); - buffer_insert_index += strlen(result); - if (buffer_insert_index == 1024) flush_buffer(); - break; - } - case 's': { - const char* str = va_arg(ap, const char*); - while (strlen(str) > 1024) - { - flush_buffer(); - memcpy(buffer, str, 1024); - str += 1024; - buffer_insert_index = 1024; - } - if (buffer_insert_index + strlen(str) > 1024) flush_buffer(); - memcpy(buffer + buffer_insert_index, str, strlen(str)); - buffer_insert_index += strlen(str); - if (buffer_insert_index == 1024) flush_buffer(); - break; - } - default: { - buffer[buffer_insert_index++] = '%'; - if (buffer_insert_index == 1024) flush_buffer(); - buffer[buffer_insert_index++] = current_char; - if (buffer_insert_index == 1024) flush_buffer(); - break; - } - } - } - } - else - { - buffer[buffer_insert_index++] = current_char; - if (buffer_insert_index == 1024) flush_buffer(); - } - format_index++; - } - - if (buffer_insert_index > 0) flush_buffer(); - return (int)written; -} - -int printf(const char* fmt, ...) -{ - va_list ap; - va_start(ap, fmt); - int written = internal_printf( - fmt, [](const char* s) { Serial::print(s); }, -1, ap); - va_end(ap); - return written; -} - -int kprintf(const char* fmt, ...) -{ - va_list ap; - va_start(ap, fmt); - int written = vkprintf(fmt, ap); - va_end(ap); - return written; -} - -int sprintf(char* __s, const char* fmt, ...) -{ - va_list ap; - va_start(ap, fmt); - if (__s) *__s = 0; - int written = internal_printf( - fmt, - [&](const char* s) { - if (__s) { strncat(__s, s, 1025); } - }, - -1, ap); - va_end(ap); - return written; -} - -int snprintf(char* __s, size_t max, const char* fmt, ...) -{ - va_list ap; - va_start(ap, fmt); - if (__s && max) *__s = 0; - int written = internal_printf( - fmt, - [&](const char* s) { - if (__s) { strncat(__s, s, 1025); } - }, - max == 0 ? 0 : max - 1, ap); - va_end(ap); - return written; -} - -int vprintf(const char* fmt, va_list ap) -{ - return internal_printf( - fmt, [](const char* s) { Serial::print(s); }, -1, ap); -} - -int vkprintf(const char* fmt, va_list ap) -{ - return internal_printf( - fmt, [](const char* s) { TextRenderer::write(s, strlen(s)); }, -1, ap); -} - -int vsprintf(char* __s, const char* fmt, va_list ap) -{ - *__s = 0; - return internal_printf( - fmt, - [&](const char* s) { - if (__s) { strncat(__s, s, 1025); } - }, - -1, ap); -} - -int vsnprintf(char* __s, size_t max, const char* fmt, va_list ap) -{ - if (max) *__s = 0; - return internal_printf( - fmt, - [&](const char* s) { - if (__s) { strncat(__s, s, 1025); } - }, - max == 0 ? 0 : max - 1, ap); -} \ No newline at end of file diff --git a/kernel/src/std/stdlib.cpp b/kernel/src/std/stdlib.cpp deleted file mode 100644 index b7d42f42..00000000 --- a/kernel/src/std/stdlib.cpp +++ /dev/null @@ -1,153 +0,0 @@ -#include "std/stdlib.h" -#include "thread/Scheduler.h" - -static void strrev(char* arr, int start, int end) -{ - char temp; - - if (start >= end) return; - - temp = *(arr + start); - *(arr + start) = *(arr + end); - *(arr + end) = temp; - - start++; - end--; - strrev(arr, start, end); -} - -char* itoa(int32_t number, char* arr, int base) -{ - int i = 0, r, negative = 0; - - if (number == 0) - { - arr[i] = '0'; - arr[i + 1] = '\0'; - return arr; - } - - if (number < 0 && base == 10) - { - number *= -1; - negative = 1; - } - - while (number != 0) - { - r = number % base; - arr[i] = (char)((r > 9) ? (r - 10) + 'a' : r + '0'); - i++; - number /= base; - } - - if (negative) - { - arr[i] = '-'; - i++; - } - - strrev(arr, 0, i - 1); - - arr[i] = '\0'; - - return arr; -} - -char* ltoa(int64_t number, char* arr, int base) -{ - int i = 0, negative = 0; - int64_t r; - - if (number == 0) - { - arr[i] = '0'; - arr[i + 1] = '\0'; - return arr; - } - - if (number < 0 && base == 10) - { - number *= -1; - negative = 1; - } - - while (number != 0) - { - r = number % base; - arr[i] = (char)((r > 9) ? (r - 10) + 'a' : r + '0'); - i++; - number /= base; - } - - if (negative) - { - arr[i] = '-'; - i++; - } - - strrev(arr, 0, i - 1); - - arr[i] = '\0'; - - return arr; -} - -char* utoa(uint32_t number, char* arr, int base) -{ - int i = 0; - uint32_t r; - - if (number == 0) - { - arr[i] = '0'; - arr[i + 1] = '\0'; - return arr; - } - - while (number != 0) - { - r = number % base; - arr[i] = (char)((r > 9) ? (r - 10) + 'a' : r + '0'); - i++; - number /= base; - } - - strrev(arr, 0, i - 1); - - arr[i] = '\0'; - - return arr; -} - -char* ultoa(uint64_t number, char* arr, int base) -{ - int i = 0; - uint64_t r; - - if (number == 0) - { - arr[i] = '0'; - arr[i + 1] = '\0'; - return arr; - } - - while (number != 0) - { - r = number % base; - arr[i] = (char)((r > 9) ? (r - 10) + 'a' : r + '0'); - i++; - number /= base; - } - - strrev(arr, 0, i - 1); - - arr[i] = '\0'; - - return arr; -} - -void sleep(uint64_t ms) -{ - Scheduler::sleep(ms); -} \ No newline at end of file diff --git a/kernel/src/std/string.cpp b/kernel/src/std/string.cpp deleted file mode 100644 index bcb3e62d..00000000 --- a/kernel/src/std/string.cpp +++ /dev/null @@ -1,157 +0,0 @@ -#include "std/string.h" -#include "std/stdlib.h" - -size_t strlen(const char* __s) -{ - const char* i = __s; - for (; *i; ++i) - ; - return (i - __s); -} - -char* strcpy(char* dest, const char* src) -{ - memcpy(dest, src, strlen(src) + 1); - return dest; -} - -char* strncpy(char* dest, const char* src, size_t n) -{ - size_t i; - for (i = 0; i < n && src[i] != 0; i++) dest[i] = src[i]; - for (; i < n; i++) dest[i] = 0; - return dest; -} - -size_t strlcpy(char* dest, const char* src, size_t size) -{ - size_t len = strlen(src); - if (size == 0) return len; - if (len < (size - 1)) - { - memcpy(dest, src, len); - dest[len] = 0; - } - else - { - memcpy(dest, src, size - 1); - dest[size - 1] = 0; - } - return len; -} - -int strcmp(const char* a, const char* b) -{ - while (*a && (*a == *b)) - { - a++; - b++; - } - return *(const unsigned char*)a - *(const unsigned char*)b; -} - -int strncmp(const char* a, const char* b, size_t n) -{ - const char* base = a; - while (*a && (*a == *b) && (size_t)(a - base) < (n - 1)) - { - a++; - b++; - } - return *(const unsigned char*)a - *(const unsigned char*)b; -} - -char* strncat(char* dest, const char* src, size_t n) -{ - size_t dest_len = strlen(dest); - size_t i; - - for (i = 0; i < n && *(src + i); i++) *(char*)(dest + dest_len + i) = *(const char*)(src + i); - - *(char*)(dest + dest_len + i) = '\0'; - - return dest; -} - -char* strcat(char* dest, const char* src) -{ - size_t dest_len = strlen(dest); - size_t i; - - for (i = 0; *(src + i); i++) *(char*)(dest + dest_len + i) = *(const char*)(src + i); - - *(char*)(dest + dest_len + i) = '\0'; - - return dest; -} - -char* strstr(char* haystack, const char* needle) -{ - size_t needle_size = strlen(needle); - size_t haystack_size = strlen(haystack); - while (*haystack) - { - if (*haystack == *needle) - { - if (needle_size <= haystack_size) - { - if (!strncmp(haystack, needle, needle_size)) return haystack; - } - else { return NULL; } - } - haystack++; - haystack_size--; - } - return NULL; -} - -void* memcpy(void* dest, const void* src, size_t n) -{ - for (size_t i = 0; i < n; ++i) { *((char*)dest + i) = *((const char*)src + i); } - return dest; -} - -void* memset(void* buf, int c, size_t n) -{ - for (size_t i = 0; i < n; ++i) { *((char*)buf + i) = (char)c; } - return buf; -} - -int memcmp(const void* a, const void* b, size_t n) -{ - if (!n) return 0; - const unsigned char* ap = (const unsigned char*)a; - const unsigned char* bp = (const unsigned char*)b; - while (--n && *ap == *bp) - { - ap++; - bp++; - } - return *ap - *bp; -} - -void* memmove(void* dest, const void* src, size_t n) -{ - if (dest == src) return dest; - if (dest > src) - for (long i = n - 1; i >= 0; i++) { *((char*)dest + i) = *((const char*)src + i); } - else - for (long i = 0; i < (long)n; i++) { *((char*)dest + i) = *((const char*)src + i); } - return dest; -} - -char* strdup(const char* src) -{ - size_t length = strlen(src); - char* duplicated = (char*)kmalloc(length + 1); - memcpy(duplicated, src, length + 1); - return duplicated; -} - -char* strrchr(const char* str, int c) -{ - const char* s = str + strlen(str); - while (s != str && *s != (char)c) s--; - if (*s == (char)c) return const_cast(s); - return NULL; -} \ No newline at end of file diff --git a/kernel/src/sys/Syscall.cpp b/kernel/src/sys/Syscall.cpp deleted file mode 100644 index 992bafa3..00000000 --- a/kernel/src/sys/Syscall.cpp +++ /dev/null @@ -1,51 +0,0 @@ -#include "sys/Syscall.h" -#include "io/Serial.h" -#include "memory/VMM.h" -#include "std/errno.h" -#include "std/string.h" -#include "thread/Scheduler.h" - -void Syscall::entry(Context* context) -{ - asm volatile("cli"); - VMM::enter_syscall_context(); - switch (context->rax) - { - case SYS_exit: sys_exit(context, (int)context->rdi); break; - case SYS_yield: sys_yield(context); break; - case SYS_sleep: sys_sleep(context, context->rdi); break; - case SYS_write: sys_write(context, (int)context->rdi, context->rsi, (const char*)context->rdx); break; - case SYS_getprocid: sys_getprocid(context, (int)context->rdi); break; - case SYS_mmap: - sys_mmap(context, (void*)context->rdi, context->rsi, (int)context->rdx, (int)context->r10, (off_t)context->r8); - break; - case SYS_munmap: sys_munmap(context, (void*)context->rdi, context->rsi); break; - case SYS_open: sys_open(context, (const char*)context->rdi, (int)context->rsi, (mode_t)context->rdx); break; - case SYS_read: sys_read(context, (int)context->rdi, context->rsi, (char*)context->rdx); break; - case SYS_close: sys_close(context, (int)context->rdi); break; - case SYS_seek: sys_seek(context, (int)context->rdi, (long)context->rsi, (int)context->rdx); break; - case SYS_execv: sys_execv(context, (const char*)context->rdi, (char**)context->rsi); break; - case SYS_fcntl: sys_fcntl(context, (int)context->rdi, (int)context->rsi, context->rdx); break; - case SYS_mprotect: sys_mprotect(context, (void*)context->rdi, context->rsi, (int)context->rdx); break; - case SYS_clock_gettime: sys_clock_gettime(context, (int)context->rdi, (struct timespec*)context->rsi); break; - case SYS_mkdir: sys_mkdir(context, (const char*)context->rdi, (mode_t)context->rsi); break; - case SYS_fork: sys_fork(context); break; - case SYS_waitpid: sys_waitpid(context, (long)context->rdi, (int*)context->rsi, (int)context->rdx); break; - case SYS_access: sys_access(context, (const char*)context->rdi, (int)context->rsi); break; - case SYS_fstat: sys_fstat(context, (int)context->rdi, (struct stat*)context->rsi); break; - case SYS_stat: sys_stat(context, (const char*)context->rdi, (struct stat*)context->rsi); break; - case SYS_pstat: sys_pstat(context, (long)context->rdi, (struct pstat*)context->rsi); break; - case SYS_getdents: - sys_getdents(context, (int)context->rdi, (struct luna_dirent*)context->rsi, (size_t)context->rdx); - break; - case SYS_dup2: sys_dup2(context, (int)context->rdi, (int)context->rsi); break; - case SYS_setuid: sys_setuid(context, (uid_t)context->rdi); break; - case SYS_setgid: sys_setgid(context, (gid_t)context->rdi); break; - case SYS_umask: sys_umask(context, (mode_t)context->rdi); break; - case SYS_ioctl: sys_ioctl(context, (int)context->rdi, (int)context->rsi, (uintptr_t)context->rdx); break; - case SYS_seteuid: sys_seteuid(context, (uid_t)context->rdi); break; - case SYS_setegid: sys_setegid(context, (gid_t)context->rdi); break; - default: context->rax = -ENOSYS; break; - } - VMM::exit_syscall_context(); -} diff --git a/kernel/src/sys/UserMemory.cpp b/kernel/src/sys/UserMemory.cpp deleted file mode 100644 index fc71fb40..00000000 --- a/kernel/src/sys/UserMemory.cpp +++ /dev/null @@ -1,224 +0,0 @@ -#include "sys/UserMemory.h" -#include "memory/Memory.h" -#include "memory/MemoryManager.h" -#include "std/stdlib.h" -#include "std/string.h" -#include "utils/Addresses.h" - -struct dynamic_string -{ - char* buf; - long capacity; - long size; -}; - -bool dynamic_expand(dynamic_string* str, long new_capacity) -{ - char* buffer = (char*)krealloc(str->buf, new_capacity); - if (!buffer) { return false; } - str->buf = buffer; - str->capacity = new_capacity; - return true; -} - -bool dynamic_push(dynamic_string* str, char c) -{ - if (str->size == str->capacity) - { - if (!dynamic_expand(str, str->capacity + 16)) return false; - } - str->buf[str->size] = c; - str->size++; - return true; -} - -bool dynamic_init(dynamic_string* str) -{ - str->buf = (char*)kmalloc(10); - if (!str->buf) return false; - str->capacity = 10; - str->size = 0; - return true; -} - -bool validate_user_readable_page(uintptr_t address) -{ - if (Memory::is_kernel_address(address)) return false; - auto rc = VMM::get_flags(address); - if (rc == (uint64_t)-1) return false; - if (rc & MAP_USER) return true; - return false; -} - -bool validate_user_writable_page(uintptr_t address) -{ - if (Memory::is_kernel_address(address)) return false; - auto rc = VMM::get_flags(address); - if (rc == (uint64_t)-1) return false; - if (rc & (MAP_USER | MAP_READ_WRITE)) return true; - return false; -} - -Result strdup_from_user(const char* user_string) -{ - uintptr_t user_ptr = (uintptr_t)user_string; - auto aligned = round_down_to_nearest_page(user_ptr); - char* ptr = nullptr; - uintptr_t index = 0; - if (aligned != user_ptr) // Otherwise, we already do this check below. - { - if (!validate_user_readable_page(aligned)) return nullptr; - auto result = MemoryManager::get_mapping((void*)VMM::get_physical(aligned), 0); - if (result.has_error()) return result.release_error(); - ptr = (char*)result.release_value(); - index = user_ptr - aligned; - } - dynamic_string str; - if (!dynamic_init(&str)) - { - if (ptr) MemoryManager::release_mapping(ptr); - return {ENOMEM}; - } - while (true) // FIXME: set a limit for this and fail with ENAMETOOLONG otherwise. - { - if (user_ptr % PAGE_SIZE == 0) - { - index = 0; - if (ptr) MemoryManager::release_mapping(ptr); - if (!validate_user_readable_page(user_ptr)) - { - kfree(str.buf); - return {EFAULT}; - } - auto result = MemoryManager::get_mapping((void*)VMM::get_physical(user_ptr), 0); - if (result.has_error()) return result.release_error(); - ptr = (char*)result.release_value(); - } - char c = ptr[index]; - if (!dynamic_push(&str, c)) - { - MemoryManager::release_mapping(ptr); - kfree(str.buf); - return {ENOMEM}; - } - if (!c) // We reached the null terminator!! - { - MemoryManager::release_mapping(ptr); - return str.buf; - } - user_ptr++; - index++; - } -} - -bool validate_user_read(uintptr_t address, size_t size) -{ - auto aligned = round_down_to_nearest_page(address); - if (aligned != address) // Otherwise, we already do this check below. - { - if (!validate_user_readable_page(aligned)) return false; - } - while (size--) - { - if (address % PAGE_SIZE == 0) - { - if (!validate_user_readable_page(address)) return false; - } - address++; - } - return true; -} - -bool validate_user_write(uintptr_t address, size_t size) -{ - auto aligned = round_down_to_nearest_page(address); - if (aligned != address) // Otherwise, we already do this check below. - { - if (!validate_user_writable_page(aligned)) return false; - } - while (size--) - { - if (address % PAGE_SIZE == 0) - { - if (!validate_user_writable_page(address)) return false; - } - address++; - } - return true; -} - -bool do_copy_from_user(const char* uptr, char* ptr, size_t size) -{ - uintptr_t user_ptr = (uintptr_t)uptr; - auto aligned = round_down_to_nearest_page(user_ptr); - char* mapping = nullptr; - uintptr_t index = 0; - if (aligned != user_ptr) // Otherwise, we already do this check below. - { - if (!validate_user_readable_page(aligned)) return false; - auto result = MemoryManager::get_mapping((void*)VMM::get_physical(aligned), 0); - if (result.has_error()) return false; // FIXME: Propagate errors. - mapping = (char*)result.release_value(); - index = user_ptr - aligned; - } - while (size--) - { - if (user_ptr % PAGE_SIZE == 0) - { - if (mapping) MemoryManager::release_mapping(mapping); - index = 0; - if (!validate_user_readable_page(user_ptr)) return false; - auto result = MemoryManager::get_mapping((void*)VMM::get_physical(user_ptr), 0); - if (result.has_error()) return false; // FIXME: Propagate errors. - mapping = (char*)result.release_value(); - } - *ptr = mapping[index]; - user_ptr++; - ptr++; - index++; - } - return true; -} - -bool do_copy_to_user(char* uptr, const char* ptr, size_t size) -{ - uintptr_t user_ptr = (uintptr_t)uptr; - auto aligned = round_down_to_nearest_page(user_ptr); - char* mapping = nullptr; - uintptr_t index = 0; - if (aligned != user_ptr) // Otherwise, we already do this check below. - { - if (!validate_user_writable_page(aligned)) return false; - auto result = MemoryManager::get_mapping((void*)VMM::get_physical(aligned)); - if (result.has_error()) return false; - mapping = (char*)result.release_value(); - index = user_ptr - aligned; - } - while (size--) - { - if (user_ptr % PAGE_SIZE == 0) - { - if (mapping) MemoryManager::release_mapping(mapping); - index = 0; - if (!validate_user_writable_page(user_ptr)) return false; - auto result = MemoryManager::get_mapping((void*)VMM::get_physical(user_ptr), 0); - if (result.has_error()) return false; - mapping = (char*)result.release_value(); - } - mapping[index] = *ptr; - user_ptr++; - ptr++; - index++; - } - return true; -} - -bool copy_from_user(const void* user_ptr, void* ptr, size_t size) -{ - return do_copy_from_user((const char*)user_ptr, (char*)ptr, size); -} - -bool copy_to_user(void* user_ptr, const void* ptr, size_t size) -{ - return do_copy_to_user((char*)user_ptr, (const char*)ptr, size); -} \ No newline at end of file diff --git a/kernel/src/sys/clock.cpp b/kernel/src/sys/clock.cpp deleted file mode 100644 index b4f7f1a8..00000000 --- a/kernel/src/sys/clock.cpp +++ /dev/null @@ -1,76 +0,0 @@ -#include "bootboot.h" -#include "interrupts/Context.h" -#include "std/errno.h" -#include "sys/UserMemory.h" -#include "thread/PIT.h" -#include "thread/Scheduler.h" -#include "utils/Time.h" -#include - -static uint64_t unix_boot_time; - -#define CLOCK_REALTIME 0 -#define CLOCK_MONOTONIC 1 -#define CLOCK_PROCTIME 2 - -struct timeval -{ - time_t tv_sec; - suseconds_t tv_usec; -}; - -struct timespec -{ - time_t tv_sec; - long tv_nsec; -}; - -static void ms_to_timespec(long ms, struct timespec* tv) -{ - tv->tv_sec = ms / 1000; - tv->tv_nsec = (ms % 1000) * 1000000; -} - -void sys_clock_gettime(Context* context, int clock, struct timespec* tp) -{ - struct timespec ktp; - Task* current_task = Scheduler::current_task(); - switch (clock) - { - case CLOCK_REALTIME: { - ms_to_timespec(PIT::ms_since_boot, &ktp); - ktp.tv_sec += unix_boot_time; - break; - } - case CLOCK_MONOTONIC: { - ms_to_timespec(PIT::ms_since_boot, &ktp); - break; - } - case CLOCK_PROCTIME: { - ms_to_timespec(current_task->cpu_time, &ktp); - break; - } - default: context->rax = -EINVAL; return; - } - if (!copy_typed_to_user(tp, &ktp)) context->rax = -EFAULT; - else - context->rax = 0; - return; -} - -extern BOOTBOOT bootboot; - -void clock_init() -{ - unix_boot_time = unix_boottime(bootboot.datetime); -} - -uint64_t clock_now() -{ - return unix_boot_time + (PIT::ms_since_boot / 1000); -} - -uint64_t clock_boot() -{ - return unix_boot_time; -} \ No newline at end of file diff --git a/kernel/src/sys/dirent.cpp b/kernel/src/sys/dirent.cpp deleted file mode 100644 index 1e205974..00000000 --- a/kernel/src/sys/dirent.cpp +++ /dev/null @@ -1,60 +0,0 @@ -#define MODULE "dir" - -#include "luna/dirent.h" -#include "fs/VFS.h" -#include "interrupts/Context.h" -#include "std/errno.h" -#include "std/string.h" -#include "sys/UserMemory.h" -#include "thread/Scheduler.h" - -void sys_getdents(Context* context, int fd, struct luna_dirent* buf, size_t count) -{ - if (fd < 0 || fd > TASK_MAX_FDS) - { - context->rax = -EBADF; - return; - } - Task* current_task = Scheduler::current_task(); - if (!current_task->files[fd].is_open()) - { - context->rax = -EBADF; - return; - } - Descriptor& dir = current_task->files[fd]; - VFS::Node* node = dir.node(); - if (node->type != VFS_DIRECTORY) - { - context->rax = -ENOTDIR; - return; - } - size_t nread = 0; - while (count) - { - VFS::Node* entry = VFS::readdir(node, dir.offset()); - if (!entry) - { - context->rax = nread; - return; - } - - luna_dirent dirent; - - dirent.total = node->length; - dirent.offset = dir.offset(); - dirent.inode = entry->inode; - strlcpy(dirent.name, entry->name, sizeof(dirent.name)); - - if (!copy_typed_to_user(buf, &dirent)) - { - context->rax = -EFAULT; - return; - } - - dir.seek(dir.offset() + 1); - buf++; - nread++; - count--; - } - context->rax = nread; -} \ No newline at end of file diff --git a/kernel/src/sys/elf/ELFLoader.cpp b/kernel/src/sys/elf/ELFLoader.cpp deleted file mode 100644 index 2673b07e..00000000 --- a/kernel/src/sys/elf/ELFLoader.cpp +++ /dev/null @@ -1,225 +0,0 @@ -#define MODULE "elf" - -#include "sys/elf/ELFLoader.h" -#include "fs/InitRD.h" -#include "fs/VFS.h" -#include "log/Log.h" -#include "memory/Memory.h" -#include "memory/MemoryManager.h" -#include "memory/VMM.h" -#include "misc/utils.h" -#include "std/ensure.h" -#include "std/errno.h" -#include "std/stdlib.h" -#include "std/string.h" -#include "sys/elf/ELF.h" -#include "utils/Addresses.h" - -static const char* format_permissions(uint32_t flags) -{ - static char perms[4]; - perms[0] = (flags & 4) > 0 ? 'r' : '-'; - perms[1] = (flags & 2) > 0 ? 'w' : '-'; - perms[2] = (flags & 1) > 0 ? 'x' : '-'; - perms[3] = 0; - return perms; -} - -static bool can_execute_segment(int flags) -{ - return flags & 1; -} - -static bool can_write_segment(int flags) -{ - return flags & 2; -} - -ELFImage* ELFLoader::load_elf_from_filesystem(const char* filename) -{ - VFS::Node* node = VFS::resolve_path(filename); - - if (!node) - { - kwarnln("Failed to open file %s for loading", filename); - return 0; - } - - if (node->type == VFS_DIRECTORY) - { - kwarnln("Failed to load %s: is a directory", filename); - return 0; - } - - ELFImage* result = load_elf_from_vfs(node); - return result; -} - -long ELFLoader::check_elf_image_from_filesystem(const char* filename) -{ - VFS::Node* node = VFS::resolve_path(filename); - - if (!node) - { - kwarnln("Failed to open file %s for checking", filename); - return -ENOENT; - } - - if (node->type == VFS_DIRECTORY) - { - kwarnln("Failed to check %s: is a directory", filename); - return -EISDIR; - } - - return check_elf_image(node); -} - -ELFImage* ELFLoader::load_elf_from_vfs(VFS::Node* node) -{ - Elf64_Ehdr elf_ehdr; - ensure(VFS::read(node, 0, sizeof(elf_ehdr), (char*)&elf_ehdr) >= 0); - ensure(strncmp((const char*)elf_ehdr.e_ident, ELFMAG, SELFMAG) == - 0); // If you haven't checked the ELF executable with check_elf_image() first, then an assertion fail is your - // fault =D - ensure(elf_ehdr.e_ident[EI_CLASS] == ELFCLASS64); - ensure(elf_ehdr.e_ident[EI_DATA] == ELFDATA2LSB); - ensure(elf_ehdr.e_type == ET_EXEC); - ensure(elf_ehdr.e_machine == EM_MACH); - ensure(elf_ehdr.e_phnum != 0); - ELFImage* image = (ELFImage*)kmalloc(sizeof(ELFImage) - sizeof(ELFSection)); - memset(image, 0, sizeof(ELFImage) - sizeof(ELFSection)); - image->entry = elf_ehdr.e_entry; - int i; - Elf64_Phdr phdr; - for (VFS::read(node, elf_ehdr.e_phoff, sizeof(Elf64_Phdr), (char*)&phdr), i = 0; i < elf_ehdr.e_phnum; - i++, VFS::read(node, elf_ehdr.e_phoff + (i * elf_ehdr.e_phentsize), sizeof(Elf64_Phdr), (char*)&phdr)) - { - if (phdr.p_type == PT_LOAD) - { - kdbgln("Loading loadable segment at address %lx, file size %ld, mem size %ld, permissions %s", phdr.p_vaddr, - phdr.p_filesz, phdr.p_memsz, format_permissions(phdr.p_flags)); - ensure(phdr.p_vaddr); - - ensure(!(can_write_segment(phdr.p_flags) && can_execute_segment(phdr.p_flags))); - - uint64_t pages = Utilities::get_blocks_from_size(PAGE_SIZE, (phdr.p_vaddr % PAGE_SIZE) + phdr.p_memsz); - void* buffer = (void*)((uint64_t)MemoryManager::get_pages_at(round_down_to_nearest_page(phdr.p_vaddr), - pages, MAP_READ_WRITE) - .release_value() // FIXME: We check for enough space before loading the ELF, - // although a race condition could happen. - + (phdr.p_vaddr % PAGE_SIZE)); - - if (VMM::is_using_kernel_address_space()) { VMM::switch_to_previous_user_address_space(); } - VMM::apply_address_space(); - - VFS::read(node, phdr.p_offset, phdr.p_filesz, (char*)buffer); - memset((void*)((uint64_t)buffer + phdr.p_filesz), 0, phdr.p_memsz - phdr.p_filesz); - - VMM::switch_back_to_kernel_address_space(); - VMM::apply_address_space(); - VMM::switch_to_previous_user_address_space(); - - int new_flags = MAP_USER | MAP_AS_OWNED_BY_TASK; - if (can_write_segment(phdr.p_flags)) new_flags |= MAP_READ_WRITE; - else if (can_execute_segment(phdr.p_flags)) - new_flags |= MAP_EXEC; - - MemoryManager::protect(buffer, pages, new_flags); - - image = (ELFImage*)krealloc(image, (sizeof(ELFImage) - sizeof(ELFSection)) + - (image->section_count + 1) * sizeof(ELFSection)); - ELFSection& section = image->sections[image->section_count]; - section.base = (uintptr_t)buffer; - section.pages = pages; - image->section_count++; - } - else { kdbgln("skipping non-loadable segment"); } - } - ensure(image->section_count); - return image; -} - -long ELFLoader::check_elf_image(VFS::Node* node) -{ - Elf64_Ehdr elf_ehdr; - if (VFS::read(node, 0, sizeof(elf_ehdr), (char*)&elf_ehdr) < (long)sizeof(elf_ehdr)) - { - kwarnln("Unable to read ELF header"); - return -ENOEXEC; - } - if (strncmp((const char*)elf_ehdr.e_ident, ELFMAG, SELFMAG) != 0) - { - kwarnln("ELF file has invalid magic, skipping"); - return -ENOEXEC; - } - if (elf_ehdr.e_ident[EI_CLASS] != ELFCLASS64) - { - kwarnln("ELF file is not ELF64, skipping"); - return -ENOEXEC; - } - if (elf_ehdr.e_ident[EI_DATA] != ELFDATA2LSB) - { - kwarnln("ELF file is not little-endian, skipping"); - return -ENOEXEC; - } - if (elf_ehdr.e_type != ET_EXEC) - { - kwarnln("not supported: ELF file is not an executable"); - return -ENOEXEC; - } - if (elf_ehdr.e_machine != EM_MACH) - { - kwarnln("Unsupported target machine"); - return -ENOEXEC; - } - if (elf_ehdr.e_phnum == 0) - { - kwarnln("ELF file has no PHDRS"); - return -ENOEXEC; - } - int i; - int loadable_sections = 0; - long memusage = 0; - Elf64_Phdr phdr; - for (VFS::read(node, elf_ehdr.e_phoff, sizeof(Elf64_Phdr), (char*)&phdr), i = 0; i < elf_ehdr.e_phnum; - i++, VFS::read(node, elf_ehdr.e_phoff + (i * elf_ehdr.e_phentsize), sizeof(Elf64_Phdr), (char*)&phdr)) - { - if (phdr.p_type == PT_LOAD) - { - if (!phdr.p_vaddr) - { - kerrorln("segment address is NULL, this is invalid :("); - return -ENOEXEC; - } - if (Memory::is_kernel_address(phdr.p_vaddr) || Memory::is_kernel_address(phdr.p_vaddr + phdr.p_memsz)) - { - kerrorln("trying to load ELF into kernel memory"); - return -ENOEXEC; - } - if (can_write_segment(phdr.p_flags) && can_execute_segment(phdr.p_flags)) - { - kwarnln("executable violates W^X"); - return -ENOEXEC; - } - loadable_sections++; - memusage += Utilities::get_blocks_from_size(PAGE_SIZE, phdr.p_memsz) * PAGE_SIZE; - } - } - if (!loadable_sections) - { - kwarnln("No loadable sections"); - return -ENOEXEC; - } - return memusage; -} - -void ELFLoader::release_elf_image(ELFImage* image) -{ - for (uint64_t i = 0; i < image->section_count; i++) - { - ELFSection& section = image->sections[i]; - kdbgln("Freeing up section %lx, was using %ld pages", section.base, section.pages); - MemoryManager::release_pages((void*)round_down_to_nearest_page(section.base), section.pages); - } - kfree(image); -} diff --git a/kernel/src/sys/exec.cpp b/kernel/src/sys/exec.cpp deleted file mode 100644 index bcbd6572..00000000 --- a/kernel/src/sys/exec.cpp +++ /dev/null @@ -1,262 +0,0 @@ -#define MODULE "exec" - -#include "interrupts/Interrupts.h" -#include "log/Log.h" -#include "memory/Memory.h" -#include "memory/MemoryManager.h" -#include "memory/PMM.h" -#include "memory/VMM.h" -#include "std/ensure.h" -#include "std/errno.h" -#include "std/stdlib.h" -#include "std/string.h" -#include "sys/Syscall.h" -#include "sys/UserMemory.h" -#include "sys/elf/ELFLoader.h" -#include "thread/Scheduler.h" - -void sys_fork(Context* context) -{ - kinfoln("fork(): attempting fork"); - - Task* parent = Scheduler::current_task(); - - Task* child = Scheduler::create_user_task(); - if (!child) - { - context->rax = -ENOMEM; - return; - } - - if (!child->allocator.inherit(parent->allocator)) - { - child->state = child->Exited; - child->exit_status = -127; // so the reaper reaps it on next reaping - context->rax = -ENOMEM; - return; - } - - child->save_context(context); - child->save_floating(); - - for (int i = 0; i < TASK_MAX_FDS; i++) { child->files[i] = parent->files[i]; } - - child->address_space = parent->address_space.clone(); - - child->ppid = parent->id; - - child->uid = parent->uid; - child->euid = parent->euid; - child->gid = parent->gid; - child->egid = parent->egid; - - child->umask = parent->umask; - - child->regs.rax = 0; - context->rax = child->id; - - strlcpy(child->name, parent->name, sizeof(child->name)); - - child->state = child->Running; - - kinfoln("fork(): forked parent %ld into child %ld", parent->id, child->id); - - return; -} - -void push_on_user_stack(uint64_t* rsp, char* value, - size_t size) // FIXME: Handle segments of stack that extend beyond one page. -{ - (*rsp) -= size; - char* kvalue = (char*)VMM::get_physical(*rsp); - ensure(kvalue != (char*)UINT64_MAX); - memcpy(kvalue, value, size); -} - -void sys_execv(Context* context, const char* pathname, char** argv) -{ - auto result = strdup_from_user(pathname); - if (result.has_error()) - { - context->rax = -result.error(); - return; - } - char* kpathname = result.release_value(); - - kinfoln("exec(): executing %s", kpathname); - - VFS::Node* program = VFS::resolve_path(kpathname); - if (!program) - { - kfree(kpathname); - context->rax = -ENOENT; - return; - } - - if (program->type == VFS_DIRECTORY) - { - kfree(kpathname); - context->rax = -EISDIR; - return; - } - - if (!VFS::can_execute(program, Scheduler::current_task()->euid, Scheduler::current_task()->egid)) - { - kfree(kpathname); - context->rax = -EACCES; - return; - } - - long memusage; - if ((memusage = ELFLoader::check_elf_image(program)) < 0) - { - kfree(kpathname); - context->rax = -ENOEXEC; - return; - } - - if ((uint64_t)memusage > PMM::get_free()) - { - kfree(kpathname); - context->rax = -ENOMEM; - return; - } - - uint64_t kargc = 0; - char** kargv = nullptr; - char* arg; - - auto free_kernel_argv_copy = [&]() { - for (uint64_t i = 0; i < kargc; i++) - { - if (kargv[i]) kfree(kargv[i]); - } - if (kargv) kfree(kargv); - }; - - // FIXME: This code is a bit messy. Should probably be refactored and moved into a separate function. - - do { - if (!copy_from_user(argv, &arg, sizeof(char*))) - { - free_kernel_argv_copy(); - context->rax = -EFAULT; - return; - } - kargv = (char**)krealloc(kargv, (kargc + 1) * sizeof(char*)); // we need a vector class for the kernel. - if (!kargv) - { - free_kernel_argv_copy(); - context->rax = -ENOMEM; - return; - } - if (arg) - { - auto rc = strdup_from_user(arg); - if (rc.has_error()) // FIXME: This could also be EFAULT. - { - free_kernel_argv_copy(); - context->rax = -rc.error(); - return; - } - kargv[kargc] = rc.release_value(); - } - else - { - kargv[kargc] = nullptr; - break; - } - kargc++; - argv++; - } while (arg != nullptr); - - kinfoln("Copied %lu arguments from user process", kargc); - - size_t stack_size = 0; - for (uint64_t i = 0; i <= kargc; i++) - { - stack_size += sizeof(char*); - if (kargv[i]) - { - stack_size += strlen(kargv[i]) + 1; // count the null byte - } - } - - if (stack_size > - ((TASK_PAGES_IN_STACK / 2) * - PAGE_SIZE)) // FIXME: Maybe we should allocate a larger stack in this case, but still set a larger upper limit. - { - free_kernel_argv_copy(); - context->rax = -E2BIG; - return; - } - - char** user_argv = (char**)kcalloc(kargc + 1, sizeof(char*)); - if (!user_argv) - { - free_kernel_argv_copy(); - context->rax = -ENOMEM; - return; - } - - Interrupts::disable(); - ensure(!Interrupts::are_enabled()); // This part is pretty sensitive. - - Task* task = Scheduler::current_task(); - ensure(task); - - // At this point, pretty much nothing can fail. (FIXME: Race conditions could happen) - - task->allocator.free(); - task->allocator - .init(); // If we had enough space for the old bitmap, we should have enough space for the new bitmap. - - task->address_space.clear(); - task->allocated_stack = (uint64_t)MemoryManager::get_pages_at(0x100000, TASK_PAGES_IN_STACK, - MAP_USER | MAP_READ_WRITE | MAP_AS_OWNED_BY_TASK) - .release_value(); // If we had enough space for the old stack, there should be - // enough space for the new stack. - - ELFImage* image = ELFLoader::load_elf_from_vfs(program); - ensure(image); // If check_elf_image succeeded, load_elf_from_vfs MUST succeed, unless something has gone terribly - // wrong. - - if (VFS::is_setuid(program)) task->euid = program->uid; - if (VFS::is_setgid(program)) task->egid = program->gid; - - strlcpy(task->name, kpathname, sizeof(task->name)); - - Scheduler::reset_task(task, image); - - for (int i = 0; i < TASK_MAX_FDS; i++) - { - Descriptor& file = task->files[i]; - if (file.close_on_exec()) { file.close(); } - } - - for (uint64_t i = 0; i <= kargc; i++) - { - if (kargv[i]) - { - push_on_user_stack(&task->regs.rsp, kargv[i], strlen(kargv[i]) + 1); - user_argv[i] = (char*)task->regs.rsp; - } - else - user_argv[i] = nullptr; - } - push_on_user_stack(&task->regs.rsp, (char*)user_argv, (kargc + 1) * sizeof(char*)); - task->regs.rdi = kargc; // argc - task->regs.rsi = task->regs.rsp; // argv - - task->regs.rsp &= (UINT64_MAX ^ 15); // align it - - free_kernel_argv_copy(); - - kfree(user_argv); - - kfree(kpathname); - - task->restore_context(context); - - return; -} \ No newline at end of file diff --git a/kernel/src/sys/id.cpp b/kernel/src/sys/id.cpp deleted file mode 100644 index 1d330359..00000000 --- a/kernel/src/sys/id.cpp +++ /dev/null @@ -1,123 +0,0 @@ -#include "std/errno.h" -#include "thread/Scheduler.h" -#include - -#define ID_PID 0 -#define ID_PPID 1 -#define ID_UID 2 -#define ID_EUID 3 -#define ID_GID 4 -#define ID_EGID 5 - -void sys_getprocid(Context* context, int field) -{ - if (field == ID_PID) - { - context->rax = Scheduler::current_task()->id; - return; - } - else if (field == ID_PPID) - { - context->rax = Scheduler::current_task()->ppid; - return; - } - else if (field == ID_UID) - { - context->rax = Scheduler::current_task()->uid; - return; - } - else if (field == ID_EUID) - { - context->rax = Scheduler::current_task()->euid; - return; - } - else if (field == ID_GID) - { - context->rax = Scheduler::current_task()->gid; - return; - } - else if (field == ID_EGID) - { - context->rax = Scheduler::current_task()->egid; - return; - } - else - { - context->rax = -EINVAL; - return; - } -} - -void sys_setuid(Context* context, uid_t uid) -{ - Task* current_task = Scheduler::current_task(); - - if (!current_task->is_superuser()) - { - if (uid != current_task->uid && uid != current_task->euid) - { - context->rax = -EPERM; - return; - } - } - - current_task->uid = uid; - current_task->euid = uid; - - context->rax = 0; -} - -void sys_seteuid(Context* context, uid_t euid) -{ - Task* current_task = Scheduler::current_task(); - - if (!current_task->is_superuser()) - { - if (euid != current_task->uid) - { - context->rax = -EPERM; - return; - } - } - - current_task->euid = euid; - - context->rax = 0; -} - -void sys_setgid(Context* context, gid_t gid) -{ - Task* current_task = Scheduler::current_task(); - - if (!current_task->is_superuser()) - { - if (gid != current_task->gid && gid != current_task->egid) - { - context->rax = -EPERM; - return; - } - } - - current_task->gid = gid; - current_task->egid = gid; - - context->rax = 0; -} - -void sys_setegid(Context* context, gid_t egid) -{ - Task* current_task = Scheduler::current_task(); - - if (!current_task->is_superuser()) - { - if (egid != current_task->gid) - { - context->rax = -EPERM; - return; - } - } - - current_task->egid = egid; - - context->rax = 0; -} \ No newline at end of file diff --git a/kernel/src/sys/mem.cpp b/kernel/src/sys/mem.cpp deleted file mode 100644 index 99a6a0b0..00000000 --- a/kernel/src/sys/mem.cpp +++ /dev/null @@ -1,226 +0,0 @@ -#define MODULE "mem" - -#include "interrupts/Context.h" -#include "log/Log.h" -#include "memory/Memory.h" -#include "memory/MemoryManager.h" -#include "memory/VMM.h" -#include "misc/utils.h" -#include "std/errno.h" -#include "thread/Scheduler.h" -#include - -#define PROT_READ 1 -#define PROT_WRITE 2 -#define PROT_NONE 0 -#define PROT_EXEC 4 - -#define MAP_FAIL(errno) 0xffffffffffffff00 | (unsigned char)(errno) - -static const char* format_prot(int prot) -{ - static char prot_string[4]; - prot_string[3] = 0; - prot_string[0] = ((prot & PROT_READ) > 0) ? 'r' : '-'; - prot_string[1] = ((prot & PROT_WRITE) > 0) ? 'w' : '-'; - prot_string[2] = ((prot & PROT_EXEC) > 0) ? 'x' : '-'; - return prot_string; -} - -static int mman_flags_from_prot(int prot) -{ - prot &= 0b111; - int flags = MAP_USER | MAP_AS_OWNED_BY_TASK; - if (prot == PROT_NONE) return MAP_AS_OWNED_BY_TASK; - if ((prot & PROT_WRITE) > 0) { flags |= MAP_READ_WRITE; } - if ((prot & PROT_EXEC) > 0) { flags |= MAP_EXEC; } - return flags; -} - -void sys_mmap(Context* context, void* address, size_t size, int prot, int fd, off_t offset) -{ - if (size < PAGE_SIZE) - { - kwarnln("mmap(): size too small"); - context->rax = MAP_FAIL(EINVAL); - return; - } - if (size % PAGE_SIZE) - { - kwarnln("mmap(): size not a multiple of PAGE_SIZE"); - context->rax = MAP_FAIL(EINVAL); - return; - } - int real_flags = mman_flags_from_prot(prot); - if (address) - { - kdbgln("mmap(): %ld pages at address %p, %s, fd %d", size / PAGE_SIZE, address, format_prot(prot), fd); - if (Memory::is_kernel_address((uintptr_t)address)) - { - kwarnln("munmap() failed: attempted to unmap a kernel page"); - context->rax = MAP_FAIL(ENOMEM); - return; - } - if (VMM::get_physical((uint64_t)address) != (uint64_t)-1) // Address is already used. - { - kwarnln("attempt to map an already mapped address"); - context->rax = MAP_FAIL(ENOMEM); - return; - } - uint64_t addr_offset = (uint64_t)address % PAGE_SIZE; - if (fd >= 0) - { - int err; - Descriptor* file = Scheduler::current_task()->open_descriptor_from_fd(fd, err); - if (!file) - { - context->rax = MAP_FAIL(err); - return; - } - context->rax = file->mmap((uint64_t)address - addr_offset, size, real_flags, offset); - return; - } - auto result = MemoryManager::get_pages_at((uint64_t)address - addr_offset, - Utilities::get_blocks_from_size(PAGE_SIZE, size), real_flags); - if (result.has_value()) - { - kdbgln("mmap() succeeded: %p", result.value()); - context->rax = (uint64_t)result.release_value(); - return; - } - else - { - kwarnln("mmap() failed: failed to allocate physical memory"); - context->rax = MAP_FAIL(result.error()); - return; - } - } - kdbgln("mmap(): %ld pages at any address, %s, fd %d", Utilities::get_blocks_from_size(PAGE_SIZE, size), - format_prot(prot), fd); - uint64_t ptr = - Scheduler::current_task()->allocator.request_virtual_pages(Utilities::get_blocks_from_size(PAGE_SIZE, size)); - if (!ptr) - { - kwarnln("mmap() failed: failed to allocate virtual address"); - context->rax = MAP_FAIL(ENOMEM); - return; - } - if (fd >= 0) - { - int err; - Descriptor* file = Scheduler::current_task()->open_descriptor_from_fd(fd, err); - if (!file) - { - context->rax = MAP_FAIL(err); - return; - } - context->rax = file->mmap(ptr, size, real_flags, offset); - return; - } - auto result = MemoryManager::get_pages_at(ptr, Utilities::get_blocks_from_size(PAGE_SIZE, size), real_flags); - if (result.has_value()) - { - kdbgln("mmap() succeeded: %p", result.value()); - context->rax = (uint64_t)result.release_value(); - return; - } - else - { - kwarnln("mmap() failed: failed to allocate physical memory"); - context->rax = MAP_FAIL(result.error()); - return; - } -} - -void sys_munmap(Context* context, void* address, size_t size) -{ - kdbgln("munmap(): attempting to unmap %p", address); - if (size < PAGE_SIZE) - { - kwarnln("munmap() failed: size is too small"); - context->rax = -EINVAL; - return; - } - if (size % PAGE_SIZE) - { - kwarnln("munmap() failed: size is not a multiple of PAGE_SIZE"); - context->rax = -EINVAL; - return; - } - if (!address) - { - kwarnln("munmap() failed: attempted to unmap page 0"); - context->rax = -EINVAL; - return; - } - if (Memory::is_kernel_address((uintptr_t)address)) - { - kwarnln("munmap() failed: attempted to unmap a kernel page"); - context->rax = -EINVAL; - return; - } - uint64_t flags = VMM::get_flags((uint64_t)address); - if (flags == (uint64_t)-1) - { - kwarnln("munmap() failed: attempted to unmap a non-existent page"); - context->rax = -EINVAL; - return; - } - uint64_t offset = (uint64_t)address % PAGE_SIZE; - Scheduler::current_task()->allocator.free_virtual_pages(((uint64_t)address - offset), - Utilities::get_blocks_from_size(PAGE_SIZE, size)); - if (flags & MAP_AS_OWNED_BY_TASK) - MemoryManager::release_pages((void*)((uint64_t)address - offset), - Utilities::get_blocks_from_size(PAGE_SIZE, size)); - else - MemoryManager::release_unaligned_mappings((void*)((uint64_t)address - offset), - Utilities::get_blocks_from_size(PAGE_SIZE, size)); - kdbgln("munmap() succeeded"); - context->rax = 0; - return; -} - -void sys_mprotect(Context* context, void* address, size_t size, int prot) -{ - kdbgln("mprotect(): attempting to protect %p with %s", address, format_prot(prot)); - - if (size < PAGE_SIZE) - { - kwarnln("mprotect() failed: size is too small"); - context->rax = -EINVAL; - return; - } - if (size % PAGE_SIZE) - { - kwarnln("mprotect() failed: size is not a multiple of PAGE_SIZE"); - context->rax = -EINVAL; - return; - } - if (!address) - { - kwarnln("mprotect() failed: attempted to protect page 0"); - context->rax = -EINVAL; - return; - } - if (Memory::is_kernel_address((uintptr_t)address)) - { - kwarnln("mprotect() failed: attempted to protect a kernel page"); - context->rax = -EINVAL; - return; - } - uint64_t flags = VMM::get_flags((uint64_t)address); - if (flags == (uint64_t)-1) - { - kwarnln("mprotect() failed: attempted to protect a non-existent page"); - context->rax = -EINVAL; - return; - } - - uint64_t offset = (uint64_t)address % PAGE_SIZE; - MemoryManager::protect((void*)((uint64_t)address - offset), Utilities::get_blocks_from_size(PAGE_SIZE, size), - flags & MAP_AS_OWNED_BY_TASK ? mman_flags_from_prot(prot) - : mman_flags_from_prot(prot) & ~(MAP_AS_OWNED_BY_TASK)); - kdbgln("mprotect() succeeded"); - context->rax = 0; - return; -} \ No newline at end of file diff --git a/kernel/src/sys/sched.cpp b/kernel/src/sys/sched.cpp deleted file mode 100644 index 6112d3c9..00000000 --- a/kernel/src/sys/sched.cpp +++ /dev/null @@ -1,24 +0,0 @@ -#include "memory/VMM.h" -#include "std/errno.h" -#include "sys/UserMemory.h" -#include "thread/Scheduler.h" - -void sys_exit(Context* context, int status) -{ - Scheduler::task_exit(context, status); -} - -void sys_yield(Context* context) -{ - context->rax = 0; - Scheduler::task_yield(context); -} - -void sys_sleep(Context* context, uint64_t ms) -{ - context->rax = 0; - Task* task = Scheduler::current_task(); - task->task_sleep = ms; - task->state = task->Sleeping; - Scheduler::task_yield(context); -} \ No newline at end of file diff --git a/kernel/src/sys/stat.cpp b/kernel/src/sys/stat.cpp deleted file mode 100644 index 5d026633..00000000 --- a/kernel/src/sys/stat.cpp +++ /dev/null @@ -1,78 +0,0 @@ -#include "fs/VFS.h" -#include "interrupts/Context.h" -#include "std/errno.h" -#include "std/stdlib.h" -#include "sys/UserMemory.h" -#include "thread/Scheduler.h" - -typedef unsigned short mode_t; -typedef unsigned long ino_t; - -struct stat // FIXME: This struct is quite stubbed out. -{ - ino_t st_ino; - mode_t st_mode; - off_t st_size; - int st_dev; // FIXME: Implement this. - int st_nlink; // FIXME: Implement this. - uid_t st_uid; - gid_t st_gid; - time_t st_atime; - time_t st_mtime; - time_t st_ctime; -}; - -void do_stat(Context* context, VFS::Node* node, struct stat* buf) -{ - struct stat stat; - stat.st_ino = node->inode; - stat.st_mode = node->mode | ((1 << (node->type)) * 010000); - stat.st_size = node->length; - stat.st_uid = node->uid; - stat.st_gid = node->gid; - stat.st_atime = node->atime; - stat.st_ctime = node->ctime; - stat.st_mtime = node->mtime; - stat.st_dev = 0; - stat.st_nlink = 0; - if (!copy_typed_to_user(buf, &stat)) context->rax = -EFAULT; - else - context->rax = 0; -} - -void sys_fstat(Context* context, int fd, struct stat* buf) -{ - Task* current_task = Scheduler::current_task(); - if (fd < 0 || fd >= TASK_MAX_FDS) - { - context->rax = -EBADF; - return; - } - Descriptor& file = current_task->files[fd]; - if (!file.is_open()) - { - context->rax = -EBADF; - return; - } - VFS::Node* node = file.node(); - return do_stat(context, node, buf); -} - -void sys_stat(Context* context, const char* path, struct stat* buf) -{ - auto result = strdup_from_user(path); - if (result.has_error()) - { - context->rax = -result.error(); - return; - } - char* kpath = result.release_value(); - VFS::Node* node = VFS::resolve_path(kpath); - kfree(kpath); - if (!node) - { - context->rax = -ENOENT; - return; - } - return do_stat(context, node, buf); -} \ No newline at end of file diff --git a/kernel/src/sys/stdio.cpp b/kernel/src/sys/stdio.cpp deleted file mode 100644 index 2058bd00..00000000 --- a/kernel/src/sys/stdio.cpp +++ /dev/null @@ -1,411 +0,0 @@ -#define MODULE "stdio" - -#include "interrupts/Context.h" -#include "io/Serial.h" -#include "log/Log.h" -#include "memory/VMM.h" -#include "render/TextRenderer.h" -#include "std/errno.h" -#include "std/stdlib.h" -#include "sys/Syscall.h" -#include "sys/UserMemory.h" -#include "thread/Scheduler.h" -#include "thread/Task.h" -#include - -#define OPEN_READ 1 -#define OPEN_WRITE 2 -#define OPEN_NONBLOCK 4 -#define OPEN_CLOEXEC 8 -#define OPEN_DIRECTORY 16 -#define OPEN_TRUNCATED 32 -#define OPEN_CREATE 64 -#define OPEN_APPEND 128 -#define OPEN_EXCL 256 - -#define SEEK_SET 0 -#define SEEK_CUR 1 -#define SEEK_END 2 - -#define FCNTL_DUPFD 0 -#define FCNTL_ISTTY 1 -#define FCNTL_GETFD 2 -#define FCNTL_SETFD 3 - -#define FD_CLOEXEC 1 - -void sys_fcntl(Context* context, int fd, int command, uintptr_t arg) -{ - Task* current_task = Scheduler::current_task(); - int err; - Descriptor* file = current_task->open_descriptor_from_fd(fd, err); - if (!file) - { - context->rax = -err; - return; - } - if (command == FCNTL_DUPFD) - { - int minfd = (int)arg; - if (minfd < 0 || minfd >= TASK_MAX_FDS) - { - context->rax = -EINVAL; - return; - } - int dupfd = current_task->alloc_fd_greater_than_or_equal(minfd); - if (dupfd < 0) - { - context->rax = -EMFILE; - return; - } - current_task->files[dupfd] = *file; - context->rax = dupfd; - kdbgln("fcntl(F_DUPFD): duplicated fd %d, result is %d", fd, dupfd); - return; - } - else if (command == FCNTL_ISTTY) - { - VFS::Node* node = file->node(); - if (node->tty) { context->rax = 1; } - else - context->rax = -ENOTTY; - return; - } - else if (command == FCNTL_GETFD) - { - int flags = 0; - if (file->close_on_exec()) context->rax |= FD_CLOEXEC; - context->rax = flags; - return; - } - else if (command == FCNTL_SETFD) - { - int flags = (int)arg; - if (flags & FD_CLOEXEC) file->set_close_on_exec(true); - else - file->set_close_on_exec(false); - context->rax = 0; - return; - } - else - { - context->rax = -EINVAL; - return; - } -} - -void sys_seek(Context* context, int fd, long offset, int whence) -{ - if (whence < SEEK_SET || whence > SEEK_END) - { - context->rax = -EINVAL; - return; - } - int err; - Descriptor* file = Scheduler::current_task()->open_descriptor_from_fd(fd, err); - if (!file) - { - context->rax = -err; - return; - } - long new_offset; - if (whence == SEEK_SET) new_offset = offset; - else if (whence == SEEK_CUR) - new_offset = offset + file->offset(); - else if (whence == SEEK_END) - new_offset = file->length() + offset; - else - __builtin_unreachable(); - if (new_offset < 0) - { - context->rax = -EINVAL; // FIXME: Is this the right error? - return; - } - if (new_offset == file->offset()) - { - context->rax = new_offset; - return; - } - int result = file->seek(new_offset); - if (result < 0) - { - context->rax = result; - return; - } - context->rax = new_offset; - return; -} - -void sys_write(Context* context, int fd, size_t size, const char* addr) -{ - if (!validate_user_read((uintptr_t)addr, size)) - { - context->rax = -EFAULT; - return; - } - int err; - Descriptor* file = Scheduler::current_task()->open_descriptor_from_fd(fd, err); - if (!file) - { - context->rax = -err; - return; - } - if (!file->can_write()) - { - context->rax = -EBADF; - return; - } - ssize_t result = file->user_write(size, addr); - context->rax = (size_t)result; - return; -} - -void sys_open(Context* context, const char* filename, int flags, mode_t mode) -{ - Task* current_task = Scheduler::current_task(); - int fd = current_task->alloc_fd(); - if (fd < 0) - { - context->rax = -EMFILE; - return; - } - - auto result = strdup_from_user(filename); - if (result.has_error()) - { - context->rax = -result.error(); - return; - } - char* kfilename = result.release_value(); - - VFS::Node* node = VFS::resolve_path(kfilename); - if (!node) - { - bool create = (flags & OPEN_CREATE) > 0; - if (create) - { - mode = mode & (~current_task->umask); - auto rc = VFS::create(kfilename, mode, current_task->euid, current_task->egid); - if (rc.has_error()) context->rax = -rc.error(); - else - { - kinfoln("Created file %s with mode %o, uid %d and gid %d", kfilename, mode, current_task->euid, - current_task->egid); - node = rc.release_value(); - goto do_open; - } - } - else { context->rax = -ENOENT; } - kfree(kfilename); - return; - } - else - { - bool excl = (flags & OPEN_EXCL) > 0; - - if (excl) - { - kfree(kfilename); - context->rax = -EEXIST; - return; - } - } - -do_open: - - bool can_read = (flags & OPEN_READ) > 0; - bool can_write = (flags & OPEN_WRITE) > 0; - if (!can_read && !can_write) - { - kfree(kfilename); - context->rax = -EINVAL; - return; - } - - if (can_read && !VFS::can_read(node, current_task->euid, current_task->egid)) - { - kwarnln("open failed because process with uid %d and gid %d couldn't open file %s with mode %o for reading", - current_task->euid, current_task->egid, kfilename, node->mode); - kfree(kfilename); - context->rax = -EACCES; - return; - } - - if (can_write && !VFS::can_write(node, current_task->euid, current_task->egid)) - { - kwarnln("open failed because process with uid %d and gid %d couldn't open file %s with mode %o for writing", - current_task->euid, current_task->egid, kfilename, node->mode); - kfree(kfilename); - context->rax = -EACCES; - return; - } - - bool able_to_block = (flags & OPEN_NONBLOCK) == 0; - bool close_on_exec = (flags & OPEN_CLOEXEC) > 0; - - bool only_directory = (flags & OPEN_DIRECTORY) > 0; - - bool truncate = (flags & OPEN_TRUNCATED) > 0; - if (truncate) - { - kfree(kfilename); - kerrorln("FIXME: open(O_TRUNC) is not implemented"); - context->rax = -ENOTSUP; - return; - } - - bool append = (flags & OPEN_APPEND) > 0; - - if (only_directory && node->type != VFS_DIRECTORY) - { - kfree(kfilename); - context->rax = -ENOTDIR; - return; - } - - kdbgln("open(): opening %s %s, allocated file descriptor %d", kfilename, - (can_read && can_write) ? "rw" - : can_read ? "r-" - : "-w", - fd); - - kfree(kfilename); - current_task->files[fd].open(node, can_read, can_write, able_to_block, close_on_exec); - - if (append && current_task->files[fd].node()->type != VFS_DEVICE) - { - current_task->files[fd].seek((long)current_task->files[fd].length()); - } - - context->rax = fd; - return; -} - -void sys_read(Context* context, int fd, size_t size, char* buffer) -{ - if (!validate_user_write((uintptr_t)buffer, size)) - { - context->rax = -EFAULT; - return; - } - int err; - Descriptor* file = Scheduler::current_task()->open_descriptor_from_fd(fd, err); - if (!file) - { - context->rax = -err; - return; - } - if (!file->can_read()) - { - context->rax = -EBADF; - return; - } - if (VFS::would_block(file->node())) - { - if (!file->able_to_block()) - { - context->rax = -EAGAIN; - return; - } - Task* current_task = Scheduler::current_task(); - current_task->state = current_task->Blocking; - current_task->block_reason = BlockReason::Reading; - current_task->blocking_read_info.fd = fd; - current_task->blocking_read_info.buf = buffer; - current_task->blocking_read_info.size = size; - return Scheduler::task_yield(context); - } - ssize_t result = file->user_read(size, buffer); - context->rax = (size_t)result; - return; -} - -void sys_close(Context* context, int fd) -{ - int err; - Descriptor* file = Scheduler::current_task()->open_descriptor_from_fd(fd, err); - if (!file) - { - context->rax = -err; - return; - } - kdbgln("close(): releasing file descriptor %d", fd); - file->close(); - context->rax = 0; - return; -} - -void sys_mkdir(Context* context, const char* filename, mode_t mode) -{ - auto result = strdup_from_user(filename); - if (result.has_error()) - { - context->rax = -result.error(); - return; - } - char* kfilename = result.release_value(); - - Task* current_task = Scheduler::current_task(); - - int rc = VFS::do_mkdir(kfilename, current_task->euid, current_task->egid, mode & (~current_task->umask)); - - kfree(kfilename); - - context->rax = rc; -} - -void sys_access(Context* context, const char* path, int) // FIXME: Use the amode argument. -{ - auto result = strdup_from_user(path); - if (result.has_error()) - { - context->rax = -result.error(); - return; - } - char* kpath = result.release_value(); - if (!VFS::exists(kpath)) { context->rax = -ENOENT; } - else - context->rax = 0; - kfree(kpath); -} - -void sys_dup2(Context* context, int fd, int fd2) -{ - int err; - Descriptor* file1 = Scheduler::current_task()->open_descriptor_from_fd(fd, err); - if (!file1) - { - context->rax = -err; - return; - } - Descriptor* file2 = Scheduler::current_task()->descriptor_from_fd(fd2, err); - if (!file2) - { - context->rax = -err; - return; - } - if (file2->is_open()) file2->close(); - *file2 = *file1; - kinfoln("dup2(): overwrote fd %d with fd %d", fd2, fd); - context->rax = fd2; -} - -void sys_umask(Context* context, mode_t cmask) -{ - Task* current_task = Scheduler::current_task(); - context->rax = current_task->umask; - current_task->umask = cmask; -} - -void sys_ioctl(Context* context, int fd, int cmd, uintptr_t arg) -{ - int err; - Descriptor* file = Scheduler::current_task()->open_descriptor_from_fd(fd, err); - if (!file) - { - context->rax = -err; - return; - } - kinfoln("ioctl(): fd %d, cmd %d, arg %lu", fd, cmd, arg); - context->rax = file->ioctl(cmd, arg); -} \ No newline at end of file diff --git a/kernel/src/thread/PIT.cpp b/kernel/src/thread/PIT.cpp deleted file mode 100644 index 074e5b5e..00000000 --- a/kernel/src/thread/PIT.cpp +++ /dev/null @@ -1,30 +0,0 @@ -#define MODULE "pit" - -#include "thread/PIT.h" -#include "io/IO.h" -#include "log/Log.h" - -#define PIT_CHANNEL_0_PORT 0x40 - -volatile uint64_t PIT::ms_since_boot = 0; -static uint16_t divisor = 65535; - -void PIT::initialize(uint64_t frequency) -{ - divisor = (uint16_t)(base_frequency / frequency); - kdbgln("Configuring PIT to use divisor %d (will tick %lu times per second)", divisor, frequency); - if (divisor < 100) divisor = 100; - IO::outb(PIT_CHANNEL_0_PORT, (uint8_t)(divisor & 0xFF)); - IO::delay(); - IO::outb(PIT_CHANNEL_0_PORT, (uint8_t)((divisor & 0xFF00) >> 8)); -} - -uint64_t PIT::frequency() -{ - return base_frequency / divisor; -} - -void PIT::tick() -{ - ms_since_boot += 1000 / frequency(); -} \ No newline at end of file diff --git a/kernel/src/thread/Scheduler.cpp b/kernel/src/thread/Scheduler.cpp deleted file mode 100644 index 9ff79db3..00000000 --- a/kernel/src/thread/Scheduler.cpp +++ /dev/null @@ -1,634 +0,0 @@ -#define MODULE "sched" - -#include "thread/Scheduler.h" -#include "interrupts/Interrupts.h" -#include "log/Log.h" -#include "memory/MemoryManager.h" -#include "memory/PMM.h" -#include "memory/VMM.h" -#include "misc/hang.h" -#include "misc/reboot.h" -#include "misc/utils.h" -#include "panic/Panic.h" -#include "std/ensure.h" -#include "std/errno.h" -#include "std/stdlib.h" -#include "std/string.h" -#include "sys/UserMemory.h" -#include "sys/elf/ELFLoader.h" -#include "thread/PIT.h" -#include "thread/Task.h" -#include "utils/Addresses.h" -#include "utils/Registers.h" - -static uint64_t task_num = 0; - -static Task idle_task; - -static uint64_t free_pid = 0; - -static Task* sched_current_task; -static Task* base_task; -static Task* end_task; - -extern "C" void idle_task_function(); - -static uint64_t frequency; - -template void sched_for_each_task(Callback callback) -{ - Task* task = base_task; - if (!task) return; - do { - if (!task) break; - bool will_continue = callback(task); - if (!will_continue) break; - task = task->next_task; - } while (task != base_task); -} - -template void sched_for_each_child(Task* task, Callback callback) -{ - sched_for_each_task([&](Task* child) { - if (child->ppid == task->id) { return callback(child); } - return true; - }); -} - -Task* Scheduler::find_by_pid(uint64_t pid) -{ - Task* result = nullptr; - sched_for_each_task([&](Task* task) { - if (task->id == pid) - { - result = task; - return false; - } - return true; - }); - return result; -} - -void Scheduler::append_task(Task* task) -{ - if (!base_task) - { - ensure(!end_task); - base_task = task; - end_task = base_task; - task->next_task = task; - task->prev_task = task; - } - else - { - end_task->next_task = task; - task->prev_task = end_task; - base_task->prev_task = task; - task->next_task = base_task; - end_task = task; - } -} - -void Scheduler::init() -{ - memset(&idle_task, 0, sizeof(Task)); - idle_task.id = free_pid++; - idle_task.regs.rip = (uint64_t)idle_task_function; - idle_task.regs.rsp = - get_top_of_stack((uint64_t)MemoryManager::get_page().release_value(), - 1); // If we OOM while creating the idle task, that's NOT good and we can panic. - idle_task.regs.cs = 0x08; - idle_task.regs.ss = 0x10; - idle_task.regs.rflags = (1 << 21) | (1 << 9); - idle_task.task_sleep = 1000; - idle_task.user_task = false; - idle_task.block_reason = BlockReason::None; - idle_task.state = idle_task.Idle; - - strlcpy(idle_task.name, "[cpu-idle]", sizeof(idle_task.name)); - - sched_current_task = &idle_task; - - frequency = 1000 / PIT::frequency(); -} - -void Scheduler::add_kernel_task(const char* taskname, void (*task)(void)) -{ - Task* new_task = new Task; - ensure(new_task); - new_task->user_task = false; - new_task->id = free_pid++; - new_task->ppid = 0; - new_task->uid = new_task->euid = new_task->gid = new_task->egid = 0; - new_task->regs.rip = (uint64_t)task; - new_task->allocated_stack = - (uint64_t)MemoryManager::get_pages(TASK_PAGES_IN_STACK).release_value(); // FIXME: Propagate errors. - new_task->regs.rsp = get_top_of_stack(new_task->allocated_stack, TASK_PAGES_IN_STACK); - new_task->regs.cs = 0x08; - new_task->regs.ss = 0x10; - new_task->regs.ds = 0x10; - new_task->regs.rflags = read_rflags() | 0x200; // enable interrupts - new_task->task_sleep = 0; - new_task->task_time = 0; - new_task->cpu_time = 0; - strlcpy(new_task->name, taskname, sizeof(new_task->name)); - append_task(new_task); - new_task->block_reason = BlockReason::None; - new_task->state = new_task->Running; - task_num++; - kinfoln("Adding kernel task: %s, starts at %lx, PID %ld, stack at %lx, total tasks: %ld", new_task->name, - new_task->regs.rip, new_task->id, new_task->regs.rsp, task_num); -} - -Task* Scheduler::create_user_task() -{ - Task* new_task = new Task; - if (!new_task) return nullptr; - memset(&new_task->regs, 0, sizeof(Context)); - new_task->user_task = true; - new_task->id = free_pid++; - new_task->ppid = 0; - new_task->task_sleep = 0; - new_task->task_time = 0; - new_task->cpu_time = 0; - new_task->block_reason = BlockReason::None; - append_task(new_task); - task_num++; - return new_task; -} - -long Scheduler::load_user_task(const char* filename) -{ - kinfoln("Loading user task: %s", filename); - Interrupts::push_and_disable(); - Task* new_task = new Task; - ensure(new_task); - memset(&new_task->regs, 0, sizeof(Context)); - new_task->id = free_pid++; - new_task->ppid = 0; - new_task->uid = new_task->euid = new_task->gid = new_task->egid = 0; - if (!new_task->allocator.init()) - { - delete new_task; - free_pid--; - Interrupts::pop(); - return -ENOMEM; - } - new_task->address_space = AddressSpace::create().release_value(); // FIXME: Propagate this error. - VMM::switch_to_user_address_space(new_task->address_space); - long result; - if ((result = ELFLoader::check_elf_image_from_filesystem(filename)) < 0) - { - delete new_task; - free_pid--; - kerrorln("Failed to load %s from initrd", filename); - Interrupts::pop(); - return result; - } - if ((uint64_t)result > PMM::get_free()) - { - delete new_task; - free_pid--; - kerrorln("Not enough memory for task %s", filename); - Interrupts::pop(); - return -ENOMEM; - } - ELFImage* image = ELFLoader::load_elf_from_filesystem(filename); - ensure(image); - new_task->user_task = true; - new_task->regs.rip = image->entry; - new_task->image = image; - new_task->umask = 0; - new_task->allocated_stack = (uint64_t)MemoryManager::get_pages_at(0x100000, TASK_PAGES_IN_STACK, - MAP_READ_WRITE | MAP_USER | MAP_AS_OWNED_BY_TASK) - .release_value(); // FIXME: Propagate errors. - if (!new_task->allocated_stack) - { - new_task->address_space.destroy(); - delete new_task; - free_pid--; - ELFLoader::release_elf_image(image); - VMM::switch_back_to_kernel_address_space(); - Interrupts::pop(); - return -ENOMEM; - } - new_task->regs.rsp = get_top_of_stack(new_task->allocated_stack, TASK_PAGES_IN_STACK); - new_task->regs.cs = 0x18 | 0x03; - new_task->regs.ss = 0x20 | 0x03; - new_task->regs.ds = 0x20 | 0x03; - new_task->regs.rflags = (1 << 21) | (1 << 9); // enable interrupts - new_task->task_sleep = 0; - new_task->task_time = 0; - new_task->cpu_time = 0; - strlcpy(new_task->name, filename, sizeof(new_task->name)); - append_task(new_task); - new_task->block_reason = BlockReason::None; - new_task->state = new_task->Running; - task_num++; - kinfoln("Adding user task: %s, loaded at %lx, PID %ld, stack at %lx, total tasks: %ld", new_task->name, - new_task->regs.rip, new_task->id, new_task->regs.rsp, task_num); - VMM::switch_back_to_kernel_address_space(); - Interrupts::pop(); - return (long)new_task->id; -} - -void Scheduler::reset_task(Task* task, ELFImage* new_image) -{ - memset(&task->regs, 0, sizeof(Context)); - task->state = task->Running; - task->regs.rip = new_image->entry; - task->image = new_image; - task->regs.rsp = get_top_of_stack(task->allocated_stack, TASK_PAGES_IN_STACK); - task->regs.cs = 0x18 | 0x03; - task->regs.ss = 0x20 | 0x03; - task->regs.ds = 0x20 | 0x03; - task->regs.rflags = (1 << 21) | (1 << 9); // enable interrupts - task->task_sleep = 0; - task->cpu_time = 0; - task->block_reason = BlockReason::None; - kinfoln("Resetting task: %s, loaded at %lx, PID %ld, stack at %lx, total tasks: %ld", task->name, task->regs.rip, - task->id, task->regs.rsp, task_num); -} - -void Scheduler::reap_task(Task* task) -{ - ensure(!Interrupts::is_in_handler()); - task_num--; - Task* exiting_task = task; - ensure(task->id != 0); // WHY IN THE WORLD WOULD WE BE REAPING THE IDLE TASK? - if (exiting_task->is_user_task()) - { - VMM::switch_back_to_kernel_address_space(); - VMM::apply_address_space(); - VMM::switch_to_user_address_space(exiting_task->address_space); - } - kinfoln("reaping task %s, PID %ld, exited with code %ld", exiting_task->name, exiting_task->id, - exiting_task->exit_status); - if (exiting_task->id == (free_pid - 1)) free_pid--; // If we are the last spawned thread, free our PID. - if (exiting_task->allocated_stack && !exiting_task->is_user_task()) - MemoryManager::release_pages((void*)exiting_task->allocated_stack, TASK_PAGES_IN_STACK); - if (exiting_task->image) kfree(exiting_task->image); - if (exiting_task->is_user_task()) - { - exiting_task->allocator.free(); - VMM::switch_back_to_kernel_address_space(); - VMM::apply_address_space(); - Interrupts::push_and_enable(); - exiting_task->address_space.destroy(); - Interrupts::pop(); - } - for (int i = 0; i < TASK_MAX_FDS; i++) { exiting_task->files[i].close(); } - delete exiting_task; -} - -void sched_common_exit(Context* context, int64_t status) -{ - if (sched_current_task->id == 1) sched_current_task->state = sched_current_task->Exited; - else - sched_current_task->state = sched_current_task->Dying; - sched_current_task->exit_status = status; - if (sched_current_task->id != 1) - { - sched_for_each_child(sched_current_task, [](Task* child) { - if (child->state != child->Exited) child->ppid = 1; - return true; - }); - } - else - { - kinfoln("PID 1 exited with code %ld", status); -#ifndef RUN_TEST_AS_INIT - reboot(); -#else - hang(); -#endif - } - Scheduler::task_yield(context); -} - -void Scheduler::task_exit(Context* context, int64_t status) -{ - ensure(Interrupts::is_in_handler()); - kdbgln("exit: task %ld finished running, used %ld ms of cpu time", sched_current_task->id, - sched_current_task->cpu_time); - sched_common_exit(context, status); -} - -void Scheduler::task_misbehave(Context* context, int64_t status) -{ - ensure(Interrupts::is_in_handler()); - kdbgln("exit: task %ld misbehaved, used %ld ms of cpu time", sched_current_task->id, sched_current_task->cpu_time); - sched_common_exit(context, status); -} - -void Scheduler::reap_tasks() -{ - Interrupts::disable(); - ensure(!Interrupts::is_in_handler()); - Task* reap_base = nullptr; - Task* reap_end = nullptr; - Task* task = base_task; - Task* task_reaping; - uint64_t iter_index = 0; - do { - if (task->state == task->Exited) - { - if (task == base_task && task == end_task) { panic("Last task exited"); } - else if (task == base_task) { base_task = task->next_task; } - else if (task == end_task) { end_task = task->prev_task; } - if (!reap_base) - { - reap_base = task; - reap_end = task; - task->prev_task->next_task = task->next_task; - task->next_task->prev_task = task->prev_task; - task->prev_task = nullptr; - task_reaping = task; - task = task->next_task; - task_reaping->next_task = nullptr; - } - else - { - reap_end->next_task = task; - task->prev_task->next_task = task->next_task; - task->next_task->prev_task = task->prev_task; - task->prev_task = nullptr; - reap_end = task; - task_reaping = task; - task = task->next_task; - task_reaping->next_task = nullptr; - } - } - else { task = task->next_task; } - iter_index++; - } while (iter_index < task_num); - task = reap_base; - while (task) - { - Task* reaped_task = task; - task = task->next_task; - reap_task(reaped_task); - } - Interrupts::enable(); -} - -static void sched_decrement_sleep_times() -{ - sched_for_each_task([](Task* task) { - if (task->task_sleep > 0) - { - task->task_sleep -= frequency; - if (task->task_sleep < 0) task->task_sleep = 0; - } - if (task->task_sleep == 0 && task->state == task->Sleeping) task->state = task->Running; - return true; - }); -} - -void Scheduler::task_tick(Context* context) -{ - ensure(Interrupts::is_in_handler()); - Interrupts::disable(); - sched_decrement_sleep_times(); - sched_current_task->task_time -= frequency; - sched_current_task->cpu_time += frequency; - if (sched_current_task->id == 0) return task_yield(context); - if (sched_current_task->task_time <= 0) - { - sched_current_task->task_time = 0; - task_yield(context); - } - Interrupts::enable(); -} - -void Scheduler::task_yield(Context* context) -{ - ensure(Interrupts::is_in_handler()); - Interrupts::disable(); - sched_current_task->save_context(context); - bool was_idle = false; - if (sched_current_task->state == sched_current_task->Idle) - { - sched_current_task = end_task; - was_idle = true; - } - Task* original_task = sched_current_task; - do { - sched_current_task = sched_current_task->next_task; - if (sched_current_task->state == sched_current_task->Blocking) - { - if (!sched_current_task->is_still_blocking()) sched_current_task->resume(); - } - if (sched_current_task->state == sched_current_task->Running) - { - if (sched_current_task->id != original_task->id || was_idle) - { - if (!was_idle && original_task->is_user_task() && !original_task->has_died()) - { - original_task->save_floating(); - } - if (sched_current_task->is_user_task()) - { - sched_current_task->switch_to_address_space(); - sched_current_task->restore_floating(); - } - else if (!was_idle && original_task->is_user_task() && !sched_current_task->is_user_task()) - { - VMM::switch_back_to_kernel_address_space(); - VMM::apply_address_space(); - } - } - sched_current_task->task_time = 20; - sched_current_task->restore_context(context); - return; - } - } while (sched_current_task != original_task); - if (!was_idle && original_task->is_user_task() && original_task->state != original_task->Exited) - { - original_task->save_floating(); - } - sched_current_task = &idle_task; - sched_current_task->task_time = frequency; - if (!was_idle) { sched_current_task->restore_context(context); } - return; -} - -void Scheduler::yield() -{ - asm volatile("int $0x42" : : "a"(1)); -} - -void Scheduler::exit(int status) -{ - asm volatile("int $0x42" : : "a"(0), "D"(status)); -} - -void Scheduler::sleep(unsigned long ms) -{ - asm volatile("int $0x42" : : "D"(ms), "a"(2)); -} - -Task* Scheduler::current_task() -{ - return sched_current_task; -} - -#define WNOHANG 1 - -void sys_waitpid(Context* context, long pid, int* wstatus, - int options) // FIXME: only allow waiting for child processes when specifying a PID. -{ - Task* child = nullptr; - if (pid == -1) - { - sched_for_each_child(sched_current_task, [&](Task* task) { - if (task->state == task->Dying) - { - child = task; - return false; - } - return true; - }); - if (!child) - { - if (options & WNOHANG) - { - context->rax = 0; // No child has exited, let's return 0. - return; - } - kdbgln("blocking wait on any child"); - sched_current_task->state = sched_current_task->Blocking; - sched_current_task->block_reason = BlockReason::Waiting; - sched_current_task->blocking_wait_info.pid = -1; - sched_current_task->blocking_wait_info.wstatus = wstatus; - return Scheduler::task_yield(context); - } - } - else - { - child = Scheduler::find_by_pid(pid); - if (!child) - { - context->rax = -ECHILD; - return; - } - } - if (child->ppid != sched_current_task->id) - { - // We are trying to call waitpid() on a task that isn't a child of ours. This is not allowed. - context->rax = -ECHILD; - return; - } - if (child->state != child->Dying) - { - if (options & WNOHANG) - { - context->rax = 0; // No child has exited, let's return 0. - return; - } - sched_current_task->state = sched_current_task->Blocking; - sched_current_task->block_reason = BlockReason::Waiting; - sched_current_task->blocking_wait_info.pid = pid; - sched_current_task->blocking_wait_info.wstatus = wstatus; - return Scheduler::task_yield(context); - } - child->state = child->Exited; - context->rax = (long)child->id; - if (wstatus) - { - int status = (int)(child->exit_status & 0xff); - if (!copy_to_user(wstatus, &status, sizeof(int))) context->rax = -EFAULT; - } -} - -bool Task::is_wait_still_blocking() -{ - Task* child = nullptr; - if (blocking_wait_info.pid == -1) - { - sched_for_each_child(sched_current_task, [&](Task* task) { - if (task->state == task->Dying) - { - child = task; - return false; - } - return true; - }); - if (!child) return true; - else - { - blocking_wait_info.pid = child->id; // We're committed to this child now. - return false; - } - } - else - { - child = Scheduler::find_by_pid(blocking_wait_info.pid); - ensure(child); // since sys_waitpid should have validated this child, and the only way for it to disappear from - // the process list is for someone to wait for it, this should be pretty safe. - if (child->state != child->Dying) return true; - else - return false; - } -} - -void Task::resume_wait() -{ - ensure(blocking_wait_info.pid != -1); // is_wait_still_blocking should have chosen a child for us if the user - // process told us to wait for any child. - Task* child = Scheduler::find_by_pid(blocking_wait_info.pid); - ensure(child); // This should also already have been validated. - - child->state = child->Exited; - regs.rax = (long)child->id; - - if (blocking_wait_info.wstatus) - { - int wstatus = (int)(child->exit_status & 0xff); - if (!copy_to_user(blocking_wait_info.wstatus, &wstatus, sizeof(int))) regs.rax = -EFAULT; - } -} - -struct pstat -{ - long pt_pid; - long pt_ppid; - char pt_name[128]; - int pt_state; - long pt_time; - uid_t pt_uid; - gid_t pt_gid; -}; - -void sys_pstat(Context* context, long pid, struct pstat* buf) -{ - Task* task; - if (pid == -1) task = Scheduler::find_by_pid(free_pid - 1); - else if (pid == 0) - task = &idle_task; - else - task = Scheduler::find_by_pid(pid); - if (!task) - { - context->rax = -ESRCH; - return; - } - if (task->state == task->Exited) // we're just waiting for the reaper to reap it - { - context->rax = -ESRCH; - return; - } - context->rax = task->id; - if (buf) - { - struct pstat stat; - stat.pt_pid = task->id; - stat.pt_ppid = task->ppid; - stat.pt_state = (int)task->state; - stat.pt_time = (long)task->cpu_time; - stat.pt_uid = task->uid; - stat.pt_gid = task->gid; - strlcpy(stat.pt_name, task->name, sizeof(stat.pt_name)); - if (!copy_to_user(buf, &stat, sizeof(struct pstat))) context->rax = -EFAULT; - } -} \ No newline at end of file diff --git a/kernel/src/thread/Spinlock.asm b/kernel/src/thread/Spinlock.asm deleted file mode 100644 index 2b2e7a43..00000000 --- a/kernel/src/thread/Spinlock.asm +++ /dev/null @@ -1,20 +0,0 @@ -global spinlock_lock_acquire -spinlock_lock_acquire: - lock bts qword [rdi], 0 - jc .spin - ret -.spin: - pause - test qword [rdi], 1 - jnz .spin - jmp spinlock_lock_acquire - -global spinlock_lock_release -spinlock_lock_release: - mov qword [rdi], 0 - ret - -global spinlock_lock_is_locked -spinlock_lock_is_locked: - mov rax, [rdi] - ret \ No newline at end of file diff --git a/kernel/src/thread/Spinlock.cpp b/kernel/src/thread/Spinlock.cpp deleted file mode 100644 index 2db971c2..00000000 --- a/kernel/src/thread/Spinlock.cpp +++ /dev/null @@ -1,27 +0,0 @@ -#include "thread/Spinlock.h" - -extern "C" void spinlock_lock_acquire(volatile uint64_t* lock); -extern "C" void spinlock_lock_release(volatile uint64_t* lock); -extern "C" int spinlock_lock_is_locked(volatile uint64_t* lock); - -void Spinlock::acquire() -{ - spinlock_lock_acquire(&m_lock); -} - -void Spinlock::release() -{ - spinlock_lock_release(&m_lock); -} - -bool Spinlock::locked() -{ - return spinlock_lock_is_locked(&m_lock); -} - -void lock(Spinlock& lock, void (*action)(void)) -{ - lock.acquire(); - action(); - lock.release(); -} \ No newline at end of file diff --git a/kernel/src/thread/Task.cpp b/kernel/src/thread/Task.cpp deleted file mode 100644 index 95a450a1..00000000 --- a/kernel/src/thread/Task.cpp +++ /dev/null @@ -1,140 +0,0 @@ -#define MODULE "sched" - -#include "thread/Task.h" -#include "log/Log.h" -#include "memory/VMM.h" -#include "std/ensure.h" -#include "std/errno.h" -#include "std/string.h" - -void Task::restore_context(Context* context) -{ - memcpy(context, ®s, sizeof(Context)); -} - -void Task::save_context(Context* context) -{ - memcpy(®s, context, sizeof(Context)); -} - -void Task::save_floating() -{ - floating_saved = true; - asm volatile("fxsave (%0)" : : "r"((char*)floating_region)); -} - -void Task::restore_floating() -{ - if (!floating_saved) return; - asm volatile("fxrstor (%0)" : : "r"((char*)floating_region)); -} - -bool Task::is_user_task() -{ - return user_task; -} - -int Task::alloc_fd() -{ - int fd; - for (fd = 0; fd < TASK_MAX_FDS; fd++) - { - if (!files[fd].is_open()) break; - } - - if (fd == TASK_MAX_FDS) { return -1; } - - return fd; -} - -int Task::alloc_fd_greater_than_or_equal(int base_fd) -{ - int fd; - if (base_fd >= TASK_MAX_FDS) return -1; - for (fd = base_fd; fd < TASK_MAX_FDS; fd++) - { - if (!files[fd].is_open()) break; - } - - if (fd == TASK_MAX_FDS) { return -1; } - - return fd; -} - -void Task::switch_to_address_space() -{ - VMM::switch_to_user_address_space(address_space); - VMM::apply_address_space(); -} - -bool Task::has_died() -{ - return state == Exited; -} - -void Task::resume_read() -{ - regs.rax = files[blocking_read_info.fd].user_read(blocking_read_info.size, blocking_read_info.buf); -} - -bool Task::is_read_still_blocking() -{ - return VFS::would_block(files[blocking_read_info.fd].node()); -} - -void Task::resume() -{ - VMM::switch_back_to_kernel_address_space(); - VMM::apply_address_space(); - VMM::switch_to_user_address_space(address_space); - switch (block_reason) - { - case BlockReason::None: return; - case BlockReason::Reading: resume_read(); break; - case BlockReason::Waiting: resume_wait(); break; - - default: ensure(false); - } - VMM::apply_address_space(); - block_reason = BlockReason::None; - state = Running; -} - -bool Task::is_still_blocking() -{ - switch (block_reason) - { - case BlockReason::None: return true; - case BlockReason::Reading: return is_read_still_blocking(); - case BlockReason::Waiting: return is_wait_still_blocking(); - - default: return true; - } -} - -Descriptor* Task::open_descriptor_from_fd(int fd, int& error) -{ - Descriptor* file = descriptor_from_fd(fd, error); - if (!file) return nullptr; - if (!file->is_open()) - { - error = EBADF; - return nullptr; - } - return file; -} - -Descriptor* Task::descriptor_from_fd(int fd, int& error) -{ - if (fd < 0 || fd >= TASK_MAX_FDS) - { - error = EBADF; - return nullptr; - } - return &files[fd]; -} - -bool Task::is_superuser() -{ - return euid == 0; -} \ No newline at end of file diff --git a/kernel/src/trace/Resolve.cpp b/kernel/src/trace/Resolve.cpp deleted file mode 100644 index 77bbc71d..00000000 --- a/kernel/src/trace/Resolve.cpp +++ /dev/null @@ -1,41 +0,0 @@ -#include "trace/Resolve.h" -#include "fs/InitRD.h" -#include "std/stdlib.h" -#include "std/string.h" -#include - -extern int kernel_start; -extern int kernel_end; - -static InitRD::File symbol_map = {"", 0, 0, (void*)-1, 0}; - -static size_t symbol_strlen(const char* symbol) -{ - const char* i = symbol; - for (; *i != '\n' && *i; ++i) - ; - return (i - symbol); -} - -void get_symbol_name(uintptr_t address, char* buffer, size_t max) -{ - if (symbol_map.addr == (void*)-1) { symbol_map = InitRD::open("sys/moon.sym"); } - if (!symbol_map.addr) { strlcpy(buffer, "(no symbols loaded)", max); } - while (address >= (uintptr_t)&kernel_start && address <= (uintptr_t)&kernel_end) - { - char addr_as_str[60]; - ultoa(address, addr_as_str, 16); - char* symbol = strstr((char*)symbol_map.addr, addr_as_str); - if (symbol) - { - symbol += 19; - size_t symlen = symbol_strlen(symbol); - size_t copylen = (max - 1) < symlen ? (max - 1) : symlen; - memcpy(buffer, symbol, copylen); - buffer[copylen] = 0; - return; - } - address--; - } - strlcpy(buffer, "(no symbol)", max); -} \ No newline at end of file diff --git a/kernel/src/trace/StackTracer.cpp b/kernel/src/trace/StackTracer.cpp deleted file mode 100644 index cf9a4572..00000000 --- a/kernel/src/trace/StackTracer.cpp +++ /dev/null @@ -1,55 +0,0 @@ -#define MODULE "trace" - -#include "trace/StackTracer.h" -#include "log/Log.h" -#include "memory/Memory.h" -#include "std/stdio.h" -#include "trace/Resolve.h" - -StackTracer::StackTracer() -{ - asm("mov %%rbp, %0" : "=r"(m_base_pointer)); -} - -StackTracer::StackTracer(uintptr_t base_pointer) : m_base_pointer(base_pointer) -{ -} - -typedef struct stackframe -{ - struct stackframe* next; - uintptr_t instruction; -} stackframe; - -void StackTracer::trace() -{ - stackframe* frame = (stackframe*)m_base_pointer; - while (frame && frame->instruction && Memory::is_kernel_address(frame->instruction)) - { - char symbol_name[512]; - get_symbol_name(frame->instruction - sizeof(uintptr_t), symbol_name, sizeof(symbol_name)); - kinfoln("%lx: %s", frame->instruction - sizeof(uintptr_t), symbol_name); - frame = frame->next; - } -} - -void StackTracer::trace_with_ip(uintptr_t ip) -{ - char symbol_name[512]; - get_symbol_name(ip, symbol_name, sizeof(symbol_name)); - kinfoln("%lx: %s", ip, symbol_name); - trace(); -} - -bool stack_trace_contains(uintptr_t address) -{ - uintptr_t base_pointer; - asm volatile("mov %%rbp, %0" : "=r"(base_pointer)); - stackframe* frame = (stackframe*)base_pointer; - while (Memory::is_kernel_address((uintptr_t)frame)) - { - if (frame->instruction == address) return true; - frame = frame->next; - } - return false; -} \ No newline at end of file diff --git a/kernel/src/utils/PageFaultReason.cpp b/kernel/src/utils/PageFaultReason.cpp deleted file mode 100644 index 054a2294..00000000 --- a/kernel/src/utils/PageFaultReason.cpp +++ /dev/null @@ -1,20 +0,0 @@ -#define MODULE "mem" - -#include "utils/PageFaultReason.h" -#include "log/Log.h" - -#define PROGRAM_STACK_BOTTOM 0x100000 - -void determine_user_page_fault_reason(uintptr_t faulting_address) -{ - if (faulting_address < 0x1000) - { - kinfoln("Address 0x%lx looks like a nullptr dereference", faulting_address); - return; - } - if (faulting_address < PROGRAM_STACK_BOTTOM && (PROGRAM_STACK_BOTTOM - faulting_address) < 0x1000) - { - kinfoln("Address 0x%lx looks like a stack overflow", faulting_address); - return; - } -} \ No newline at end of file diff --git a/kernel/src/utils/StringParsing.cpp b/kernel/src/utils/StringParsing.cpp deleted file mode 100644 index 0662aa52..00000000 --- a/kernel/src/utils/StringParsing.cpp +++ /dev/null @@ -1,49 +0,0 @@ -#include "utils/StringParsing.h" - -int isdigit(int c) -{ - return c >= '0' && c < ':'; -} - -int isodigit(int c) -{ - return c >= '0' && c < '8'; -} - -int isxdigit(int c) -{ - return isdigit(c) || ((unsigned int)c | 32) - 'a' < 6; -} - -template -static T string_to_integer_type(const char* str, int base, ValidDigitChecker checker, Converter converter) -{ - bool neg = false; - T val = 0; - - switch (*str) - { - case '-': - neg = true; - str++; - break; - case '+': str++; break; - default: break; - } - - while (checker(*str)) { val = (base * val) + converter(*str++); } - - return (neg ? -val : val); -} - -long parse_decimal(const char* str) -{ - return string_to_integer_type( - str, 10, [](char c) { return isdigit(c); }, [](char c) { return c - '0'; }); -} - -long parse_octal(const char* str) -{ - return string_to_integer_type( - str, 8, [](char c) { return isodigit(c); }, [](char c) { return c - '0'; }); -} \ No newline at end of file diff --git a/kernel/src/utils/Time.cpp b/kernel/src/utils/Time.cpp deleted file mode 100644 index 0476a6b2..00000000 --- a/kernel/src/utils/Time.cpp +++ /dev/null @@ -1,42 +0,0 @@ -#define MODULE "time" - -#include "utils/Time.h" -#include "log/Log.h" - -int isleap(int year) -{ - return year % 4 == 0 && (year % 100 != 0 || year % 400 == 0); -} - -int make_yday(int year, int month) -{ - static const short int upto[12] = {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334}; - int yd; - - yd = upto[month - 1]; - if (month > 2 && isleap(year)) yd++; - return yd; -} - -uint64_t broken_down_to_unix(uint64_t year, uint64_t yday, uint64_t hour, uint64_t min, uint64_t sec) -{ - return sec + min * 60 + hour * 3600 + yday * 86400 + (year - 70) * 31536000 + ((year - 69) / 4) * 86400 - - ((year - 1) / 100) * 86400 + ((year + 299) / 400) * 86400; -} - -static int bcd_number_to_decimal(int num) -{ - return ((num >> 4) * 10) + (num & 0xf); -} - -uint64_t unix_boottime(uint8_t boottime[8]) -{ - int year = bcd_number_to_decimal(boottime[0]) * 100 + bcd_number_to_decimal(boottime[1]); - int month = bcd_number_to_decimal(boottime[2]); - int day = bcd_number_to_decimal(boottime[3]); - int hour = bcd_number_to_decimal(boottime[4]); - int minute = bcd_number_to_decimal(boottime[5]); - int second = bcd_number_to_decimal(boottime[6]); - kinfoln("UTC boot time: %d-%d-%d %d:%d:%d", year, month, day, hour, minute, second); - return broken_down_to_unix(year - 1900, make_yday(year, month) + (day - 1), hour, minute, second); -} \ No newline at end of file diff --git a/libs/Makefile b/libs/Makefile deleted file mode 100644 index a0712517..00000000 --- a/libs/Makefile +++ /dev/null @@ -1,8 +0,0 @@ -build: - @$(MAKE) -C libc build - -install: - @$(MAKE) -C libc install - -clean: - @$(MAKE) -C libc clean \ No newline at end of file diff --git a/libs/libc/Makefile b/libs/libc/Makefile deleted file mode 100644 index 804c5682..00000000 --- a/libs/libc/Makefile +++ /dev/null @@ -1,87 +0,0 @@ -LIBC_DIR := $(LUNA_ROOT)/libs/libc -LIBC_SRC := $(LIBC_DIR)/src -LIBC_OBJ := $(LIBC_DIR)/lib -LIBC_BIN := $(LIBC_DIR)/bin - -DESTDIR ?= $(LUNA_BASE)/usr/lib - -CFLAGS := -Os -nostdlib -ffunction-sections -fdata-sections -fno-asynchronous-unwind-tables -fno-omit-frame-pointer -pedantic -Wall -Wextra -Werror -Wfloat-equal -Wdisabled-optimization -Wformat=2 -Winit-self -Wmissing-include-dirs -Wswitch-default -Wcast-qual -Wundef -Wcast-align -Wwrite-strings -Wlogical-op -Wredundant-decls -Wshadow -Wconversion -CXXFLAGS := -fno-rtti -fno-exceptions -Wsign-promo -Wstrict-null-sentinel -Wctor-dtor-privacy -ASMFLAGS := -felf64 - -rwildcard=$(foreach d,$(wildcard $(1:=/*)),$(call rwildcard,$d,$2) $(filter $(subst *,%,$2),$d)) - -CXX_SRC = $(call rwildcard,$(LIBC_SRC),*.cpp) -C_SRC = $(call rwildcard,$(LIBC_SRC),*.c) -ASM_SRC = $(call rwildcard,$(LIBC_SRC),*.asm) - -OBJS = $(patsubst $(LIBC_SRC)/%.cpp, $(LIBC_OBJ)/%.cpp.o, $(CXX_SRC)) -OBJS += $(patsubst $(LIBC_SRC)/%.c, $(LIBC_OBJ)/%.c.o, $(C_SRC)) -OBJS += $(patsubst $(LIBC_SRC)/%.asm, $(LIBC_OBJ)/%.asm.o, $(ASM_SRC)) - -$(LIBC_OBJ)/%.cpp.o: $(LIBC_SRC)/%.cpp - @mkdir -p $(@D) - @$(CXX) $(CFLAGS) $(CXXFLAGS) -o $@ -c $^ - @echo " CXX $^" - -$(LIBC_OBJ)/%.c.o: $(LIBC_SRC)/%.c - @mkdir -p $(@D) - @$(CC) $(CFLAGS) -o $@ -c $^ - @echo " CC $^" - -$(LIBC_OBJ)/%.asm.o: $(LIBC_SRC)/%.asm - @mkdir -p $(@D) - @$(ASM) $(ASMFLAGS) -o $@ $^ - @echo " ASM $^" - -$(LIBC_BIN)/libc.a: $(OBJS) - @mkdir -p $(@D) - @$(AR) rcs $@ $(OBJS) - @echo " AR $@" - -$(LIBC_BIN)/crt0.o: $(LIBC_DIR)/crt0.asm - @mkdir -p $(@D) - @$(ASM) $(ASMFLAGS) -o $@ $^ - @echo " ASM $^" - -$(LIBC_BIN)/crti.o: $(LIBC_DIR)/crti.asm - @mkdir -p $(@D) - @$(ASM) $(ASMFLAGS) -o $@ $^ - @echo " ASM $^" - -$(LIBC_BIN)/crtn.o: $(LIBC_DIR)/crtn.asm - @mkdir -p $(@D) - @$(ASM) $(ASMFLAGS) -o $@ $^ - @echo " ASM $^" - -build: $(LIBC_BIN)/crt0.o $(LIBC_BIN)/crti.o $(LIBC_BIN)/crtn.o $(LIBC_BIN)/libc.a - -$(DESTDIR)/libc.a: $(LIBC_BIN)/libc.a - @mkdir -p $(@D) - @cp $^ $@ - @rm -f $(DESTDIR)/libm.a - @ln -s $@ $(DESTDIR)/libm.a - @echo " INSTALL $^" - -$(DESTDIR)/crt0.o: $(LIBC_BIN)/crt0.o - @mkdir -p $(@D) - @cp $^ $@ - @echo " INSTALL $^" - -$(DESTDIR)/crti.o: $(LIBC_BIN)/crti.o - @mkdir -p $(@D) - @cp $^ $@ - @echo " INSTALL $^" - -$(DESTDIR)/crtn.o: $(LIBC_BIN)/crtn.o - @mkdir -p $(@D) - @cp $^ $@ - @echo " INSTALL $^" - -install: $(DESTDIR)/libc.a $(DESTDIR)/crt0.o $(DESTDIR)/crti.o $(DESTDIR)/crtn.o - -clean: - rm -rf $(LIBC_OBJ)/* - rm -rf $(LIBC_BIN)/* - rm -f $(DESTDIR)/libc.a - rm -f $(DESTDIR)/crt*.o \ No newline at end of file diff --git a/libs/libc/crt0.asm b/libs/libc/crt0.asm deleted file mode 100644 index 71973e6a..00000000 --- a/libs/libc/crt0.asm +++ /dev/null @@ -1,35 +0,0 @@ -section .text - -extern _init -extern main -extern _fini -extern initialize_libc -extern exit - -global _start -_start: - ; Set up end of the stack frame linked list. - xor rbp, rbp - push rbp ; rip=0 - push rbp ; rbp=0 - mov rbp, rsp - - push rdi - push rsi - - call initialize_libc - - call _init - - pop rsi ; argv - pop rdi ; argc - - call main - - push rax - - call _fini - - pop rdi - - call exit \ No newline at end of file diff --git a/libs/libc/crti.asm b/libs/libc/crti.asm deleted file mode 100644 index 6b5aed06..00000000 --- a/libs/libc/crti.asm +++ /dev/null @@ -1,11 +0,0 @@ -section .init -global _init -_init: - push rbp - mov rbp, rsp - -section .fini -global _fini -_fini: - push rbp - mov rbp, rsp \ No newline at end of file diff --git a/libs/libc/crtn.asm b/libs/libc/crtn.asm deleted file mode 100644 index 5d8b3e55..00000000 --- a/libs/libc/crtn.asm +++ /dev/null @@ -1,7 +0,0 @@ -section .init - pop rbp - ret - -section .fini - pop rbp - ret \ No newline at end of file diff --git a/libs/libc/include/alloca.h b/libs/libc/include/alloca.h deleted file mode 100644 index 17b377cb..00000000 --- a/libs/libc/include/alloca.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _ALLOCA_H -#define _ALLOCA_H - -#define alloca __builtin_alloca - -#endif \ No newline at end of file diff --git a/libs/libc/include/assert.h b/libs/libc/include/assert.h deleted file mode 100644 index 2090bd17..00000000 --- a/libs/libc/include/assert.h +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef _ASSERT_H -#define _ASSERT_H - -#include -#include - -#ifdef __cplusplus -extern "C" -{ -#endif - - __lc_noreturn bool __assertion_failed(const char* file, int line, const char* function, const char* expr); - -#ifdef __cplusplus -} -#endif - -#ifdef NDEBUG -#define assert(expr) (void)0 -#else -#define assert(expr) (bool)(expr) || __assertion_failed(__FILE__, __LINE__, __FUNCTION__, #expr) // Verify a condition. -#endif - -#endif \ No newline at end of file diff --git a/libs/libc/include/bits/error.h b/libs/libc/include/bits/error.h deleted file mode 100644 index 8e92d81f..00000000 --- a/libs/libc/include/bits/error.h +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef _BITS_ERROR_H -#define _BITS_ERROR_H - -#include - -#define _RETURN_WITH_ERRNO(rc, type) \ - do { \ - if (rc < 0) \ - { \ - errno = (int)(-rc); \ - return -1; \ - } \ - errno = 0; \ - return (type)rc; \ - } while (0) - -#define _RETURN_WITH_MEMORY_ERRNO(rc, type) \ - do { \ - if ((unsigned long int)rc > 0xffffffffffffff00) \ - { \ - errno = (int)((rc)&0xff); \ - return (type)-1; \ - } \ - errno = 0; \ - return (type)rc; \ - } while (0) - -#endif \ No newline at end of file diff --git a/libs/libc/include/bits/getprocid.h b/libs/libc/include/bits/getprocid.h deleted file mode 100644 index aa0396a4..00000000 --- a/libs/libc/include/bits/getprocid.h +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef _BITS_GETPROCID_H -#define _BITS_GETPROCID_H - -#define ID_PID 0 -#define ID_PPID 1 -#define ID_UID 2 -#define ID_EUID 3 -#define ID_GID 4 -#define ID_EGID 5 - -#endif \ No newline at end of file diff --git a/libs/libc/include/bits/liballoc.h b/libs/libc/include/bits/liballoc.h deleted file mode 100644 index 1375c4fe..00000000 --- a/libs/libc/include/bits/liballoc.h +++ /dev/null @@ -1,74 +0,0 @@ -#ifndef _BITS_LIBALLOC_H -#define _BITS_LIBALLOC_H - -#include - -/** \defgroup ALLOCHOOKS liballoc hooks - * - * These are the OS specific functions which need to - * be implemented on any platform that the library - * is expected to work on. - */ - -/** @{ */ - -// If we are told to not define our own size_t, then we skip the define. -//#define _HAVE_UINTPTR_T -// typedef unsigned long uintptr_t; - -// This lets you prefix malloc and friends -#define PREFIX(func) func - -#ifdef __cplusplus -extern "C" -{ -#endif - - /** This function is supposed to lock the memory data structures. It - * could be as simple as disabling interrupts or acquiring a spinlock. - * It's up to you to decide. - * - * \return 0 if the lock was acquired successfully. Anything else is - * failure. - */ - extern int liballoc_lock(); - - /** This function unlocks what was previously locked by the liballoc_lock - * function. If it disabled interrupts, it enables interrupts. If it - * had acquiried a spinlock, it releases the spinlock. etc. - * - * \return 0 if the lock was successfully released. - */ - extern int liballoc_unlock(); - - /** This is the hook into the local system which allocates pages. It - * accepts an integer parameter which is the number of pages - * required. The page size was set up in the liballoc_init function. - * - * \return NULL if the pages were not allocated. - * \return A pointer to the allocated memory. - */ - extern void* liballoc_alloc(size_t); - - /** This frees previously allocated memory. The void* parameter passed - * to the function is the exact same value returned from a previous - * liballoc_alloc call. - * - * The integer value is the number of pages to free. - * - * \return 0 if the memory was successfully freed. - */ - extern int liballoc_free(void*, size_t); - - extern void* PREFIX(malloc)(size_t); ///< The standard function. - extern void* PREFIX(realloc)(void*, size_t); ///< The standard function. - extern void* PREFIX(calloc)(size_t, size_t); ///< The standard function. - extern void PREFIX(free)(void*); ///< The standard function. - -#ifdef __cplusplus -} -#endif - -/** @} */ - -#endif diff --git a/libs/libc/include/bits/macros.h b/libs/libc/include/bits/macros.h deleted file mode 100644 index 12ca8372..00000000 --- a/libs/libc/include/bits/macros.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef _BITS_MACROS_H -#define _BITS_MACROS_H - -#define __lc_noreturn __attribute__((noreturn)) -#define __lc_align(n) __attribute__((aligned(n))) -#define __lc_deprecated(msg) __attribute__((deprecated(msg))) -#define __lc_is_deprecated __attribute__((deprecated)) -#define __lc_unreachable __builtin_unreachable -#define __lc_used __attribute__((used)) -#define __lc_unused __attribute__((unused)) - -#endif \ No newline at end of file diff --git a/libs/libc/include/bits/seek.h b/libs/libc/include/bits/seek.h deleted file mode 100644 index ed0e59d3..00000000 --- a/libs/libc/include/bits/seek.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef _BITS_SEEK_H -#define _BITS_SEEK_H - -#define SEEK_SET 0 // Seek from beginning of file. -#define SEEK_CUR 1 // Seek from current position. -#define SEEK_END 2 // Seek from end of file. - -#endif \ No newline at end of file diff --git a/libs/libc/include/ctype.h b/libs/libc/include/ctype.h deleted file mode 100644 index ac08800d..00000000 --- a/libs/libc/include/ctype.h +++ /dev/null @@ -1,64 +0,0 @@ -#ifndef _CTYPE_H -#define _CTYPE_H - -#include - -#ifdef __cplusplus -extern "C" -{ -#endif - - /* Is this character alphanumeric? */ - int isalnum(int c); - - /* Is this character a letter? */ - int isalpha(int c); - - /* Is this character part of ASCII? */ - int isascii(int c); - - /* Is this character a blank character (space or tab)? */ - int isblank(int c); - - /* Is this character a control character? */ - int iscntrl(int c); - - /* Is this character a digit? */ - int isdigit(int c); - - /* Is this character any printable character except space? */ - int isgraph(int c); - - /* Is this character a lowercase letter? */ - int islower(int c); - - /* Is this character any printable character (including space)? */ - int isprint(int c); - - /* Is this character any printable character which is not a space or an alphanumeric character? */ - int ispunct(int c); - - /* Is this character any space character (space, form feed, newline, carriage return, tab, vertical tab)? */ - int isspace(int c); - - /* Is this character an uppercase letter? */ - int isupper(int c); - - /* Is this character a hexadecimal digit (0-9, a-f, A-F)? */ - int isxdigit(int c); - - /* Returns the lowercase form of the specified character. */ - int tolower(int c); - - /* Returns the uppercase form of the specified character. */ - int toupper(int c); - - /* Returns the character c, truncated to fit in the ASCII character set. This function should not be used, as it - * will convert accented letters into random characters. */ - __lc_is_deprecated int toascii(int c); - -#ifdef __cplusplus -} -#endif - -#endif \ No newline at end of file diff --git a/libs/libc/include/dirent.h b/libs/libc/include/dirent.h deleted file mode 100644 index 26f3dc0b..00000000 --- a/libs/libc/include/dirent.h +++ /dev/null @@ -1,66 +0,0 @@ -#ifndef _DIRENT_H -#define _DIRENT_H - -#include -#include - -/* An entry in a directory. */ -struct dirent -{ - ino_t d_ino; - off_t d_off; - unsigned short d_reclen; - unsigned char d_type; - char d_name[NAME_MAX]; -}; - -#define DT_BLK 1 // This is a block device. -#define DT_CHR 2 // This is a character device. -#define DT_DIR 3 // This is a directory. -#define DT_FIFO 4 // This is a named pipe (FIFO). -#define DT_LNK 5 // This is a symbolic link. -#define DT_REG 6 // This is a regular file. -#define DT_SOCK 7 // This is a UNIX domain socket. -#define DT_UNKNOWN 0 // The file type could not be determined. - -/* A stream representing a directory. */ -typedef struct -{ - int d_dirfd; -} DIR; - -#ifdef __cplusplus -extern "C" -{ -#endif - - /* Opens the directory at path and returns a handle to it, or NULL on error. */ - DIR* opendir(const char* path); - - /* Returns a new directory handle associated with the file descriptor fd. */ - DIR* fdopendir(int fd); - - /* Closes the directory stream. */ - int closedir(DIR* stream); - - /* Reads an entry from the directory stream. The contents of the pointer returned may be overwritten by subsequent - * calls to readdir(). */ - struct dirent* readdir(DIR* stream); - - /* Returns the file descriptor associated with stream. */ - int dirfd(DIR* stream); - - /* Positions stream's offset at the start of the directory. */ - void rewinddir(DIR* stream); - - /* Returns the current offset position for stream. */ - long telldir(DIR* stream); - - /* Moves stream's read offset to offset, which should be the return value of a previous call to telldir(). */ - void seekdir(DIR* stream, long offset); - -#ifdef __cplusplus -} -#endif - -#endif \ No newline at end of file diff --git a/libs/libc/include/errno.h b/libs/libc/include/errno.h deleted file mode 100644 index 53d58486..00000000 --- a/libs/libc/include/errno.h +++ /dev/null @@ -1,84 +0,0 @@ -#ifndef _ERRNO_H -#define _ERRNO_H - -/* The last error encountered during a call to a library or system function. */ -extern int errno; - -#define EPERM 1 // Operation not permitted -#define ENOENT 2 // No such file or directory -#define ESRCH 3 // No such process -#define EINTR 4 // Interrupted system call. Not implemented. -#define EIO 5 // Input/output error. Not implemented. -#define ENXIO 6 // No such device or address. Not implemented. -#define E2BIG 7 // Argument list too long -#define ENOEXEC 8 // Exec format error -#define EBADF 9 // Bad file descriptor -#define ECHILD 10 // No child processes -#define EAGAIN 11 // Resource temporarily unavailable -#define EWOULDBLOCK 11 // Resource temporarily unavailable -#define ENOMEM 12 // Cannot allocate memory -#define EACCES 13 // Permission denied -#define EFAULT 14 // Bad address -#define EBUSY 16 // Device or resource busy. Not implemented. -#define EEXIST 17 // File exists -#define EXDEV 18 // Invalid cross-device link. Not implemented. -#define ENODEV 19 // No such device. Not implemented. -#define ENOTDIR 20 // Not a directory -#define EISDIR 21 // Is a directory -#define EINVAL 22 // Invalid argument -#define ENFILE 23 // Too many open files in system. Not implemented. -#define EMFILE 24 // Too many open files -#define ENOTTY 25 // Inappropriate ioctl for device -#define EFBIG 27 // File too large. Not implemented. -#define ENOSPC 28 // No space left on device -#define ESPIPE 29 // Illegal seek. Not implemented. -#define EROFS 30 // Read-only file system. Not implemented. -#define EMLINK 31 // Too many links. Not implemented. -#define EPIPE 32 // Broken pipe. Not implemented. -#define EDOM 33 // Numerical argument out of domain. Not implemented. -#define ERANGE 34 // Numerical result out of range -#define EDEADLK 35 // Resource deadlock avoided. Not implemented. -#define ENAMETOOLONG 36 // File name too long. Not implemented. -#define ENOLCK 37 // No locks available. Not implemented. -#define ENOSYS 38 // Function not implemented -#define ENOTEMPTY 39 // Directory not empty. Not implemented. -#define ELOOP 40 // Too many levels of symbolic links. Not implemented. -#define ENOMSG 42 // No message of desired type. Not implemented. -#define EOVERFLOW 75 // Value too large for defined data type. Not implemented. -#define EILSEQ 84 // Invalid or incomplete multibyte or wide character. Not implemented. -#define ENOTSOCK 88 // Socket operation on non-socket. Not implemented. -#define ENOTSUP 95 // Operation not supported -#define EOPNOTSUPP 95 // Operation not supported -#define EADDRINUSE 98 // Address already in use. Not implemented. -#define ENETRESET 102 // Network dropped connection on reset. Not implemented. -#define ECONNRESET 104 // Connection reset by peer. Not implemented. -#define EISCONN 106 // Transport endpoint is already connected. Not implemented. -#define ETIMEDOUT 110 // Connection timed out. Not implemented. -#define EALREADY 114 // Operation already in progress. Not implemented. - -// FIXME: Right now I don't want to have to order and label these, since we have no net support anyways. -#define EADDRNOTAVAIL -1 -#define EAFNOSUPPORT -2 -#define ECONNABORTED -3 -#define ECONNREFUSED -4 -#define EDESTADDRREQ -5 -#define EHOSTUNREACH -6 -#define EINPROGRESS -7 -#define EMSGSIZE -8 -#define ENETDOWN -9 -#define ENETRESET -10 -#define ENETUNREACH -11 -#define ENOBUFS -12 -#define ENOMSG -13 -#define ENOPROTOOPT -14 -#define ENOTCONN -15 -#define ENOTSOCK -16 -#define EPROTONOSUPPORT -17 -#define EPROTOTYPE -18 - -#ifdef _GNU_SOURCE // Give it only to programs that ask for it. -/* Name used to invoke calling program. Same value as argv[0] in main(), but can be used globally. */ -extern char* program_invocation_name; -#endif - -#endif \ No newline at end of file diff --git a/libs/libc/include/fcntl.h b/libs/libc/include/fcntl.h deleted file mode 100644 index 0af71315..00000000 --- a/libs/libc/include/fcntl.h +++ /dev/null @@ -1,58 +0,0 @@ -#ifndef _FCNTL_H -#define _FCNTL_H - -#include - -/* Open for reading only. */ -#define O_RDONLY 1 -/* Open for writing only. */ -#define O_WRONLY 2 -/* Open for reading and writing. */ -#define O_RDWR 3 -/* Open without blocking. */ -#define O_NONBLOCK 4 -/* Close the opened file descriptor on a call to execve(). */ -#define O_CLOEXEC 8 -/* Refuse to open the file if it is not a directory. */ -#define O_DIRECTORY 16 -/* Truncate the file on open. */ -#define O_TRUNC 32 -/* Create the file if it doesn't exist. */ -#define O_CREAT 64 -/* Open the file for appending. */ -#define O_APPEND 128 -/* Fail to open the file if it already exists. */ -#define O_EXCL 256 - -/* Duplicate a file descriptor. */ -#define F_DUPFD 0 -/* Is a file descriptor a TTY? */ -#define F_ISTTY 1 -/* Get the file descriptor flags. */ -#define F_GETFD 2 -/* Set the file descriptor flags. */ -#define F_SETFD 3 - -/* Close the file descriptor on a call to execve(). */ -#define FD_CLOEXEC 1 - -#ifdef __cplusplus -extern "C" -{ -#endif - - /* Opens the file specified by pathname. Returns a file descriptor on success, or -1 on error. */ - int open(const char* pathname, int flags, ...); - - /* Opens the file specified by pathname, creating it if it doesn't exist or overwriting it otherwise. Calling this - * function is equivalent to calling open(pathname, O_WRONLY|O_CREAT|O_TRUNC, mode) */ - int creat(const char* pathname, mode_t mode); - - /* Performs an operation on the file descriptor fd determined by cmd. */ - int fcntl(int fd, int cmd, ...); - -#ifdef __cplusplus -} -#endif - -#endif \ No newline at end of file diff --git a/libs/libc/include/inttypes.h b/libs/libc/include/inttypes.h deleted file mode 100644 index ecc873d1..00000000 --- a/libs/libc/include/inttypes.h +++ /dev/null @@ -1,71 +0,0 @@ -#ifndef _INTTYPES_H -#define _INTTYPES_H - -#include - -#define __PRI64_PREFIX "l" - -#define PRId8 "d" -#define PRId16 "d" -#define PRId32 "d" -#define PRId64 __PRI64_PREFIX "d" -#define PRIdLEAST8 "d" -#define PRIdLEAST16 "d" -#define PRIdLEAST32 "d" -#define PRIdLEAST64 __PRI64_PREFIX "d" -#define PRIdFAST8 "d" -#define PRIdFAST16 "d" -#define PRIdFAST32 "d" -#define PRIdFAST64 __PRI64_PREFIX "d" -#define PRIdMAX __PRI64_PREFIX "d" -#define PRIdPTR __PRI64_PREFIX "d" -#define PRIi8 "d" -#define PRIi16 "d" -#define PRIi32 "d" -#define PRIi64 __PRI64_PREFIX "d" -#define PRIiLEAST8 "d" -#define PRIiLEAST16 "d" -#define PRIiLEAST32 "d" -#define PRIiLEAST64 __PRI64_PREFIX "d" -#define PRIiFAST8 "d" -#define PRIiFAST16 "d" -#define PRIiFAST32 "d" -#define PRIiFAST64 __PRI64_PREFIX "d" -#define PRIiMAX __PRI64_PREFIX "d" -#define PRIiPTR __PRI64_PREFIX "d" -#define PRIu8 "u" -#define PRIu16 "u" -#define PRIu32 "u" -#define PRIu64 __PRI64_PREFIX "u" -#define PRIuLEAST8 "u" -#define PRIuLEAST16 "u" -#define PRIuLEAST32 "u" -#define PRIuLEAST64 __PRI64_PREFIX "u" -#define PRIuFAST8 "u" -#define PRIuFAST16 "u" -#define PRIuFAST32 "u" -#define PRIuFAST64 __PRI64_PREFIX "u" -#define PRIuMAX __PRI64_PREFIX "u" -#define PRIuPTR __PRI64_PREFIX "u" -#define PRIx8 "x" -#define PRIx16 "x" -#define PRIx32 "x" -#define PRIx64 __PRI64_PREFIX "x" -#define PRIxLEAST8 "x" -#define PRIxLEAST16 "x" -#define PRIxLEAST32 "x" -#define PRIxLEAST64 __PRI64_PREFIX "x" -#define PRIxFAST8 "x" -#define PRIxFAST16 "x" -#define PRIxFAST32 "x" -#define PRIxFAST64 __PRI64_PREFIX "x" -#define PRIxMAX __PRI64_PREFIX "x" -#define PRIxPTR __PRI64_PREFIX "x" -#define PRIX8 PRIx8 -#define PRIX16 PRIx16 -#define PRIX32 PRIx32 -#define PRIX64 PRIx64 -#define PRIXMAX PRIxMAX -#define PRIXPTR PRIxPTR - -#endif \ No newline at end of file diff --git a/libs/libc/include/libgen.h b/libs/libc/include/libgen.h deleted file mode 100644 index a6479447..00000000 --- a/libs/libc/include/libgen.h +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef _LIBGEN_H -#define _LIBGEN_H - -#ifdef __cplusplus -extern "C" -{ -#endif - - /* Returns the last component of a path. This function is allowed to modify the string passed to it, so it should - * probably be a copy of another string. */ - char* basename(char* path); - - /* Returns the parent directory of a path. This function is allowed to modify the string passed to it, so it should - * probably be a copy of another string. */ - char* dirname(char* path); - -#ifdef __cplusplus -} -#endif - -#endif \ No newline at end of file diff --git a/libs/libc/include/locale.h b/libs/libc/include/locale.h deleted file mode 100644 index c2182e6a..00000000 --- a/libs/libc/include/locale.h +++ /dev/null @@ -1,49 +0,0 @@ -#ifndef _LOCALE_H -#define _LOCALE_H - -#define LC_ALL 0 -#define LC_CTYPE 1 -#define LC_COLLATE 2 -#define LC_NUMERIC 3 -#define LC_MONETARY 4 -#define LC_TIME 5 - -/* Structure representing numeric formatting information for the current locale. */ -struct lconv -{ - char* decimal_point; - char* thousands_sep; - char* grouping; - char* int_curr_symbol; - char* currency_symbol; - char* mon_decimal_point; - char* mon_thousands_sep; - char* mon_grouping; - char* positive_sign; - char* negative_sign; - char int_frac_digits; - char frac_digits; - char p_cs_precedes; - char p_sep_by_space; - char n_cs_precedes; - char n_sep_by_space; - char p_sign_posn; - char n_sign_posn; -}; - -#ifdef __cplusplus -extern "C" -{ -#endif - - /* Set or query the current locale. */ - char* setlocale(int category, const char* locale); - - /* Retrieve numeric formatting information for the current locale. */ - struct lconv* localeconv(void); - -#ifdef __cplusplus -} -#endif - -#endif \ No newline at end of file diff --git a/libs/libc/include/luna.h b/libs/libc/include/luna.h deleted file mode 100644 index 7ed32c00..00000000 --- a/libs/libc/include/luna.h +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef _LUNA_H -#define _LUNA_H - -#include -#include -#include - -#ifdef __cplusplus -extern "C" -{ -#endif - - /* Returns a numeric identifier associated with the current process, depending on field. */ - long getprocid(int field); - - /* Sleeps for ms milliseconds. */ - unsigned int msleep(unsigned int ms); - - /* Prints a message to standard error and aborts the program. */ - __lc_noreturn void __luna_abort(const char* message); - -#ifdef __cplusplus -} -#endif - -#define NOT_IMPLEMENTED(message) __luna_abort("not implemented: " message "\n") - -#endif \ No newline at end of file diff --git a/libs/libc/include/luna/dirent.h b/libs/libc/include/luna/dirent.h deleted file mode 100644 index 6b7f3237..00000000 --- a/libs/libc/include/luna/dirent.h +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef _LUNA_DIRENT_H -#define _LUNA_DIRENT_H - -#include -#include - -struct luna_dirent -{ - ino_t inode; - char name[NAME_MAX]; - size_t total; - off_t offset; -}; - -#ifdef __cplusplus -extern "C" -{ -#endif - - /* Retrieve directory entries from the kernel. This is the raw interface, use readdir() instead. */ - ssize_t getdents(int fd, struct luna_dirent* buf, size_t count); - -#ifdef __cplusplus -} -#endif - -#endif \ No newline at end of file diff --git a/libs/libc/include/luna/os-limits.h b/libs/libc/include/luna/os-limits.h deleted file mode 100644 index 6e62f706..00000000 --- a/libs/libc/include/luna/os-limits.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef _LUNA_OS_LIMITS_H -#define _LUNA_OS_LIMITS_H - -#define OPEN_MAX 32 -#define ATEXIT_MAX 32 - -#define NAME_MAX 64 -#define PATH_MAX 4096 - -#define PAGESIZE 4096 -#define PAGE_SIZE 4096 - -#endif \ No newline at end of file diff --git a/libs/libc/include/luna/pstat.h b/libs/libc/include/luna/pstat.h deleted file mode 100644 index fe6e4295..00000000 --- a/libs/libc/include/luna/pstat.h +++ /dev/null @@ -1,38 +0,0 @@ -#ifndef _LUNA_PSTAT_H -#define _LUNA_PSTAT_H - -#include - -struct pstat -{ - pid_t pt_pid; - pid_t pt_ppid; - char pt_name[128]; - int pt_state; - long pt_time; - uid_t pt_uid; - gid_t pt_gid; -}; - -#define PT_IDLE 0 -#define PT_RUNNING 1 -#define PT_SLEEPING 2 -#define PT_ZOMBIE 3 -#define PT_WAITING 4 - -#ifdef __cplusplus -extern "C" -{ -#endif - - /* Returns information about the process with PID pid in buf, if buf is non-null. Luna-specific. */ - pid_t pstat(pid_t pid, struct pstat* buf); - - /* Returns a string representation of the process state in buf. */ - const char* pstatname(struct pstat* buf); - -#ifdef __cplusplus -} -#endif - -#endif \ No newline at end of file diff --git a/libs/libc/include/luna/syscall.h b/libs/libc/include/luna/syscall.h deleted file mode 100644 index 850d1007..00000000 --- a/libs/libc/include/luna/syscall.h +++ /dev/null @@ -1,70 +0,0 @@ -#ifndef _LUNA_SYSCALL_H -#define _LUNA_SYSCALL_H - -#include - -typedef unsigned long sysarg_t; - -#ifdef __cplusplus -extern "C" -{ -#endif - - long __luna_syscall0(long sys_num); - long __luna_syscall1(long sys_num, sysarg_t arg0); - long __luna_syscall2(long sys_num, sysarg_t arg0, sysarg_t arg1); - long __luna_syscall3(long sys_num, sysarg_t arg0, sysarg_t arg1, sysarg_t arg2); - long __luna_syscall4(long sys_num, sysarg_t arg0, sysarg_t arg1, sysarg_t arg2, sysarg_t arg3); - long __luna_syscall5(long sys_num, sysarg_t arg0, sysarg_t arg1, sysarg_t arg2, sysarg_t arg3, sysarg_t arg4); - - inline long __fast_syscall0(long number) - { - long result = __luna_syscall0(number); - _RETURN_WITH_ERRNO(result, long); - } - - inline long __fast_syscall1(long number, sysarg_t arg0) - { - long result = __luna_syscall1(number, arg0); - _RETURN_WITH_ERRNO(result, long); - } - - inline long __fast_syscall2(long number, sysarg_t arg0, sysarg_t arg1) - { - long result = __luna_syscall2(number, arg0, arg1); - _RETURN_WITH_ERRNO(result, long); - } - - inline long __fast_syscall3(long number, sysarg_t arg0, sysarg_t arg1, sysarg_t arg2) - { - long result = __luna_syscall3(number, arg0, arg1, arg2); - _RETURN_WITH_ERRNO(result, long); - } - - inline long __fast_syscall4(long number, sysarg_t arg0, sysarg_t arg1, sysarg_t arg2, sysarg_t arg3) - { - long result = __luna_syscall4(number, arg0, arg1, arg2, arg3); - _RETURN_WITH_ERRNO(result, long); - } - - inline long __fast_syscall5(long number, sysarg_t arg0, sysarg_t arg1, sysarg_t arg2, sysarg_t arg3, sysarg_t arg4) - { - long result = __luna_syscall5(number, arg0, arg1, arg2, arg3, arg4); - _RETURN_WITH_ERRNO(result, long); - } - -#define __lc_fast_syscall0(number) __fast_syscall0(number) -#define __lc_fast_syscall1(number, arg0) __fast_syscall1(number, (sysarg_t)arg0) -#define __lc_fast_syscall2(number, arg0, arg1) __fast_syscall2(number, (sysarg_t)arg0, (sysarg_t)arg1) -#define __lc_fast_syscall3(number, arg0, arg1, arg2) \ - __fast_syscall3(number, (sysarg_t)arg0, (sysarg_t)arg1, (sysarg_t)arg2) -#define __lc_fast_syscall4(number, arg0, arg1, arg2, arg3) \ - __fast_syscall4(number, (sysarg_t)arg0, (sysarg_t)arg1, (sysarg_t)arg2, (sysarg_t)arg3) -#define __lc_fast_syscall5(number, arg0, arg1, arg2, arg3, arg4) \ - __fast_syscall5(number, (sysarg_t)arg0, (sysarg_t)arg1, (sysarg_t)arg2, (sysarg_t)arg3, (sysarg_t)arg4) - -#ifdef __cplusplus -} -#endif - -#endif \ No newline at end of file diff --git a/libs/libc/include/luna/vfs.h b/libs/libc/include/luna/vfs.h deleted file mode 100644 index e34c83eb..00000000 --- a/libs/libc/include/luna/vfs.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef _LUNA_VFS_H -#define _LUNA_VFS_H - -#define __VFS_FILE 0x0 -#define __VFS_DIRECTORY 0x1 -#define __VFS_DEVICE 0x2 - -#define __VFS_TO_IFMT(type) ((1 << type) * 010000) - -#endif \ No newline at end of file diff --git a/libs/libc/include/math.h b/libs/libc/include/math.h deleted file mode 100644 index ced52044..00000000 --- a/libs/libc/include/math.h +++ /dev/null @@ -1,90 +0,0 @@ -#ifndef _MATH_H -#define _MATH_H - -typedef float float_t; -typedef double double_t; - -#define FP_NAN 0 -#define FP_INFINITE 1 -#define FP_ZERO 2 -#define FP_SUBNORMAL 3 -#define FP_NORMAL 4 -#define fpclassify(x) __builtin_fpclassify(FP_NAN, FP_INFINITE, FP_ZERO, FP_SUBNORMAL, FP_ZERO, x) - -#ifdef __cplusplus -extern "C" -{ -#endif - - double cos(double val); - float cosf(float val); - long double cosl(long double val); - double sin(double val); - float sinf(float val); - long double sinl(long double val); - double tan(double val); - float tanf(float val); - long double tanl(long double val); - double acos(double val); - float acosf(float val); - long double acosl(long double val); - double asin(double val); - float asinf(float val); - long double asinl(long double val); - double atan(double val); - float atanf(float val); - long double atanl(long double val); - double cosh(double val); - float coshf(float val); - long double coshl(long double val); - double sinh(double val); - float sinhf(float val); - long double sinhl(long double val); - double tanh(double val); - float tanhf(float val); - long double tanhl(long double val); - double log(double val); - float logf(float val); - long double logl(long double val); - double exp(double val); - float expf(float val); - long double expl(long double val); - double sqrt(double val); - float sqrtf(float val); - long double sqrtl(long double val); - double fabs(double val); - float fabsf(float val); - long double fabsl(long double val); - double floor(double val); - float floorf(float val); - long double floorl(long double val); - double ceil(double val); - float ceilf(float val); - long double ceill(long double val); - double log10(double val); - float log10f(float val); - long double log10l(long double val); - double fmod(double val1, double val2); - float fmodf(float val1, float val2); - long double fmodl(long double val1, long double val2); - double pow(double val1, double val2); - float powf(float val1, float val2); - long double powl(long double val1, long double val2); - double atan2(double val1, double val2); - float atan2f(float val1, float val2); - long double atan2l(long double val1, long double val2); - double frexp(double val1, int* val2); - float frexpf(float val1, int* val2); - long double frexpl(long double val1, int* val2); - double ldexp(double val1, int val2); - float ldexpf(float val1, int val2); - long double ldexpl(long double val1, int val2); - double modf(double val1, double* val2); - float modff(float val1, float* val2); - long double modfl(long double val1, long double* val2); - -#ifdef __cplusplus -} -#endif - -#endif \ No newline at end of file diff --git a/libs/libc/include/memory.h b/libs/libc/include/memory.h deleted file mode 100644 index e69de29b..00000000 diff --git a/libs/libc/include/pwd.h b/libs/libc/include/pwd.h deleted file mode 100644 index 517a5f38..00000000 --- a/libs/libc/include/pwd.h +++ /dev/null @@ -1,42 +0,0 @@ -#ifndef _PWD_H -#define _PWD_H - -#include - -/* Structure representing a password file entry. */ -struct passwd -{ - char* pw_name; - char* pw_passwd; - uid_t pw_uid; - gid_t pw_gid; - char* pw_gecos; - char* pw_dir; - char* pw_shell; -}; - -#ifdef __cplusplus -extern "C" -{ -#endif - - /* Returns the next password file entry. */ - struct passwd* getpwent(void); - - /* Returns the first password file entry with a login name matching name, or NULL if there are none. */ - struct passwd* getpwnam(const char* name); - - /* Returns the first password file entry with a user ID matching uid, or NULL if there are none. */ - struct passwd* getpwuid(uid_t uid); - - /* Rewinds to the first password file entry. */ - void setpwent(void); - - /* Ends password file processing. */ - void endpwent(void); - -#ifdef __cplusplus -} -#endif - -#endif \ No newline at end of file diff --git a/libs/libc/include/sched.h b/libs/libc/include/sched.h deleted file mode 100644 index baebea5a..00000000 --- a/libs/libc/include/sched.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef _SCHED_H -#define _SCHED_H - -#ifdef __cplusplus -extern "C" -{ -#endif - - /* Yield the processor. */ - int sched_yield(void); - -#ifdef __cplusplus -} -#endif - -#endif \ No newline at end of file diff --git a/libs/libc/include/setjmp.h b/libs/libc/include/setjmp.h deleted file mode 100644 index d42054aa..00000000 --- a/libs/libc/include/setjmp.h +++ /dev/null @@ -1,32 +0,0 @@ -#ifndef _SETJMP_H -#define _SETJMP_H - -#include -#include - -typedef uintptr_t jmp_buf[8]; -typedef uintptr_t sigjmp_buf[8]; - -#ifdef __cplusplus -extern "C" -{ -#endif - - /* Saves the current execution state in env. Returns 0 when called from the first time, or nonzero when returning - * from longjmp. */ - int setjmp(jmp_buf env); - - /* Right now, does the exact same as setjmp() (savesigs is ignored), since signals are not implemented. */ - int sigsetjmp(sigjmp_buf env, int savesigs); - - /* Restores the execution state saved in env by a setjmp() call. */ - __lc_noreturn void longjmp(jmp_buf env, int val); - - /* Right now, does the exact same as longjmp(), since signals are not implemented. */ - __lc_noreturn void siglongjmp(sigjmp_buf env, int val); - -#ifdef __cplusplus -} -#endif - -#endif \ No newline at end of file diff --git a/libs/libc/include/signal.h b/libs/libc/include/signal.h deleted file mode 100644 index 691bf0bc..00000000 --- a/libs/libc/include/signal.h +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef _SIGNAL_H -#define _SIGNAL_H - -typedef int sig_atomic_t; // On the x86, writes to aligned 32-bit and 64-bit integers are always atomic. (Or that's what - // I understood) - -#define SIGINT 1 // Not implemented. - -#ifdef __cplusplus -extern "C" -{ -#endif - - void (*signal(int sig, void (*func)(int)))(int); // Not implemented. - int raise(int sig); // Not implemented. - -#ifdef __cplusplus -} -#endif - -#endif \ No newline at end of file diff --git a/libs/libc/include/stdio.h b/libs/libc/include/stdio.h deleted file mode 100644 index df882d0b..00000000 --- a/libs/libc/include/stdio.h +++ /dev/null @@ -1,176 +0,0 @@ -#ifndef _STDIO_H -#define _STDIO_H - -#include -#include -#include - -#include - -#define FOPEN_MAX 32 // Maximum number of files that can be simultaneously opened with fopen(). -#define BUFSIZ 1024 // Standard buffer size. -#define FILENAME_MAX 1024 // Dummy value, we don't have a limit for filenames right now. - -/* A stream representing a file. */ -typedef struct -{ - int f_fd; - int f_eof; - int f_err; - char* f_buf; - long f_bufsize; - long f_bufoff; - long f_bufrsize; -} FILE; - -extern FILE* stderr; -extern FILE* stdout; -extern FILE* stdin; - -#define stdin stdin // The standard input stream. -#define stdout stdout // The standard output stream. -#define stderr stderr // The standard error stream. - -#define EOF -1 // End of file. - -#define _IONBF 0 // Not buffered. -#define _IOLBF 1 // Line buffered. -#define _IOFBF 2 // Fully buffered. - -typedef off_t fpos_t; // An offset into a file. - -#ifdef __cplusplus -extern "C" -{ -#endif - - /* Closes the file handle stream. */ - int fclose(FILE* stream); - - /* Does not do anything for now, since buffered IO is not implemented yet. */ - int fflush(FILE* stream); - - /* Opens the file specified by pathname. Returns the file handle on success, or NULL on error. */ - FILE* fopen(const char* pathname, const char* mode); - - /* Returns a new file associated with the file descriptor fd. */ - FILE* fdopen(int fd, const char* mode); - - /* Opens the file specified by pathname and points the file handle stream to it. */ - FILE* freopen(const char* pathname, const char* mode, FILE* stream); - - /* Returns the file descriptor associated with the file stream. */ - int fileno(FILE* stream); - - /* Writes formatted output according to the string format to the file stream. */ - int fprintf(FILE* stream, const char* format, ...); - - /* Reads nmemb items of size size from the file stream into buf. */ - size_t fread(void* buf, size_t size, size_t nmemb, FILE* stream); - - /* Moves stream's read/write offset by offset, depending on whence. */ - int fseek(FILE* stream, long offset, int whence); - - /* Moves stream's read/write offset by offset, depending on whence. */ - int fseeko(FILE* stream, off_t offset, int whence); - - /* Moves stream's read/write offset to the offset stored in the pos structure. */ - int fsetpos(FILE* stream, const fpos_t* pos); - - /* Returns the current offset for stream. */ - long ftell(FILE* stream); - - /* Returns the current offset for stream. */ - off_t ftello(FILE* stream); - - /* Stores the current offset for stream in the pos structure. */ - int fgetpos(FILE* stream, fpos_t* pos); - - /* Rewinds stream's offset to start of file. */ - void rewind(FILE* stream); - - /* Writes nmemb items of size size from buf into the file stream. */ - size_t fwrite(const void* buf, size_t size, size_t nmemb, FILE* stream); - - /* Reads a line from stream into buf. */ - char* fgets(char* buf, int size, FILE* stream); - - /* Retrieves a character from stream. */ - int fgetc(FILE* stream); - - /* Retrieves a character from stream. */ - int getc(FILE* stream); - - int ungetc(int, FILE*); // Not implemented. - - /* Retrieves a character from standard input. */ - int getchar(); - - /* Returns nonzero if the error flag in stream was set. */ - int ferror(FILE* stream); - - /* Returns nonzero if the end-of-file flag in stream was set. */ - int feof(FILE* stream); - - /* Clears the error and end-of-file flags from stream. */ - void clearerr(FILE* stream); - - void setbuf(FILE*, char*); // Not implemented. - int setvbuf(FILE*, char*, int, size_t); // Not implemented. - - /* Writes formatted output according to the string format to the file stream. */ - int vfprintf(FILE* stream, const char* format, va_list ap); - - /* Writes formatted output according to the string format to standard output. */ - int printf(const char* format, ...); - - /* Writes formatted output according to the string format to standard output. */ - int vprintf(const char* format, va_list ap); - - /* Writes formatted output according to the string format to the string str. This function is unsafe, use snprintf - * instead. */ - int sprintf(char* str, const char* format, ...); - - /* Writes at most max bytes of formatted output according to the string format to the string str.*/ - int snprintf(char* str, size_t max, const char* format, ...); - - /* Writes formatted output according to the string format to the string str. This function is unsafe, use vsnprintf - * instead. */ - int vsprintf(char* str, const char* format, va_list ap); - - /* Writes at most max bytes of formatted output according to the string format to the string str. */ - int vsnprintf(char* str, size_t max, const char* format, va_list ap); - - int sscanf(const char*, const char*, ...); // Not implemented. - int fscanf(FILE*, const char*, ...); // Not implemented. - int scanf(const char*, ...); // Not implemented. - - /* Writes the string str followed by a trailing newline to stdout. */ - int puts(const char* str); - - /* Writes the string str to the file stream. */ - int fputs(const char* str, FILE* stream); - - /* Writes the character c to the file stream. */ - int fputc(int c, FILE* stream); - - /* Writes the character c to the file stream. */ - int putc(int c, FILE* stream); - - /* Writes the character c to standard output. */ - int putchar(int c); - - /* Prints a message to standard error consisting of the string str followed by a colon and the string representation - * of the last error encountered during a call to a system or library function. */ - void perror(const char* str); - - int remove(const char* pathname); // Not implemented. - int rename(const char* oldpath, const char* newpath); // Not implemented. - - FILE* tmpfile(void); // Not implemented. - -#ifdef __cplusplus -} -#endif - -#endif \ No newline at end of file diff --git a/libs/libc/include/stdlib.h b/libs/libc/include/stdlib.h deleted file mode 100644 index a665c356..00000000 --- a/libs/libc/include/stdlib.h +++ /dev/null @@ -1,140 +0,0 @@ -#ifndef _STDLIB_H -#define _STDLIB_H - -#include -#include -#include - -#define EXIT_SUCCESS 0 // Value to use when calling exit() to represent successful execution. -#define EXIT_FAILURE 1 // Value to use when calling exit() to represent failed execution. - -#define RAND_MAX INT_MAX // Maximum number returned by rand(). - -#define MB_CUR_MAX 1 // Maximum length of multibyte characters in the current locale. - -// Return type for an integer division. -typedef struct -{ - int quot; - int rem; -} div_t; - -// Return type for a long integer division. -typedef struct -{ - long quot; - long rem; -} ldiv_t; - -// Return type for a long integer division. -typedef struct -{ - long long quot; - long long rem; -} lldiv_t; - -#ifdef __cplusplus -extern "C" -{ -#endif - - /* Aborts the program. */ - __lc_noreturn void abort(void); - - /* Normally exits the program with the specified status code. */ - __lc_noreturn void exit(int status); - - /* Abnormally exits the program with the specified status code. */ - __lc_noreturn void _Exit(int status); - - /* Registers a handler function to be run at normal program termination. */ - int atexit(void (*handler)(void)); - - /* Returns a floating point number parsed from the string str. */ - float atof(const char* str); - - /* Returns an integer (of type int) parsed from the string str. */ - int atoi(const char* str); - - /* Returns an integer (of type long) parsed from the string str. */ - long atol(const char* str); - - /* Returns an integer (of type long long) parsed from the string str. */ - long long atoll(const char* str); - - /* Returns an integer (of type unsigned long) parsed from the string str. */ - unsigned long strtoul(const char* str, char** endptr, int base); - - double strtod(const char* str, char** endptr); // Not implemented. - - /* Returns an integer (of type long) parsed from the string str. */ - long strtol(const char* str, char** endptr, int base); - - /* Not implemented. */ - char* getenv(const char*); - - /* Allocates n bytes of memory and returns a pointer to it. This memory should be freed by calling free() when it is - * not in use anymore. */ - void* malloc(size_t n); - - /* Allocates enough bytes of memory for an array containing nmemb items of size n and returns a pointer to it. This - * memory should be freed by calling free() when it is not in use anymore. */ - void* calloc(size_t nmemb, size_t n); - - /* Resizes memory allocated by malloc() or calloc() to n bytes. Returns a pointer to the new resized region of - * memory, which should be used instead of the old one. This memory should be freed by calling free() when it is not - * in use anymore. */ - void* realloc(void* ptr, size_t n); - - /* Frees a pointer to memory allocated by malloc(), calloc() or realloc(). Accessing the contents of ptr afterwards - * is undefined behavior. */ - void free(void* ptr); - - /* Returns a random number. */ - int rand(void); - - /* Seeds the random number generator with the specified seed. */ - void srand(unsigned int seed); - - /* Returns the absolute value of an integer. */ - int abs(int val); - - /* Returns the absolute value of an integer. */ - long labs(long val); - - /* Returns the absolute value of an integer. */ - long long llabs(long long val); - - /* Returns the result of dividing a by b. */ - div_t div(int a, int b); - - /* Returns the result of dividing a by b. */ - ldiv_t ldiv(long a, long b); - - /* Returns the result of dividing a by b. */ - lldiv_t lldiv(long long a, long long b); - - /* Runs a shell command. */ - int system(const char* command); - - /* Sorts the array pointed to by base of nmemb items of the specified size using the comparison function compar. */ - void qsort(void* base, size_t nmemb, size_t size, int (*compar)(const void*, const void*)); - - /* Searches the sorted array base of nmemb items of the specified size for the given key using the comparison - * function compar. */ - void* bsearch(const void* key, const void* base, size_t nmemb, size_t size, - int (*compar)(const void*, const void*)); - - size_t mbstowcs(wchar_t* dest, const char* src, - size_t n); // Not implemented. - - /* Generate a unique filename from the template string str. The last 6 bytes of str must be 'XXXXXX', and they will - * be replaced with random characters. This function is deprecated due to race conditions; between the name being - * generated and creating a file with that name, that filename could have already been used. */ - __lc_is_deprecated char* mktemp(char* str); - -#ifdef __cplusplus -} -#endif - -#endif \ No newline at end of file diff --git a/libs/libc/include/string.h b/libs/libc/include/string.h deleted file mode 100644 index cdfb4dee..00000000 --- a/libs/libc/include/string.h +++ /dev/null @@ -1,105 +0,0 @@ -#ifndef _STRING_H -#define _STRING_H - -#include -#include - -#ifdef __cplusplus -extern "C" -{ -#endif - - /* Copies n bytes from src to dst. */ - void* memcpy(void* dest, const void* src, size_t n); - - /* Sets n bytes of buf to c, cast to a character. */ - void* memset(void* buf, int c, size_t n); - - /* Searches for the character c in n bytes of buf. */ - void* memchr(const void* buf, int c, size_t n); - - /* Compares n bytes of memory at a and b. */ - int memcmp(const void* a, const void* b, size_t n); - - /* Copies n bytes from src to dst. Can be used if src and dst overlap. */ - void* memmove(void* dest, const void* src, size_t n); - - /* Returns a heap-allocated copy of the string str. Should be freed when it is not used anymore. */ - char* strdup(const char* str); - - /* Returns a heap-allocated copy of the string str, copying at maximum max bytes. Should be freed when it is not - * used anymore. */ - char* strndup(const char* str, size_t max); - - /* Returns the length of the string str. */ - size_t strlen(const char* str); - - /* Returns the length of the string str, while examining at most max bytes of str. */ - size_t strnlen(const char* str, size_t max); - - /* Copies at most size-1 bytes from the string src into dest, null-terminating the result. */ - size_t strlcpy(char* dst, const char* src, size_t size); - - /* Copies at most max bytes from the string src into dest. */ - char* strncpy(char* dest, const char* src, size_t max); - - /* Returns a pointer to the first occurrence of the character c in str, or NULL if it is not found. */ - char* strchr(const char* str, int c); - - /* Returns a pointer to the last occurrence of the character c in str, or NULL if it is not found. */ - char* strrchr(const char* str, int c); - - /* Returns a pointer to the first occurrence of the character c in str, or a pointer to the terminating null byte of - * str if it is not found. */ - char* strchrnul(const char* str, int c); - - /* Concatenates at most max bytes of the string src into dest. */ - char* strncat(char* dest, const char* src, size_t max); - - /* Returns the length of the initial segment of str which consists entirely of bytes not in reject. */ - size_t strcspn(const char* str, const char* reject); - - /* Returns the length of the initial segment of str which consists entirely of bytes in accept. */ - size_t strspn(const char* str, const char* accept); - - /* Returns a pointer to the first occurrence of any character of b in a. */ - char* strpbrk(const char* a, const char* b); - - /* Compares strings a and b. You might prefer to use the safer strncmp function. */ - int strcmp(const char* a, const char* b); - - /* Compares at most max bytes of the strings a and b. */ - int strncmp(const char* a, const char* b, size_t max); - - /* Compares a and b based on the current locale. */ - int strcoll(const char* a, const char* b); - - /* Transforms src based on the current locale and stores n bytes of it in dest. */ - size_t strxfrm(char* dest, const char* src, size_t n); - - /* Searches for the needle string in the haystack string. */ - char* strstr(const char* haystack, const char* needle); - - /* Returns the error string associated with the error number err. */ - char* strerror(int err); - - /* Copies the string src into dest. This function is unsafe, use strlcpy instead. */ - __lc_deprecated("strcpy is unsafe and should not be used; use strlcpy instead") char* strcpy(char* dest, - const char* src); - - /* Concatenates the string src into dest. This function is unsafe, use strncat instead. */ - __lc_deprecated("strcat is unsafe and should not be used; use strncat instead") char* strcat(char* dest, - const char* src); - -#ifdef _GNU_SOURCE - /* Copies the string src into dest, returning a pointer to the end of dest. */ - __lc_is_deprecated char* stpcpy(char* dest, const char* src); -#endif - - char* strtok(char* str, const char* delim); // Not implemented. - -#ifdef __cplusplus -} -#endif - -#endif \ No newline at end of file diff --git a/libs/libc/include/strings.h b/libs/libc/include/strings.h deleted file mode 100644 index dd0952ad..00000000 --- a/libs/libc/include/strings.h +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef _STRINGS_H -#define _STRINGS_H - -#include - -#ifdef __cplusplus -extern "C" -{ -#endif - - /* Clears n bytes of buf. */ - void bzero(void* buf, size_t n); - - /* Copies n bytes of src into dest. */ - void bcopy(void* dest, const void* src, size_t n); - - /* Compares strings a and b while treating uppercase and lowercase characters as the same. */ - int strcasecmp(const char* a, const char* b); - - /* Compares at most max bytes of strings a and b while treating uppercase and lowercase characters as the same. */ - int strncasecmp(const char* a, const char* b, size_t max); - -#ifdef __cplusplus -} -#endif - -#endif \ No newline at end of file diff --git a/libs/libc/include/sys/ioctl.h b/libs/libc/include/sys/ioctl.h deleted file mode 100644 index 2de4dac5..00000000 --- a/libs/libc/include/sys/ioctl.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef _SYS_IOCTL_H -#define _SYS_IOCTL_H - -#include - -/* Get the width of a framebuffer device. */ -#define FB_GET_WIDTH 0 -/* Get the height of a framebuffer device. */ -#define FB_GET_HEIGHT 1 -/* Get the scanline of a framebuffer device. */ -#define FB_GET_SCANLINE 2 - -#ifdef __cplusplus -extern "C" -{ -#endif - - /* Perform an arbitrary operation on an open file descriptor. Many operations are device-specific. */ - int ioctl(int fd, int cmd, ...); - -#ifdef __cplusplus -} -#endif - -#endif \ No newline at end of file diff --git a/libs/libc/include/sys/mman.h b/libs/libc/include/sys/mman.h deleted file mode 100644 index e2b86308..00000000 --- a/libs/libc/include/sys/mman.h +++ /dev/null @@ -1,41 +0,0 @@ -#ifndef _SYS_MMAN_H -#define _SYS_MMAN_H - -#include -#include // for off_t - -/* Address returned by mmap when it fails. */ -#define MAP_FAILED (void*)-1 - -#define PROT_NONE 0 -#define PROT_READ 1 -#define PROT_WRITE 2 -#define PROT_EXEC 4 - -#define PAGE_SIZE 4096 - -#define MAP_PRIVATE 0 -#define MAP_SHARED 1 -#define MAP_ANONYMOUS 2 - -#ifdef __cplusplus -extern "C" -{ -#endif - - /* Maps size bytes of memory (rounded up to the nearest page-aligned size) into the current process's address - * space at addr. If addr is null, the kernel will choose an address. */ - void* mmap(void* addr, size_t size, int prot, int flags, int fd, off_t offset); - - /* Unmaps size bytes of memory (rounded up to the nearest page-aligned size) at addr from the current process's - * address space. */ - int munmap(void* addr, size_t size); - - /* Changes the permissions of size bytes of memory at addr zaccording to the prot argument. */ - int mprotect(void* addr, size_t size, int prot); - -#ifdef __cplusplus -} -#endif - -#endif \ No newline at end of file diff --git a/libs/libc/include/sys/param.h b/libs/libc/include/sys/param.h deleted file mode 100644 index e69de29b..00000000 diff --git a/libs/libc/include/sys/stat.h b/libs/libc/include/sys/stat.h deleted file mode 100644 index 7c54a3e0..00000000 --- a/libs/libc/include/sys/stat.h +++ /dev/null @@ -1,82 +0,0 @@ -#ifndef _SYS_STAT_H -#define _SYS_STAT_H - -#include -#include - -struct stat // FIXME: This struct is quite stubbed out. -{ - ino_t st_ino; - mode_t st_mode; - off_t st_size; - int st_dev; // Not implemented. - int st_nlink; // Not implemented. - uid_t st_uid; - gid_t st_gid; - time_t st_atime; - time_t st_mtime; - time_t st_ctime; -}; - -/* Type of file. */ -#define S_IFMT 070000 -/* Directory. */ -#define S_IFDIR __VFS_TO_IFMT(__VFS_DIRECTORY) -/* Regular file. */ -#define S_IFREG __VFS_TO_IFMT(__VFS_FILE) -/* Character device. */ -#define S_IFCHR __VFS_TO_IFMT(__VFS_DEVICE) - -#define __S_IFCMP(mode, value) (mode & S_IFMT) == value - -/* Is it a directory? */ -#define S_ISDIR(mode) (__S_IFCMP((mode), S_IFDIR)) -/* Is it a regular file? */ -#define S_ISREG(mode) (__S_IFCMP((mode), S_IFREG)) -/* Is it a character device? */ -#define S_ISCHR(mode) (__S_IFCMP((mode), S_IFCHR)) - -// Not implemented. -#define S_ISBLK(mode) ((mode)&0) -#define S_ISFIFO(mode) ((mode)&0) - -#define S_IRWXU 0700 -#define S_IRUSR 0400 -#define S_IWUSR 0200 -#define S_IXUSR 0100 -#define S_IRWXG 070 -#define S_IRGRP 040 -#define S_IWGRP 020 -#define S_IXGRP 010 -#define S_IRWXO 07 -#define S_IROTH 04 -#define S_IWOTH 02 -#define S_IXOTH 01 -#define S_ISUID 04000 -#define S_ISGID 02000 - -#ifdef __cplusplus -extern "C" -{ -#endif - - /* Creates a new directory at the path pathname with the specified mode. */ - int mkdir(const char* pathname, mode_t mode); - - /* Returns information about the file pointed to by fd in buf. */ - int fstat(int fd, struct stat* buf); - - /* Returns information about the file pointed at path in buf. */ - int stat(const char* pathname, struct stat* buf); - - /* Changes the current process' file creation mask. */ - mode_t umask(mode_t cmask); - - int chmod(const char* pathname, mode_t mode); // Not implemented. - int fchmod(int fd, mode_t mode); // Not implemented. - -#ifdef __cplusplus -} -#endif - -#endif \ No newline at end of file diff --git a/libs/libc/include/sys/syscall.h b/libs/libc/include/sys/syscall.h deleted file mode 100644 index 27842925..00000000 --- a/libs/libc/include/sys/syscall.h +++ /dev/null @@ -1,35 +0,0 @@ -#ifndef _SYS_SYSCALL_H -#define _SYS_SYSCALL_H - -#define SYS_exit 0 -#define SYS_yield 1 -#define SYS_sleep 2 -#define SYS_write 3 -#define SYS_getprocid 4 -#define SYS_mmap 5 -#define SYS_munmap 6 -#define SYS_open 7 -#define SYS_read 8 -#define SYS_close 9 -#define SYS_seek 10 -#define SYS_execv 11 -#define SYS_fcntl 12 -#define SYS_mprotect 13 -#define SYS_clock_gettime 14 -#define SYS_mkdir 15 -#define SYS_fork 16 -#define SYS_waitpid 17 -#define SYS_access 18 -#define SYS_fstat 19 -#define SYS_pstat 20 -#define SYS_getdents 21 -#define SYS_stat 22 -#define SYS_dup2 23 -#define SYS_setuid 24 -#define SYS_setgid 25 -#define SYS_umask 26 -#define SYS_ioctl 27 -#define SYS_seteuid 28 -#define SYS_setegid 29 - -#endif \ No newline at end of file diff --git a/libs/libc/include/sys/time.h b/libs/libc/include/sys/time.h deleted file mode 100644 index 39f5707f..00000000 --- a/libs/libc/include/sys/time.h +++ /dev/null @@ -1,26 +0,0 @@ -#ifndef _SYS_TIME_H -#define _SYS_TIME_H - -#include -#include - -// Captures elapsed time with microsecond precision. -struct timeval -{ - time_t tv_sec; - suseconds_t tv_usec; -}; - -#ifdef __cplusplus -extern "C" -{ -#endif - - /* Retrieves the current time and stores it in tp. */ - __lc_is_deprecated int gettimeofday(struct timeval* tp, void* tzp); - -#ifdef __cplusplus -} -#endif - -#endif \ No newline at end of file diff --git a/libs/libc/include/sys/types.h b/libs/libc/include/sys/types.h deleted file mode 100644 index 9e96a25f..00000000 --- a/libs/libc/include/sys/types.h +++ /dev/null @@ -1,40 +0,0 @@ -#ifndef _SYS_TYPES_H -#define _SYS_TYPES_H - -/* The type of a process identifier. */ -typedef long int pid_t; - -/* The type returned by sizeof(). */ -typedef unsigned long int size_t; - -/* Signed version of size_t. */ -typedef long int ssize_t; - -/* The type of an offset into a file. */ -typedef long int off_t; - -/* The type of a file's mode. */ -typedef unsigned short mode_t; - -/* The type of a filesystem inode. */ -typedef unsigned long ino_t; - -/* Value representing a time unit since the start of the current program. */ -typedef long int clock_t; - -/* Value representing time in seconds. */ -typedef long int time_t; - -/* Type representing signed time in microseconds. */ -typedef long int suseconds_t; - -/* Type representing a user ID. */ -typedef int uid_t; - -/* Type representing a group ID. */ -typedef int gid_t; - -/* Type representing a system clock. */ -typedef int clockid_t; - -#endif \ No newline at end of file diff --git a/libs/libc/include/sys/wait.h b/libs/libc/include/sys/wait.h deleted file mode 100644 index 792ad645..00000000 --- a/libs/libc/include/sys/wait.h +++ /dev/null @@ -1,30 +0,0 @@ -#ifndef _SYS_WAIT_H -#define _SYS_WAIT_H - -#include - -/* Has the child process exited by calling exit() or _exit()? */ -#define WIFEXITED(status) ((status) || 1) - -/* What was the child's exit status? */ -#define WEXITSTATUS(status) (char)((status)&0xff) - -/* Do not block the current process if no child has exited. */ -#define WNOHANG 1 - -#ifdef __cplusplus -extern "C" -{ -#endif - - /* Waits for the child process to finish running. */ - pid_t waitpid(pid_t pid, int* wstatus, int options); - - /* Waits for any child process to finish running. */ - pid_t wait(int* wstatus); - -#ifdef __cplusplus -} -#endif - -#endif \ No newline at end of file diff --git a/libs/libc/include/time.h b/libs/libc/include/time.h deleted file mode 100644 index 1e66f35a..00000000 --- a/libs/libc/include/time.h +++ /dev/null @@ -1,87 +0,0 @@ -#ifndef _TIME_H -#define _TIME_H - -#include -#include -#include - -// Structure representing broken-down time. -struct tm -{ - int tm_sec; - int tm_min; - int tm_hour; - int tm_mday; - int tm_mon; - int tm_year; - int tm_wday; - int tm_yday; - int tm_isdst; -}; - -// Captures elapsed time with nanosecond precision. -struct timespec -{ - time_t tv_sec; - long tv_nsec; -}; - -#define CLOCKS_PER_SEC 10000000 // Number of clock_t per second. - -#define CLOCK_REALTIME 0 -#define CLOCK_MONOTONIC 1 -#define CLOCK_PROCTIME 2 - -#ifdef __cplusplus -extern "C" -{ -#endif - - /* Returns a number representing how much CPU time has been used by this process. Divide this by CLOCKS_PER_SEC to - * get the value in seconds. */ - clock_t clock(void); - - /* Returns the current UNIX time in seconds, which is also stored in tloc if it is nonnull. */ - time_t time(time_t* tloc); - - /* Retrieves precise time from a specific system clock. */ - int clock_gettime(clockid_t clock_id, struct timespec* tp); - - /* Converts the UNIX timestamp time to broken-down time in UTC. */ - struct tm* gmtime(const time_t* time); - - /* Converts the UNIX timestamp time to broken-down time in UTC. Thread-safe. */ - struct tm* gmtime_r(const time_t* time, struct tm* result); - - /* Converts the UNIX timestamp time to broken-down time in local time. */ - struct tm* localtime(const time_t* time); - - /* Converts the UNIX timestamp time to broken-down time in local time. Thread-safe. */ - struct tm* localtime_r(const time_t* time, struct tm* result); - - /* Returns a string representation of the broken-down time in the time structure. */ - char* asctime(const struct tm* time); - - /* Fills buf with the string representation of the broken-down time in the time structure. Thread-safe. */ - char* asctime_r(const struct tm* time, char buf[26]); - - /* Returns a string representation of time. */ - char* ctime(const time_t* time); - - /* Fills buf with a string representation of time. Thread-safe. */ - char* ctime_r(const time_t* time, char buf[26]); - - /* Returns the UNIX timestamp representation of the broken-down time in the time structure. */ - time_t mktime(struct tm* time); - - /* Fills str with a formatted string representation of time according to the format string. */ - size_t strftime(char* str, size_t max, const char* format, const struct tm* time); - - /* Returns the difference between two times. */ - double difftime(time_t time2, time_t time1); - -#ifdef __cplusplus -} -#endif - -#endif \ No newline at end of file diff --git a/libs/libc/include/unistd.h b/libs/libc/include/unistd.h deleted file mode 100644 index aaa87201..00000000 --- a/libs/libc/include/unistd.h +++ /dev/null @@ -1,121 +0,0 @@ -#ifndef _UNISTD_H -#define _UNISTD_H - -#include -#include -#include -#include - -// Standard IO streams. -#define STDIN_FILENO 0 // The standard input stream. -#define STDOUT_FILENO 1 // The standard output stream. -#define STDERR_FILENO 2 // The standard error stream. - -// Possible arguments to access() -#define F_OK 0 // Check for a file's existence. -#define R_OK 1 // Check whether a file is readable. -#define W_OK 2 // Check whether a file is writable. -#define X_OK 4 // Check whether a file is executable. - -// Name values for pathconf() -#define _PC_PATH_MAX 0 // Maximum length of a path relative to the provided name. - -#ifdef __cplusplus -extern "C" -{ -#endif - - /* Executes the program program, passing the arguments in the argument list argv. On success, does not return. */ - int execv(const char* program, char* const argv[]); - - /* Not implemented. */ - int execve(const char*, char* const[], char* const[]); - /* Not implemented. */ - int execvp(const char*, char* const[]); - - /* Creates an identical copy (child) of the current process (parent). Returns 0 to the child, and the child's PID to - * the parent. */ - pid_t fork(void); - - /* Returns the current process' process ID. */ - pid_t getpid(void); - - /* Returns the current process' parent's process ID. */ - pid_t getppid(void); - - /* Returns the current process' real user ID. */ - uid_t getuid(void); - - /* Returns the current process' effective user ID. */ - uid_t geteuid(void); - - /* Returns the current process' real group ID. */ - gid_t getgid(void); - - /* Returns the current process' effective group ID. */ - gid_t getegid(void); - - /* Sets the current process' real and effective user IDs. */ - int setuid(uid_t uid); - - /* Sets the current process' effective user ID. */ - int seteuid(uid_t euid); - - /* Sets the current process' real and effective group IDs. */ - int setgid(gid_t gid); - - /* Sets the current process' effective group ID. */ - int setegid(gid_t egid); - - /* Terminates the program with the status code status. */ - __lc_noreturn void _exit(int status); - - /* Calls the kernel for a specific service, determined by number. */ - long syscall(long number, ...); - - /* Suspends execution for a chosen amount of seconds. */ - unsigned int sleep(unsigned int seconds); - - /* Reads count bytes from the file descriptor fd into the memory at buf. */ - ssize_t read(int fd, void* buf, size_t count); - - /* Writes count bytes of the memory at buf to the file descriptor fd. */ - ssize_t write(int fd, const void* buf, size_t count); - - /* Closes the file descriptor fd. */ - int close(int fd); - - /* Moves the read/write file offset for fd to offset, depending on whence. */ - off_t lseek(int fd, off_t offset, int whence); - - /* Returns a copy of the file descriptor fd. */ - int dup(int fd); - - /* Causes the file descriptor fd2 to refer to the file descriptor fd. */ - int dup2(int fd, int fd2); - - /* Checks if the current program can access the file or directory at path. */ - int access(const char* path, int amode); - - /* Checks if the file descriptor fd refers to a terminal. */ - int isatty(int fd); - - /* Writes the current process's current working directory to buf. */ - char* getcwd(char* buf, size_t size); - - int unlink(const char* path); // Not implemented. - int rmdir(const char* path); // Not implemented. - int chdir(const char* path); // Not implemented. - int pipe(int fd[2]); // Not implemented. - - /* Returns a configuration value for the file at path. */ - long pathconf(const char* path, int name); - - /* Returns the maximum number of file descriptors a process can have open at the same time. */ - int getdtablesize(void); - -#ifdef __cplusplus -} -#endif - -#endif \ No newline at end of file diff --git a/libs/libc/include/utime.h b/libs/libc/include/utime.h deleted file mode 100644 index 6111ecdb..00000000 --- a/libs/libc/include/utime.h +++ /dev/null @@ -1,23 +0,0 @@ -#ifndef _UTIME_H -#define _UTIME_H - -#include - -struct utimbuf -{ - time_t actime; - time_t modtime; -}; - -#ifdef __cplusplus -extern "C" -{ -#endif - - int utime(const char*, const struct utimbuf*); // Not implemented. - -#ifdef __cplusplus -} -#endif - -#endif \ No newline at end of file diff --git a/libs/libc/include/wchar.h b/libs/libc/include/wchar.h deleted file mode 100644 index a206751e..00000000 --- a/libs/libc/include/wchar.h +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef _WCHAR_H -#define _WCHAR_H - -#include -#include - -typedef unsigned int wint_t; - -#ifdef __cplusplus -extern "C" -{ -#endif - - /* Return the length of a wide-character string. */ - size_t wcslen(const wchar_t* str); - - /* Concatenates the wide-character string src into dest. */ - __lc_is_deprecated wchar_t* wcscat(wchar_t* dest, const wchar_t* src); - -#ifdef __cplusplus -} -#endif - -#endif \ No newline at end of file diff --git a/libs/libc/src/assert.cpp b/libs/libc/src/assert.cpp deleted file mode 100644 index c0c64a1c..00000000 --- a/libs/libc/src/assert.cpp +++ /dev/null @@ -1,12 +0,0 @@ -#include -#include -#include - -extern "C" -{ - __lc_noreturn bool __assertion_failed(const char* file, int line, const char* function, const char* expr) - { - fprintf(stderr, "%s:%d: %s: Assertion '%s' failed.", file, line, function, expr); - abort(); - } -} \ No newline at end of file diff --git a/libs/libc/src/atexit.cpp b/libs/libc/src/atexit.cpp deleted file mode 100644 index a27b81f2..00000000 --- a/libs/libc/src/atexit.cpp +++ /dev/null @@ -1,25 +0,0 @@ -#include -#include - -#define ATEXIT_MAX_FUNCS 32 - -typedef void (*atexit_func_t)(void); - -atexit_func_t atexit_functions[ATEXIT_MAX_FUNCS]; -int atexit_function_count = 0; - -extern "C" -{ - int atexit(atexit_func_t handler) - { - if (atexit_function_count >= ATEXIT_MAX_FUNCS) return -1; - atexit_functions[atexit_function_count++] = handler; - return 0; - } - - __lc_noreturn void exit(int status) - { - for (int i = 0; i < atexit_function_count; i++) { atexit_functions[i](); } - _exit(status); - } -} \ No newline at end of file diff --git a/libs/libc/src/bits/bindings.c b/libs/libc/src/bits/bindings.c deleted file mode 100644 index 40bdca95..00000000 --- a/libs/libc/src/bits/bindings.c +++ /dev/null @@ -1,24 +0,0 @@ -#include -#include - -int liballoc_lock() -{ - return 0; -} - -int liballoc_unlock() -{ - return 0; -} - -void* liballoc_alloc(size_t size) -{ - void* result = mmap(NULL, size * PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_ANONYMOUS, 0, 0); - if (result == MAP_FAILED) return 0; - return (void*)result; -} - -int liballoc_free(void* address, size_t size) -{ - return munmap(address, size * PAGE_SIZE); -} \ No newline at end of file diff --git a/libs/libc/src/bits/liballoc.c b/libs/libc/src/bits/liballoc.c deleted file mode 100644 index e5bdabef..00000000 --- a/libs/libc/src/bits/liballoc.c +++ /dev/null @@ -1,748 +0,0 @@ -#include - -#pragma GCC push_options -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wsign-conversion" // FIXME: Actually solve these warnings. - -#include -#include - -/** Durand's Amazing Super Duper Memory functions. */ - -#define VERSION "1.1" -#define ALIGNMENT \ - 16ul // 4ul ///< This is the byte alignment that memory must be allocated on. IMPORTANT for GTK and - // other stuff. - -#define ALIGN_TYPE char /// unsigned char[16] /// unsigned short -#define ALIGN_INFO \ - sizeof(ALIGN_TYPE) * 16 ///< Alignment information is stored right before the pointer. This is the number of bytes - ///< of information stored there. - -#define USE_CASE1 -#define USE_CASE2 -#define USE_CASE3 -#define USE_CASE4 -#define USE_CASE5 - -/** This macro will conveniently align our pointer upwards */ -#define ALIGN(ptr) \ - if (ALIGNMENT > 1) \ - { \ - uintptr_t align_diff; \ - ptr = (void*)((uintptr_t)ptr + ALIGN_INFO); \ - align_diff = (uintptr_t)ptr & (ALIGNMENT - 1); \ - if (align_diff != 0) \ - { \ - align_diff = ALIGNMENT - align_diff; \ - ptr = (void*)((uintptr_t)ptr + align_diff); \ - } \ - *((ALIGN_TYPE*)((uintptr_t)ptr - ALIGN_INFO)) = align_diff + ALIGN_INFO; \ - } - -#define UNALIGN(ptr) \ - if (ALIGNMENT > 1) \ - { \ - uintptr_t align_diff = *((ALIGN_TYPE*)((uintptr_t)ptr - ALIGN_INFO)); \ - if (align_diff < (ALIGNMENT + ALIGN_INFO)) { ptr = (void*)((uintptr_t)ptr - align_diff); } \ - } - -#define LIBALLOC_MAGIC 0xc001c0de -#define LIBALLOC_DEAD 0xdeaddead - -#if defined DEBUG || defined INFO -#include -#include - -#define FLUSH() fflush(stdout) - -#endif - -/** A structure found at the top of all system allocated - * memory blocks. It details the usage of the memory block. - */ -struct liballoc_major -{ - struct liballoc_major* prev; ///< Linked list information. - struct liballoc_major* next; ///< Linked list information. - unsigned int pages; ///< The number of pages in the block. - unsigned int size; ///< The number of pages in the block. - unsigned int usage; ///< The number of bytes used in the block. - struct liballoc_minor* first; ///< A pointer to the first allocated memory in the block. -}; - -/** This is a structure found at the beginning of all - * sections in a major block which were allocated by a - * malloc, calloc, realloc call. - */ -struct liballoc_minor -{ - struct liballoc_minor* prev; ///< Linked list information. - struct liballoc_minor* next; ///< Linked list information. - struct liballoc_major* block; ///< The owning block. A pointer to the major structure. - unsigned int magic; ///< A magic number to idenfity correctness. - unsigned int size; ///< The size of the memory allocated. Could be 1 byte or more. - unsigned int req_size; ///< The size of memory requested. -}; - -static struct liballoc_major* l_memRoot = NULL; ///< The root memory block acquired from the system. -static struct liballoc_major* l_bestBet = NULL; ///< The major with the most free memory. - -static unsigned int l_pageSize = 4096; ///< The size of an individual page. Set up in liballoc_init. -static unsigned int l_pageCount = 16; ///< The number of pages to request per chunk. Set up in liballoc_init. -static unsigned long long l_allocated = 0; ///< Running total of allocated memory. -static unsigned long long l_inuse = 0; ///< Running total of used memory. - -static long long l_warningCount = 0; ///< Number of warnings encountered -static long long l_errorCount = 0; ///< Number of actual errors -static long long l_possibleOverruns = 0; ///< Number of possible overruns - -// *********** HELPER FUNCTIONS ******************************* - -static void* liballoc_memset(void* s, int c, size_t n) -{ - unsigned int i; - for (i = 0; i < n; i++) ((char*)s)[i] = c; - - return s; -} -static void* liballoc_memcpy(void* s1, const void* s2, size_t n) -{ - char* cdest; - const char* csrc; - unsigned int* ldest = (unsigned int*)s1; - const unsigned int* lsrc = (const unsigned int*)s2; - - while (n >= sizeof(unsigned int)) - { - *ldest++ = *lsrc++; - n -= sizeof(unsigned int); - } - - cdest = (char*)ldest; - csrc = (const char*)lsrc; - - while (n > 0) - { - *cdest++ = *csrc++; - n -= 1; - } - - return s1; -} - -#if defined DEBUG || defined INFO -static void liballoc_dump() -{ -#ifdef DEBUG - struct liballoc_major* maj = l_memRoot; - struct liballoc_minor* min = NULL; -#endif - - printf("liballoc: ------ Memory data ---------------\n"); - printf("liballoc: System memory allocated: %i bytes\n", l_allocated); - printf("liballoc: Memory in used (malloc'ed): %i bytes\n", l_inuse); - printf("liballoc: Warning count: %i\n", l_warningCount); - printf("liballoc: Error count: %i\n", l_errorCount); - printf("liballoc: Possible overruns: %i\n", l_possibleOverruns); - -#ifdef DEBUG - while (maj != NULL) - { - printf("liballoc: %x: total = %i, used = %i\n", maj, maj->size, maj->usage); - - min = maj->first; - while (min != NULL) - { - printf("liballoc: %x: %i bytes\n", min, min->size); - min = min->next; - } - - maj = maj->next; - } -#endif - - FLUSH(); -} -#endif - -// *************************************************************** - -static struct liballoc_major* allocate_new_page(unsigned int size) -{ - unsigned int st; - struct liballoc_major* maj; - - // This is how much space is required. - st = size + sizeof(struct liballoc_major); - st += sizeof(struct liballoc_minor); - - // Perfect amount of space? - if ((st % l_pageSize) == 0) st = st / (l_pageSize); - else - st = st / (l_pageSize) + 1; - // No, add the buffer. - - // Make sure it's >= the minimum size. - if (st < l_pageCount) st = l_pageCount; - - maj = (struct liballoc_major*)liballoc_alloc(st); - - if (maj == NULL) - { - l_warningCount += 1; -#if defined DEBUG || defined INFO - printf("liballoc: WARNING: liballoc_alloc( %i ) return NULL\n", st); - FLUSH(); -#endif - return NULL; // uh oh, we ran out of memory. - } - - maj->prev = NULL; - maj->next = NULL; - maj->pages = st; - maj->size = st * l_pageSize; - maj->usage = sizeof(struct liballoc_major); - maj->first = NULL; - - l_allocated += maj->size; - -#ifdef DEBUG - printf("liballoc: Resource allocated %x of %i pages (%i bytes) for %i size.\n", maj, st, maj->size, size); - - printf("liballoc: Total memory usage = %i KB\n", (int)((l_allocated / (1024)))); - FLUSH(); -#endif - - return maj; -} - -void* PREFIX(malloc)(size_t req_size) -{ - int startedBet = 0; - unsigned long long bestSize = 0; - void* p = NULL; - uintptr_t diff; - struct liballoc_major* maj; - struct liballoc_minor* min; - struct liballoc_minor* new_min; - unsigned long size = req_size; - - // For alignment, we adjust size so there's enough space to align. - if (ALIGNMENT > 1) { size += ALIGNMENT + ALIGN_INFO; } - // So, ideally, we really want an alignment of 0 or 1 in order - // to save space. - - liballoc_lock(); - - if (size == 0) - { - l_warningCount += 1; -#if defined DEBUG || defined INFO - printf("liballoc: WARNING: alloc( 0 ) called from %x\n", __builtin_return_address(0)); - FLUSH(); -#endif - liballoc_unlock(); - return PREFIX(malloc)(1); - } - - if (l_memRoot == NULL) - { -#if defined DEBUG || defined INFO -#ifdef DEBUG - printf("liballoc: initialization of liballoc " VERSION "\n"); -#endif - atexit(liballoc_dump); - FLUSH(); -#endif - - // This is the first time we are being used. - l_memRoot = allocate_new_page(size); - if (l_memRoot == NULL) - { - liballoc_unlock(); -#ifdef DEBUG - printf("liballoc: initial l_memRoot initialization failed\n", p); - FLUSH(); -#endif - return NULL; - } - -#ifdef DEBUG - printf("liballoc: set up first memory major %x\n", l_memRoot); - FLUSH(); -#endif - } - -#ifdef DEBUG - printf("liballoc: %x PREFIX(malloc)( %i ): ", __builtin_return_address(0), size); - FLUSH(); -#endif - - // Now we need to bounce through every major and find enough space.... - - maj = l_memRoot; - startedBet = 0; - - // Start at the best bet.... - if (l_bestBet != NULL) - { - bestSize = l_bestBet->size - l_bestBet->usage; - - if (bestSize > (size + sizeof(struct liballoc_minor))) - { - maj = l_bestBet; - startedBet = 1; - } - } - - while (maj != NULL) - { - diff = maj->size - maj->usage; - // free memory in the block - - if (bestSize < diff) - { - // Hmm.. this one has more memory then our bestBet. Remember! - l_bestBet = maj; - bestSize = diff; - } - -#ifdef USE_CASE1 - - // CASE 1: There is not enough space in this major block. - if (diff < (size + sizeof(struct liballoc_minor))) - { -#ifdef DEBUG - printf("CASE 1: Insufficient space in block %x\n", maj); - FLUSH(); -#endif - - // Another major block next to this one? - if (maj->next != NULL) - { - maj = maj->next; // Hop to that one. - continue; - } - - if (startedBet == 1) // If we started at the best bet, - { // let's start all over again. - maj = l_memRoot; - startedBet = 0; - continue; - } - - // Create a new major block next to this one and... - maj->next = allocate_new_page(size); // next one will be okay. - if (maj->next == NULL) break; // no more memory. - maj->next->prev = maj; - maj = maj->next; - - // .. fall through to CASE 2 .. - } - -#endif - -#ifdef USE_CASE2 - - // CASE 2: It's a brand new block. - if (maj->first == NULL) - { - maj->first = (struct liballoc_minor*)((uintptr_t)maj + sizeof(struct liballoc_major)); - - maj->first->magic = LIBALLOC_MAGIC; - maj->first->prev = NULL; - maj->first->next = NULL; - maj->first->block = maj; - maj->first->size = size; - maj->first->req_size = req_size; - maj->usage += size + sizeof(struct liballoc_minor); - - l_inuse += size; - - p = (void*)((uintptr_t)(maj->first) + sizeof(struct liballoc_minor)); - - ALIGN(p); - -#ifdef DEBUG - printf("CASE 2: returning %x\n", p); - FLUSH(); -#endif - liballoc_unlock(); // release the lock - return p; - } - -#endif - -#ifdef USE_CASE3 - - // CASE 3: Block in use and enough space at the start of the block. - diff = (uintptr_t)(maj->first); - diff -= (uintptr_t)maj; - diff -= sizeof(struct liballoc_major); - - if (diff >= (size + sizeof(struct liballoc_minor))) - { - // Yes, space in front. Squeeze in. - maj->first->prev = (struct liballoc_minor*)((uintptr_t)maj + sizeof(struct liballoc_major)); - maj->first->prev->next = maj->first; - maj->first = maj->first->prev; - - maj->first->magic = LIBALLOC_MAGIC; - maj->first->prev = NULL; - maj->first->block = maj; - maj->first->size = size; - maj->first->req_size = req_size; - maj->usage += size + sizeof(struct liballoc_minor); - - l_inuse += size; - - p = (void*)((uintptr_t)(maj->first) + sizeof(struct liballoc_minor)); - ALIGN(p); - -#ifdef DEBUG - printf("CASE 3: returning %x\n", p); - FLUSH(); -#endif - liballoc_unlock(); // release the lock - return p; - } - -#endif - -#ifdef USE_CASE4 - - // CASE 4: There is enough space in this block. But is it contiguous? - min = maj->first; - - // Looping within the block now... - while (min != NULL) - { - // CASE 4.1: End of minors in a block. Space from last and end? - if (min->next == NULL) - { - // the rest of this block is free... is it big enough? - diff = (uintptr_t)(maj) + maj->size; - diff -= (uintptr_t)min; - diff -= sizeof(struct liballoc_minor); - diff -= min->size; - // minus already existing usage.. - - if (diff >= (size + sizeof(struct liballoc_minor))) - { - // yay.... - min->next = (struct liballoc_minor*)((uintptr_t)min + sizeof(struct liballoc_minor) + min->size); - min->next->prev = min; - min = min->next; - min->next = NULL; - min->magic = LIBALLOC_MAGIC; - min->block = maj; - min->size = size; - min->req_size = req_size; - maj->usage += size + sizeof(struct liballoc_minor); - - l_inuse += size; - - p = (void*)((uintptr_t)min + sizeof(struct liballoc_minor)); - ALIGN(p); - -#ifdef DEBUG - printf("CASE 4.1: returning %x\n", p); - FLUSH(); -#endif - liballoc_unlock(); // release the lock - return p; - } - } - - // CASE 4.2: Is there space between two minors? - if (min->next != NULL) - { - // is the difference between here and next big enough? - diff = (uintptr_t)(min->next); - diff -= (uintptr_t)min; - diff -= sizeof(struct liballoc_minor); - diff -= min->size; - // minus our existing usage. - - if (diff >= (size + sizeof(struct liballoc_minor))) - { - // yay...... - new_min = (struct liballoc_minor*)((uintptr_t)min + sizeof(struct liballoc_minor) + min->size); - - new_min->magic = LIBALLOC_MAGIC; - new_min->next = min->next; - new_min->prev = min; - new_min->size = size; - new_min->req_size = req_size; - new_min->block = maj; - min->next->prev = new_min; - min->next = new_min; - maj->usage += size + sizeof(struct liballoc_minor); - - l_inuse += size; - - p = (void*)((uintptr_t)new_min + sizeof(struct liballoc_minor)); - ALIGN(p); - -#ifdef DEBUG - printf("CASE 4.2: returning %x\n", p); - FLUSH(); -#endif - - liballoc_unlock(); // release the lock - return p; - } - } // min->next != NULL - - min = min->next; - } // while min != NULL ... - -#endif - -#ifdef USE_CASE5 - - // CASE 5: Block full! Ensure next block and loop. - if (maj->next == NULL) - { -#ifdef DEBUG - printf("CASE 5: block full\n"); - FLUSH(); -#endif - - if (startedBet == 1) - { - maj = l_memRoot; - startedBet = 0; - continue; - } - - // we've run out. we need more... - maj->next = allocate_new_page(size); // next one guaranteed to be okay - if (maj->next == NULL) break; // uh oh, no more memory..... - maj->next->prev = maj; - } - -#endif - - maj = maj->next; - } // while (maj != NULL) - - liballoc_unlock(); // release the lock - -#ifdef DEBUG - printf("All cases exhausted. No memory available.\n"); - FLUSH(); -#endif -#if defined DEBUG || defined INFO - printf("liballoc: WARNING: PREFIX(malloc)( %i ) returning NULL.\n", size); - liballoc_dump(); - FLUSH(); -#endif - return NULL; -} - -void PREFIX(free)(void* ptr) -{ - struct liballoc_minor* min; - struct liballoc_major* maj; - - if (ptr == NULL) - { - l_warningCount += 1; -#if defined DEBUG || defined INFO - printf("liballoc: WARNING: PREFIX(free)( NULL ) called from %x\n", __builtin_return_address(0)); - FLUSH(); -#endif - return; - } - - UNALIGN(ptr); - - liballoc_lock(); // lockit - - min = (struct liballoc_minor*)((uintptr_t)ptr - sizeof(struct liballoc_minor)); - - if (min->magic != LIBALLOC_MAGIC) - { - l_errorCount += 1; - - // Check for overrun errors. For all bytes of LIBALLOC_MAGIC - if (((min->magic & 0xFFFFFF) == (LIBALLOC_MAGIC & 0xFFFFFF)) || - ((min->magic & 0xFFFF) == (LIBALLOC_MAGIC & 0xFFFF)) || ((min->magic & 0xFF) == (LIBALLOC_MAGIC & 0xFF))) - { - l_possibleOverruns += 1; -#if defined DEBUG || defined INFO - printf("liballoc: ERROR: Possible 1-3 byte overrun for magic %x != %x\n", min->magic, LIBALLOC_MAGIC); - FLUSH(); -#endif - } - - if (min->magic == LIBALLOC_DEAD) - { -#if defined DEBUG || defined INFO - printf("liballoc: ERROR: multiple PREFIX(free)() attempt on %x from %x.\n", ptr, - __builtin_return_address(0)); - FLUSH(); -#endif - } - else - { -#if defined DEBUG || defined INFO - printf("liballoc: ERROR: Bad PREFIX(free)( %x ) called from %x\n", ptr, __builtin_return_address(0)); - FLUSH(); -#endif - } - - // being lied to... - liballoc_unlock(); // release the lock - return; - } - -#ifdef DEBUG - printf("liballoc: %x PREFIX(free)( %x ): ", __builtin_return_address(0), ptr); - FLUSH(); -#endif - - maj = min->block; - - l_inuse -= min->size; - - maj->usage -= (min->size + sizeof(struct liballoc_minor)); - min->magic = LIBALLOC_DEAD; // No mojo. - - if (min->next != NULL) min->next->prev = min->prev; - if (min->prev != NULL) min->prev->next = min->next; - - if (min->prev == NULL) maj->first = min->next; - // Might empty the block. This was the first - // minor. - - // We need to clean up after the majors now.... - - if (maj->first == NULL) // Block completely unused. - { - if (l_memRoot == maj) l_memRoot = maj->next; - if (l_bestBet == maj) l_bestBet = NULL; - if (maj->prev != NULL) maj->prev->next = maj->next; - if (maj->next != NULL) maj->next->prev = maj->prev; - l_allocated -= maj->size; - - liballoc_free(maj, maj->pages); - } - else - { - if (l_bestBet != NULL) - { - int bestSize = l_bestBet->size - l_bestBet->usage; - int majSize = maj->size - maj->usage; - - if (majSize > bestSize) l_bestBet = maj; - } - } - -#ifdef DEBUG - printf("OK\n"); - FLUSH(); -#endif - - liballoc_unlock(); // release the lock -} - -void* PREFIX(calloc)(size_t nobj, size_t size) -{ - int real_size; - void* p; - - real_size = nobj * size; - - p = PREFIX(malloc)(real_size); - - liballoc_memset(p, 0, real_size); - - return p; -} - -void* PREFIX(realloc)(void* p, size_t size) -{ - void* ptr; - struct liballoc_minor* min; - unsigned int real_size; - - // Honour the case of size == 0 => free old and return NULL - if (size == 0) - { - PREFIX(free)(p); - return NULL; - } - - // In the case of a NULL pointer, return a simple malloc. - if (p == NULL) return PREFIX(malloc)(size); - - // Unalign the pointer if required. - ptr = p; - UNALIGN(ptr); - - liballoc_lock(); // lockit - - min = (struct liballoc_minor*)((uintptr_t)ptr - sizeof(struct liballoc_minor)); - - // Ensure it is a valid structure. - if (min->magic != LIBALLOC_MAGIC) - { - l_errorCount += 1; - - // Check for overrun errors. For all bytes of LIBALLOC_MAGIC - if (((min->magic & 0xFFFFFF) == (LIBALLOC_MAGIC & 0xFFFFFF)) || - ((min->magic & 0xFFFF) == (LIBALLOC_MAGIC & 0xFFFF)) || ((min->magic & 0xFF) == (LIBALLOC_MAGIC & 0xFF))) - { - l_possibleOverruns += 1; -#if defined DEBUG || defined INFO - printf("liballoc: ERROR: Possible 1-3 byte overrun for magic %x != %x\n", min->magic, LIBALLOC_MAGIC); - FLUSH(); -#endif - } - - if (min->magic == LIBALLOC_DEAD) - { -#if defined DEBUG || defined INFO - printf("liballoc: ERROR: multiple PREFIX(free)() attempt on %x from %x.\n", ptr, - __builtin_return_address(0)); - FLUSH(); -#endif - } - else - { -#if defined DEBUG || defined INFO - printf("liballoc: ERROR: Bad PREFIX(free)( %x ) called from %x\n", ptr, __builtin_return_address(0)); - FLUSH(); -#endif - } - - // being lied to... - liballoc_unlock(); // release the lock - return NULL; - } - - // Definitely a memory block. - - real_size = min->req_size; - - if (real_size >= size) - { - min->req_size = size; - liballoc_unlock(); - return p; - } - - liballoc_unlock(); - - // If we got here then we're reallocating to a block bigger than us. - ptr = PREFIX(malloc)(size); // We need to allocate new memory - liballoc_memcpy(ptr, p, real_size); - PREFIX(free)(p); - - return ptr; -} - -#pragma GCC pop_options diff --git a/libs/libc/src/ctype.cpp b/libs/libc/src/ctype.cpp deleted file mode 100644 index 8610ce6b..00000000 --- a/libs/libc/src/ctype.cpp +++ /dev/null @@ -1,86 +0,0 @@ -#include - -extern "C" -{ - int isalnum(int c) - { - return isalpha(c) || isdigit(c); - } - - int isalpha(int c) - { - return islower(c) || isupper(c); - } - - int isascii(int c) - { - return !(c & ~0x7f); - } - - int isblank(int c) - { - return c == ' ' || c == '\t'; - } - - int iscntrl(int c) - { - return (unsigned int)c < 0x20 || c == 0x7f; - } - - int isdigit(int c) - { - return c >= '0' && c < ':'; - } - - int isgraph(int c) - { - return (unsigned int)c - 0x21 < 0x5e; - } - - int islower(int c) - { - return c >= 'a' && c < '{'; - } - - int isprint(int c) - { - return (unsigned int)c - 0x20 < 0x5f; - } - - int ispunct(int c) - { - return isgraph(c) && !isalnum(c); - } - - int isspace(int c) - { - return c == ' ' || (unsigned int)c - '\t' < 5; - } - - int isupper(int c) - { - return c >= 'A' && c < '['; - } - - int isxdigit(int c) - { - return isdigit(c) || ((unsigned int)c | 32) - 'a' < 6; - } - - int tolower(int c) - { - if (isupper(c)) return c | 32; - return c; - } - - int toupper(int c) - { - if (islower(c)) return c & 0x5f; - return c; - } - - int toascii(int c) - { - return c & 0x7f; - } -} \ No newline at end of file diff --git a/libs/libc/src/cxxabi.cpp b/libs/libc/src/cxxabi.cpp deleted file mode 100644 index 47734a45..00000000 --- a/libs/libc/src/cxxabi.cpp +++ /dev/null @@ -1,50 +0,0 @@ -typedef void* (*cxa_atexit_func_t)(void*); - -struct cxa_atexit_entry -{ - cxa_atexit_func_t function; - void* argument; - void* dso_handle; -}; - -#define CXA_ATEXIT_MAX 64 - -int cxa_atexit_entry_count = 0; - -cxa_atexit_entry cxa_atexit_entries[CXA_ATEXIT_MAX]; - -extern "C" -{ - int __cxa_atexit(cxa_atexit_func_t func, void* arg, void* dso) - { - if (cxa_atexit_entry_count >= CXA_ATEXIT_MAX) return -1; - cxa_atexit_entries[cxa_atexit_entry_count].function = func; - cxa_atexit_entries[cxa_atexit_entry_count].argument = arg; - cxa_atexit_entries[cxa_atexit_entry_count].dso_handle = dso; - cxa_atexit_entry_count++; - return 0; - } - - void __cxa_finalize(void* f) - { - int i = cxa_atexit_entry_count; - if (!f) - { - while (i--) - { - if (cxa_atexit_entries[i].function) { cxa_atexit_entries[i].function(cxa_atexit_entries[i].argument); } - } - } - else - { - while (i--) - { - if (cxa_atexit_entries[i].function == (cxa_atexit_func_t)f) - { - cxa_atexit_entries[i].function(cxa_atexit_entries[i].argument); - cxa_atexit_entries[i].function = 0; - } - } - } - } -} \ No newline at end of file diff --git a/libs/libc/src/dirent.cpp b/libs/libc/src/dirent.cpp deleted file mode 100644 index 48523a19..00000000 --- a/libs/libc/src/dirent.cpp +++ /dev/null @@ -1,73 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include - -extern "C" -{ - DIR* opendir(const char* path) - { - int fd = open(path, O_RDONLY | O_DIRECTORY); - if (fd < 0) return NULL; - return fdopendir(fd); - } - - DIR* fdopendir(int fd) - { - if (fd < 0) return NULL; - DIR* result = (DIR*)malloc(sizeof(DIR)); - if (!result) return NULL; - result->d_dirfd = fd; - return result; - } - - int closedir(DIR* stream) - { - int status = close(stream->d_dirfd); - if (status < 0) - { - int savederr = errno; - free(stream); - errno = savederr; // free might reset errno. We don't want that. - } - else { free(stream); } - return status; - } - - struct dirent* readdir(DIR* stream) - { - static struct dirent result; - struct luna_dirent ent; - ssize_t nread = getdents(stream->d_dirfd, &ent, 1); // FIXME: Use a buffer to avoid too many system calls. - if (nread <= 0) return NULL; // Either EOF or error. - result.d_ino = ent.inode; - result.d_reclen = sizeof(result); - result.d_off = ent.offset; - result.d_type = DT_UNKNOWN; - strlcpy(result.d_name, ent.name, NAME_MAX); - return &result; - } - - int dirfd(DIR* stream) - { - return stream->d_dirfd; - } - - void rewinddir(DIR* stream) - { - lseek(stream->d_dirfd, 0, SEEK_SET); - } - - long telldir(DIR* stream) - { - return lseek(stream->d_dirfd, 0, SEEK_CUR); - } - - void seekdir(DIR* stream, long offset) - { - lseek(stream->d_dirfd, offset, SEEK_SET); - } -} \ No newline at end of file diff --git a/libs/libc/src/errno.cpp b/libs/libc/src/errno.cpp deleted file mode 100644 index ccd33dd5..00000000 --- a/libs/libc/src/errno.cpp +++ /dev/null @@ -1,4 +0,0 @@ -#include - -int errno; -char* program_invocation_name; \ No newline at end of file diff --git a/libs/libc/src/fcntl.cpp b/libs/libc/src/fcntl.cpp deleted file mode 100644 index c6a7d64d..00000000 --- a/libs/libc/src/fcntl.cpp +++ /dev/null @@ -1,33 +0,0 @@ -#include -#include -#include -#include -#include - -extern "C" -{ - int open(const char* pathname, int flags, ...) - { - va_list ap; - va_start(ap, flags); - long result = __lc_fast_syscall3(SYS_open, pathname, flags, va_arg(ap, unsigned int)); - va_end(ap); - return (int)result; - } - - int creat(const char* pathname, mode_t mode) - { - return (int)__lc_fast_syscall3(SYS_open, pathname, O_WRONLY | O_CREAT | O_TRUNC, - mode); // we don't need to pass this through to open(), we can avoid variadic - // stuff since we're sure mode exists. - } - - int fcntl(int fd, int cmd, ...) - { - va_list ap; - va_start(ap, cmd); - long result = __lc_fast_syscall3(SYS_fcntl, fd, cmd, va_arg(ap, uintptr_t)); - va_end(ap); - return (int)result; - } -} \ No newline at end of file diff --git a/libs/libc/src/file.cpp b/libs/libc/src/file.cpp deleted file mode 100644 index d686d8da..00000000 --- a/libs/libc/src/file.cpp +++ /dev/null @@ -1,305 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include - -FILE* stderr; -FILE* stdout; -FILE* stdin; - -static void file_read_buf(FILE* stream) -{ - if (!stream->f_buf) - { - stream->f_buf = (char*)malloc(BUFSIZ); // FIXME: Handle errors. - stream->f_bufrsize = BUFSIZ; - } - stream->f_bufoff = 0; - ssize_t nread = read(stream->f_fd, stream->f_buf, stream->f_bufrsize); - if (nread < 0) - { - stream->f_err = 1; - return; - } - if (nread == 0) - { - stream->f_eof = 1; - return; - } - stream->f_bufsize = nread; -} - -static int file_parse_mode(const char* mode) -{ - int flags = 0; - switch (mode[0]) - { - case 'r': flags |= O_RDONLY; break; - case 'w': - flags |= O_WRONLY; - flags |= O_CREAT; - flags |= O_TRUNC; - break; - case 'a': - flags |= O_WRONLY; - flags |= O_CREAT; - flags |= O_APPEND; - break; - default: errno = EINVAL; return -1; - } - - if (strchr(mode, '+')) flags |= O_RDWR; - return flags; -} - -extern "C" -{ - int fclose(FILE* stream) - { - if (stream->f_buf) free(stream->f_buf); - int status = close(stream->f_fd); - if (status < 0) - { - int savederr = errno; - free(stream); // We do not want to leak memory. man fclose(3) says that whether fclose() fails or not, any - // further operation on the stream results in undefined behavior. So we are free to free the - // stream. - errno = savederr; // free might reset errno. We don't want that. - } - else { free(stream); } - return status; - } - - int fflush(FILE*) - { - return 0; // FIXME: Implement buffered IO. - } - - FILE* fopen(const char* pathname, const char* mode) - { - int flags = file_parse_mode(mode); - if (flags < 0) return NULL; - int fd = open(pathname, flags, 0666); // If we create the file, create it as rw-rw-rw-. - if (fd < 0) { return 0; } - return fdopen(fd, mode); - } - - FILE* fdopen(int fd, const char*) - { - if (fd < 0) // FIXME: Also check if the mode string is compatible with how fd was opened. - { - errno = EBADF; - return 0; - } - FILE* stream = (FILE*)malloc(sizeof(FILE)); - if (!stream) { return 0; } - stream->f_fd = fd; - clearerr(stream); - stream->f_buf = 0; - stream->f_bufoff = 0; - stream->f_bufsize = 0; - return stream; - } - - FILE* freopen(const char* pathname, const char* mode, - FILE* stream) // FIXME: If pathname is NULL, open the original file with the new mode. - { - int flags = file_parse_mode(mode); - if (flags < 0) return NULL; - int fd = open(pathname, flags, 0666); // If we create the file, create it as rw-rw-rw-. - if (fd < 0) { return 0; } - - fflush(stream); // To make it future-proof. - fclose(stream); - - stream->f_fd = fd; - clearerr(stream); - return stream; - } - - int fileno(FILE* stream) - { - return stream->f_fd; - } - - size_t fread(void* buf, size_t size, size_t nmemb, FILE* stream) - { - size_t rsize = size * nmemb; - ssize_t status = read(stream->f_fd, buf, rsize); - if (status < 0) - { - stream->f_err = 1; - return 0; - } - if (status == 0 && rsize) stream->f_eof = 1; - if (status == 0) return (size_t)status; - return (size_t)status / size; - } - - char* fgets(char* buf, int size, FILE* stream) - { - char* s = buf; - int original_size = size; - while (size > 1) - { - if (stream->f_bufoff < stream->f_bufsize) - { - *buf = *(stream->f_buf + stream->f_bufoff); - stream->f_bufoff++; - if (*buf == '\n') - { - buf++; - break; - } - if (*buf == '\b') - { - if (size != original_size) - { - buf--; - size++; - } - } - else - { - buf++; - size--; - } - } - else - { - file_read_buf(stream); - if (ferror(stream)) return NULL; - if (feof(stream)) break; - } - } - if (size == original_size && feof(stream)) return NULL; // EOF while reading the first character - *buf = 0; - return s; - } - - int fgetc(FILE* stream) - { - char result; - read: - if (stream->f_bufoff < stream->f_bufsize) - { - result = *(stream->f_buf + stream->f_bufoff); - stream->f_bufoff++; - } - else - { - file_read_buf(stream); - if (ferror(stream)) return EOF; - if (feof(stream)) return EOF; - goto read; - } - return (int)result; - } - - int getc(FILE* stream) - { - return fgetc(stream); - } - - int getchar() - { - return fgetc(stdin); - } - - int ungetc(int c, FILE* stream) - { - if (stream->f_bufoff > 0) - { - stream->f_bufoff--; - stream->f_buf[stream->f_bufoff] = (char)c; - return c; - } - else - { - return EOF; // FIXME: Handle this case properly. - } - } - - int ferror(FILE* stream) - { - return stream->f_err; - } - - int feof(FILE* stream) - { - return stream->f_eof; - } - - void clearerr(FILE* stream) - { - stream->f_err = stream->f_eof = 0; - } - - int fseek(FILE* stream, long offset, int whence) - { - long result = lseek(stream->f_fd, offset, whence); - if (result < 0) { return -1; } - return 0; - } - - int fseeko(FILE* stream, off_t offset, int whence) - { - return fseek(stream, offset, whence); - } - - int fsetpos(FILE* stream, const fpos_t* pos) - { - return fseek(stream, *pos, SEEK_SET); - } - - long ftell(FILE* stream) - { - return lseek(stream->f_fd, 0, SEEK_CUR); - } - - off_t ftello(FILE* stream) - { - return ftell(stream); - } - - int fgetpos(FILE* stream, fpos_t* pos) - { - long result = ftell(stream); - if (result < 0) { return -1; } - *pos = result; - return 0; - } - - void rewind(FILE* stream) - { - lseek(stream->f_fd, 0, SEEK_SET); - clearerr(stream); - } - - size_t fwrite(const void* buf, size_t size, size_t nmemb, FILE* stream) - { - size_t rsize = size * nmemb; - ssize_t status = write(stream->f_fd, buf, rsize); - if (status < 0) - { - stream->f_err = 1; - return 0; - } - if (status == 0 && rsize) stream->f_eof = 1; - if (status == 0) return (size_t)status; - return (size_t)status / size; - } - - void setbuf(FILE*, char*) - { - NOT_IMPLEMENTED("setbuf"); - } - - int setvbuf(FILE*, char*, int, size_t) - { - NOT_IMPLEMENTED("setvbuf"); - } -} \ No newline at end of file diff --git a/libs/libc/src/init.cpp b/libs/libc/src/init.cpp deleted file mode 100644 index 00a777d4..00000000 --- a/libs/libc/src/init.cpp +++ /dev/null @@ -1,69 +0,0 @@ -#include -#include -#include -#include -#include - -char** environ = {nullptr}; - -static void terminate_libc() -{ - fclose(stdout); - fclose(stderr); - fclose(stdin); -} - -static void initialize_random() -{ - unsigned int seed = 3735928559U; - - int fd = open("/dev/random", O_RDONLY | O_CLOEXEC); // If we somehow fail to close this file, close it on exec. - FILE* fp = fdopen(fd, "r"); - if (!fp) - { - errno = 0; - goto failed_to_read_dev_random; - } - - fread(&seed, sizeof(seed), 1, fp); - if (ferror(fp)) - { - errno = 0; - fclose(fp); - goto failed_to_read_dev_random; - } - - fclose(fp); - -failed_to_read_dev_random: - srand(seed); // If we failed, this will be seeded with a known value. Else, it will be seeded with a random value - // from the kernel. - return; -} - -static void check_for_file(int fd, FILE** target_stream, const char* path, const char* mode) -{ - if (lseek(fd, 0, SEEK_CUR) < 0) - { - if (errno == EBADF) *target_stream = fopen(path, mode); - else - exit(-errno); - if (!*target_stream) exit(-errno); - errno = 0; - } - else { *target_stream = fdopen(fd, mode); } -} - -extern char* program_invocation_name; - -extern "C" void initialize_libc(int, char** argv) -{ - check_for_file(STDIN_FILENO, &stdin, "/dev/console", "r"); - check_for_file(STDOUT_FILENO, &stdout, "/dev/console", "a"); - check_for_file(STDERR_FILENO, &stderr, "/dev/console", "a"); - - if (argv) program_invocation_name = argv[0]; - - initialize_random(); - atexit(terminate_libc); -} \ No newline at end of file diff --git a/libs/libc/src/libgen.cpp b/libs/libc/src/libgen.cpp deleted file mode 100644 index c1bcbfc6..00000000 --- a/libs/libc/src/libgen.cpp +++ /dev/null @@ -1,50 +0,0 @@ -#include -#include - -static char dot[] = "."; - -extern "C" -{ - char* basename(char* path) - { - // If path is NULL, or the string's length is 0, return . - if (!path) return dot; - size_t len = strlen(path); - if (!len) return dot; - - // Strip trailing slashes. - char* it = path + len - 1; - while (*it == '/' && it != path) { it--; } - *(it + 1) = 0; - if (it == path) return path; - - // Return path from the first character if there are no more slashes, or from the first character after the last - // slash. - char* beg = strrchr(path, '/'); - if (!beg) return path; - return beg + 1; - } - - char* dirname(char* path) - { - // If path is NULL, or the string's length is 0, return . - if (!path) return dot; - size_t len = strlen(path); - if (!len) return dot; - - // Strip trailing slashes. - char* it = path + len - 1; - while (*it == '/' && it != path) { it--; } - *(char*)(it + 1) = 0; - if (it == path) return path; - - // Search for the last slash. If there is none, return . - // Otherwise, we end the string there and return. - char* end = strrchr(path, '/'); - if (!end) return dot; - if (end != path) *end = 0; - else - *(end + 1) = 0; - return path; - } -} \ No newline at end of file diff --git a/libs/libc/src/locale.cpp b/libs/libc/src/locale.cpp deleted file mode 100644 index 656cfa3b..00000000 --- a/libs/libc/src/locale.cpp +++ /dev/null @@ -1,25 +0,0 @@ -#include -#include -#include - -static char default_locale[] = "C"; - -static char dot[] = "."; -static char empty[] = ""; - -static struct lconv default_lconv = {dot, empty, empty, empty, empty, empty, - empty, empty, empty, empty, CHAR_MAX, CHAR_MAX, - CHAR_MAX, CHAR_MAX, CHAR_MAX, CHAR_MAX, CHAR_MAX, CHAR_MAX}; - -extern "C" -{ - char* setlocale(int, const char*) - { - return default_locale; - } - - struct lconv* localeconv(void) - { - return &default_lconv; - } -} \ No newline at end of file diff --git a/libs/libc/src/luna.cpp b/libs/libc/src/luna.cpp deleted file mode 100644 index 48dc1285..00000000 --- a/libs/libc/src/luna.cpp +++ /dev/null @@ -1,25 +0,0 @@ -#include -#include -#include -#include -#include -#include - -extern "C" -{ - long getprocid(int field) - { - return __lc_fast_syscall1(SYS_getprocid, field); - } - - unsigned int msleep(unsigned int ms) - { - return (unsigned int)__lc_fast_syscall1(SYS_sleep, ms); - } - - __lc_noreturn void __luna_abort(const char* message) - { - fputs(message, stderr); - abort(); - } -} \ No newline at end of file diff --git a/libs/libc/src/luna/dirent.cpp b/libs/libc/src/luna/dirent.cpp deleted file mode 100644 index 967e2e5b..00000000 --- a/libs/libc/src/luna/dirent.cpp +++ /dev/null @@ -1,11 +0,0 @@ -#include -#include -#include - -extern "C" -{ - ssize_t getdents(int fd, struct luna_dirent* buf, size_t count) - { - return __lc_fast_syscall3(SYS_getdents, fd, buf, count); - } -} \ No newline at end of file diff --git a/libs/libc/src/luna/pstat.cpp b/libs/libc/src/luna/pstat.cpp deleted file mode 100644 index 1221b6de..00000000 --- a/libs/libc/src/luna/pstat.cpp +++ /dev/null @@ -1,24 +0,0 @@ -#include -#include -#include - -extern "C" -{ - pid_t pstat(pid_t pid, struct pstat* buf) - { - return __lc_fast_syscall2(SYS_pstat, pid, buf); - } - - const char* pstatname(struct pstat* buf) - { - switch (buf->pt_state) - { - case PT_IDLE: return "Idle"; - case PT_RUNNING: return "Running"; - case PT_SLEEPING: return "Sleeping"; - case PT_WAITING: return "Waiting"; - case PT_ZOMBIE: return "Zombie"; - default: return "Unknown"; - } - } -} \ No newline at end of file diff --git a/libs/libc/src/luna/syscall.asm b/libs/libc/src/luna/syscall.asm deleted file mode 100644 index b6c1797c..00000000 --- a/libs/libc/src/luna/syscall.asm +++ /dev/null @@ -1,50 +0,0 @@ -global __luna_syscall0 -__luna_syscall0: - mov rax, rdi - int 0x42 - ret - -global __luna_syscall1 -__luna_syscall1: - mov rax, rdi - mov rdi, rsi - int 0x42 - ret - -global __luna_syscall2 -__luna_syscall2: - mov rax, rdi - mov rdi, rsi - mov rsi, rdx - int 0x42 - ret - -global __luna_syscall3 -__luna_syscall3: - mov rax, rdi - mov rdi, rsi - mov rsi, rdx - mov rdx, rcx - int 0x42 - ret - -global __luna_syscall4 -__luna_syscall4: - mov rax, rdi - mov rdi, rsi - mov rsi, rdx - mov rdx, rcx - mov r10, r8 - int 0x42 - ret - -global __luna_syscall5 -__luna_syscall5: - mov rax, rdi - mov rdi, rsi - mov rsi, rdx - mov rdx, rcx - mov r10, r8 - mov r8, r9 - int 0x42 - ret \ No newline at end of file diff --git a/libs/libc/src/math.cpp b/libs/libc/src/math.cpp deleted file mode 100644 index 52367eb0..00000000 --- a/libs/libc/src/math.cpp +++ /dev/null @@ -1,106 +0,0 @@ -#include - -// FIXME: Provide our own definitions instead of relying on the compiler's builtins. - -#define WRAP_AROUND_BUILTIN(name) \ - double name(double val) \ - { \ - return __builtin_##name(val); \ - } \ - float name##f(float val) \ - { \ - return __builtin_##name##f(val); \ - } \ - long double name##l(long double val) \ - { \ - return __builtin_##name##l(val); \ - } - -#define WRAP_AROUND_BUILTIN2(name) \ - double name(double val1, double val2) \ - { \ - return __builtin_##name(val1, val2); \ - } \ - float name##f(float val1, float val2) \ - { \ - return __builtin_##name##f(val1, val2); \ - } \ - long double name##l(long double val1, long double val2) \ - { \ - return __builtin_##name##l(val1, val2); \ - } - -#define WRAP_AROUND_BUILTIN_WITH_PARAMETER_TYPE(name, type) \ - double name(double val1, type val2) \ - { \ - return __builtin_##name(val1, val2); \ - } \ - float name##f(float val1, type val2) \ - { \ - return __builtin_##name##f(val1, val2); \ - } \ - long double name##l(long double val1, type val2) \ - { \ - return __builtin_##name##l(val1, val2); \ - } - -#define WRAP_AROUND_BUILTIN_WITH_POINTER(name) \ - double name(double val1, double* val2) \ - { \ - return __builtin_##name(val1, val2); \ - } \ - float name##f(float val1, float* val2) \ - { \ - return __builtin_##name##f(val1, val2); \ - } \ - long double name##l(long double val1, long double* val2) \ - { \ - return __builtin_##name##l(val1, val2); \ - } - -extern "C" -{ - WRAP_AROUND_BUILTIN(cos); - - WRAP_AROUND_BUILTIN(sin); - - WRAP_AROUND_BUILTIN(tan); - - WRAP_AROUND_BUILTIN(acos); - - WRAP_AROUND_BUILTIN(asin); - - WRAP_AROUND_BUILTIN(atan); - - WRAP_AROUND_BUILTIN(cosh); - - WRAP_AROUND_BUILTIN(sinh); - - WRAP_AROUND_BUILTIN(tanh); - - WRAP_AROUND_BUILTIN(log); - - WRAP_AROUND_BUILTIN(exp); - - WRAP_AROUND_BUILTIN(sqrt); - - WRAP_AROUND_BUILTIN(fabs); - - WRAP_AROUND_BUILTIN(floor); - - WRAP_AROUND_BUILTIN(ceil); - - WRAP_AROUND_BUILTIN(log10); - - WRAP_AROUND_BUILTIN2(fmod); - - WRAP_AROUND_BUILTIN2(pow); - - WRAP_AROUND_BUILTIN2(atan2); - - WRAP_AROUND_BUILTIN_WITH_PARAMETER_TYPE(frexp, int*); - - WRAP_AROUND_BUILTIN_WITH_PARAMETER_TYPE(ldexp, int); - - WRAP_AROUND_BUILTIN_WITH_POINTER(modf); -} \ No newline at end of file diff --git a/libs/libc/src/printf.cpp b/libs/libc/src/printf.cpp deleted file mode 100644 index 3be32613..00000000 --- a/libs/libc/src/printf.cpp +++ /dev/null @@ -1,331 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -typedef long int ssize_t; - -static void printf_strrev(char* arr, int size) -{ - int left = 0; - int right = size - 1; - for (int i = left; i < right; i++) - { - char temp = arr[i]; - arr[i] = arr[right]; - arr[right] = temp; - right--; - } -} - -template static char* printf_unsigned_to_string(IntegerType number, char* arr, int base) -{ - int i = 0; - - if (number == 0) - { - arr[i] = '0'; - arr[i + 1] = '\0'; - return arr; - } - - while (number != 0) - { - IntegerType r = number % (IntegerType)base; - arr[i] = (char)((r > 9) ? (r - 10) + 'a' : r + '0'); - i++; - number /= base; - } - - printf_strrev(arr, i); - - arr[i] = '\0'; - - return arr; -} - -template static char* printf_signed_to_string(IntegerType number, char* arr, int base) -{ - int i = 0, negative = 0; - - if (number == 0) - { - arr[i] = '0'; - arr[i + 1] = '\0'; - return arr; - } - - if (number < 0 && base == 10) - { - number *= -1; - negative = 1; - } - - while (number != 0) - { - IntegerType r = number % base; - arr[i] = (char)((r > 9) ? (r - 10) + 'a' : r + '0'); - i++; - number /= base; - } - - if (negative) - { - arr[i] = '-'; - i++; - } - - printf_strrev(arr, i); - - arr[i] = '\0'; - - return arr; -} - -#pragma GCC push_options -#pragma GCC optimize("O0") - -template -static int internal_printf(const char* format, PutString put_string_callback, ssize_t max, va_list ap) -{ - char buffer[1025]; // 1024 with null terminator - size_t format_size = strlen(format); - size_t format_index = 0; - size_t buffer_insert_index = 0; - ssize_t max_remaining = max; - size_t written = 0; - - auto flush_buffer = [&]() { - size_t buffer_length = buffer_insert_index; - written += buffer_length; - buffer_insert_index = 0; - if (max_remaining < 0) - { - buffer[buffer_length] = 0; - put_string_callback(buffer); - return; - } - if (max_remaining == 0) { return; } - if (buffer_length <= (size_t)max_remaining) - { - max_remaining -= buffer_length; - buffer[buffer_length] = 0; - put_string_callback(buffer); - } - else - { - buffer[max_remaining] = 0; - max_remaining = 0; - put_string_callback(buffer); - } - }; - - auto append_string = [&](const char* str) { - while (strlen(str) > 1024) - { - flush_buffer(); - memcpy(buffer, str, 1024); - str += 1024; - buffer_insert_index = 1024; - } - if (buffer_insert_index + strlen(str) > 1024) flush_buffer(); - memcpy(buffer + buffer_insert_index, str, strlen(str)); - buffer_insert_index += strlen(str); - if (buffer_insert_index == 1024) flush_buffer(); - }; - - auto append_char = [&](char c) { - buffer[buffer_insert_index++] = c; - if (buffer_insert_index == 1024) flush_buffer(); - }; - - bool is_long = false; - bool is_unsigned_long = false; - - bool preserve_format = false; - - while (format_index < format_size) - { - char current_char = format[format_index]; - if (current_char == '%' || preserve_format) - { - if (!preserve_format && format_index + 1 == format_size) // end of format string - { - format_index++; - continue; - } - else - { - if (!preserve_format) format_index++; - preserve_format = false; - current_char = format[format_index]; - switch (current_char) - { - case 'c': { - append_char((char)va_arg(ap, int)); - break; - } - case '%': { - append_char('%'); - break; - } - case 'z': { - is_unsigned_long = true; - preserve_format = true; - break; - } - case 'l': { - is_long = true; - preserve_format = true; - break; - } - case 'i': - case 'd': { - char result[32]; - if (is_unsigned_long) - { - printf_unsigned_to_string(va_arg(ap, uint64_t), result, 10); - is_unsigned_long = is_long = false; - } - else if (is_long) - { - printf_signed_to_string(va_arg(ap, int64_t), result, 10); - is_unsigned_long = is_long = false; - } - else { printf_signed_to_string(va_arg(ap, int32_t), result, 10); } - append_string(result); - break; - } - case 'u': { - char result[32]; - if (is_unsigned_long || is_long) - { - printf_unsigned_to_string(va_arg(ap, uint64_t), result, 10); - is_unsigned_long = is_long = false; - } - else { printf_unsigned_to_string(va_arg(ap, uint32_t), result, 10); } - append_string(result); - break; - } - case 'x': { - char result[32]; - if (is_unsigned_long || is_long) - { - printf_unsigned_to_string(va_arg(ap, uint64_t), result, 16); - is_unsigned_long = is_long = false; - } - else { printf_unsigned_to_string(va_arg(ap, uint32_t), result, 16); } - append_string(result); - break; - } - case 'p': { - char result[32]; - printf_unsigned_to_string(va_arg(ap, uint64_t), result, 16); - append_string(result); - break; - } - case 'm': { - append_string(strerror(errno)); - break; - } - case 's': { - append_string(va_arg(ap, const char*)); - break; - } - default: { - fputs("printf: unknown format specifier ", stderr); - fputc('%', stderr); - fputc(current_char, stderr); - fputc('\n', stderr); - abort(); - } - } - } - } - else { append_char(current_char); } - format_index++; - } - - if (buffer_insert_index > 0) flush_buffer(); - return (int)written; -} - -#pragma GCC pop_options - -extern "C" -{ - int vprintf(const char* format, va_list ap) - { - return vfprintf(stdout, format, ap); - } - - int vsprintf(char* str, const char* format, va_list ap) - { - if (str) *str = 0; // so strncat starts from the beginning - return internal_printf( - format, - [&](const char* s) { - if (str) strncat(str, s, 1025); - }, - -1, ap); - } - - int vsnprintf(char* str, size_t max, const char* format, va_list ap) - { - if (max && str) *str = 0; // so strncat starts from the beginning - return internal_printf( - format, - [&](const char* s) { - if (str) strncat(str, s, 1025); - }, - max == 0 ? 0 : max - 1, ap); - } - - int snprintf(char* str, size_t max, const char* format, ...) - { - va_list ap; - va_start(ap, format); - int written = vsnprintf(str, max, format, ap); - va_end(ap); - return written; - } - - int sprintf(char* str, const char* format, ...) - { - va_list ap; - va_start(ap, format); - int written = vsprintf(str, format, ap); - va_end(ap); - return written; - } - - int printf(const char* format, ...) - { - va_list ap; - va_start(ap, format); - int written = vfprintf(stdout, format, ap); - va_end(ap); - return written; - } - - int fprintf(FILE* stream, const char* format, ...) - { - va_list ap; - va_start(ap, format); - int written = vfprintf(stream, format, ap); - va_end(ap); - return written; - } - - int vfprintf(FILE* stream, const char* format, va_list ap) - { - return internal_printf( - format, [&](const char* s) { fwrite(s, strlen(s), 1, stream); }, -1, ap); - } -} \ No newline at end of file diff --git a/libs/libc/src/pwd.cpp b/libs/libc/src/pwd.cpp deleted file mode 100644 index e33493fb..00000000 --- a/libs/libc/src/pwd.cpp +++ /dev/null @@ -1,196 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include - -static FILE* pwd_file = nullptr; -static FILE* pwnam_file = nullptr; -static FILE* pwuid_file = nullptr; - -static int initialize_pwd(FILE** stream) -{ - int pwfd = open("/etc/passwd", O_RDONLY | O_CLOEXEC); - if (pwfd < 0) return 0; - FILE* file = fdopen(pwfd, "r"); - if (!file) return 0; - *stream = file; - return 1; -} - -static int pwd_unbuffered_fgetc(FILE* stream) -{ - char c; - fread(&c, 1, 1, stream); - if (ferror(stream) || feof(stream)) return EOF; - return (int)c; -} - -static char* pwd_unbuffered_fgets(char* buf, size_t size, FILE* stream) -{ - char* s = buf; - memset(buf, 0, size); - while (size) - { - int c = pwd_unbuffered_fgetc(stream); - if (c == EOF) - { - if (ferror(stream)) return NULL; - if (feof(stream)) - { - if (s != buf) return s; - else - return NULL; - }; - } - size--; - *buf = (char)c; - buf++; - *buf = 0; - if ((char)c == '\n') return s; - } - return s; -} - -static char* pwd_strchrtok(char* s, char delim) -{ - static char* saved = nullptr; - if (s) saved = s; - else - s = saved; - if (!saved) return nullptr; - char* loc = strchr(saved, delim); - if (loc) - { - saved = loc + 1; - if (*saved == 0) saved = nullptr; - *loc = 0; - } - else { saved = nullptr; } - return s; -} - -static void pwd_strip_newline(char* buf) -{ - size_t len = strlen(buf); - if (buf[len - 1] == '\n') buf[len - 1] = 0; -} - -static struct passwd* internal_getpwent(FILE* stream) -{ -#define PWENT_INVALID \ - do { \ - errno = EINVAL; \ - return NULL; \ - } while (0) - - static struct passwd result; - static char buf[BUFSIZ]; - - if (!pwd_unbuffered_fgets(buf, BUFSIZ, stream)) return NULL; - pwd_strip_newline(buf); - result.pw_name = pwd_strchrtok(buf, ':'); - if (!result.pw_name) PWENT_INVALID; - result.pw_passwd = pwd_strchrtok(NULL, ':'); - if (!result.pw_passwd) PWENT_INVALID; - char* uid_string = pwd_strchrtok(NULL, ':'); - if (!uid_string) PWENT_INVALID; - result.pw_uid = atoi(uid_string); - char* gid_string = pwd_strchrtok(NULL, ':'); - if (!gid_string) PWENT_INVALID; - result.pw_gid = atoi(gid_string); - result.pw_gecos = pwd_strchrtok(NULL, ':'); - if (!result.pw_gecos) PWENT_INVALID; - result.pw_dir = pwd_strchrtok(NULL, ':'); - if (!result.pw_dir) PWENT_INVALID; - result.pw_shell = pwd_strchrtok(NULL, ':'); - if (!result.pw_shell) PWENT_INVALID; - return &result; -} - -extern "C" -{ - struct passwd* getpwent() - { - if (!pwd_file) - { - if (!initialize_pwd(&pwd_file)) return NULL; - } - if (feof(pwd_file)) - { - endpwent(); - return NULL; - } - return internal_getpwent(pwd_file); - } - - struct passwd* getpwnam(const char* name) - { - if (!pwnam_file) - { - if (!initialize_pwd(&pwnam_file)) return NULL; - } - else - rewind(pwnam_file); - struct passwd* pwd = internal_getpwent(pwnam_file); - while (pwd) - { - if (strcmp(pwd->pw_name, name) == 0) break; - if (feof(pwnam_file)) - { - pwd = nullptr; - break; - } - pwd = internal_getpwent(pwnam_file); - } - return pwd; // if we matched one, pwd contains a pointer to it. else it is NULL - } - - struct passwd* getpwuid(uid_t uid) - { - if (!pwuid_file) - { - if (!initialize_pwd(&pwuid_file)) return NULL; - } - else - rewind(pwuid_file); - struct passwd* pwd = internal_getpwent(pwuid_file); - while (pwd) - { - if (pwd->pw_uid == uid) break; - if (feof(pwuid_file)) - { - pwd = nullptr; - break; - } - pwd = internal_getpwent(pwuid_file); - } - return pwd; // if we matched one, pwd contains a pointer to it. else it is NULL - } - - void setpwent() - { - if (pwd_file) rewind(pwd_file); - } - - void endpwent() - { - if (pwd_file) - { - fclose(pwd_file); - pwd_file = nullptr; - } - if (pwuid_file) - { - fclose(pwuid_file); - pwuid_file = nullptr; - } - if (pwnam_file) - { - fclose(pwnam_file); - pwnam_file = nullptr; - } - } -} \ No newline at end of file diff --git a/libs/libc/src/rand.cpp b/libs/libc/src/rand.cpp deleted file mode 100644 index 8398928d..00000000 --- a/libs/libc/src/rand.cpp +++ /dev/null @@ -1,64 +0,0 @@ -#include -#include -#include -#include - -typedef uint32_t word_t; -#define STATE_SIZE 624 -#define MIDDLE 397 -#define INIT_SHIFT 30 -#define INIT_FACT 1812433253 -#define TWIST_MASK 0x9908b0df -#define SHIFT1 11 -#define MASK1 0xffffffff -#define SHIFT2 7 -#define MASK2 0x9d2c5680 -#define SHIFT3 15 -#define MASK3 0xefc60000 -#define SHIFT4 18 - -#define LOWER_MASK 0x7fffffff -#define UPPER_MASK (~(word_t)LOWER_MASK) - -static word_t state[STATE_SIZE]; -static size_t index = STATE_SIZE + 1; - -static void twist() -{ - for (size_t i = 0; i < STATE_SIZE; i++) - { - word_t x = (state[i] & UPPER_MASK) | (state[(i + 1) % STATE_SIZE] & LOWER_MASK); - x = (x >> 1) ^ (x & 1 ? TWIST_MASK : 0); - state[i] = state[(i + MIDDLE) % STATE_SIZE] ^ x; - } - index = 0; -} - -extern "C" -{ - int rand() - { - if (index >= STATE_SIZE) - { - assert(index == STATE_SIZE && "Mersenne generator was never seeded"); - twist(); - } - - word_t y = state[index]; - y ^= (y >> SHIFT1) & MASK1; - y ^= (y << SHIFT2) & MASK2; - y ^= (y << SHIFT3) & MASK3; - y ^= y >> SHIFT4; - - index++; - return y; - } - - void srand(unsigned int seed) - { - index = STATE_SIZE; - state[0] = seed; - for (size_t i = 1; i < STATE_SIZE; i++) - state[i] = (word_t)((INIT_FACT * (state[i - 1] ^ (state[i - 1] >> INIT_SHIFT))) + i); - } -} \ No newline at end of file diff --git a/libs/libc/src/sched.cpp b/libs/libc/src/sched.cpp deleted file mode 100644 index 917b17d6..00000000 --- a/libs/libc/src/sched.cpp +++ /dev/null @@ -1,11 +0,0 @@ -#include -#include -#include - -extern "C" -{ - int sched_yield() - { - return (int)__lc_fast_syscall0(SYS_yield); - } -} \ No newline at end of file diff --git a/libs/libc/src/setjmp.asm b/libs/libc/src/setjmp.asm deleted file mode 100644 index 21526397..00000000 --- a/libs/libc/src/setjmp.asm +++ /dev/null @@ -1,36 +0,0 @@ -global _setjmp -global setjmp -_setjmp: -setjmp: - mov rsi, 0 - mov [rdi], rbx - mov [rdi+8], r12 - mov [rdi+16], r13 - mov [rdi+24], r14 - mov [rdi+32], r15 - mov [rdi+40], rbp - mov [rdi+48], rsp - mov rax, [rsp] - mov [rdi+56], rax - xor rax, rax - ret - -global _longjmp -global longjmp -_longjmp: -longjmp: - mov rax, rsi - cmp rax, 0 - jne .nonzero - mov rax, 1 -.nonzero: - mov rbx, [rdi] - mov r12, [rdi+8] - mov r13, [rdi+16] - mov r14, [rdi+24] - mov r15, [rdi+32] - mov rbp, [rdi+40] - mov rsp, [rdi+48] - mov rcx, [rdi+56] - mov [rsp], rcx - ret \ No newline at end of file diff --git a/libs/libc/src/setjmp.cpp b/libs/libc/src/setjmp.cpp deleted file mode 100644 index d7d0e226..00000000 --- a/libs/libc/src/setjmp.cpp +++ /dev/null @@ -1,15 +0,0 @@ -#include -#include - -extern "C" -{ - int sigsetjmp(sigjmp_buf env, int) - { - return setjmp(env); - } - - __lc_noreturn void siglongjmp(sigjmp_buf env, int val) - { - longjmp(env, val); - } -} \ No newline at end of file diff --git a/libs/libc/src/signal.cpp b/libs/libc/src/signal.cpp deleted file mode 100644 index a82b3f9d..00000000 --- a/libs/libc/src/signal.cpp +++ /dev/null @@ -1,15 +0,0 @@ -#include -#include - -extern "C" -{ - void (*signal(int, void (*)(int)))(int) - { - NOT_IMPLEMENTED("signal"); - } - - int raise(int) - { - NOT_IMPLEMENTED("raise"); - } -} \ No newline at end of file diff --git a/libs/libc/src/stdio.cpp b/libs/libc/src/stdio.cpp deleted file mode 100644 index 1d6a0542..00000000 --- a/libs/libc/src/stdio.cpp +++ /dev/null @@ -1,82 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include - -extern "C" -{ - int puts(const char* s) - { - int nwritten = fputs(s, stdout); - if (nwritten < 0) return -1; - if (putchar('\n') < 0) return -1; - return nwritten + 1; - } - - int fputs(const char* s, FILE* stream) - { - int result = (int)fwrite(s, strlen(s), 1, stream); - if (ferror(stream)) return -1; - return result; - } - - int fputc(int c, FILE* stream) - { - char chr = (char)c; - fwrite(&chr, 1, 1, stream); - if (ferror(stream)) { return -1; } - return c; - } - - int putc(int c, FILE* stream) - { - return fputc(c, stream); - } - - int putchar(int c) - { - return fputc(c, stdout); - } - - void perror(const char* s) - { - int savederr = - errno; // This was necessary before, but even more now since we clear errno on successful syscalls now. - if (s && *s) { fprintf(stderr, "%s: ", s); } - fprintf(stderr, "%s\n", strerror(savederr)); - } - - int remove(const char*) - { - NOT_IMPLEMENTED("remove"); - } - - int sscanf(const char*, const char*, ...) - { - NOT_IMPLEMENTED("sscanf"); - } - - int fscanf(FILE*, const char*, ...) - { - NOT_IMPLEMENTED("fscanf"); - } - - int scanf(const char*, ...) - { - NOT_IMPLEMENTED("scanf"); - } - - int rename(const char*, const char*) - { - NOT_IMPLEMENTED("rename"); - } - - FILE* tmpfile() - { - errno = ENOTSUP; - return NULL; - } -} \ No newline at end of file diff --git a/libs/libc/src/stdlib.cpp b/libs/libc/src/stdlib.cpp deleted file mode 100644 index 012f8c27..00000000 --- a/libs/libc/src/stdlib.cpp +++ /dev/null @@ -1,311 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -template static T string_to_integer_type(const char* str) -{ - bool neg = false; - T val = 0; - - switch (*str) - { - case '-': - neg = true; - str++; - break; - case '+': str++; break; - default: break; - } - - while (isdigit(*str)) { val = (10 * val) + (*str++ - '0'); } - - return (neg ? -val : val); -} - -template static T string_to_float_type(const char* str) -{ - bool neg = false; - T val = 0; - - T small = 0; - - switch (*str) - { - case '-': - neg = true; - str++; - break; - case '+': str++; break; - default: break; - } - - while (isdigit(*str)) { val = (10 * val) + (T)(*str++ - '0'); } - if (*str == '.') - { - str++; - T div = 10; - while (isdigit(*str)) - { - small = small + (T)(*str++ - '0') / div; - div *= 10; - } - - val += small; - } - - return (neg ? -val : val); -} - -template static inline Struct common_div(Arg a, Arg b) -{ - Struct result; - result.quot = a / b; - result.rem = a % b; - - if (a >= 0 && result.rem < 0) - { - result.quot++; - result.rem -= b; - } - - return result; -} - -static void qswap(void* ptr1, void* ptr2, size_t size) -{ - char* x = (char*)ptr1; - char* y = (char*)ptr2; - - while (size--) - { - char t = *x; - *x = *y; - *y = t; - x += 1; - y += 1; - } -} - -static size_t partition(void* base, size_t start, size_t end, size_t size, int (*compar)(const void*, const void*)) -{ - auto atindex = [&base, &size](size_t index) { return (void*)((char*)base + (index * size)); }; - - void* pivot = atindex(end); - size_t i = (start - 1); - - for (size_t j = start; j <= end - 1; j++) - { - if (compar(atindex(j), pivot) < 0) - { - i++; - qswap(atindex(i), atindex(j), size); - } - } - - qswap(atindex(i + 1), pivot, size); - return i + 1; -} - -static void quicksort(void* base, size_t start, size_t end, size_t size, int (*compar)(const void*, const void*)) -{ - if (start < end) - { - size_t pivot = partition(base, start, end, size, compar); - quicksort(base, start, pivot - 1, size, compar); - quicksort(base, pivot + 1, end, size, compar); - } -} - -void* binary_search(const void* key, const void* base, size_t start, size_t end, size_t size, - int (*compar)(const void*, const void*)) -{ - auto atindex = [&base, &size](size_t index) { return (const void*)((const char*)base + (index * size)); }; - - if (end >= start) - { - size_t middle = start + (end - start) / 2; - int rc = compar(atindex(middle), key); - - if (rc == 0) return const_cast(atindex(middle)); // we found it!! - - if (rc < 0) return binary_search(key, base, middle + 1, end, size, compar); - - return binary_search(key, base, start, middle - 1, size, compar); - } - - return NULL; -} - -extern "C" -{ - __lc_noreturn void abort() - { - _Exit(-1); - } - - float atof(const char* str) - { - return string_to_float_type(str); - } - - int atoi(const char* str) - { - return string_to_integer_type(str); - } - - long atol(const char* str) - { - return string_to_integer_type(str); - } - - long long atoll(const char* str) - { - return string_to_integer_type(str); - } - - unsigned long strtoul(const char* str, char** endptr, int base) - { - if (base != 0 && base != 10) NOT_IMPLEMENTED("strtoul with base not in (0,10)"); - if (endptr) NOT_IMPLEMENTED("strtoul with non-null endptr"); - return string_to_integer_type(str); - } - - long strtol(const char* str, char** endptr, int base) - { - if (base != 0 && base != 10) NOT_IMPLEMENTED("strtol with base not in (0,10)"); - if (endptr) NOT_IMPLEMENTED("strtol with non-null endptr"); - return string_to_integer_type(str); - } - - char* getenv(const char*) - { - return NULL; // FIXME: Not implemented :) - } - - __lc_noreturn void _Exit(int status) - { - __lc_fast_syscall1(SYS_exit, status); - __lc_unreachable(); - } - - int abs(int val) - { - return __builtin_abs(val); - } - - long labs(long val) - { - return __builtin_labs(val); - } - - long long llabs(long long val) - { - return __builtin_llabs(val); - } - - div_t div(int a, int b) - { - return common_div(a, b); - } - - ldiv_t ldiv(long a, long b) - { - return common_div(a, b); - } - - lldiv_t lldiv(long long a, long long b) - { - return common_div(a, b); - } - - int system(const char* command) - { - pid_t child = fork(); - if (child < 0) return -1; - if (child == 0) - { - char* argv[] = {const_cast("/bin/sh"), const_cast("-c"), const_cast(command), - nullptr}; // FIXME: This is very verbose. - execv(argv[0], argv); - exit(127); - } - int status; - waitpid(child, &status, 0); - return status; - } - - void qsort(void* base, size_t nmemb, size_t size, int (*compar)(const void*, const void*)) - { - quicksort(base, 0, nmemb - 1, size, compar); - } - - void* bsearch(const void* key, const void* base, size_t nmemb, size_t size, int (*compar)(const void*, const void*)) - { - return binary_search(key, base, 0, nmemb - 1, size, compar); - } - - size_t mbstowcs(wchar_t*, const char*, size_t) - { - NOT_IMPLEMENTED("mbstowcs"); - } - - static void gentemp(char* startptr) - { - for (int i = 0; i < 6; i++) - { - startptr[i] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890"[rand() % 63]; - } - } - - char* mktemp(char* str) - { - size_t len = strlen(str); - if (len < 6) - { - errno = EINVAL; - return NULL; - } - char* startptr = str + (len - 6); - if (strncmp(startptr, "XXXXXX", 6)) - { - errno = EINVAL; - return NULL; - } - do { - gentemp(startptr); - } while (access(str, F_OK) == 0); - return str; - } - - char* mkdtemp(char* str) - { - size_t len = strlen(str); - if (len < 6) - { - errno = EINVAL; - return NULL; - } - char* startptr = str + (len - 6); - if (strncmp(startptr, "XXXXXX", 6)) - { - errno = EINVAL; - return NULL; - } - do { - gentemp(startptr); - } while (mkdir(str, 0700) < 0 && errno == EEXIST); - if (errno) return NULL; - return str; - } - - double strtod(const char*, char**) - { - NOT_IMPLEMENTED("strtod"); - } -} \ No newline at end of file diff --git a/libs/libc/src/strftime.cpp b/libs/libc/src/strftime.cpp deleted file mode 100644 index d185f5bf..00000000 --- a/libs/libc/src/strftime.cpp +++ /dev/null @@ -1,318 +0,0 @@ -#include -#include -#include -#include -#include - -static void printf_strrev(char* arr, int size) -{ - int left = 0; - int right = size - 1; - for (int i = left; i < right; i++) - { - char temp = arr[i]; - arr[i] = arr[right]; - arr[right] = temp; - right--; - } -} - -template static char* printf_unsigned_to_string(IntegerType number, char* arr, int base) -{ - int i = 0; - - if (number == 0) - { - arr[i] = '0'; - arr[i + 1] = '\0'; - return arr; - } - - while (number != 0) - { - IntegerType r = number % (IntegerType)base; - arr[i] = (char)((r > 9) ? (r - 10) + 'a' : r + '0'); - i++; - number /= base; - } - - printf_strrev(arr, i); - - arr[i] = '\0'; - - return arr; -} - -template static char* printf_signed_to_string(IntegerType number, char* arr, int base) -{ - int i = 0, negative = 0; - - if (number == 0) - { - arr[i] = '0'; - arr[i + 1] = '\0'; - return arr; - } - - if (number < 0 && base == 10) - { - number *= -1; - negative = 1; - } - - while (number != 0) - { - IntegerType r = number % base; - arr[i] = (char)((r > 9) ? (r - 10) + 'a' : r + '0'); - i++; - number /= base; - } - - if (negative) - { - arr[i] = '-'; - i++; - } - - printf_strrev(arr, i); - - arr[i] = '\0'; - - return arr; -} - -const char* short_week_days[] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"}; -const char* long_week_days[] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"}; -const char* short_month_names[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}; -const char* long_month_names[] = {"January", "February", "March", "April", "May", "June", - "July", "August", "September", "October", "November", "December"}; - -extern "C" size_t strftime(char* s, size_t max, const char* format, const struct tm* time) -{ - char buffer[1025]; // 1024 with null terminator - size_t format_size = strlen(format); - size_t format_index = 0; - size_t buffer_insert_index = 0; - ssize_t max_remaining = (ssize_t)max; - size_t written = 0; - - if (s && max) *s = 0; - - auto flush_buffer = [&]() { - size_t buffer_length = buffer_insert_index; - written += buffer_length; - buffer_insert_index = 0; - if (max_remaining < 0) - { - buffer[buffer_length] = 0; - if (s) strncat(s, buffer, sizeof(buffer)); - return; - } - if (max_remaining == 0) { return; } - if (buffer_length <= (size_t)max_remaining) - { - max_remaining -= buffer_length; - buffer[buffer_length] = 0; - if (s) strncat(s, buffer, sizeof(buffer)); - } - else - { - buffer[max_remaining] = 0; - max_remaining = 0; - if (s) strncat(s, buffer, sizeof(buffer)); - } - }; - - auto append_string = [&](const char* str) { - while (strlen(str) > 1024) - { - flush_buffer(); - memcpy(buffer, str, 1024); - str += 1024; - buffer_insert_index = 1024; - } - if (buffer_insert_index + strlen(str) > 1024) flush_buffer(); - memcpy(buffer + buffer_insert_index, str, strlen(str)); - buffer_insert_index += strlen(str); - if (buffer_insert_index == 1024) flush_buffer(); - }; - - auto append_char = [&](char c) { - buffer[buffer_insert_index++] = c; - if (buffer_insert_index == 1024) flush_buffer(); - }; - - while (format_index < format_size) - { - char current_char = format[format_index]; - if (current_char == '%') - { - if (format_index + 1 == format_size) // end of format string - { - format_index++; - continue; - } - else - { - format_index++; - current_char = format[format_index]; - switch (current_char) - { - case '%': { - append_char('%'); - break; - } - case 'a': { - append_string(short_week_days[time->tm_wday % 7]); - break; - } - case 'A': { - append_string(long_week_days[time->tm_wday % 7]); - break; - } - case 'b': { - append_string(short_month_names[(time->tm_mon - 1) % 12]); - break; - } - case 'B': { - append_string(long_month_names[(time->tm_mon - 1) % 12]); - break; - } - case 'c': { - char buf[32]; - append_string(short_week_days[time->tm_wday % 7]); - append_char(' '); - append_string(short_month_names[(time->tm_mon - 1) % 12]); - append_char(' '); - printf_signed_to_string(time->tm_mday, buf, 10); - append_string(buf); - append_char(' '); - printf_signed_to_string(time->tm_hour % 24, buf, 10); - append_string(buf); - append_char(':'); - printf_signed_to_string(time->tm_min % 60, buf, 10); - append_string(buf); - append_char(':'); - printf_signed_to_string(time->tm_sec % 60, buf, 10); - append_string(buf); - append_char(' '); - printf_signed_to_string(time->tm_year + 1900, buf, 10); - append_string(buf); - break; - } - case 'd': { - char buf[30]; - printf_signed_to_string(time->tm_mday % 32, buf, 10); - append_string(buf); - break; - } - case 'H': { - char buf[30]; - printf_signed_to_string(time->tm_hour % 24, buf, 10); - append_string(buf); - break; - } - case 'I': { - char buf[30]; - int hour = time->tm_hour % 12; - if (hour == 0) hour = 12; - printf_signed_to_string(hour, buf, 10); - append_string(buf); - break; - } - case 'j': { - char buf[30]; - printf_signed_to_string(time->tm_yday % 367, buf, 10); - append_string(buf); - break; - } - case 'm': { - char buf[30]; - printf_signed_to_string(time->tm_mon % 13, buf, 10); - append_string(buf); - break; - } - case 'M': { - char buf[30]; - printf_signed_to_string(time->tm_min % 60, buf, 10); - append_string(buf); - break; - } - case 'p': { - if (time->tm_hour < 12) append_string("AM"); - else - append_string("PM"); - break; - } - case 'P': { - if (time->tm_hour < 12) append_string("am"); - else - append_string("pm"); - break; - } - case 'S': { - char buf[30]; - printf_signed_to_string(time->tm_sec % 61, buf, 10); - append_string(buf); - break; - } - case 'w': { - char buf[30]; - printf_signed_to_string(time->tm_wday % 7, buf, 10); - append_string(buf); - break; - } - case 'x': { - char buf[30]; - printf_signed_to_string(time->tm_mon % 13, buf, 10); - append_string(buf); - append_char('/'); - printf_signed_to_string(time->tm_mday % 32, buf, 10); - append_string(buf); - append_char('/'); - printf_signed_to_string((time->tm_year + 1900) % 100, buf, 10); - append_string(buf); - break; - } - case 'X': { - char buf[30]; - printf_signed_to_string(time->tm_hour % 24, buf, 10); - append_string(buf); - append_char(':'); - printf_signed_to_string(time->tm_min % 60, buf, 10); - append_string(buf); - append_char(':'); - printf_signed_to_string(time->tm_sec % 60, buf, 10); - append_string(buf); - break; - } - case 'y': { - char buf[30]; - printf_signed_to_string((time->tm_year + 1900) % 100, buf, 10); - append_string(buf); - break; - } - case 'Y': { - char buf[30]; - printf_signed_to_string(time->tm_year + 1900, buf, 10); - append_string(buf); - break; - } - case 'Z': { - append_string("UTC"); // FIXME: Add timezone support. - break; - } - default: { - fprintf(stderr, "strftime: unknown format specifier %%%c\n", current_char); - abort(); - } - } - } - } - else { append_char(current_char); } - format_index++; - } - - if (buffer_insert_index > 0) flush_buffer(); - return written; -} \ No newline at end of file diff --git a/libs/libc/src/string.cpp b/libs/libc/src/string.cpp deleted file mode 100644 index 44184d4f..00000000 --- a/libs/libc/src/string.cpp +++ /dev/null @@ -1,311 +0,0 @@ -#include -#include -#include -#include - -extern "C" -{ - void* memcpy(void* dest, const void* src, size_t n) - { - for (size_t i = 0; i < n; ++i) { *((char*)dest + i) = *((const char*)src + i); } - return dest; - } - - void* memset(void* buf, int c, size_t n) - { - for (size_t i = 0; i < n; ++i) { *((char*)buf + i) = (char)c; } - return buf; - } - - void* memchr(const void* buf, int c, size_t n) - { - const char* s = (const char*)buf; - for (; n && *s != (char)c; s++, n--) - ; - if (n) return (void*)(const_cast(s)); - return NULL; - } - - int memcmp(const void* a, const void* b, size_t n) - { - if (!n) return 0; - const unsigned char* ap = (const unsigned char*)a; - const unsigned char* bp = (const unsigned char*)b; - while (--n && *ap == *bp) - { - ap++; - bp++; - } - return *ap - *bp; - } - - void* memmove(void* dest, const void* src, size_t n) - { - if (dest == src) return dest; - if (dest > src) - for (long i = n - 1; i >= 0; i++) { *((char*)dest + i) = *((const char*)src + i); } - else - for (long i = 0; i < (long)n; i++) { *((char*)dest + i) = *((const char*)src + i); } - return dest; - } - - char* strdup(const char* str) - { - size_t len = strlen(str); - char* dest = (char*)malloc(len + 1); - if (!dest) return dest; - return (char*)memcpy(dest, str, len + 1); - } - - char* strndup(const char* str, size_t max) - { - size_t len = strnlen(str, max); - char* dest = (char*)malloc(len + 1); - if (!dest) return dest; - memcpy(dest, str, len); - dest[len] = 0; - return dest; - } - - size_t strlen(const char* str) - { - const char* i = str; - for (; *i; ++i) - ; - return (i - str); - } - - size_t strnlen(const char* str, size_t max) - { - char* p = (char*)memchr(str, 0, max); - return p ? p - str : max; - } - - char* strcpy(char* dest, const char* src) - { - return (char*)memcpy(dest, src, strlen(src) + 1); - } - - char* strncpy(char* dest, const char* src, size_t max) - { - size_t i; - for (i = 0; i < max && src[i] != 0; i++) dest[i] = src[i]; - for (; i < max; i++) dest[i] = 0; - return dest; - } - - size_t strlcpy(char* dest, const char* src, size_t size) - { - size_t len = strlen(src); - if (size == 0) return len; - if (len < (size - 1)) - { - memcpy(dest, src, len); - dest[len] = 0; - } - else - { - memcpy(dest, src, size - 1); - dest[size - 1] = 0; - } - return len; - } - - char* stpcpy(char* dest, const char* src) - { - size_t len = strlen(src); - size_t rc = strlcpy(dest, src, len + 1); - return dest + rc; - } - - int strcmp(const char* a, const char* b) - { - while (*a && (*a == *b)) - { - a++; - b++; - } - return *(const unsigned char*)a - *(const unsigned char*)b; - } - - int strncmp(const char* a, const char* b, size_t max) - { - const char* base = a; - while (*a && (*a == *b) && (size_t)(a - base) < (max - 1)) - { - a++; - b++; - } - return *(const unsigned char*)a - *(const unsigned char*)b; - } - - int strcoll(const char* a, const char* b) - { - return strcmp(a, b); - } - - size_t strxfrm(char* dest, const char* src, size_t n) - { - strncpy(dest, src, n); - return n; - } - - size_t strcspn(const char* str, const char* reject) - { - const char* s = str; - while (*s) - { - const char* rp = reject; - while (*rp) - { - if (*s == *rp) return s - str; - rp++; - } - s++; - } - return s - str; - } - - size_t strspn(const char* str, const char* accept) - { - const char* s = str; - while (*s) - { - const char* ap = accept; - bool match = false; - while (*ap) - { - if (*s == *ap) - { - match = true; - break; - } - ap++; - } - if (!match) return s - str; - s++; - } - return s - str; - } - - char* strpbrk(const char* a, const char* b) - { - while (*a) - { - if (strchr(b, *a)) return const_cast(a); - a++; - } - return NULL; - } - - char* strcat(char* dest, const char* src) - { - size_t dest_len = strlen(dest); - size_t i; - - for (i = 0; *(src + i); i++) *(dest + dest_len + i) = *(src + i); - - *(dest + dest_len + i) = '\0'; - - return dest; - } - - char* strncat(char* dest, const char* src, size_t max) - { - size_t dest_len = strlen(dest); - size_t i; - - for (i = 0; i < max && *(src + i); i++) *(dest + dest_len + i) = *(src + i); - - *(dest + dest_len + i) = '\0'; - - return dest; - } - - char* strchr(const char* str, int c) - { - while (*str && *str != (char)c) str++; - if (*str) return const_cast(str); - return NULL; - } - - char* strchrnul(const char* str, int c) - { - while (*str && *str != (char)c) str++; - return const_cast(str); - } - - char* strrchr(const char* str, int c) - { - const char* s = str + strlen(str); - while (s != str && *s != (char)c) s--; - if (s != str) return const_cast(s); - if (*s == (char)c) return const_cast(s); - return NULL; - } - - char* strstr(const char* haystack, const char* needle) - { - size_t needle_size = strlen(needle); - size_t haystack_size = strlen(haystack); - while (*haystack) - { - if (*haystack == *needle) - { - if (needle_size <= haystack_size) - { - if (!strncmp(haystack, needle, needle_size)) return const_cast(haystack); - } - else { return NULL; } - } - haystack++; - haystack_size--; - } - return NULL; - } - -#pragma GCC push_options -#pragma GCC diagnostic ignored "-Wwrite-strings" - - char* strerror(int err) - { - switch (err) - { - case EPERM: return "Operation not permitted"; - case ENOENT: return "No such file or directory"; - case ESRCH: return "No such process"; - case EINTR: return "Interrupted system call"; - case EIO: return "Input/output error"; - case E2BIG: return "Argument list too long"; - case ENOEXEC: return "Exec format error"; - case EBADF: return "Bad file descriptor"; - case ECHILD: return "No child processes"; - case EAGAIN: return "Resource temporarily unavailable"; - case ENOMEM: return "Cannot allocate memory"; - case EACCES: return "Permission denied"; - case EFAULT: return "Bad address"; - case EEXIST: return "File exists"; - case ENOTDIR: return "Not a directory"; - case EISDIR: return "Is a directory"; - case EINVAL: return "Invalid argument"; - case EMFILE: return "Too many open files"; - case ENOTTY: return "Inappropriate ioctl for device"; - case EFBIG: return "File too large"; - case ENOSPC: return "No space left on device"; - case EPIPE: return "Broken pipe"; - case EDOM: return "Numerical argument out of domain"; - case ERANGE: return "Numerical result out of range"; - case ENOSYS: return "Function not implemented"; - case ENOTSUP: return "Operation not supported"; - case 0: return "Success"; - default: return "Unknown error"; - } - } - -#pragma GCC pop_options - - char* strtok(char*, const char*) - { - NOT_IMPLEMENTED("strtok"); - } -} \ No newline at end of file diff --git a/libs/libc/src/strings.cpp b/libs/libc/src/strings.cpp deleted file mode 100644 index b8f436e5..00000000 --- a/libs/libc/src/strings.cpp +++ /dev/null @@ -1,43 +0,0 @@ -#include -#include -#include - -static char lowercase(char c) -{ - if (isalpha(c)) return (char)tolower(c); - return c; -} - -extern "C" -{ - void bzero(void* buf, size_t n) - { - memset(buf, 0, n); - } - - void bcopy(void* dest, const void* src, size_t n) - { - memcpy(dest, src, n); - } - - int strcasecmp(const char* a, const char* b) - { - while (*a && (lowercase(*a) == lowercase(*b))) - { - a++; - b++; - } - return (unsigned char)lowercase(*a) - (unsigned char)lowercase(*b); - } - - int strncasecmp(const char* a, const char* b, size_t max) - { - const char* base = a; - while (*a && (lowercase(*a) == lowercase(*b)) && (size_t)(a - base) < (max - 1)) - { - a++; - b++; - } - return (unsigned char)lowercase(*a) - (unsigned char)lowercase(*b); - } -} \ No newline at end of file diff --git a/libs/libc/src/sys/ioctl.cpp b/libs/libc/src/sys/ioctl.cpp deleted file mode 100644 index 053fb7e6..00000000 --- a/libs/libc/src/sys/ioctl.cpp +++ /dev/null @@ -1,17 +0,0 @@ -#include -#include -#include -#include -#include - -extern "C" -{ - int ioctl(int fd, int cmd, ...) - { - va_list ap; - va_start(ap, cmd); - long result = __lc_fast_syscall3(SYS_ioctl, fd, cmd, va_arg(ap, uintptr_t)); - va_end(ap); - return (int)result; - } -} \ No newline at end of file diff --git a/libs/libc/src/sys/mman.cpp b/libs/libc/src/sys/mman.cpp deleted file mode 100644 index 3a5b6b1a..00000000 --- a/libs/libc/src/sys/mman.cpp +++ /dev/null @@ -1,24 +0,0 @@ -#include -#include -#include - -extern "C" -{ - // FIXME: Implement a POSIX-compliant mmap. - void* mmap(void* addr, size_t len, int prot, int flags, int fd, off_t offset) - { - long result = __luna_syscall5(SYS_mmap, (sysarg_t)addr, (sysarg_t)len, (sysarg_t)prot, - flags & MAP_ANONYMOUS ? (sysarg_t)-1 : (sysarg_t)fd, (sysarg_t)offset); - _RETURN_WITH_MEMORY_ERRNO(result, void*); - } - - int munmap(void* addr, size_t len) - { - return (int)__lc_fast_syscall2(SYS_munmap, addr, len); - } - - int mprotect(void* addr, size_t size, int prot) - { - return (int)__lc_fast_syscall3(SYS_mprotect, addr, size, prot); - } -} \ No newline at end of file diff --git a/libs/libc/src/sys/stat.cpp b/libs/libc/src/sys/stat.cpp deleted file mode 100644 index f2820101..00000000 --- a/libs/libc/src/sys/stat.cpp +++ /dev/null @@ -1,37 +0,0 @@ -#include -#include -#include -#include - -extern "C" -{ - int mkdir(const char* pathname, mode_t mode) - { - return (int)__lc_fast_syscall2(SYS_mkdir, pathname, mode); - } - - int fstat(int fd, struct stat* buf) - { - return (int)__lc_fast_syscall2(SYS_fstat, fd, buf); - } - - int stat(const char* path, struct stat* buf) - { - return (int)__lc_fast_syscall2(SYS_stat, path, buf); - } - - mode_t umask(mode_t cmask) - { - return (mode_t)__lc_fast_syscall1(SYS_umask, cmask); - } - - int chmod(const char*, mode_t) - { - NOT_IMPLEMENTED("chmod"); - } - - int fchmod(int, mode_t) - { - NOT_IMPLEMENTED("fchmod"); - } -} \ No newline at end of file diff --git a/libs/libc/src/sys/wait.cpp b/libs/libc/src/sys/wait.cpp deleted file mode 100644 index ca9e524e..00000000 --- a/libs/libc/src/sys/wait.cpp +++ /dev/null @@ -1,16 +0,0 @@ -#include -#include -#include - -extern "C" -{ - pid_t waitpid(pid_t pid, int* wstatus, int options) - { - return __lc_fast_syscall3(SYS_waitpid, pid, wstatus, options); - } - - pid_t wait(int* wstatus) - { - return waitpid(-1, wstatus, 0); - } -} \ No newline at end of file diff --git a/libs/libc/src/syscall.cpp b/libs/libc/src/syscall.cpp deleted file mode 100644 index bad85517..00000000 --- a/libs/libc/src/syscall.cpp +++ /dev/null @@ -1,69 +0,0 @@ -#include -#include -#include -#include -#include - -extern "C" long syscall(long number, ...) -{ - typedef unsigned long arg; - long result; - va_list ap; - va_start(ap, number); - switch (number) - { - case SYS_yield: - case SYS_fork: result = __luna_syscall0(number); break; - case SYS_exit: - case SYS_getprocid: - case SYS_close: - case SYS_umask: - case SYS_setuid: - case SYS_setgid: - case SYS_seteuid: - case SYS_setegid: - case SYS_sleep: result = __luna_syscall1(number, va_arg(ap, arg)); break; - case SYS_munmap: - case SYS_execv: - case SYS_access: - case SYS_fstat: - case SYS_stat: - case SYS_mkdir: - case SYS_dup2: - case SYS_clock_gettime: - case SYS_pstat: { - arg arg0 = va_arg(ap, arg); - arg arg1 = va_arg(ap, arg); - result = __luna_syscall2(number, arg0, arg1); - break; - } - case SYS_open: - case SYS_getdents: - case SYS_fcntl: - case SYS_seek: - case SYS_write: - case SYS_read: - case SYS_ioctl: - case SYS_mprotect: - case SYS_waitpid: { - arg arg0 = va_arg(ap, arg); - arg arg1 = va_arg(ap, arg); - arg arg2 = va_arg(ap, arg); - result = __luna_syscall3(number, arg0, arg1, arg2); - break; - } - case SYS_mmap: { - arg arg0 = va_arg(ap, arg); - arg arg1 = va_arg(ap, arg); - arg arg2 = va_arg(ap, arg); - arg arg3 = va_arg(ap, arg); - arg arg4 = va_arg(ap, arg); - result = __luna_syscall5(number, arg0, arg1, arg2, arg3, arg4); - break; - } - default: result = -ENOSYS; break; - } - va_end(ap); - if (number == SYS_mmap) { _RETURN_WITH_MEMORY_ERRNO(result, long int); } - else { _RETURN_WITH_ERRNO(result, long); } -} \ No newline at end of file diff --git a/libs/libc/src/time.cpp b/libs/libc/src/time.cpp deleted file mode 100644 index f6516871..00000000 --- a/libs/libc/src/time.cpp +++ /dev/null @@ -1,183 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include - -#define SECONDS_PER_DAY 86400 - -static int isleap(int year) -{ - return year % 4 == 0 && (year % 100 != 0 || year % 400 == 0); -} - -static int make_yday(int year, int month) -{ - static const short int upto[12] = {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334}; - int yd; - - yd = upto[month - 1]; - if (month > 2 && isleap(year)) yd++; - return yd; -} - -static int day_of_week(int year, int mon, int day) -{ - static int t[] = {0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4}; - year -= mon < 3; - return (year + year / 4 - year / 100 + year / 400 + t[mon - 1] + day) % 7; -} - -static time_t broken_down_to_unix(time_t year, time_t yday, time_t hour, time_t min, time_t sec) -{ - return sec + min * 60 + hour * 3600 + yday * 86400 + (year - 70) * 31536000 + ((year - 69) / 4) * 86400 - - ((year - 1) / 100) * 86400 + ((year + 299) / 400) * 86400; -} - -static void time_to_struct_tm(time_t time, struct tm* result) -{ - result->tm_isdst = 0; // No DST/timezone support for now. - - int year = 1970; - - while (time > 0) - { - time_t seconds_in_year = (isleap(year) ? 366 : 365) * SECONDS_PER_DAY; - if (seconds_in_year <= time) - { - year++; - time -= seconds_in_year; - continue; - } - break; - } - - int month_days[] = {31, isleap(year) ? 29 : 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; - - int month = 0; - - while (1) - { - time_t seconds_in_month = month_days[month] * SECONDS_PER_DAY; - if (seconds_in_month <= time) - { - month++; - time -= seconds_in_month; - continue; - } - break; - } - - int day = (int)(time / SECONDS_PER_DAY); - time %= SECONDS_PER_DAY; - - assert(day < month_days[month]); - - int hour = (int)(time / 3600); - time %= 3600; - - int min = (int)(time / 60); - time %= 60; - - result->tm_year = year - 1900; - result->tm_mon = month + 1; - result->tm_yday = make_yday(year, month + 1) + day; - result->tm_wday = day_of_week(year, month + 1, day + 1); - result->tm_mday = day + 1; - result->tm_hour = hour; - result->tm_min = min; - result->tm_sec = (int)time; -} - -const char* wday_names[] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"}; -const char* month_names[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}; - -extern "C" -{ - clock_t clock() - { - struct timespec tp; - clock_gettime(CLOCK_PROCTIME, &tp); - return (tp.tv_sec * CLOCKS_PER_SEC) + (tp.tv_nsec / 1000); - } - - time_t time(time_t* tloc) - { - struct timespec tp; - clock_gettime(CLOCK_REALTIME, &tp); - if (tloc) { *tloc = tp.tv_sec; } - return tp.tv_sec; - } - - int clock_gettime(clockid_t clock_id, struct timespec* tp) - { - return (int)__lc_fast_syscall2(SYS_clock_gettime, clock_id, tp); - } - - int gettimeofday(struct timeval* tp, __lc_unused void* tzp) - { - struct timespec tspec; - clock_gettime(CLOCK_REALTIME, &tspec); - tp->tv_sec = tspec.tv_sec; - tp->tv_usec = tspec.tv_nsec / 1000; - return 0; - } - - struct tm* localtime(const time_t* time) - { - static struct tm result; - return localtime_r(time, &result); - } - - struct tm* gmtime(const time_t* time) - { - static struct tm result; - return gmtime_r(time, &result); - } - - struct tm* localtime_r(const time_t* time, struct tm* result) - { - return gmtime_r(time, result); // FIXME: Implement timezones. - } - - struct tm* gmtime_r(const time_t* time, struct tm* result) - { - time_to_struct_tm(*time, result); - return result; - } - - char* asctime_r(const struct tm* time, char buf[26]) - { - strftime(buf, 26, "%a %b %d %H:%M:%S %Y\n", time); - return buf; - } - - char* asctime(const struct tm* time) - { - static char buf[26]; - return asctime_r(time, buf); - } - - char* ctime_r(const time_t* time, char buf[26]) - { - struct tm stm; - return asctime_r(localtime_r(time, &stm), buf); - } - - char* ctime(const time_t* time) - { - return asctime(localtime(time)); - } - - time_t mktime(struct tm* time) - { - return broken_down_to_unix(time->tm_year, time->tm_yday, time->tm_hour, time->tm_min, time->tm_sec); - } - - double difftime(time_t time2, time_t time1) - { - return (double)(time2 - time1); - } -} \ No newline at end of file diff --git a/libs/libc/src/unistd.cpp b/libs/libc/src/unistd.cpp deleted file mode 100644 index 29ec9fed..00000000 --- a/libs/libc/src/unistd.cpp +++ /dev/null @@ -1,180 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include - -extern "C" -{ - int execv(const char* program, char* const argv[]) - { - return (int)__lc_fast_syscall2(SYS_execv, program, argv); - } - - int execve(const char*, char* const[], char* const[]) - { - NOT_IMPLEMENTED("execve"); - } - int execvp(const char*, char* const[]) - { - NOT_IMPLEMENTED("execvp"); - } - - pid_t fork(void) - { - return __lc_fast_syscall0(SYS_fork); - } - - pid_t getpid(void) - { - return getprocid(ID_PID); - } - - pid_t getppid(void) - { - return getprocid(ID_PPID); - } - - uid_t getuid(void) - { - return (uid_t)getprocid(ID_UID); - } - - uid_t geteuid(void) - { - return (uid_t)getprocid(ID_EUID); - } - - gid_t getgid(void) - { - return (gid_t)getprocid(ID_GID); - } - - gid_t getegid(void) - { - return (gid_t)getprocid(ID_EGID); - } - - int setuid(uid_t uid) - { - return (int)__lc_fast_syscall1(SYS_setuid, uid); - } - - int seteuid(uid_t euid) - { - return (int)__lc_fast_syscall1(SYS_seteuid, euid); - } - - int setgid(gid_t gid) - { - return (int)__lc_fast_syscall1(SYS_setgid, gid); - } - - int setegid(gid_t egid) - { - return (int)__lc_fast_syscall1(SYS_setegid, egid); - } - - unsigned int sleep(unsigned int seconds) - { - return msleep(seconds * 1000); - } - - ssize_t read(int fd, void* buf, size_t count) - { - return __lc_fast_syscall3(SYS_read, fd, count, buf); // yes, our read() syscall is in the wrong order. - } - - ssize_t write(int fd, const void* buf, size_t count) - { - return __lc_fast_syscall3(SYS_write, fd, count, buf); // yes, our write() syscall is in the wrong order. - } - - int close(int fd) - { - return (int)__lc_fast_syscall1(SYS_close, fd); - } - - off_t lseek(int fd, off_t offset, int whence) - { - return __lc_fast_syscall3(SYS_seek, fd, offset, whence); - } - - __lc_noreturn void _exit(int status) - { - __lc_fast_syscall1(SYS_exit, status); - __lc_unreachable(); - } - - int dup(int fd) - { - return fcntl(fd, F_DUPFD, 0); - } - - int dup2(int fd, int fd2) - { - return (int)__lc_fast_syscall2(SYS_dup2, fd, fd2); - } - - int access(const char* path, int amode) - { - return (int)__lc_fast_syscall2(SYS_access, path, amode); - } - - int isatty(int fd) - { - int result = fcntl(fd, F_ISTTY); - if (result < 0) return 0; - return 1; - } - - char* getcwd(char* buf, size_t size) - { - const char* dummy_cwd = "/"; // FIXME: Actually retrieve the current working directory from the kernel. - if (size < 2) - { - errno = ERANGE; - return NULL; - } - if (!buf) { buf = (char*)malloc(size); } - strlcpy(buf, dummy_cwd, 2); - return buf; - } - - int unlink(const char*) - { - NOT_IMPLEMENTED("unlink"); - } - - int rmdir(const char*) - { - NOT_IMPLEMENTED("rmdir"); - } - - int chdir(const char*) - { - NOT_IMPLEMENTED("chdir"); - } - - int pipe(int[2]) - { - NOT_IMPLEMENTED("pipe"); - } - - long pathconf(const char* path, int name) - { - switch (name) - { - case _PC_PATH_MAX: return PATH_MAX - (strlen(path) + 1); - default: errno = EINVAL; return -1; - } - } - - int getdtablesize(void) - { - return OPEN_MAX; - } -} \ No newline at end of file diff --git a/libs/libc/src/utime.cpp b/libs/libc/src/utime.cpp deleted file mode 100644 index b3ffb991..00000000 --- a/libs/libc/src/utime.cpp +++ /dev/null @@ -1,10 +0,0 @@ -#include -#include - -extern "C" -{ - int utime(const char*, const struct utimbuf*) - { - NOT_IMPLEMENTED("utime"); - } -} \ No newline at end of file diff --git a/libs/libc/src/wchar.cpp b/libs/libc/src/wchar.cpp deleted file mode 100644 index 50d32df9..00000000 --- a/libs/libc/src/wchar.cpp +++ /dev/null @@ -1,24 +0,0 @@ -#include - -extern "C" -{ - size_t wcslen(const wchar_t* str) - { - const wchar_t* i = str; - for (; *i; ++i) - ; - return (i - str); - } - - wchar_t* wcscat(wchar_t* dest, const wchar_t* src) - { - size_t dest_len = wcslen(dest); - size_t i; - - for (i = 0; *(src + i); i++) *(dest + dest_len + i) = *(src + i); - - *(dest + dest_len + i) = L'\0'; - - return dest; - } -} \ No newline at end of file diff --git a/luna/Types.h b/luna/Types.h new file mode 100644 index 00000000..d2dc477b --- /dev/null +++ b/luna/Types.h @@ -0,0 +1,10 @@ +#include + +typedef uint8_t u8; +typedef uint16_t u16; +typedef uint32_t u32; +typedef uint64_t u64; +typedef int8_t i8; +typedef int16_t i16; +typedef int32_t i32; +typedef int64_t i64; \ No newline at end of file diff --git a/ports/add-port.sh b/ports/add-port.sh deleted file mode 100755 index 222931ac..00000000 --- a/ports/add-port.sh +++ /dev/null @@ -1,140 +0,0 @@ -#!/usr/bin/env bash - -set -e - -cd $(dirname $0)/.. - -unset LUNA_BASE - -source tools/env.sh - -cd ports - -unset pkgname -unset pkgver -unset pkgurl -unset pkgmode -unset setupdir -unset builddir -unset installdir -unset srcdir -unset port_unpack -unset port_patch -unset port_configure -unset port_build -unset port_install -unset port_uninstall - -export DESTDIR=${DESTDIR:-"$LUNA_ROOT/initrd"} - -export listdir=$PWD - -if [ -z $1 ] -then - echo "Usage: add-port.sh " - exit 1 -fi - -if [ -d $1 ] -then - pkgscript=$1/package.sh -elif [ -f $1 ] -then - pkgscript=$1 -else - echo "Unrecognized argument: $1" - exit 1 -fi - -export portdir=$(realpath $(dirname $pkgscript)) -export workdir=$portdir/workdir -mkdir -p $workdir - -source $pkgscript - -if ! [ -z ${pkgdeps+x} ] -then - echo "Installing dependencies of $pkgname..." - for pkg in ${pkgdeps[@]} - do - set +e - grep $pkg ports.list >/dev/null - if [ "$?" = "0" ] - then - echo "Dependency $pkg is already installed." - else - echo "Installing dependency $pkg..." - ./add-port.sh $pkg - fi - set -e - done -fi - -echo "Building $pkgname version $pkgver..." - -cd $workdir - -if ! [ -d $srcdir ] -then - mkdir -p $setupdir - cd $setupdir - - echo "Downloading $pkgname version $pkgver..." - - case $pkgmode in - "web") wget $pkgurl;; - "git") git clone $pkgurl;; - *) echo "Don't know how to download package mode '$pkgmode'"; exit 1;; - esac - - set +e - command -v port_unpack >/dev/null - set -e - if [ "$?" = "0" ] - then - echo "Unpacking $pkgname version $pkgver..." - port_unpack | filter-lines $pkgname "unpack" - fi - - set +e - command -v port_patch >/dev/null - set -e - if [ "$?" = "0" ] - then - echo "Patching $pkgname version $pkgver..." - port_patch | filter-lines $pkgname "patch" - fi -fi - -cd $workdir - -mkdir -p $builddir -cd $builddir - -set +e -command -v port_configure >/dev/null -set -e -if [ "$?" = "0" ] -then - echo "Configuring $pkgname version $pkgver..." - port_configure | filter-lines $pkgname "configure" -fi - -echo "Making $pkgname version $pkgver..." -port_build | filter-lines $pkgname "build" # this one is required - -cd $workdir - -mkdir -p $installdir -cd $installdir - -echo "Installing $pkgname version $pkgver..." -port_install | filter-lines $pkgname "install" - -if ! [ "$SKIP_ADD_TO_PORTS_LIST" = "1" ] -then - echo "$pkgname" >> $listdir/ports.list - cat $listdir/ports.list | sort | uniq | tee $listdir/ports.list >/dev/null # avoid duplicates - - echo "Success! Registered port: $pkgname version $pkgver." -fi \ No newline at end of file diff --git a/ports/bc/bc.patch b/ports/bc/bc.patch deleted file mode 100644 index a4a4ffdc..00000000 --- a/ports/bc/bc.patch +++ /dev/null @@ -1,60 +0,0 @@ -diff --color -rN -u bc-vanilla/include/library.h bc-6.0.4/include/library.h ---- a/bc-6.0.4/include/library.h 2022-09-26 19:34:34.000000000 +0200 -+++ b/bc-6.0.4/include/library.h 2022-10-15 14:59:11.413415573 +0200 -@@ -36,7 +36,7 @@ - #ifndef LIBBC_PRIVATE_H - #define LIBBC_PRIVATE_H - --#ifndef _WIN32 -+#if !defined(_WIN32) && !defined(__luna__) - - #include - -@@ -236,13 +236,17 @@ - BcVm* - bcl_getspecific(void); - --#ifndef _WIN32 -+#if !defined(_WIN32) && !defined(__luna__) - - typedef pthread_key_t BclTls; - - #else // _WIN32 - -+#ifdef __luna__ -+typedef int BclTls; -+#else - typedef DWORD BclTls; -+#endif - - #endif // _WIN32 - -diff --color -rN -u bc-vanilla/src/vm.c bc-6.0.4/src/vm.c ---- a/bc-6.0.4/src/vm.c 2022-09-26 19:34:35.000000000 +0200 -+++ b/bc-6.0.4/src/vm.c 2022-10-21 17:29:13.511229371 +0200 -@@ -193,7 +193,7 @@ - static void - bc_vm_sigaction(void) - { --#ifndef _WIN32 -+#if !defined(_WIN32) && !defined(__luna__) - - struct sigaction sa; - -@@ -223,11 +223,15 @@ - if (BC_TTY) sigaction(SIGHUP, &sa, NULL); - #endif // BC_ENABLE_HISTORY - --#else // _WIN32 -+#else -+ -+#ifndef __luna__ - - signal(SIGTERM, bc_vm_sig); - signal(SIGINT, bc_vm_sig); - -+#endif -+ - #endif // _WIN32 - } - diff --git a/ports/bc/package.sh b/ports/bc/package.sh deleted file mode 100644 index a307fd32..00000000 --- a/ports/bc/package.sh +++ /dev/null @@ -1,40 +0,0 @@ -pkgname="bc" -pkgver="6.0.4" -pkgurl="https://github.com/gavinhoward/bc/releases/download/$pkgver/bc-$pkgver.tar.gz" - -pkgmode="web" - -setupdir="$workdir" -builddir="$workdir/build" -installdir="$workdir/build" -srcdir="$workdir/bc-$pkgver" - -port_unpack() -{ - tar xvf bc-$pkgver.tar.gz -} - -port_patch() -{ - patch -u -i $portdir/bc.patch -p 1 -d $workdir -} - -port_configure() -{ - HOSTCC=gcc PREFIX=${PREFIX:-""} $srcdir/configure --disable-nls --bc-only --disable-history --disable-man-pages -} - -port_build() -{ - make -j$(nproc) -} - -port_install() -{ - make install -} - -port_uninstall() -{ - make uninstall -} \ No newline at end of file diff --git a/ports/binutils/binutils.patch b/ports/binutils/binutils.patch deleted file mode 100644 index 6c8e94a6..00000000 --- a/ports/binutils/binutils.patch +++ /dev/null @@ -1,144 +0,0 @@ -diff --color -rN -u binutils-2.38/bfd/config.bfd binutils-2.38/bfd/config.bfd ---- a/binutils-2.38/bfd/config.bfd 2022-01-22 13:14:07.000000000 +0100 -+++ b/binutils-2.38/bfd/config.bfd 2022-11-09 16:09:46.143869977 +0100 -@@ -651,6 +651,11 @@ - targ_selvecs="iamcu_elf32_vec i386_pei_vec" - targ64_selvecs="x86_64_elf64_vec x86_64_elf32_vec x86_64_pe_vec x86_64_pei_vec l1om_elf64_vec k1om_elf64_vec" - ;; -+ i[3-7]86-*-luna*) -+ targ_defvec=i386_elf32_vec -+ targ_selvecs= -+ targ64_selvecs=x86_64_elf64_vec -+ ;; - i[3-7]86-*-redox*) - targ_defvec=i386_elf32_vec - targ_selvecs= -@@ -706,6 +711,11 @@ - targ_selvecs="i386_elf32_vec iamcu_elf32_vec x86_64_elf32_vec i386_pei_vec x86_64_pe_vec x86_64_pei_vec l1om_elf64_vec k1om_elf64_vec" - want64=true - ;; -+ x86_64-*-luna*) -+ targ_defvec=x86_64_elf64_vec -+ targ_selvecs=i386_elf32_vec -+ want64=true -+ ;; - x86_64-*-mingw* | x86_64-*-pe | x86_64-*-pep | x86_64-*-cygwin) - targ_defvec=x86_64_pe_vec - targ_selvecs="x86_64_pe_vec x86_64_pei_vec x86_64_pe_big_vec x86_64_elf64_vec l1om_elf64_vec k1om_elf64_vec i386_pe_vec i386_pei_vec i386_elf32_vec iamcu_elf32_vec" -diff --color -rN -u binutils-2.38/gas/configure.tgt binutils-2.38/gas/configure.tgt ---- a/binutils-2.38/gas/configure.tgt 2022-01-22 13:14:08.000000000 +0100 -+++ b/binutils-2.38/gas/configure.tgt 2022-11-09 16:09:46.144869977 +0100 -@@ -238,6 +238,7 @@ - x86_64*-linux-gnux32) arch=x86_64:32 ;; - esac ;; - i386-*-lynxos*) fmt=elf em=lynx ;; -+ i386-*-luna*) fmt=elf em=gnu ;; - i386-*-redox*) fmt=elf ;; - i386-*-solaris*) fmt=elf em=solaris ;; - i386-*-freebsd* \ -diff --color -rN -u binutils-2.38/gas/messages.c binutils-2.38/gas/messages.c ---- a/binutils-2.38/gas/messages.c 2022-01-22 13:14:08.000000000 +0100 -+++ b/binutils-2.38/gas/messages.c 2022-11-09 16:26:03.275802078 +0100 -@@ -324,7 +324,9 @@ - signal_crash (int signo) - { - /* Reset, to prevent unbounded recursion. */ -+#ifndef __luna__ - signal (signo, SIG_DFL); -+#endif - - as_abort (NULL, 0, strsignal (signo)); - } -diff --color -rN -u binutils-2.38/ld/configure.tgt binutils-2.38/ld/configure.tgt ---- a/binutils-2.38/ld/configure.tgt 2022-01-22 15:19:36.000000000 +0100 -+++ b/binutils-2.38/ld/configure.tgt 2022-11-09 16:09:46.145869977 +0100 -@@ -329,6 +329,11 @@ - targ64_extra_emuls="elf_x86_64 elf32_x86_64 elf_l1om elf_k1om" - targ64_extra_libpath="elf_x86_64 elf32_x86_64" - ;; -+i[3-7]86-*-luna*) -+ targ_emul=elf_i386_luna -+ targ_extra_emuls=elf_i386 -+ targ64_extra_emuls="elf_x86_64_luna elf_x86_64" -+ ;; - i[3-7]86-*-redox*) targ_emul=elf_i386 - targ_extra_emuls=elf_x86_64 - ;; -@@ -967,6 +972,10 @@ - targ_extra_libpath="elf_i386 elf32_x86_64 elf_l1om elf_k1om" - tdir_elf_i386=`echo ${targ_alias} | sed -e 's/x86_64/i386/'` - ;; -+x86_64-*-luna*) -+ targ_emul=elf_x86_64_luna -+ targ_extra_emuls="elf_i386_luna elf_x86_64 elf_i386" -+ ;; - x86_64-*-redox*) targ_emul=elf_x86_64 - targ_extra_emuls=elf_i386 - ;; -diff --color -rN -u binutils-2.38/ld/emulparams/elf_i386_luna.sh binutils-2.38/ld/emulparams/elf_i386_luna.sh ---- a/binutils-2.38/ld/emulparams/elf_i386_luna.sh 1970-01-01 01:00:00.000000000 +0100 -+++ b/binutils-2.38/ld/emulparams/elf_i386_luna.sh 2022-11-09 16:09:46.145869977 +0100 -@@ -0,0 +1,3 @@ -+source_sh ${srcdir}/emulparams/elf_i386.sh -+TEXT_START_ADDR=0x08000000 -+MAXPAGESIZE=0x1000 -\ No newline at end of file -diff --color -rN -u binutils-2.38/ld/emulparams/elf_x86_64_luna.sh binutils-2.38/ld/emulparams/elf_x86_64_luna.sh ---- a/binutils-2.38/ld/emulparams/elf_x86_64_luna.sh 1970-01-01 01:00:00.000000000 +0100 -+++ b/binutils-2.38/ld/emulparams/elf_x86_64_luna.sh 2022-11-09 16:09:46.145869977 +0100 -@@ -0,0 +1,2 @@ -+source_sh ${srcdir}/emulparams/elf_x86_64.sh -+MAXPAGESIZE=0x1000 -\ No newline at end of file -diff --color -rN -u binutils-2.38/ld/Makefile.am binutils-2.38/ld/Makefile.am ---- a/binutils-2.38/ld/Makefile.am 2022-01-22 13:14:09.000000000 +0100 -+++ b/binutils-2.38/ld/Makefile.am 2022-11-09 16:09:46.145869977 +0100 -@@ -278,6 +278,7 @@ - eelf32xtensa.c \ - eelf32z80.c \ - eelf_i386.c \ -+ eelf_i386_luna.c \ - eelf_i386_be.c \ - eelf_i386_fbsd.c \ - eelf_i386_haiku.c \ -@@ -464,6 +465,7 @@ - eelf_x86_64_fbsd.c \ - eelf_x86_64_haiku.c \ - eelf_x86_64_sol2.c \ -+ eelf_x86_64_luna.c \ - ehppa64linux.c \ - ei386pep.c \ - emmo.c -diff --color -rN -u binutils-2.38/ld/Makefile.in binutils-2.38/ld/Makefile.in ---- a/binutils-2.38/ld/Makefile.in 2022-02-09 12:49:03.000000000 +0100 -+++ b/binutils-2.38/ld/Makefile.in 2022-11-09 16:09:46.146869977 +0100 -@@ -769,6 +769,7 @@ - eelf32xtensa.c \ - eelf32z80.c \ - eelf_i386.c \ -+ eelf_i386_luna.c \ - eelf_i386_be.c \ - eelf_i386_fbsd.c \ - eelf_i386_haiku.c \ -@@ -954,6 +955,7 @@ - eelf_x86_64_fbsd.c \ - eelf_x86_64_haiku.c \ - eelf_x86_64_sol2.c \ -+ eelf_x86_64_luna.c \ - ehppa64linux.c \ - ei386pep.c \ - emmo.c -diff --color -rN -u binutils-2.38/libiberty/pex-unix.c binutils-2.38/libiberty/pex-unix.c ---- a/binutils-2.38/libiberty/pex-unix.c 2022-01-22 13:14:09.000000000 +0100 -+++ b/binutils-2.38/libiberty/pex-unix.c 2022-11-09 16:25:21.767804963 +0100 -@@ -773,8 +773,10 @@ - { - /* If we are cleaning up when the caller didn't retrieve process - status for some reason, encourage the process to go away. */ -+#ifndef __luna__ - if (done) - kill (pid, SIGTERM); -+#endif - - if (pex_wait (obj, pid, status, time) < 0) - { diff --git a/ports/binutils/package.sh b/ports/binutils/package.sh deleted file mode 100644 index e712b772..00000000 --- a/ports/binutils/package.sh +++ /dev/null @@ -1,48 +0,0 @@ -pkgname="binutils" -pkgver="2.38" -pkgurl="https://ftp.gnu.org/gnu/binutils/binutils-$pkgver.tar.xz" - -pkgmode="web" - -pkgdeps=('gmp' 'mpfr' 'mpc') - -setupdir="$workdir" -builddir="$workdir/build" -installdir="$workdir/build" -srcdir="$workdir/binutils-$pkgver" - -port_unpack() -{ - tar xvf binutils-$pkgver.tar.xz -} - -port_patch() -{ - patch -u -i $portdir/binutils.patch -p 1 -d $workdir -} - -port_configure() -{ - CFLAGS="-ffunction-sections -fdata-sections" LDFLAGS="-Wl,--gc-sections" $srcdir/configure --target=x86_64-luna --prefix="" --disable-werror --disable-nls --disable-dependency-tracking --with-build-sysroot=$LUNA_ROOT/base --host=x86_64-luna -} - -port_build() -{ - make -j$(nproc) -} - -port_install() -{ - make install-strip-binutils - rm -rf $DESTDIR/include/ - rm -rf $DESTDIR/lib/ - rm -rf $DESTDIR/share/ - rm -rf $DESTDIR/x86_64-luna/ - # keep only a few binaries since we only use an initial ramdisk for now, which doesn't like having many of these large binaries - rm -f $DESTDIR/bin/{ar,as,elfedit,gprof,ld,ld.bfd,objcopy,ranlib,strip} -} - -port_uninstall() -{ - rm -f $DESTDIR/bin/{addr2line,c++filt,nm,objdump,readelf,size,strings} -} \ No newline at end of file diff --git a/ports/gmp/gmp.patch b/ports/gmp/gmp.patch deleted file mode 100644 index ab6934dd..00000000 --- a/ports/gmp/gmp.patch +++ /dev/null @@ -1,11 +0,0 @@ -diff --color -rN -u gmp-vanilla/invalid.c gmp-6.2.1/invalid.c ---- a/gmp-6.2.1/invalid.c 2020-11-14 19:45:09.000000000 +0100 -+++ b/gmp-6.2.1/invalid.c 2022-10-26 21:09:20.102237128 +0200 -@@ -77,6 +77,6 @@ - void - __gmp_invalid_operation (void) - { -- raise (SIGFPE); -+// raise (SIGFPE); - abort (); - } diff --git a/ports/gmp/package.sh b/ports/gmp/package.sh deleted file mode 100644 index d8fde85b..00000000 --- a/ports/gmp/package.sh +++ /dev/null @@ -1,44 +0,0 @@ -pkgname="gmp" -pkgver="6.2.1" -pkgurl="https://ftp.gnu.org/gnu/gmp/gmp-$pkgver.tar.xz" - -pkgmode="web" - -islib=1 - -setupdir="$workdir" -builddir="$workdir/build" -installdir="$workdir/build" -srcdir="$workdir/gmp-$pkgver" - -port_unpack() -{ - tar xvf gmp-$pkgver.tar.xz -} - -port_patch() -{ - patch -u -i $portdir/gmp.patch -p 1 -d $workdir -} - -port_configure() -{ - CC_FOR_BUILD=gcc $srcdir/configure --enable-shared=no --with-gnu-ld --host=x86_64-luna --prefix=/usr -} - -port_build() -{ - make -j$(nproc) -} - -port_install() -{ - make DESTDIR=$LUNA_BASE install - rm -f $LUNA_BASE/usr/lib/*.la -} - -port_uninstall() -{ - make DESTDIR=$LUNA_BASE uninstall - rm -f $LUNA_BASE/usr/lib/libgmp.a -} \ No newline at end of file diff --git a/ports/list-ports.sh b/ports/list-ports.sh deleted file mode 100755 index d812c1fe..00000000 --- a/ports/list-ports.sh +++ /dev/null @@ -1,56 +0,0 @@ -#!/usr/bin/env bash - -set -e - -cd $(dirname $0)/.. - -source tools/env.sh - -cd ports - -unset_vars() -{ - unset pkgname - unset pkgver - unset pkgurl - unset pkgmode - unset setupdir - unset builddir - unset installdir - unset srcdir - unset port_unpack - unset port_patch - unset port_configure - unset port_build - unset port_install - unset port_uninstall -} - -if ! [ -f ./ports.list ] -then - echo "No ports installed." - exit 0 -fi - -export HAVE_PORTS=0 - -install_port() -{ - HAVE_PORTS=1 - unset_vars - cd $LUNA_ROOT/ports - export DESTDIR=${DESTDIR:-"$LUNA_ROOT/initrd"} - export portdir=$PWD/$1 - export workdir=$portdir/workdir - source $portdir/package.sh - echo "$pkgname $pkgver" -} - -while read package; do - install_port $package -done < ./ports.list - -if [ "$HAVE_PORTS" = "0" ] -then - echo "No ports installed." -fi \ No newline at end of file diff --git a/ports/make-package.sh b/ports/make-package.sh deleted file mode 100755 index 41424b89..00000000 --- a/ports/make-package.sh +++ /dev/null @@ -1,24 +0,0 @@ -#!/usr/bin/env bash - -set -e - -source $(dirname $0)/../tools/env.sh - -export DESTDIR=$PWD/pkgroot -export SKIP_ADD_TO_PORTS_LIST=1 - -source $LUNA_ROOT/ports/$1/package.sh - -mkdir pkgroot - -$LUNA_ROOT/ports/add-port.sh $pkgname - -cd pkgroot - -tar cJf ../$pkgname-$pkgver.pkg.tar.xz * - -cd - - -rm -rf pkgroot - -echo "Built package $pkgname-$pkgver.pkg.tar.xz" \ No newline at end of file diff --git a/ports/mpc/package.sh b/ports/mpc/package.sh deleted file mode 100644 index d28aaa7d..00000000 --- a/ports/mpc/package.sh +++ /dev/null @@ -1,41 +0,0 @@ -pkgname="mpc" -pkgver="1.2.1" -pkgurl="https://ftp.gnu.org/gnu/mpc/mpc-$pkgver.tar.gz" - -pkgmode="web" - -pkgdeps=('gmp' 'mpfr') - -islib=1 - -setupdir="$workdir" -builddir="$workdir/build" -installdir="$workdir/build" -srcdir="$workdir/mpc-$pkgver" - -port_unpack() -{ - tar xvf mpc-$pkgver.tar.gz -} - -port_configure() -{ - $srcdir/configure --host=x86_64-luna --with-gnu-ld --enable-shared=no --prefix=/usr -} - -port_build() -{ - make -j$(nproc) -} - -port_install() -{ - make DESTDIR=$LUNA_BASE install - rm -f $LUNA_BASE/usr/lib/*.la -} - -port_uninstall() -{ - make DESTDIR=$LUNA_BASE uninstall - rm -f $LUNA_BASE/usr/lib/libmpc.a -} \ No newline at end of file diff --git a/ports/mpfr/package.sh b/ports/mpfr/package.sh deleted file mode 100644 index b9df3d56..00000000 --- a/ports/mpfr/package.sh +++ /dev/null @@ -1,41 +0,0 @@ -pkgname="mpfr" -pkgver="4.1.0" -pkgurl="https://ftp.gnu.org/gnu/mpfr/mpfr-$pkgver.tar.gz" - -pkgmode="web" - -pkgdeps=('gmp') - -islib=1 - -setupdir="$workdir" -builddir="$workdir/build" -installdir="$workdir/build" -srcdir="$workdir/mpfr-$pkgver" - -port_unpack() -{ - tar xvf mpfr-$pkgver.tar.gz -} - -port_configure() -{ - $srcdir/configure --with-gnu-ld --host=x86_64-luna --enable-shared=no --prefix=/usr -} - -port_build() -{ - make -j$(nproc) -} - -port_install() -{ - make DESTDIR=$LUNA_BASE install - rm -f $LUNA_BASE/usr/lib/*.la -} - -port_uninstall() -{ - make DESTDIR=$LUNA_BASE uninstall - rm -f $LUNA_BASE/usr/lib/libmpfr.a -} \ No newline at end of file diff --git a/ports/nasm/nasm.patch b/ports/nasm/nasm.patch deleted file mode 100644 index 49e2d0fc..00000000 --- a/ports/nasm/nasm.patch +++ /dev/null @@ -1,13 +0,0 @@ -diff --color -rN -u nasm-vanilla/Makefile.in nasm-2.15.05/Makefile.in ---- a/nasm-2.15.05/Makefile.in 2020-08-28 18:04:43.000000000 +0200 -+++ b/nasm-2.15.05/Makefile.in 2022-10-30 18:00:40.386258721 +0100 -@@ -389,9 +389,6 @@ - $(MKDIR_P) $(DESTDIR)$(bindir) - $(INSTALL_PROGRAM) nasm$(X) $(DESTDIR)$(bindir)/nasm$(X) - $(INSTALL_PROGRAM) ndisasm$(X) $(DESTDIR)$(bindir)/ndisasm$(X) -- $(MKDIR_P) $(DESTDIR)$(mandir)/man1 -- $(INSTALL_DATA) $(srcdir)/nasm.1 $(DESTDIR)$(mandir)/man1/nasm.1 -- $(INSTALL_DATA) $(srcdir)/ndisasm.1 $(DESTDIR)$(mandir)/man1/ndisasm.1 - - clean: - for d in . $(SUBDIRS) $(XSUBDIRS); do \ diff --git a/ports/nasm/package.sh b/ports/nasm/package.sh deleted file mode 100644 index baf8787d..00000000 --- a/ports/nasm/package.sh +++ /dev/null @@ -1,41 +0,0 @@ -pkgname="nasm" -pkgver="2.15.05" -pkgurl="https://www.nasm.us/pub/nasm/releasebuilds/$pkgver/nasm-$pkgver.tar.gz" - -pkgmode="web" - -setupdir="$workdir" -builddir="$workdir/build" -installdir="$workdir/build" -srcdir="$workdir/nasm-$pkgver" - -port_unpack() -{ - tar xvf nasm-$pkgver.tar.gz -} - -port_patch() -{ - patch -u -i $portdir/nasm.patch -p 1 -d $workdir -} - -port_configure() -{ - $srcdir/configure --host=x86_64-luna --prefix="" -} - -port_build() -{ - make -j$(nproc) -} - -port_install() -{ - make install - $STRIP $DESTDIR/bin/{nasm,ndisasm} -} - -port_uninstall() # nasm's Makefile does not provide an uninstall target. -{ - rm -f $DESTDIR/bin/{nasm,ndisasm} -} \ No newline at end of file diff --git a/ports/remove-port.sh b/ports/remove-port.sh deleted file mode 100755 index 22cc8240..00000000 --- a/ports/remove-port.sh +++ /dev/null @@ -1,45 +0,0 @@ -#!/usr/bin/env bash - -set -e - -cd $(dirname $0)/.. - -source tools/env.sh - -cd ports - -export DESTDIR=${DESTDIR:-"$LUNA_ROOT/initrd"} -export listdir=$PWD - -if [ -z $1 ] -then - echo "Usage: remove-port.sh " - exit 1 -fi - -if [ -d $1 ] -then - pkgscript=$1/package.sh -elif [ -f $1 ] -then - pkgscript=$1 -else - echo "Unrecognized argument: $1" - exit 1 -fi - -export portdir=$(realpath $(dirname $pkgscript)) -export workdir=$portdir/workdir -mkdir -p $workdir - -source $pkgscript - -echo "Removing $pkgname version $pkgver..." - -cd $installdir -port_uninstall | filter-lines $pkgname "uninstall" - -rm -rf $workdir -cat $listdir/ports.list | grep -v $pkgname | tee $listdir/ports.list >/dev/null - -echo "Success! Removed port: $pkgname version $pkgver." \ No newline at end of file diff --git a/tests/Makefile b/tests/Makefile deleted file mode 100644 index 38f21741..00000000 --- a/tests/Makefile +++ /dev/null @@ -1,9 +0,0 @@ -build: - make -C libc build - -install: - make -C libc install - -test: - make -C libc test - \ No newline at end of file diff --git a/tests/Test.h b/tests/Test.h deleted file mode 100644 index 4836e95f..00000000 --- a/tests/Test.h +++ /dev/null @@ -1,45 +0,0 @@ -#ifndef __TEST_H_ -#define __TEST_H_ -#include - -int printf(const char*, ...); - -#define DEFINE_TEST(name) bool test_##name() -#define START_TEST(name) printf("testing whether %s works... ", #name) -#define START_TEST_CASE(name) printf("testing %s...\n", #name) - -#define TEST_SUCCESS() \ - do { \ - printf("yes!\n"); \ - return true; \ - } while (0) - -#define TEST_FAIL(expr) \ - do { \ - printf("no (%s)\n", #expr); \ - return false; \ - } while (0) - -#define TEST_NOT_SURE(expr) \ - do { \ - printf("not sure (%s)\n", #expr); \ - return true; \ - } while (0) - -#define EXPECT(expr) \ - do { \ - if (!(expr)) { TEST_FAIL(expr); } \ - } while (0) - -#define EXPECT_EQ(a, b) EXPECT((a) == (b)) - -#define EXPECT_NOT_EQ(a, b) EXPECT((a) != (b)) - -#define EXPECT_NOT_CRASHED() TEST_SUCCESS() - -#define RUN_TEST(name) \ - do { \ - if (!test_##name()) return 1; \ - } while (0) - -#endif \ No newline at end of file diff --git a/tests/libc/Makefile b/tests/libc/Makefile deleted file mode 100644 index 698044bc..00000000 --- a/tests/libc/Makefile +++ /dev/null @@ -1,15 +0,0 @@ -TESTDIR := $(LUNA_ROOT)/tests/libc -DESTDIR := $(LUNA_ROOT)/initrd/bin - -build: - @mkdir -p $(TESTDIR)/bin - $(LUNA_ROOT)/tools/sync-libc.sh - $(CC) $(TESTDIR)/string.c $(TESTDIR)/stdlib.c $(TESTDIR)/wchar.c $(TESTDIR)/Test.c -I$(LUNA_ROOT)/tests -o $(TESTDIR)/bin/test-libc -Wall -Wextra -Wno-deprecated-declarations -Wno-stringop-overread -Werror - -install: - $(LUNA_ROOT)/tools/clean.sh - @mkdir -p $(DESTDIR) - cp $(TESTDIR)/bin/test-libc $(DESTDIR)/test-libc - -test: - CFLAGS="-DRUN_TEST_AS_INIT=/bin/test-libc" $(LUNA_ROOT)/tools/run.sh \ No newline at end of file diff --git a/tests/libc/Test.c b/tests/libc/Test.c deleted file mode 100644 index afc9b17d..00000000 --- a/tests/libc/Test.c +++ /dev/null @@ -1,70 +0,0 @@ -#include "Test.h" - -// string.h -DEFINE_TEST(memset); -DEFINE_TEST(memcpy); -DEFINE_TEST(memchr); -DEFINE_TEST(memcmp); -DEFINE_TEST(memmove); -DEFINE_TEST(strlen); -DEFINE_TEST(strnlen); -DEFINE_TEST(strcmp); -DEFINE_TEST(strncmp); -DEFINE_TEST(strcspn); -DEFINE_TEST(strspn); -DEFINE_TEST(strchr); -DEFINE_TEST(strchrnul); -DEFINE_TEST(strrchr); -DEFINE_TEST(strpbrk); -DEFINE_TEST(strdup); -DEFINE_TEST(strndup); - -// stdlib.h -DEFINE_TEST(atoi); -DEFINE_TEST(atol); -DEFINE_TEST(atoll); -DEFINE_TEST(srand); -DEFINE_TEST(malloc); -DEFINE_TEST(calloc); -DEFINE_TEST(mktemp); -DEFINE_TEST(qsort); -DEFINE_TEST(bsearch); - -// wchar.h -DEFINE_TEST(wcslen); - -int main() -{ - START_TEST_CASE(string.h); - RUN_TEST(memset); - RUN_TEST(memcpy); - RUN_TEST(memchr); - RUN_TEST(memcmp); - RUN_TEST(memmove); - RUN_TEST(strlen); - RUN_TEST(strnlen); - RUN_TEST(strcmp); - RUN_TEST(strncmp); - RUN_TEST(strcspn); - RUN_TEST(strspn); - RUN_TEST(strchr); - RUN_TEST(strchrnul); - RUN_TEST(strrchr); - RUN_TEST(strpbrk); - RUN_TEST(strdup); - RUN_TEST(strndup); - - START_TEST_CASE(stdlib.h); - RUN_TEST(atoi); - RUN_TEST(atol); - RUN_TEST(atoll); - RUN_TEST(srand); - RUN_TEST(malloc); - RUN_TEST(calloc); - RUN_TEST(mktemp); - RUN_TEST(qsort); - RUN_TEST(bsearch); - - START_TEST_CASE(wchar.h); - RUN_TEST(wcslen); -} \ No newline at end of file diff --git a/tests/libc/stdlib.c b/tests/libc/stdlib.c deleted file mode 100644 index d869808c..00000000 --- a/tests/libc/stdlib.c +++ /dev/null @@ -1,234 +0,0 @@ -#include "Test.h" -#include -#include -#include - -DEFINE_TEST(atoi) -{ - START_TEST(atoi); - - const char* str = "42"; - int num = atoi(str); - - EXPECT_EQ(num, 42); - - str = "-56"; - num = atoi(str); - - EXPECT_EQ(num, -56); - - str = "Not a number"; - num = atoi(str); - - EXPECT_EQ(num, 0); - - TEST_SUCCESS(); -} - -DEFINE_TEST(atol) -{ - START_TEST(atol); - - const char* str = "42"; - long num = atol(str); - - EXPECT_EQ(num, 42); - - str = "-56"; - num = atol(str); - - EXPECT_EQ(num, -56); - - str = "Not a number"; - num = atol(str); - - EXPECT_EQ(num, 0); - - str = "68719476735"; - num = atol(str); - - EXPECT_EQ(num, 68719476735); - - TEST_SUCCESS(); -} - -DEFINE_TEST(atoll) -{ - START_TEST(atoll); - - const char* str = "42"; - long long num = atoll(str); - - EXPECT_EQ(num, 42); - - str = "-56"; - num = atoll(str); - - EXPECT_EQ(num, -56); - - str = "Not a number"; - num = atoll(str); - - EXPECT_EQ(num, 0); - - str = "68719476735"; - num = atoll(str); - - EXPECT_EQ(num, 68719476735); - - TEST_SUCCESS(); -} - -DEFINE_TEST(srand) -{ - START_TEST(srand); - - srand(5849); - - int val = rand(); - - EXPECT_EQ(val, -1731894882); - - TEST_SUCCESS(); -} - -DEFINE_TEST(malloc) -{ - START_TEST(malloc); - - int* ptr = malloc(6 * sizeof(int)); - - if (!ptr) - { - TEST_NOT_SURE(ptr); - return true; - } - - *ptr = 6; - - EXPECT_EQ(*ptr, 6); - - ptr[5] = 4; - - EXPECT_EQ(ptr[5], 4); - - free(ptr); - - TEST_SUCCESS(); -} - -DEFINE_TEST(calloc) -{ - START_TEST(calloc); - - int* ptr = calloc(6, sizeof(int)); - - if (!ptr) { TEST_NOT_SURE(ptr); } - - EXPECT_EQ(*ptr, 0); - EXPECT_EQ(ptr[5], 0); - - *ptr = 6; - - EXPECT_EQ(*ptr, 6); - - ptr[5] = 4; - - EXPECT_EQ(ptr[5], 4); - - free(ptr); - - TEST_SUCCESS(); -} - -DEFINE_TEST(mktemp) -{ - START_TEST(mktemp); - - char template[] = "/tmp/file.XXXXXX"; - - const char* template2 = "/tmp/file.XXXXXX"; - - char* ptr = mktemp(template); - - EXPECT_NOT_EQ(ptr, NULL); // mktemp only fails if we give it an invalid template. - - int rc = access(ptr, F_OK); - - EXPECT_NOT_EQ(rc, 0); // FIXME: This could actually happen, since that's why mktemp is deprecated. - // Another process could create the file between generating the name and actually using it. - - rc = strcmp(ptr, template2); - - EXPECT_NOT_EQ(rc, 0); - - TEST_SUCCESS(); -} - -static int compare_char(const void* p1, const void* p2) -{ - const char* c1 = (const char*)p1; - const char* c2 = (const char*)p2; - if (*c1 < *c2) return -1; - if (*c1 > *c2) return 1; - return 0; -} - -static int compare_int(const void* p1, const void* p2) -{ - const int* c1 = (const int*)p1; - const int* c2 = (const int*)p2; - if (*c1 < *c2) return -1; - if (*c1 > *c2) return 1; - return 0; -} - -DEFINE_TEST(qsort) -{ - START_TEST(qsort); - - char unsorted[] = "elacbkdjf"; - const char sorted[] = "abcdefjkl"; - - qsort(unsorted, 9, sizeof(char), compare_char); - - int rc = memcmp(sorted, unsorted, 9); - - EXPECT_EQ(rc, 0); - - int unsorted2[] = {1500, 45, 3, 11, 41, 90, 6, 32, 5, 76}; - const int sorted2[] = {3, 5, 6, 11, 32, 41, 45, 76, 90, 1500}; - - qsort(unsorted2, 10, sizeof(int), compare_int); - - rc = memcmp(unsorted2, sorted2, 10); - - EXPECT_EQ(rc, 0); - - TEST_SUCCESS(); -} - -DEFINE_TEST(bsearch) -{ - START_TEST(bsearch); - - const char sorted[] = "abcdefjkl"; - char key = 'j'; - - char* ptr = bsearch(&key, sorted, 9, sizeof(char), compare_char); // try with sorted array first - - EXPECT_EQ(*ptr, 'j'); - EXPECT_EQ(ptr, &sorted[6]); - - int unsorted[] = {1500, 45, 3, 11, 41, 90, 6, 32, 5, 76}; - qsort(unsorted, 10, sizeof(int), compare_int); - - int key2 = 90; - - int* ptr2 = bsearch(&key2, unsorted, 10, sizeof(int), compare_int); - - EXPECT_EQ(*ptr2, 90); - EXPECT_EQ(ptr2, &unsorted[8]); - - TEST_SUCCESS(); -} \ No newline at end of file diff --git a/tests/libc/string.c b/tests/libc/string.c deleted file mode 100644 index 30a3554e..00000000 --- a/tests/libc/string.c +++ /dev/null @@ -1,385 +0,0 @@ -#include "Test.h" -#include -#include - -DEFINE_TEST(memset) -{ - START_TEST(memset); - - char test[10]; - char* ptr = memset(test, 0, 10); - - EXPECT_EQ(ptr, test); - - for (int i = 0; i < 10; i++) { EXPECT_EQ(test[i], 0); } - - ptr = memset(test, 42, 10); - - EXPECT_EQ(ptr, test); - - for (int i = 0; i < 10; i++) { EXPECT_EQ(test[i], 42); } - - TEST_SUCCESS(); -} - -DEFINE_TEST(memcpy) -{ - START_TEST(memcpy); - - char buf[20] = "Nothing is going on"; - const char* str = "Something is going!"; - - char* ptr = memcpy(buf, str, 20); - - EXPECT_EQ(ptr, buf); - - for (int i = 0; i < 20; i++) { EXPECT_EQ(buf[i], str[i]); } - - const char* new = "Well..."; - - ptr = memcpy(buf, new, 7); - - EXPECT_EQ(ptr, buf); - - for (int i = 0; i < 7; i++) { EXPECT_EQ(buf[i], new[i]); } - for (int i = 7; i < 20; i++) { EXPECT_EQ(buf[i], str[i]); } - - TEST_SUCCESS(); -} - -DEFINE_TEST(memchr) -{ - START_TEST(memchr); - - char buf[20] = "abcdefghijklmnopqrs"; - - char* ptr = memchr(buf, 'z', 20); - - EXPECT_EQ(ptr, NULL); - - ptr = memchr(buf, 'd', 20); - - EXPECT_EQ(ptr, buf + 3); - - ptr = memchr(buf, 's', 20); - - EXPECT_EQ(ptr, buf + 18); - - TEST_SUCCESS(); -} - -DEFINE_TEST(memcmp) -{ - START_TEST(memcmp); - - char buf[20] = "abcdefghijklmnopqrs"; - char buf2[20] = "abcdefghijklmnopqrp"; - - int val = memcmp(buf, buf, 20); - - EXPECT_EQ(val, 0); - - val = memcmp(buf, buf2, 20); - - EXPECT(val > 0); - - val = memcmp(buf2, buf, 20); - - EXPECT(val < 0); - - TEST_SUCCESS(); -} - -DEFINE_TEST(memmove) -{ - START_TEST(memmove); - - char buf[20] = "Nothing is going on"; - const char* str = "Something is going!"; - - char* ptr = memmove(buf, str, 20); - - EXPECT_EQ(ptr, buf); - - for (int i = 0; i < 20; i++) { EXPECT_EQ(buf[i], str[i]); } - - const char* new = "Well..."; - - ptr = memmove(buf, new, 7); - - EXPECT_EQ(ptr, buf); - - for (int i = 0; i < 7; i++) { EXPECT_EQ(buf[i], new[i]); } - for (int i = 7; i < 20; i++) { EXPECT_EQ(buf[i], str[i]); } - - char newbuf[16] = "part_a is part_b"; - char result[16] = "is part_b part_b"; - - ptr = memmove(newbuf, newbuf + 7, 9); - - EXPECT_EQ(ptr, newbuf); - - EXPECT(memcmp(newbuf, result, 16) == 0); // we have tested memcmp at this point - - TEST_SUCCESS(); -} - -DEFINE_TEST(strlen) -{ - START_TEST(strlen); - - const char* str = "Hello, World!"; - - size_t len = strlen(str); - - EXPECT_EQ(len, 13); - - char null[] = {'\0'}; - - len = strlen(null); - - EXPECT_EQ(len, 0); - - TEST_SUCCESS(); -} - -DEFINE_TEST(strnlen) -{ - START_TEST(strnlen); - - const char* str = "What is going on?"; - - size_t len = strnlen(str, 20); - - EXPECT_EQ(len, 17); - - len = strnlen(str, 15); - - EXPECT_EQ(len, 15); - - char buf[] = {'H', 'e', 'l', 'l', 'o'}; - - len = strnlen(buf, sizeof(buf)); - - EXPECT_EQ(len, sizeof(buf)); - - TEST_SUCCESS(); -} - -DEFINE_TEST(strcmp) -{ - START_TEST(strcmp); - - const char* str1 = "Hello, World!"; - const char* str2 = "Hello, Planet!"; - - int rc = strcmp(str1, str1); - - EXPECT_EQ(rc, 0); - - rc = strcmp(str1, str2); - - EXPECT(rc > 0); - - rc = strcmp(str2, str1); - - EXPECT(rc < 0); - - TEST_SUCCESS(); -} - -DEFINE_TEST(strncmp) -{ - START_TEST(strncmp); - - const char* str1 = "Hello, World!"; - const char* str2 = "Hello, Planet!"; - - int rc = strncmp(str1, str1, 14); - - EXPECT_EQ(rc, 0); - - rc = strncmp(str1, str2, 14); - - EXPECT(rc > 0); - - rc = strncmp(str2, str1, 14); - - EXPECT(rc < 0); - - rc = strncmp(str1, str2, 6); - - EXPECT_EQ(rc, 0); - - TEST_SUCCESS(); -} - -DEFINE_TEST(strcspn) -{ - START_TEST(strcspn); - - const char* str = "This string has vowels"; - const char* vowels = "aeiou"; - - size_t len = strcspn(str, vowels); - - EXPECT_EQ(len, 2); - - str = "WWWWW"; - len = strcspn(str, vowels); - - EXPECT_EQ(len, 5); - - TEST_SUCCESS(); -} - -DEFINE_TEST(strspn) -{ - START_TEST(strspn); - - const char* str = "This is a test string"; - const char* accept = "This "; - - size_t len = strspn(str, accept); - - EXPECT_EQ(len, 8); - - str = "WWWWW"; - len = strspn(str, accept); - - EXPECT_EQ(len, 0); - - str = "This is hi"; - len = strspn(str, accept); - - EXPECT_EQ(len, 10); - - TEST_SUCCESS(); -} - -DEFINE_TEST(strchr) -{ - START_TEST(strchr); - - const char* str = "Hello, world!"; - - char* ptr = strchr(str, 'l'); - - EXPECT_EQ(ptr, str + 2); - - ptr = strchr(str, 'u'); - - EXPECT_EQ(ptr, NULL); - - ptr = strchr(str, '!'); - - EXPECT_EQ(ptr, str + 12); - - TEST_SUCCESS(); -} - -DEFINE_TEST(strchrnul) -{ - START_TEST(strchrnul); - - const char* str = "Hello, world!"; - - char* ptr = strchrnul(str, 'l'); - - EXPECT_EQ(ptr, str + 2); - - ptr = strchrnul(str, 'u'); - - EXPECT_EQ(ptr, str + 13); - - ptr = strchrnul(str, '!'); - - EXPECT_EQ(ptr, str + 12); - - TEST_SUCCESS(); -} - -DEFINE_TEST(strrchr) -{ - START_TEST(strrchr); - - const char* str = "Hello, world!"; - - char* ptr = strrchr(str, 'l'); - - EXPECT_EQ(ptr, str + 10); - - ptr = strrchr(str, 'u'); - - EXPECT_EQ(ptr, NULL); - - ptr = strrchr(str, '!'); - - EXPECT_EQ(ptr, str + 12); - - TEST_SUCCESS(); -} - -DEFINE_TEST(strpbrk) -{ - START_TEST(strpbrk); - - const char* str = "Hello, world!"; - const char* vowels = "aeiou"; - - char* ptr = strpbrk(str, vowels); - - EXPECT_EQ(ptr, str + 1); - - str = "There are more vowels"; - ptr = strpbrk(str, vowels); - - EXPECT_EQ(ptr, str + 2); - - str = "zzzzzz"; - ptr = strpbrk(str, vowels); - - EXPECT_EQ(ptr, NULL); - - TEST_SUCCESS(); -} - -DEFINE_TEST(strdup) -{ - START_TEST(strdup); - - const char* orig = "Well hello there!"; - - char* copy = strdup(orig); - if (!copy) { TEST_NOT_SURE(copy); } - - EXPECT(memcmp(orig, copy, 17) == 0); - - free(copy); - - TEST_SUCCESS(); -} - -DEFINE_TEST(strndup) -{ - START_TEST(strndup); - - const char* orig = "Well hello there!"; - - char* copy = strndup(orig, 17); - if (!copy) { TEST_NOT_SURE(copy); } - - EXPECT(memcmp(orig, copy, 17) == 0); - - free(copy); - - copy = strndup(orig, 12); - if (!copy) { TEST_NOT_SURE(copy); } - - EXPECT_NOT_EQ(memcmp(orig, copy, 14), - 0); // FIXME: This is undefined behaviour and the memory could also be by chance identical. - - free(copy); - - TEST_SUCCESS(); -} \ No newline at end of file diff --git a/tests/libc/wchar.c b/tests/libc/wchar.c deleted file mode 100644 index bec6dc7e..00000000 --- a/tests/libc/wchar.c +++ /dev/null @@ -1,21 +0,0 @@ -#include "Test.h" -#include - -DEFINE_TEST(wcslen) -{ - START_TEST(wcslen); - - const wchar_t* str = L"Hello, World!"; - - size_t len = wcslen(str); - - EXPECT_EQ(len, 13); - - wchar_t null[] = {L'\0'}; - - len = wcslen(null); - - EXPECT_EQ(len, 0); - - TEST_SUCCESS(); -} \ No newline at end of file