diff --git a/.gdbconf b/.gdbconf deleted file mode 100644 index d03031b8..00000000 --- a/.gdbconf +++ /dev/null @@ -1,4 +0,0 @@ -file kernel/bin/moon.elf -break _start -target remote :1234 -continue \ No newline at end of file diff --git a/.gitignore b/.gitignore index c2d28f12..aae1c6e2 100644 --- a/.gitignore +++ b/.gitignore @@ -1,15 +1,5 @@ Luna.iso toolchain/ .vscode/ -**/*.o -initrd/boot/moon.elf -kernel/bin/moon.elf -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 +initrd/boot/ +moon/target/** \ No newline at end of file diff --git a/apps/Makefile b/apps/Makefile deleted file mode 100644 index 4e704baa..00000000 --- a/apps/Makefile +++ /dev/null @@ -1,23 +0,0 @@ -APPS := init sh uname uptime hello ps ls args cat stat su session date mkdir - -APPS_DIR := $(LUNA_ROOT)/apps -APPS_SRC := $(APPS_DIR)/src -APPS_BIN := $(APPS_DIR)/bin - -REAL_APPS := $(patsubst %, $(APPS_BIN)/%, $(APPS)) - -CFLAGS := -Wall -Wextra -Werror -Os -fno-asynchronous-unwind-tables - -$(APPS_BIN)/%: $(APPS_SRC)/%.c - @mkdir -p $(@D) - $(CC) $(CFLAGS) -o $@ $^ - -build: $(REAL_APPS) - -install: $(REAL_APPS) - @mkdir -p $(LUNA_ROOT)/initrd/bin - cp $(REAL_APPS) $(LUNA_ROOT)/initrd/bin - @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.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 c0033782..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, sizeof(buf) - 1, 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 9287b846..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]", 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/session.c b/apps/src/session.c deleted file mode 100644 index 90704812..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) - { - setuid(user->pw_uid); - setgid(user->pw_gid); - 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 f06c7814..00000000 --- a/apps/src/sh.c +++ /dev/null @@ -1,359 +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_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 9479e753..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 (getuid() != 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 (setuid(user->pw_uid) < 0) - { - perror("setuid"); - return EXIT_FAILURE; - } - - if (setgid(user->pw_gid) < 0) - { - perror("setgid"); - 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/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/initrd/sys/config b/initrd/sys/config index e197bfe0..926fdc83 100644 --- a/initrd/sys/config +++ b/initrd/sys/config @@ -1,3 +1,3 @@ screen=1024x768 -kernel=boot/moon.elf +kernel=boot/moon verbose=1 \ No newline at end of file diff --git a/kernel/Makefile b/kernel/Makefile deleted file mode 100644 index af19b9d3..00000000 --- a/kernel/Makefile +++ /dev/null @@ -1,71 +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 ${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.elf - -$(MOON_OBJ)/main.cpp.o: $(MOON_SRC)/main.cpp - @mkdir -p $(@D) - $(CXX) $(CFLAGS) -fno-stack-protector $(CXXFLAGS) -o $@ -c $^ - -$(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 - -$(MOON_OBJ)/init/Init.cpp.o: $(MOON_SRC)/init/Init.cpp - @mkdir -p $(@D) - $(CXX) $(CFLAGS) -fno-stack-protector $(CXXFLAGS) -o $@ -c $^ - -$(MOON_OBJ)/%.cpp.o: $(MOON_SRC)/%.cpp - @mkdir -p $(@D) - $(CXX) $(CFLAGS) $(CXXFLAGS) -o $@ -c $^ - -$(MOON_OBJ)/%.c.o: $(MOON_SRC)/%.c - @mkdir -p $(@D) - $(CC) $(CFLAGS) -o $@ -c $^ - -$(MOON_OBJ)/%.asm.o: $(MOON_SRC)/%.asm - @mkdir -p $(@D) - $(ASM) $(ASMFLAGS) -o $@ $^ - -build: $(OBJS) - @mkdir -p $(MOON_BIN) - $(CC) $(OBJS) $(LDFLAGS) -o $(MOON_BIN)/moon.elf - -clean: - rm -rf $(MOON_OBJ)/* - rm -rf $(MOON_BIN)/* - -install: $(MOON_BIN)/moon.elf - @mkdir -p $(LUNA_ROOT)/initrd/boot - cp $^ $(LUNA_ROOT)/initrd/boot/moon.elf - $(LUNA_ROOT)/tools/generate-symbols.sh - $(STRIP) $(LUNA_ROOT)/initrd/boot/moon.elf - -.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 3b8359b3..00000000 --- a/kernel/include/cpu/CPU.h +++ /dev/null @@ -1,13 +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); -} \ 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 482c8604..00000000 --- a/kernel/include/fs/FileDescriptor.h +++ /dev/null @@ -1,76 +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); - - 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/VFS.h b/kernel/include/fs/VFS.h deleted file mode 100644 index 67a63640..00000000 --- a/kernel/include/fs/VFS.h +++ /dev/null @@ -1,82 +0,0 @@ -#pragma once -#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); - - 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* 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); - - int would_block(Node* node); - - void mount_root(Node* root); - - Node* resolve_path(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 d7ce5d96..00000000 --- a/kernel/include/fs/devices/Console.h +++ /dev/null @@ -1,9 +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); -} \ 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/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/init/InitRD.h b/kernel/include/init/InitRD.h deleted file mode 100644 index d0ce7b42..00000000 --- a/kernel/include/init/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/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/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 2b17c328..00000000 --- a/kernel/include/memory/AddressSpace.h +++ /dev/null @@ -1,21 +0,0 @@ -#pragma once -#include "memory/Paging.h" - -struct AddressSpace -{ - static AddressSpace 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 240c9a21..00000000 --- a/kernel/include/memory/MemoryManager.h +++ /dev/null @@ -1,34 +0,0 @@ -#pragma once -#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 - -namespace MemoryManager -{ - void init(); - - void* get_mapping(void* physicalAddress, int flags = MAP_READ_WRITE); - void release_mapping(void* mapping); - - void* get_unaligned_mapping(void* physicalAddress, int flags = MAP_READ_WRITE); - void* 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); - - void* get_page(int flags = MAP_READ_WRITE); - void* get_pages(uint64_t count, int flags = MAP_READ_WRITE); - - void* get_page_at(uint64_t addr, int flags = MAP_READ_WRITE); - void* 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); -} \ 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 991361d5..00000000 --- a/kernel/include/memory/PMM.h +++ /dev/null @@ -1,27 +0,0 @@ -#pragma once -#include - -#define PMM_FAILED (void*)-1 -#define PMM_DID_FAIL(addr) (void*)addr == PMM_FAILED - -namespace PMM -{ - void init(); - - void* request_page(); - void* 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 37530b37..00000000 --- a/kernel/include/memory/Paging.h +++ /dev/null @@ -1,29 +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 : 52; - - void set_address(uint64_t addr); - uint64_t get_address(); -}; - -struct PageTable -{ - PageDirectoryEntry entries[512]; -} __attribute__((aligned(PAGE_SIZE))); \ 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 ad736def..00000000 --- a/kernel/include/memory/VMM.h +++ /dev/null @@ -1,45 +0,0 @@ -#pragma once -#include "memory/AddressSpace.h" -#include "memory/Paging.h" - -enum Flags -{ - ReadWrite = 1 << 0, - User = 1 << 1, - Execute = 1 << 2 -}; -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_user(PageTable* root, uint64_t vaddr); - - void flush_tlb(uint64_t addr); - - 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/assert.h b/kernel/include/std/assert.h deleted file mode 100644 index 79ea434a..00000000 --- a/kernel/include/std/assert.h +++ /dev/null @@ -1,6 +0,0 @@ -#pragma once -#include "panic/Panic.h" - -#define ASSERT(expr) (bool)(expr) || panic("Assertion failed: " #expr) - -#define TODO(message) panic("TODO: " message) \ 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 d9a7ec48..00000000 --- a/kernel/include/std/libgen.h +++ /dev/null @@ -1,4 +0,0 @@ -#pragma once - -char* basename(char* path); -char* dirname(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 94ffba07..00000000 --- a/kernel/include/sys/Syscall.h +++ /dev/null @@ -1,72 +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_paint 4 -#define SYS_getprocid 5 -#define SYS_mmap 6 -#define SYS_munmap 7 -#define SYS_open 8 -#define SYS_read 9 -#define SYS_close 10 -#define SYS_seek 11 -#define SYS_execv 12 -#define SYS_fcntl 13 -#define SYS_mprotect 14 -#define SYS_clock_gettime 15 -#define SYS_mkdir 16 -#define SYS_fork 17 -#define SYS_waitpid 18 -#define SYS_access 19 -#define SYS_fstat 20 -#define SYS_pstat 21 -#define SYS_getdents 22 -#define SYS_stat 23 -#define SYS_dup2 24 -#define SYS_setuid 25 -#define SYS_setgid 26 -#define SYS_umask 27 - -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_paint(Context* context, uint64_t x, uint64_t y, uint64_t w, uint64_t h, uint64_t col); -void sys_getprocid(Context* context, int field); -void sys_mmap(Context* context, void* address, size_t size, int prot); -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, int new_uid, int new_euid); -void sys_setgid(Context* context, int new_gid, int new_egid); -void sys_umask(Context* context, mode_t cmask); \ 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 0da06379..00000000 --- a/kernel/include/sys/UserMemory.h +++ /dev/null @@ -1,43 +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" - -char* strdup_from_user(const char* user_string); - -// FIXME: Map the physical addresses into kernel address space. Right now, something overwrites KernelHeap and crashes -// it, so that's not really possible. But it should be done in the future. - -template T* user_address_to_typed_pointer(V address) -{ - uint64_t phys = VMM::get_physical((uint64_t)address); - if (phys == (uint64_t)-1) - { - kinfoln("warning: user pointer is not mapped in its address space"); - return nullptr; - } - // return (T*)MemoryManager::get_unaligned_mappings((void*)phys, Utilities::get_blocks_from_size(PAGE_SIZE, S), - // MAP_READ_WRITE); - return (T*)phys; -} - -template void free_user_typed_pointer(T*) -{ - // MemoryManager::release_unaligned_mappings(ptr, Utilities::get_blocks_from_size(PAGE_SIZE, S)); -} - -template T* obtain_user_ref(T* user_ptr) -{ - return user_address_to_typed_pointer(user_ptr); -} - -template void release_user_ref(T* ptr) -{ - return free_user_typed_pointer(ptr); -} \ 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 8faf4a8d..00000000 --- a/kernel/include/thread/Task.h +++ /dev/null @@ -1,116 +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" - -#define TASK_MAX_FDS 32 - -enum class BlockReason -{ - None, - Reading, - Waiting, -}; - -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; - - int uid; - int euid; - int gid; - int 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; - - 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(); - - 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/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/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/moon.ld b/kernel/moon.ld deleted file mode 100644 index 68fe520f..00000000 --- a/kernel/moon.ld +++ /dev/null @@ -1,31 +0,0 @@ -ENTRY(_main) -OUTPUT_FORMAT(elf64-x86-64) - -mmio = 0xfffffffff8000000; /* these are configurable for level 2 loaders */ -fb = 0xfffffffffc000000; -bootboot = 0xffffffffffe00000; -environment = 0xffffffffffe01000; -/* initstack = 1024; */ -PHDRS -{ - boot PT_LOAD; /* one single loadable segment */ -} -SECTIONS -{ - . = 0xffffffffffe02000; - kernel_start = .; - .text : { - KEEP(*(.text.boot)) *(.text .text.*) /* code */ - *(.rodata .rodata.*) /* data */ - *(.data .data.*) - } :boot - .bss (NOLOAD) : { /* bss */ - . = ALIGN(16); - *(.bss .bss.*) - *(COMMON) - } :boot - kernel_end = .; - - /DISCARD/ : { *(.eh_frame) *(.comment) } -} - diff --git a/kernel/src/acpi/RSDT.cpp b/kernel/src/acpi/RSDT.cpp deleted file mode 100644 index 410644ba..00000000 --- a/kernel/src/acpi/RSDT.cpp +++ /dev/null @@ -1,107 +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; - -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); - - 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); - } - - 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); - 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 173951f4..00000000 --- a/kernel/src/cpu/CPU.cpp +++ /dev/null @@ -1,91 +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; -} - -static bool _has_feature(int feature) -{ - return (CPU::get_feature_bitmask() & (uint64_t)(1 << 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 59ce5da1..00000000 --- a/kernel/src/fs/FileDescriptor.cpp +++ /dev/null @@ -1,58 +0,0 @@ -#include "fs/FileDescriptor.h" -#include "std/errno.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; -} - -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/VFS.cpp b/kernel/src/fs/VFS.cpp deleted file mode 100644 index ef0deae2..00000000 --- a/kernel/src/fs/VFS.cpp +++ /dev/null @@ -1,296 +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; - } -} - -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 (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 (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* bstr = strdup(pathname); - char* dstr = strdup(pathname); - - char* base = basename(bstr); - char* dir = dirname(dstr); - - kdbgln("mkdir(): creating %s in directory %s", base, dir); - - int result = mkdir(dir, base); - - kfree(bstr); - kfree(dstr); - - return result; -} - -int VFS::do_mkdir(const char* pathname, int uid, int gid, mode_t mode) -{ - char* bstr = strdup(pathname); - char* dstr = strdup(pathname); - - char* base = basename(bstr); - char* dir = dirname(dstr); - - kdbgln("mkdir(): creating %s in directory %s", base, dir); - - int result = do_mkdir(dir, base, uid, gid, mode); - - kfree(bstr); - kfree(dstr); - - return result; -} - -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 8ba7f978..00000000 --- a/kernel/src/fs/devices/Console.cpp +++ /dev/null @@ -1,31 +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" - -extern uint64_t clock_boot(); - -VFS::Node* ConsoleDevice::create_new(const char* devname) -{ - VFS::Node* dev = new VFS::Node; - dev->write_func = ConsoleDevice::write; - dev->inode = 0; - dev->length = 0; - dev->type = VFS_DEVICE; - dev->flags = 0; - dev->tty = 1; - 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 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; -} \ 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 a4db91e6..00000000 --- a/kernel/src/fs/devices/DeviceFS.cpp +++ /dev/null @@ -1,59 +0,0 @@ -#include "fs/devices/DeviceFS.h" -#include "fs/devices/Console.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_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/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 d1e2785a..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 = 0200; - 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 7d47da61..00000000 --- a/kernel/src/gdt/GDT.cpp +++ /dev/null @@ -1,112 +0,0 @@ -#define MODULE "gdt" - -#include "gdt/GDT.h" -#include "log/Log.h" -#include "memory/MemoryManager.h" -#include "std/assert.h" -#include "std/string.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) -{ - ASSERT(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] = - (uint64_t)MemoryManager::get_pages(4) + (PAGE_SIZE * 4) - 8; // allocate 16KB for the syscall stack - 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 59146d9b..00000000 --- a/kernel/src/init/Init.cpp +++ /dev/null @@ -1,76 +0,0 @@ -#define MODULE "init" - -#include "init/Init.h" -#include "bootboot.h" -#include "cpu/CPU.h" -#include "init/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/hang.h" -#include "rand/Init.h" -#include "rand/Mersenne.h" -#include "render/Framebuffer.h" -#include "render/TextRenderer.h" -#include "std/assert.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(); - -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); - - MemoryManager::init(); - - 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/init/InitRD.cpp b/kernel/src/init/InitRD.cpp deleted file mode 100644 index afde38a0..00000000 --- a/kernel/src/init/InitRD.cpp +++ /dev/null @@ -1,429 +0,0 @@ -#define MODULE "initrd" - -#include "init/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" - -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; - result.size = 0; - memcpy(result.name, header->name, 100); - int multiplier = - 1; // why they decided to store the size as an octal-encoded string instead of an integer is beyond me - for (int i = 10; i >= 0; i--) - { - result.size += (multiplier * (header->size[i] - 48)); - multiplier *= 8; - } - result.addr = (void*)((uint64_t)header + TAR_BLOCKSIZE); - result.size_in_blocks = Utilities::get_blocks_from_size(TAR_BLOCKSIZE, result.size); - result.mode = 0; - multiplier = 1; - for (int i = 6; i >= 0; i--) - { - result.mode += (mode_t)(multiplier * (header->mode[i] - 48)); - multiplier *= 8; - } - 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.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)); - 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/interrupts/Entry.cpp b/kernel/src/interrupts/Entry.cpp deleted file mode 100644 index a08445a3..00000000 --- a/kernel/src/interrupts/Entry.cpp +++ /dev/null @@ -1,61 +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 "misc/hang.h" -#include "panic/Panic.h" -#include "std/assert.h" -#include "std/stdio.h" -#include "sys/Syscall.h" -#include "thread/Scheduler.h" -#include "trace/StackTracer.h" - -extern "C" void common_handler(Context* context) -{ - ASSERT(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 - { - 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 - { - 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); - - 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 38a1e79d..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/assert.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) -{ - ASSERT(handler != nullptr); - ASSERT(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 22142735..00000000 --- a/kernel/src/interrupts/IRQ.cpp +++ /dev/null @@ -1,35 +0,0 @@ -#define MODULE "irq" - -#include "interrupts/IRQ.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); - bool ignore = false; - char key = translate_scancode(scancode, &ignore); - if (ignore) break; - KeyboardDevice::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/Log.cpp b/kernel/src/log/Log.cpp deleted file mode 100644 index 6faf779b..00000000 --- a/kernel/src/log/Log.cpp +++ /dev/null @@ -1,95 +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; - -static bool log_level_enabled(LogLevel level) -{ - return level_mask & (1 << (int)level); -} - -static bool log_backend_enabled(Backend backend) -{ - return backend_mask & (1 << (int)backend); -} - -static 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); -} - -static 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 deleted file mode 100644 index ab5c3751..00000000 --- a/kernel/src/main.cpp +++ /dev/null @@ -1,82 +0,0 @@ -#define MODULE "main" - -#include "config.h" -#include "cpu/CPU.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/assert.h" -#include "std/stdlib.h" -#include "thread/PIT.h" -#include "thread/Scheduler.h" - -#define STRINGIZE(x) #x -#define STRINGIZE_VALUE_OF(x) STRINGIZE(x) - -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(); - - kinfoln("Loaded GDT"); - - Interrupts::install(); - - IDT::load(); - - kinfoln("Loaded IDT"); - - PIT::initialize(1000); // 1000 times per second - - kinfoln("Prepared PIT"); - - Scheduler::init(); - - kinfoln("Prepared scheduler"); - -#ifdef RUN_TEST_AS_INIT - ASSERT(Scheduler::load_user_task(STRINGIZE_VALUE_OF(RUN_TEST_AS_INIT)) > 0); -#else - ASSERT(Scheduler::load_user_task("/bin/init") > 0); -#endif - - Scheduler::add_kernel_task("[reaper]", []() { - while (1) - { - sleep(400); - Scheduler::reap_tasks(); - } - }); - - kinfoln("Prepared scheduler tasks"); - - ASSERT(VFS::mkdir("/dev") == 0); - VFS::mount("/dev", DeviceFS::get()); - - Init::finish_kernel_boot(); - - PIC::remap(); - PIC::enable_master(0b11111100); - PIC::enable_slave(0b11111111); - - Interrupts::enable(); - - while (1) halt(); -} \ 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 e844fe54..00000000 --- a/kernel/src/memory/AddressSpace.cpp +++ /dev/null @@ -1,240 +0,0 @@ -#define MODULE "vmm" - -#include "memory/AddressSpace.h" -#include "log/Log.h" -#include "memory/PMM.h" -#include "memory/VMM.h" -#include "std/stdlib.h" -#include "std/string.h" -#include "utils/move.h" - -AddressSpace AddressSpace::create() -{ - AddressSpace result; - result.m_pml4 = (PageTable*)PMM::request_page(); - 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) - { - 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) - { - 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) - { - 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; - 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) - { - 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) - { - 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) - { - 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; - 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) -{ - PageTable* dst = (PageTable*)PMM::request_page(); - if (PMM_DID_FAIL(dst)) { return 0; } - 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) - { - 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) - { - 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) - { - 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.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 43463d8e..00000000 --- a/kernel/src/memory/KernelHeap.cpp +++ /dev/null @@ -1,136 +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)); - kinfoln("page bitmap located at %p", (void*)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 1e3dec5b..00000000 --- a/kernel/src/memory/MemoryManager.cpp +++ /dev/null @@ -1,197 +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 "std/assert.h" - -void MemoryManager::init() -{ - KernelHeap::clear(); - PMM::init(); - VMM::init(); - PMM::map_bitmap_to_virtual(); -} - -void* 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 0; - } - VMM::map(virtualAddress, (uint64_t)physicalAddress, flags); - return (void*)virtualAddress; -} - -void* 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 0; - } - VMM::map(virtualAddress, (uint64_t)physicalAddress - offset, flags); - return (void*)(virtualAddress + offset); -} - -void* 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 0; - } - 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); -} - -void* 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 0; - } - return get_page_at(virtualAddress, flags); -} - -void* MemoryManager::get_page_at(uint64_t addr, int flags) -{ - void* physicalAddress = PMM::request_page(); - if (PMM_DID_FAIL(physicalAddress)) - { -#ifdef MM_DEBUG - kwarnln("OOM while allocating one page of memory. this is not good..."); -#endif - return 0; - } - VMM::map(addr, (uint64_t)physicalAddress, flags); - return (void*)addr; -} - -void MemoryManager::release_page(void* page) -{ - uint64_t physicalAddress = VMM::get_physical((uint64_t)page); - ASSERT(physicalAddress != UINT64_MAX); // this address is not mapped in the virtual address space... - VMM::unmap((uint64_t)page); - PMM::free_page((void*)physicalAddress); -} - -void* 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 0; // 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); -} - -void* 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++) - { - void* physicalAddress = PMM::request_page(); - if (PMM_DID_FAIL(physicalAddress)) // 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 - return 0; - } - VMM::map(addr + (i * PAGE_SIZE), (uint64_t)physicalAddress, 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); - ASSERT(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); } -} \ 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 aa167b57..00000000 --- a/kernel/src/memory/PMM.cpp +++ /dev/null @@ -1,189 +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/assert.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; - ASSERT((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; } -} - -void* 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 PMM_FAILED; -} - -void* 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 PMM_FAILED; -} - -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)); -} \ 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 9f7a5fca..00000000 --- a/kernel/src/memory/VMM.cpp +++ /dev/null @@ -1,298 +0,0 @@ -#define MODULE "vmm" - -#include "memory/VMM.h" -#include "log/Log.h" -#include "memory/PMM.h" -#include "misc/utils.h" -#include "std/assert.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; - -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; -} - -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; - 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 0; // Not mapped - - uint64_t flags = 0; - if (pde->user) flags |= User; - if (pde->read_write) flags |= ReadWrite; - 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); - } - - 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 (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 = [&]() { - pt = (PageTable*)PMM::request_page(); - ASSERT(!(PMM_DID_FAIL(pt))); - 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::flush_tlb(uint64_t addr) -{ - asm volatile("invlpg (%0)" : : "r"(addr) : "memory"); -} - -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) - { - space_last_pdp = (PageTable*)PMM::request_page(); // FIXME: Add out-of-memory checks. - 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 d3acdd69..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); -} - -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 e80c16cf..00000000 --- a/kernel/src/memory/liballoc/liballoc.c +++ /dev/null @@ -1,747 +0,0 @@ -#include "memory/liballoc/liballoc.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; -#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/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 76e815d6..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 14 -#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/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/panic/Panic.cpp b/kernel/src/panic/Panic.cpp deleted file mode 100644 index eac29e7c..00000000 --- a/kernel/src/panic/Panic.cpp +++ /dev/null @@ -1,176 +0,0 @@ -#define MODULE "panic" - -#include "panic/Panic.h" -#include "init/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; - -static 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 c984281c..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() -{ - kdbgln("Preparing random number generator"); - - has_rdrand = CPU::has_feature(CPU::Features::RDRAND); - has_rdseed = asm_test_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 53a887cb..00000000 --- a/kernel/src/rand/Mersenne.cpp +++ /dev/null @@ -1,62 +0,0 @@ -#define MODULE "rand" - -#include "rand/Mersenne.h" -#include "std/assert.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) - { - 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; -} \ 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 d59a1a9b..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 "init/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 908aee15..00000000 --- a/kernel/src/std/libgen.cpp +++ /dev/null @@ -1,47 +0,0 @@ -#include "std/libgen.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; -} \ 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 18af8db5..00000000 --- a/kernel/src/std/stdio.cpp +++ /dev/null @@ -1,289 +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 '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 97cb07c2..00000000 --- a/kernel/src/sys/Syscall.cpp +++ /dev/null @@ -1,47 +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_paint: sys_paint(context, context->rdi, context->rsi, context->rdx, context->r10, context->r8); 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); 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, (int)context->rdi, (int)context->rsi); break; - case SYS_setgid: sys_setgid(context, (int)context->rdi, (int)context->rsi); break; - case SYS_umask: sys_umask(context, (mode_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 6ca659ff..00000000 --- a/kernel/src/sys/UserMemory.cpp +++ /dev/null @@ -1,10 +0,0 @@ -#include "sys/UserMemory.h" -#include "std/string.h" - -char* strdup_from_user( - const char* user_string) // FIXME: This function is a little hacky. Use the obtain_user_ref and similar functions. -{ - uint64_t phys = VMM::get_physical((uint64_t)user_string); - if (phys == (uint64_t)-1) { return nullptr; } - return strdup((const char*)phys); -} \ 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 1d13b879..00000000 --- a/kernel/src/sys/clock.cpp +++ /dev/null @@ -1,83 +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 = obtain_user_ref(tp); - if (!ktp) - { - context->rax = -EFAULT; // FIXME: Not sure if clock_gettime can return EFAULT. - return; - } - 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: - release_user_ref(ktp); - context->rax = -EINVAL; - return; - } - release_user_ref(ktp); - 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 89eb16c0..00000000 --- a/kernel/src/sys/dirent.cpp +++ /dev/null @@ -1,61 +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; - } - - auto* kdirent = obtain_user_ref(buf); - if (!kdirent) - { - context->rax = -EFAULT; - return; - } - - kdirent->total = node->length; - kdirent->offset = dir.offset(); - kdirent->inode = entry->inode; - strlcpy(kdirent->name, entry->name, sizeof(kdirent->name)); - - release_user_ref(kdirent); - - 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 02cda298..00000000 --- a/kernel/src/sys/elf/ELFLoader.cpp +++ /dev/null @@ -1,201 +0,0 @@ -#define MODULE "elf" - -#include "sys/elf/ELFLoader.h" -#include "fs/VFS.h" -#include "init/InitRD.h" -#include "log/Log.h" -#include "memory/Memory.h" -#include "memory/MemoryManager.h" -#include "memory/VMM.h" -#include "misc/utils.h" -#include "std/assert.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; -} - -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; - ASSERT(VFS::read(node, 0, sizeof(elf_ehdr), (char*)&elf_ehdr) >= 0); - ASSERT(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 - ASSERT(elf_ehdr.e_ident[EI_CLASS] == ELFCLASS64); - ASSERT(elf_ehdr.e_ident[EI_DATA] == ELFDATA2LSB); - ASSERT(elf_ehdr.e_type == ET_EXEC); - ASSERT(elf_ehdr.e_machine == EM_MACH); - ASSERT(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)); - ASSERT(phdr.p_vaddr); - - 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) + - (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(); - - MemoryManager::protect(buffer, pages, phdr.p_flags & 2 ? MAP_READ_WRITE | MAP_USER : MAP_USER); - - 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"); } - } - ASSERT(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; - } - 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); -} \ No newline at end of file diff --git a/kernel/src/sys/exec.cpp b/kernel/src/sys/exec.cpp deleted file mode 100644 index c110c661..00000000 --- a/kernel/src/sys/exec.cpp +++ /dev/null @@ -1,264 +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/assert.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->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); - ASSERT(kvalue != (char*)UINT64_MAX); - memcpy(kvalue, value, size); -} - -void sys_execv(Context* context, const char* pathname, char** argv) -{ - char* kpathname = strdup_from_user(pathname); - if (!kpathname) - { - context->rax = -EFAULT; - return; - } - - 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); - }; - - do { - if (Memory::is_kernel_address((uintptr_t)argv)) - { - free_kernel_argv_copy(); - context->rax = -EFAULT; - return; - } - arg = (char**)VMM::get_physical((uint64_t)argv); - if (arg == (char**)UINT64_MAX) - { - free_kernel_argv_copy(); - context->rax = -EFAULT; - return; - } - kargv = (char**)krealloc(kargv, (kargc + 1) * sizeof(char*)); - if (!kargv) - { - free_kernel_argv_copy(); - context->rax = -ENOMEM; - return; - } - if (*arg) - { - char* kcopy = strdup_from_user(*arg); - if (!kcopy) - { - free_kernel_argv_copy(); - context->rax = -ENOMEM; - return; - } - kargv[kargc] = kcopy; - } - 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(); - ASSERT(!Interrupts::are_enabled()); // This part is pretty sensitive. - - Task* task = Scheduler::current_task(); - ASSERT(task); - - // At this point, pretty much nothing can fail. - - 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); // 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); - ASSERT(image); // If check_elf_image succeeded, load_elf_from_vfs MUST succeed, unless something has gone terribly - // wrong. - - if (VFS::is_setuid(program)) task->uid = program->uid; - if (VFS::is_setgid(program)) task->gid = 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 3385428d..00000000 --- a/kernel/src/sys/id.cpp +++ /dev/null @@ -1,96 +0,0 @@ -#include "std/errno.h" -#include "thread/Scheduler.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 - -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, int new_uid, int new_euid) -{ - Task* current_task = Scheduler::current_task(); - - if (!current_task->is_superuser()) - { - if (new_uid != current_task->uid && new_uid != current_task->euid) - { - context->rax = -EPERM; - return; - } - if (new_euid != current_task->euid && new_euid != current_task->uid) - { - context->rax = -EPERM; - return; - } - } - - current_task->uid = new_uid; - current_task->euid = new_euid; - - context->rax = 0; -} - -void sys_setgid(Context* context, int new_gid, int new_egid) -{ - Task* current_task = Scheduler::current_task(); - - if (!current_task->is_superuser()) - { - if (new_gid != current_task->gid && new_gid != current_task->egid) - { - context->rax = -EPERM; - return; - } - if (new_egid != current_task->egid && new_egid != current_task->gid) - { - context->rax = -EPERM; - return; - } - } - - current_task->gid = new_gid; - current_task->egid = new_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 aa51f14a..00000000 --- a/kernel/src/sys/mem.cpp +++ /dev/null @@ -1,191 +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 MAP_READ 1 -#define MAP_WRITE 2 -#define MAP_NONE 0 - -#define MAP_FAIL(errno) 0xffffffffffffff00 | (unsigned char)(errno) - -static const char* format_prot(int prot) -{ - static char prot_string[3]; - prot_string[2] = 0; - prot_string[0] = ((prot & MAP_READ) > 0) ? 'r' : '-'; - prot_string[1] = ((prot & MAP_WRITE) > 0) ? 'w' : '-'; - return prot_string; -} - -static int mman_flags_from_prot(int prot) -{ - prot &= 0b11; - if (prot == MAP_NONE) return 0; - if ((prot & MAP_WRITE) > 0) return MAP_USER | MAP_READ_WRITE; - return MAP_USER; -} - -void sys_mmap(Context* context, void* address, size_t size, int prot) -{ - 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", size / PAGE_SIZE, address, format_prot(prot)); - 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 offset = (uint64_t)address % PAGE_SIZE; - void* result = MemoryManager::get_pages_at((uint64_t)address - offset, - Utilities::get_blocks_from_size(PAGE_SIZE, size), real_flags); - if (result) - { - kdbgln("mmap() succeeded: %p", result); - context->rax = (uint64_t)result; - return; - } - else - { - kwarnln("mmap() failed: failed to allocate physical memory"); - context->rax = MAP_FAIL(ENOMEM); - return; - } - } - kdbgln("mmap(): %ld pages at any address, %s", Utilities::get_blocks_from_size(PAGE_SIZE, size), format_prot(prot)); - 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; - } - void* result = MemoryManager::get_pages_at(ptr, Utilities::get_blocks_from_size(PAGE_SIZE, size), real_flags); - if (result) - { - kdbgln("mmap() succeeded: %p", result); - context->rax = (uint64_t)result; - return; - } - else - { - kwarnln("mmap() failed: failed to allocate physical memory"); - context->rax = MAP_FAIL(ENOMEM); - 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 phys = VMM::get_physical((uint64_t)address); - if (phys == (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)); - MemoryManager::release_pages((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 phys = VMM::get_physical((uint64_t)address); - if (phys == (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), - mman_flags_from_prot(prot)); - kdbgln("mprotect() succeeded"); - context->rax = 0; - return; -} \ No newline at end of file diff --git a/kernel/src/sys/paint.cpp b/kernel/src/sys/paint.cpp deleted file mode 100644 index 18e462c1..00000000 --- a/kernel/src/sys/paint.cpp +++ /dev/null @@ -1,27 +0,0 @@ -#include "bootboot.h" -#include "interrupts/Context.h" -#include "render/Framebuffer.h" -#include "std/errno.h" -#include - -extern BOOTBOOT bootboot; - -void sys_paint(Context* context, uint64_t x, uint64_t y, uint64_t w, uint64_t h, uint64_t c) -{ - if ((x + w) > bootboot.fb_width) - { - context->rax = -EINVAL; - return; - } - if ((y + h) > bootboot.fb_height) - { - context->rax = -EINVAL; - return; - } - - uint32_t color = (uint32_t)c; - - framebuffer0.paint_rect((uint32_t)x, (uint32_t)y, (uint32_t)w, (uint32_t)h, Color::from_integer(color)); - - context->rax = 0; -} \ 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 d9eaa750..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. - 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* kstat = obtain_user_ref(buf); - if (!kstat) - { - context->rax = -EFAULT; // FIXME: The manual doesn't say fstat can return EFAULT, but it seems logical here... - return; - } - kstat->st_ino = node->inode; - kstat->st_mode = node->mode | ((1 << (node->type)) * 010000); - kstat->st_size = node->length; - kstat->st_uid = node->uid; - kstat->st_gid = node->gid; - kstat->st_atime = node->atime; - kstat->st_ctime = node->ctime; - kstat->st_mtime = node->mtime; - release_user_ref(kstat); - 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) -{ - char* kpath = strdup_from_user(path); - if (!kpath) - { - context->rax = -EFAULT; - return; - } - 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 8cc05a74..00000000 --- a/kernel/src/sys/stdio.cpp +++ /dev/null @@ -1,383 +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->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()->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 (!addr) - { - context->rax = -EFAULT; - return; - } - int err; - Descriptor* file = Scheduler::current_task()->descriptor_from_fd(fd, err); - if (!file) - { - context->rax = -err; - return; - } - if (!file->can_write()) - { - context->rax = -EBADF; - return; - } - ssize_t result = file->write(size, (const char*)VMM::get_physical((uint64_t)addr)); - context->rax = (size_t)result; - return; -} - -void sys_open(Context* context, const char* filename, int flags, mode_t) // FIXME: mode is not used. -{ - Task* current_task = Scheduler::current_task(); - int fd = current_task->alloc_fd(); - if (fd < 0) - { - context->rax = -EMFILE; - return; - } - - char* kfilename = strdup_from_user(filename); - if (!kfilename) - { - context->rax = -EFAULT; - return; - } - - VFS::Node* node = VFS::resolve_path(kfilename); - if (!node) - { - bool create = (flags & OPEN_CREATE) > 0; - if (create) kwarnln("FIXME: open(O_CREAT) is not implemented"); - kfree(kfilename); - context->rax = -ENOENT; - return; - } - else - { - bool excl = (flags & OPEN_EXCL) > 0; - - if (excl) - { - kfree(kfilename); - context->rax = -EEXIST; - return; - } - } - - 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 %d 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 %d 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 (!buffer) - { - context->rax = -EFAULT; - return; - } - int err; - Descriptor* file = Scheduler::current_task()->descriptor_from_fd(fd, err); - if (!file) - { - context->rax = -err; - return; - } - if (!file->is_open() || !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 = (char*)VMM::get_physical((uint64_t)buffer); // FIXME: Handle errors. - current_task->blocking_read_info.size = size; - return Scheduler::task_yield(context); - } - ssize_t result = - file->read(size, (char*)VMM::get_physical((uint64_t)buffer)); // FIXME: Handle errors, and big buffers which may - // not be across continuous physical pages. - context->rax = (size_t)result; - return; -} - -void sys_close(Context* context, int fd) -{ - int err; - Descriptor* file = Scheduler::current_task()->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) -{ - char* kfilename = strdup_from_user(filename); - if (!kfilename) - { - context->rax = -EFAULT; - return; - } - - 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. -{ - char* kpath = strdup_from_user(path); - 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()->descriptor_from_fd(fd, err); - if (!file1) - { - context->rax = -err; - return; - } - if (!file1->is_open()) - { - context->rax = -EBADF; - 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; -} \ 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 8248095d..00000000 --- a/kernel/src/thread/Scheduler.cpp +++ /dev/null @@ -1,669 +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/assert.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 { - 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) - { - ASSERT(!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(), 1); - 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; - ASSERT(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); // 16 KB is enough for everyone, right? - 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; - ASSERT(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(); - 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); - ASSERT(image); - new_task->user_task = true; - new_task->regs.rip = image->entry; - new_task->image = image; - new_task->allocated_stack = (uint64_t)MemoryManager::get_pages_at( - 0x100000, TASK_PAGES_IN_STACK, MAP_READ_WRITE | MAP_USER); // 16 KB is enough for everyone, right? - 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) -{ - ASSERT(!Interrupts::is_in_handler()); - task_num--; - Task* exiting_task = task; - ASSERT(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 - { -#ifndef RUN_TEST_AS_INIT - reboot(); -#else - hang(); -#endif - } - Scheduler::task_yield(context); -} - -void Scheduler::task_exit(Context* context, int64_t status) -{ - ASSERT(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) -{ - ASSERT(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(); - ASSERT(!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) -{ - ASSERT(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) -{ - ASSERT(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; - } - int* kwstatus; - if (wstatus) - { - kwstatus = obtain_user_ref(wstatus); - if (!kwstatus) - { - context->rax = -EFAULT; - 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; - if (wstatus) sched_current_task->blocking_wait_info.wstatus = kwstatus; - else - sched_current_task->blocking_wait_info.wstatus = nullptr; - 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; - } - int* kwstatus; - if (wstatus) - { - kwstatus = obtain_user_ref(wstatus); - if (!kwstatus) - { - context->rax = -EFAULT; - return; - } - } - sched_current_task->state = sched_current_task->Blocking; - sched_current_task->block_reason = BlockReason::Waiting; - sched_current_task->blocking_wait_info.pid = pid; - if (wstatus) sched_current_task->blocking_wait_info.wstatus = kwstatus; - else - sched_current_task->blocking_wait_info.wstatus = nullptr; - return Scheduler::task_yield(context); - } - if (wstatus) - { - int* kwstatus = obtain_user_ref(wstatus); - if (kwstatus) - { - *kwstatus = (int)(child->exit_status & 0xff); - release_user_ref(kwstatus); - } - else - { - kinfoln("wstatus ptr is invalid: %p", (void*)wstatus); - child->state = child->Exited; - context->rax = -EFAULT; - return; - } - } - child->state = child->Exited; - context->rax = (long)child->id; -} - -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); - ASSERT(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() -{ - ASSERT(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); - ASSERT(child); // This should also already have been validated. - - if (blocking_wait_info.wstatus) - { - *blocking_wait_info.wstatus = (int)(child->exit_status & 0xff); - release_user_ref(blocking_wait_info.wstatus); - } - - child->state = child->Exited; - regs.rax = (long)child->id; -} - -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; - } - if (buf) - { - struct pstat* kpstat = obtain_user_ref(buf); - if (!kpstat) - { - context->rax = -EFAULT; - return; - } - kpstat->pt_pid = task->id; - kpstat->pt_ppid = task->ppid; - kpstat->pt_state = (int)task->state; - kpstat->pt_time = (long)task->cpu_time; - kpstat->pt_uid = task->uid; - kpstat->pt_gid = task->gid; - strlcpy(kpstat->pt_name, task->name, sizeof(kpstat->pt_name)); - release_user_ref(kpstat); - } - context->rax = task->id; - return; -} \ 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 89c4f772..00000000 --- a/kernel/src/thread/Task.cpp +++ /dev/null @@ -1,133 +0,0 @@ -#define MODULE "sched" - -#include "thread/Task.h" -#include "log/Log.h" -#include "memory/VMM.h" -#include "std/assert.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].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_previous_user_address_space(); - switch (block_reason) - { - case BlockReason::None: return; - case BlockReason::Reading: resume_read(); break; - case BlockReason::Waiting: resume_wait(); break; - - default: ASSERT(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::descriptor_from_fd(int fd, int& error) -{ - if (fd < 0 || fd >= TASK_MAX_FDS) - { - error = EBADF; - return nullptr; - } - if (!files[fd].is_open()) - { - error = EBADF; - return nullptr; - } - return &files[fd]; -} - -bool Task::is_superuser() -{ - return euid == 0 || egid == 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 6ed569ee..00000000 --- a/kernel/src/trace/Resolve.cpp +++ /dev/null @@ -1,41 +0,0 @@ -#include "trace/Resolve.h" -#include "init/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/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 6ff35a0d..00000000 --- a/libs/libc/Makefile +++ /dev/null @@ -1,74 +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 -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 $^ - -$(LIBC_OBJ)/%.c.o: $(LIBC_SRC)/%.c - @mkdir -p $(@D) - $(CC) $(CFLAGS) -o $@ -c $^ - -$(LIBC_OBJ)/%.asm.o: $(LIBC_SRC)/%.asm - @mkdir -p $(@D) - $(ASM) $(ASMFLAGS) -o $@ $^ - -$(LIBC_BIN)/libc.a: $(OBJS) - @mkdir -p $(@D) - $(AR) rcs $@ $(OBJS) - -$(LIBC_BIN)/crt0.o: $(LIBC_DIR)/crt0.asm - @mkdir -p $(@D) - $(ASM) $(ASMFLAGS) -o $@ $^ - -$(LIBC_BIN)/crti.o: $(LIBC_DIR)/crti.asm - @mkdir -p $(@D) - $(ASM) $(ASMFLAGS) -o $@ $^ - -$(LIBC_BIN)/crtn.o: $(LIBC_DIR)/crtn.asm - @mkdir -p $(@D) - $(ASM) $(ASMFLAGS) -o $@ $^ - -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 $^ $@ - -$(DESTDIR)/crt0.o: $(LIBC_BIN)/crt0.o - @mkdir -p $(@D) - cp $^ $@ - -$(DESTDIR)/crti.o: $(LIBC_BIN)/crti.o - @mkdir -p $(@D) - cp $^ $@ - -$(DESTDIR)/crtn.o: $(LIBC_BIN)/crtn.o - @mkdir -p $(@D) - cp $^ $@ - -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 ad7a5729..00000000 --- a/libs/libc/include/dirent.h +++ /dev/null @@ -1,57 +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]; -}; - -/* 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 242141b6..00000000 --- a/libs/libc/include/errno.h +++ /dev/null @@ -1,40 +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 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 ENOMEM 12 // Cannot allocate memory -#define EACCES 13 // Permission denied -#define EFAULT 14 // Bad address -#define EEXIST 17 // File exists -#define ENOTDIR 20 // Not a directory -#define EISDIR 21 // Is a directory -#define EINVAL 22 // Invalid argument -#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 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 ENOSYS 38 // Function not implemented -#define ENOTSUP 95 // Operation not supported -#define EOPNOTSUPP 95 // Operation not supported - -#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 7aeaeae1..00000000 --- a/libs/libc/include/fcntl.h +++ /dev/null @@ -1,52 +0,0 @@ -#ifndef _FCNTL_H -#define _FCNTL_H - -/* 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, ...); - - /* 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 2fc432d9..00000000 --- a/libs/libc/include/locale.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef _LOCALE_H -#define _LOCALE_H - -#define LC_ALL 0 -#define LC_CTYPE 1 -#define LC_COLLATE 2 - -#ifdef __cplusplus -extern "C" -{ -#endif - - char* setlocale(int category, const char* locale); // Not implemented. - -#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 4d1ebb27..00000000 --- a/libs/libc/include/luna/os-limits.h +++ /dev/null @@ -1,12 +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 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 e69de29b..00000000 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 8790b487..00000000 --- a/libs/libc/include/signal.h +++ /dev/null @@ -1,9 +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. - -#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 6157c1b3..00000000 --- a/libs/libc/include/stdio.h +++ /dev/null @@ -1,174 +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. - - /* 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. - - 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 397c9d3d..00000000 --- a/libs/libc/include/stdlib.h +++ /dev/null @@ -1,129 +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(). - -// 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); - - /* 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); - - void qsort(void*, size_t, size_t, int (*)(const void*, const void*)); // Not implemented. - - void* bsearch(const void*, const void*, size_t, size_t, int (*)(const void*, const void*)); // Not implemented. - - size_t mbstowcs(wchar_t* dest, const char* src, - size_t n); // Not implemented. - - char* mktemp(char* base); // Not implemented. - -#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 854c2eab..00000000 --- a/libs/libc/include/string.h +++ /dev/null @@ -1,95 +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); - - /* 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 __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/mman.h b/libs/libc/include/sys/mman.h deleted file mode 100644 index 054e9c48..00000000 --- a/libs/libc/include/sys/mman.h +++ /dev/null @@ -1,40 +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 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 93a00ba6..00000000 --- a/libs/libc/include/sys/stat.h +++ /dev/null @@ -1,77 +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. - 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)) - -#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 f4699257..00000000 --- a/libs/libc/include/sys/syscall.h +++ /dev/null @@ -1,33 +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_paint 4 -#define SYS_getprocid 5 -#define SYS_mmap 6 -#define SYS_munmap 7 -#define SYS_open 8 -#define SYS_read 9 -#define SYS_close 10 -#define SYS_seek 11 -#define SYS_execv 12 -#define SYS_fcntl 13 -#define SYS_mprotect 14 -#define SYS_clock_gettime 15 -#define SYS_mkdir 16 -#define SYS_fork 17 -#define SYS_waitpid 18 -#define SYS_access 19 -#define SYS_fstat 20 -#define SYS_pstat 21 -#define SYS_getdents 22 -#define SYS_stat 23 -#define SYS_dup2 24 -#define SYS_setuid 25 -#define SYS_setgid 26 -#define SYS_umask 27 - -#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 3921b6ff..00000000 --- a/libs/libc/include/time.h +++ /dev/null @@ -1,84 +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); - -#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 146464d9..00000000 --- a/libs/libc/include/unistd.h +++ /dev/null @@ -1,110 +0,0 @@ -#ifndef _UNISTD_H -#define _UNISTD_H - -#include -#include -#include -#include - -#define STDIN_FILENO 0 // The standard input stream. -#define STDOUT_FILENO 1 // The standard output stream. -#define STDERR_FILENO 2 // The standard error stream. - -#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. - -#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 uid); - - /* 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 gid); - - /* 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. - -#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 e69de29b..00000000 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 5c58ef0b..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, 0, 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/dirent.cpp b/libs/libc/src/dirent.cpp deleted file mode 100644 index 221f7cca..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 = 0; - 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 0d37118c..00000000 --- a/libs/libc/src/fcntl.cpp +++ /dev/null @@ -1,26 +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 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 147a82e0..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) - { - ssize_t status = - read(stream->f_fd, buf, - size * nmemb); // FIXME: This function should use file_read_buf() to not conflict with fgets(). - if (status < 0) - { - stream->f_err = 1; - return 0; - } - if (status == 0) stream->f_eof = 1; - return (size_t)status; - } - - 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); // FIXME: Store the last seeked position in the file struct to avoid redundant syscalls - // maybe? We'd have to update this value in fread() and fwrite() as well... - } - - 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) - { - ssize_t status = write(stream->f_fd, buf, size * nmemb); - if (status < 0) - { - stream->f_err = 1; - return 0; - } - if (status == 0) stream->f_eof = 1; - return (size_t)status; - } - - 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 5c740b7b..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(-127); - if (!*target_stream) exit(-127); - 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/kbd", "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 bf6167c0..00000000 --- a/libs/libc/src/locale.cpp +++ /dev/null @@ -1,12 +0,0 @@ -#include -#include - -static char default_locale[] = "C"; - -extern "C" -{ - char* setlocale(int, const char*) - { - return default_locale; - } -} \ 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/printf.cpp b/libs/libc/src/printf.cpp deleted file mode 100644 index efe3a60c..00000000 --- a/libs/libc/src/printf.cpp +++ /dev/null @@ -1,330 +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 '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/stdio.cpp b/libs/libc/src/stdio.cpp deleted file mode 100644 index 737d0cca..00000000 --- a/libs/libc/src/stdio.cpp +++ /dev/null @@ -1,72 +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"); - } - - 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 d924674e..00000000 --- a/libs/libc/src/stdlib.cpp +++ /dev/null @@ -1,195 +0,0 @@ -#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; -} - -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*, size_t, size_t, int (*)(const void*, const void*)) - { - NOT_IMPLEMENTED("qsort"); - } - - void* bsearch(const void*, const void*, size_t, size_t, int (*)(const void*, const void*)) - { - NOT_IMPLEMENTED("bsearch"); - } - - size_t mbstowcs(wchar_t*, const char*, size_t) - { - NOT_IMPLEMENTED("mbstowcs"); - } - - char* mktemp(char*) - { - NOT_IMPLEMENTED("mktemp"); - } -} \ 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 092123c2..00000000 --- a/libs/libc/src/string.cpp +++ /dev/null @@ -1,292 +0,0 @@ -#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; - } - - 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 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++) *(char*)(dest + dest_len + i) = *(const char*)(src + i); - - *(char*)(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++) *(char*)(dest + dest_len + i) = *(const char*)(src + i); - - *(char*)(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 -} \ 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 7c27a9ba..00000000 --- a/libs/libc/src/strings.cpp +++ /dev/null @@ -1,43 +0,0 @@ -#include -#include -#include - -static char fold(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 && (fold(*a) == fold(*b))) - { - a++; - b++; - } - return (unsigned char)fold(*a) - (unsigned char)fold(*b); - } - - int strncasecmp(const char* a, const char* b, size_t max) - { - const char* base = a; - while (*a && (fold(*a) == fold(*b)) && (size_t)(a - base) < (max - 1)) - { - a++; - b++; - } - return (unsigned char)fold(*a) - (unsigned char)fold(*b); - } -} \ 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 ec4356f1..00000000 --- a/libs/libc/src/sys/mman.cpp +++ /dev/null @@ -1,23 +0,0 @@ -#include -#include -#include - -extern "C" -{ - // FIXME: Implement a POSIX-compliant mmap. - void* mmap(void* addr, size_t len, int prot, int, int, off_t) - { - long result = __luna_syscall3(SYS_mmap, (sysarg_t)addr, (sysarg_t)len, (sysarg_t)prot); - _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 42602131..00000000 --- a/libs/libc/src/syscall.cpp +++ /dev/null @@ -1,67 +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_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_setuid: - case SYS_setgid: - 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_mprotect: - case SYS_waitpid: - case SYS_mmap: { - 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_paint: { - 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 4643eec5..00000000 --- a/libs/libc/src/time.cpp +++ /dev/null @@ -1,178 +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); - } -} \ 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 304bcabf..00000000 --- a/libs/libc/src/unistd.cpp +++ /dev/null @@ -1,166 +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_syscall2(SYS_setuid, uid, uid); - } - - int seteuid(uid_t uid) - { - return (int)__lc_fast_syscall2(SYS_setuid, getprocid(ID_UID), uid); - } - - int setgid(gid_t gid) - { - return (int)__lc_fast_syscall2(SYS_setgid, gid, gid); - } - - int setegid(gid_t gid) - { - return (int)__lc_fast_syscall2(SYS_setgid, getprocid(ID_GID), gid); - } - - 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"); - } -} \ 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/moon/.cargo/config.toml b/moon/.cargo/config.toml new file mode 100644 index 00000000..031d0482 --- /dev/null +++ b/moon/.cargo/config.toml @@ -0,0 +1,6 @@ +[unstable] +build-std-features = ["compiler-builtins-mem"] +build-std = ["core", "compiler_builtins"] + +[build] +target = "triplets/moon-x86.json" \ No newline at end of file diff --git a/moon/Cargo.lock b/moon/Cargo.lock new file mode 100644 index 00000000..41cd94e9 --- /dev/null +++ b/moon/Cargo.lock @@ -0,0 +1,7 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "moon" +version = "0.1.0" diff --git a/moon/Cargo.toml b/moon/Cargo.toml new file mode 100644 index 00000000..ed44c50e --- /dev/null +++ b/moon/Cargo.toml @@ -0,0 +1,18 @@ +[package] +name = "moon" +version = "0.1.0" +edition = "2021" +license = "BSD-2-Clause" + +[profile.dev] +panic = "abort" +opt-level = 2 + +[profile.release] +panic = "abort" +opt-level = 's' +strip = "debuginfo" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/moon/moon.ld b/moon/moon.ld new file mode 100644 index 00000000..d95d7845 --- /dev/null +++ b/moon/moon.ld @@ -0,0 +1,45 @@ +ENTRY(_start) +OUTPUT_FORMAT(elf64-x86-64) + +mmio = 0xfffffffff8000000; +fb = 0xfffffffffc000000; +bootboot = 0xffffffffffe00000; +environment = 0xffffffffffe01000; +initstack = 4096; + +KERNEL_OFFSET = 0xffffffffffe02000; + +PHDRS +{ + boot PT_LOAD FILEHDR PHDRS; +} +SECTIONS +{ + . = 0xffffffffffe02000; + .text . + SIZEOF_HEADERS : AT(ADDR(.text) - KERNEL_OFFSET + SIZEOF_HEADERS) { + __text_start = .; + KEEP(*(.text.boot)) *(.text .text.* .gnu.linkonce.t*) + . = ALIGN(4096); + __text_end = .; + } :boot + + .rodata : AT(ADDR(.rodata) - KERNEL_OFFSET) { + __rodata_start = .; + *(.rodata*) + . = ALIGN(4096); + __rodata_end = .; + } :boot + + .data : AT(ADDR(.data) - KERNEL_OFFSET) { + __data_start = .; + *(.data*) + . = ALIGN(4096); + __data_end = .; + __bss_start = .; + *(.bss*) + . = ALIGN(4096); + __bss_end = .; + } :boot + + /DISCARD/ : { *(.eh_frame) *(.comment) } +} diff --git a/moon/src/bootboot.rs b/moon/src/bootboot.rs new file mode 100644 index 00000000..33101537 --- /dev/null +++ b/moon/src/bootboot.rs @@ -0,0 +1,89 @@ +#![allow(dead_code)] + +pub const BOOTBOOT_MAGIC: &'static [u8; 5usize] = b"BOOT\0"; +pub const PROTOCOL_MINIMAL: u32 = 0; +pub const PROTOCOL_STATIC: u32 = 1; +pub const PROTOCOL_DYNAMIC: u32 = 2; +pub const PROTOCOL_BIGENDIAN: u32 = 128; +pub const LOADER_BIOS: u32 = 0; +pub const LOADER_UEFI: u32 = 4; +pub const LOADER_RPI: u32 = 8; +pub const FB_ARGB: u32 = 0; +pub const FB_RGBA: u32 = 1; +pub const FB_ABGR: u32 = 2; +pub const FB_BGRA: u32 = 3; +pub const MMAP_USED: u32 = 0; +pub const MMAP_FREE: u32 = 1; +pub const MMAP_ACPI: u32 = 2; +pub const MMAP_MMIO: u32 = 3; +pub const INITRD_MAXSIZE: u32 = 16; + +pub const BOOTBOOT_MMIO: u64 = 0xfffffffff8000000; /* memory mapped IO virtual address */ +pub const BOOTBOOT_FB: u64 = 0xfffffffffc000000; /* frame buffer virtual address */ +pub const BOOTBOOT_INFO: u64 = 0xffffffffffe00000; /* bootboot struct virtual address */ +pub const BOOTBOOT_ENV: u64 = 0xffffffffffe01000; /* environment string virtual address */ +pub const BOOTBOOT_CORE: u64 = 0xffffffffffe02000; /* core loadable segment start */ + +#[repr(C, packed)] +#[derive(Debug, Copy, Clone)] +pub struct MMapEnt { + pub ptr: u64, + pub size: u64, +} + +#[repr(C, packed)] +#[derive(Copy, Clone)] +pub struct BOOTBOOT { + pub magic: [u8; 4usize], + pub size: u32, + pub protocol: u8, + pub fb_type: u8, + pub numcores: u16, + pub bspid: u16, + pub timezone: i16, + pub datetime: [u8; 8usize], + pub initrd_ptr: u64, + pub initrd_size: u64, + pub fb_ptr: *mut u8, + pub fb_size: u32, + pub fb_width: u32, + pub fb_height: u32, + pub fb_scanline: u32, + pub arch: arch_union, + pub mmap: MMapEnt, +} + +#[repr(C)] +#[derive(Copy, Clone)] +pub union arch_union { + pub x86_64: arch_x86, + pub aarch64: arch_aarch64, + _bindgen_union_align: [u64; 8usize], +} + +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct arch_x86 { + pub acpi_ptr: u64, + pub smbi_ptr: u64, + pub efi_ptr: u64, + pub mp_ptr: u64, + pub unused0: u64, + pub unused1: u64, + pub unused2: u64, + pub unused3: u64, +} + + +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct arch_aarch64 { + pub acpi_ptr: u64, + pub mmio_ptr: u64, + pub efi_ptr: u64, + pub unused0: u64, + pub unused1: u64, + pub unused2: u64, + pub unused3: u64, + pub unused4: u64, +} \ No newline at end of file diff --git a/moon/src/main.rs b/moon/src/main.rs new file mode 100644 index 00000000..750db61e --- /dev/null +++ b/moon/src/main.rs @@ -0,0 +1,13 @@ +#![no_std] +#![no_main] + +mod video; +mod bootboot; +mod panic; +mod util; + +#[no_mangle] +pub extern "C" fn _start() -> ! { + video::clear(0xffffffff); + loop {} +} diff --git a/moon/src/panic.rs b/moon/src/panic.rs new file mode 100644 index 00000000..a5f300c2 --- /dev/null +++ b/moon/src/panic.rs @@ -0,0 +1,6 @@ +use core::panic::PanicInfo; + +#[panic_handler] +fn panic(_info: &PanicInfo) -> ! { + loop {} +} \ No newline at end of file diff --git a/moon/src/util.rs b/moon/src/util.rs new file mode 100644 index 00000000..0757e313 --- /dev/null +++ b/moon/src/util.rs @@ -0,0 +1,5 @@ +use crate::bootboot::{BOOTBOOT, BOOTBOOT_INFO}; + +pub fn get_bootboot() -> BOOTBOOT { + return unsafe { *(BOOTBOOT_INFO as *const BOOTBOOT) } +} \ No newline at end of file diff --git a/moon/src/video.rs b/moon/src/video.rs new file mode 100644 index 00000000..071b6deb --- /dev/null +++ b/moon/src/video.rs @@ -0,0 +1,27 @@ +use crate::bootboot::{BOOTBOOT, BOOTBOOT_FB}; +use crate::util::get_bootboot; + +use BOOTBOOT_FB as FB; + +pub fn put_pixel(x: u32, y: u32, color: u32) -> () { + let boot: BOOTBOOT = get_bootboot(); + let ptr: u64 = FB + (boot.fb_scanline * y) as u64 + (x * 4) as u64; + unsafe { *(ptr as *mut u32) = color }; +} + +pub fn draw_rect(x: u32, y: u32, width: u32, height: u32, color: u32) -> () { + let boot: BOOTBOOT = get_bootboot(); + for i in y..(y + height) + { + let addr: u64 = FB + (boot.fb_scanline * i) as u64 + (x * 4) as u64; + for ptr in (addr..(addr + (width*4) as u64)).step_by(4) + { + unsafe { *(ptr as *mut u32) = color }; + } + } +} + +pub fn clear(color: u32) -> () { + let boot: BOOTBOOT = get_bootboot(); + draw_rect(0, 0, boot.fb_width, boot.fb_height, color) +} \ No newline at end of file diff --git a/moon/triplets/moon-x86.json b/moon/triplets/moon-x86.json new file mode 100644 index 00000000..b2e890fb --- /dev/null +++ b/moon/triplets/moon-x86.json @@ -0,0 +1,26 @@ +{ + "llvm-target": "x86_64-unknown-none", + "data-layout": "e-m:e-i64:64-f80:128-n8:16:32:64-S128", + "arch": "x86_64", + "target-endian": "little", + "target-pointer-width": "64", + "target-c-int-width": "32", + "os": "none", + "executables": true, + "linker-flavor": "ld.lld", + "linker": "rust-lld", + "panic-strategy": "abort", + "disable-redzone": true, + "features": "-mmx,-sse,+soft-float", + "dynamic-linking": false, + "relocation-model": "pic", + "code-model": "kernel", + "exe-suffix": "", + "has-rpath": false, + "no-default-libraries": true, + "position-independent-executables": false, + "pre-link-args": { + "ld.lld": ["--script=./moon.ld"] + } + } + \ 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/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 c09679ef..00000000 --- a/ports/list-ports.sh +++ /dev/null @@ -1,55 +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." -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 e099120b..00000000 --- a/ports/nasm/package.sh +++ /dev/null @@ -1,42 +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 - rm -f $DESTDIR/bin/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 1ba9da60..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)/Test.c -I$(LUNA_ROOT)/tests -o $(TESTDIR)/bin/test-libc -Wall -Wextra -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 07d30a79..00000000 --- a/tests/libc/Test.c +++ /dev/null @@ -1,54 +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(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); - -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(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); -} \ No newline at end of file diff --git a/tests/libc/stdlib.c b/tests/libc/stdlib.c deleted file mode 100644 index db5a56ce..00000000 --- a/tests/libc/stdlib.c +++ /dev/null @@ -1,140 +0,0 @@ -#include "Test.h" -#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(); -} \ No newline at end of file diff --git a/tests/libc/string.c b/tests/libc/string.c deleted file mode 100644 index bd50a930..00000000 --- a/tests/libc/string.c +++ /dev/null @@ -1,337 +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(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/tools/binutils.patch b/tools/binutils.patch deleted file mode 100644 index d375e06f..00000000 --- a/tools/binutils.patch +++ /dev/null @@ -1,117 +0,0 @@ -diff --color -rN -u binutils-2.38/bfd/config.bfd build/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-10-01 22:12:16.914033792 +0200 -@@ -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 build/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-10-01 22:12:38.115093972 +0200 -@@ -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/ld/configure.tgt build/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-10-01 22:15:04.853571062 +0200 -@@ -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 build/binutils-2.38/ld/emulparams/elf_i386_luna.sh ---- a/dev/null 1970-01-01 01:00:00.000000000 +0100 -+++ b/binutils-2.38/ld/emulparams/elf_i386_luna.sh 2022-10-01 21:52:12.394068335 +0200 -@@ -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 build/binutils-2.38/ld/emulparams/elf_x86_64_luna.sh ---- a/dev/null 1970-01-01 01:00:00.000000000 +0100 -+++ b/binutils-2.38/ld/emulparams/elf_x86_64_luna.sh 2022-10-01 21:53:00.411200592 +0200 -@@ -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 build/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-10-01 22:18:02.660263017 +0200 -@@ -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 build/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-10-01 22:17:46.740196925 +0200 -@@ -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 --git a/tools/build-debug.sh b/tools/build-debug.sh deleted file mode 100755 index 877def35..00000000 --- a/tools/build-debug.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/usr/bin/env bash - -set -e -source $(dirname $0)/env.sh - -MOON_BUILD_DEBUG=1 tools/rebuild-iso.sh \ No newline at end of file diff --git a/tools/build-iso.sh b/tools/build-iso.sh index c810c1e9..c9371bc6 100755 --- a/tools/build-iso.sh +++ b/tools/build-iso.sh @@ -5,11 +5,7 @@ source $(dirname $0)/env.sh cd $LUNA_ROOT -tools/setup.sh - -tools/install-headers.sh - -make -j$(nproc) -make install +tools/build.sh +tools/install.sh mkbootimg luna.json Luna.iso \ No newline at end of file diff --git a/tools/build-stable-iso.sh b/tools/build-stable-iso.sh index 270c97b1..2b33114d 100755 --- a/tools/build-stable-iso.sh +++ b/tools/build-stable-iso.sh @@ -5,4 +5,7 @@ source $(dirname $0)/env.sh cd $LUNA_ROOT -MOON_BUILD_STABLE=1 tools/rebuild-iso.sh \ No newline at end of file +tools/build-stable.sh +tools/install-stable.sh + +mkbootimg luna.json Luna.iso \ No newline at end of file diff --git a/tools/gdb.sh b/tools/build-stable.sh old mode 100755 new mode 100644 similarity index 58% rename from tools/gdb.sh rename to tools/build-stable.sh index f0363a98..c0a5a8bc --- a/tools/gdb.sh +++ b/tools/build-stable.sh @@ -1,6 +1,8 @@ #!/usr/bin/env bash - set -e + source $(dirname $0)/env.sh -gdb -x .gdbconf \ No newline at end of file +cd $LUNA_ROOT/moon + +cargo build --release \ No newline at end of file diff --git a/tools/build.sh b/tools/build.sh index 0d0e5d9e..373be215 100755 --- a/tools/build.sh +++ b/tools/build.sh @@ -3,10 +3,6 @@ set -e source $(dirname $0)/env.sh -cd $LUNA_ROOT +cd $LUNA_ROOT/moon -tools/setup.sh - -tools/install-headers.sh - -make -j$(nproc) \ No newline at end of file +cargo build \ No newline at end of file diff --git a/tools/clean.sh b/tools/clean.sh index e005b12c..1d77d998 100755 --- a/tools/clean.sh +++ b/tools/clean.sh @@ -3,6 +3,6 @@ set -e source $(dirname $0)/env.sh -cd $LUNA_ROOT +cd $LUNA_ROOT/moon -make clean \ No newline at end of file +cargo clean \ No newline at end of file diff --git a/tools/debug.sh b/tools/debug.sh deleted file mode 100755 index ad05afad..00000000 --- a/tools/debug.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/usr/bin/env bash - -set -e -source $(dirname $0)/env.sh - -qemu-system-x86_64 -cdrom Luna.iso -smp 1 -m 256M -serial stdio -d int,cpu_reset -s $@ \ No newline at end of file diff --git a/tools/env.sh b/tools/env.sh index 4a9e8061..fb401817 100755 --- a/tools/env.sh +++ b/tools/env.sh @@ -1,16 +1,3 @@ #!/usr/bin/env bash export LUNA_ROOT=${LUNA_ROOT:-$(realpath $(dirname $0)/..)} -export LUNA_BASE=${LUNA_BASE:-$LUNA_ROOT/base} -export PATH=$LUNA_ROOT/toolchain/x86-64-luna/bin:$LUNA_ROOT/toolchain/dist:$PATH - -export CC=x86_64-luna-gcc -export CXX=x86_64-luna-g++ -export LD=x86_64-luna-ld -export AR=x86_64-luna-ar -export ASM=nasm -export STRIP=x86_64-luna-strip - -filter-lines() -{ - sed $'s|^|\x1b[32m('"$1/$2"$')\x1b[39m |' -} \ No newline at end of file +export PATH=$LUNA_ROOT/toolchain/dist:$PATH \ No newline at end of file diff --git a/tools/gcc.patch b/tools/gcc.patch deleted file mode 100644 index 04500e4d..00000000 --- a/tools/gcc.patch +++ /dev/null @@ -1,137 +0,0 @@ -diff --color -rN -u gcc-12.2.0/config.sub build/gcc-12.2.0/config.sub ---- a/gcc-12.2.0/config.sub 2022-08-19 10:09:52.128656687 +0200 -+++ b/gcc-12.2.0/config.sub 2022-10-02 11:27:45.660055384 +0200 -@@ -1723,7 +1723,7 @@ - | hpux* | unos* | osf* | luna* | dgux* | auroraux* | solaris* \ - | sym* | plan9* | psp* | sim* | xray* | os68k* | v88r* \ - | hiux* | abug | nacl* | netware* | windows* \ -- | os9* | macos* | osx* | ios* \ -+ | os9* | macos* | osx* | ios* | luna* \ - | mpw* | magic* | mmixware* | mon960* | lnews* \ - | amigaos* | amigados* | msdos* | newsos* | unicos* | aof* \ - | aos* | aros* | cloudabi* | sortix* | twizzler* \ -diff --color -rN -u gcc-12.2.0/fixincludes/mkfixinc.sh build/gcc-12.2.0/fixincludes/mkfixinc.sh ---- a/gcc-12.2.0/fixincludes/mkfixinc.sh 2022-08-19 10:09:52.160657095 +0200 -+++ b/gcc-12.2.0/fixincludes/mkfixinc.sh 2022-10-02 11:27:45.662055397 +0200 -@@ -12,6 +12,8 @@ - # Check for special fix rules for particular targets - case $machine in - i?86-*-cygwin* | \ -+ *-luna* | \ -+ *-*-luna* | \ - i?86-*-mingw32* | \ - x86_64-*-mingw32* | \ - powerpc-*-eabisim* | \ -diff --color -rN -u gcc-12.2.0/gcc/config/i386/x86_64-luna-kernel build/gcc-12.2.0/gcc/config/i386/x86_64-luna-kernel ---- a/dev/null 1970-01-01 01:00:00.000000000 +0100 -+++ b/gcc-12.2.0/gcc/config/i386/x86_64-luna-kernel 2022-10-02 11:45:30.955856133 +0200 -@@ -0,0 +1,4 @@ -+#Add libgcc multilib variant without red-zone requirement, for use in the kernel -+ -+MULTILIB_OPTIONS += mno-red-zone -+MULTILIB_DIRNAMES += no-red-zone -\ No newline at end of file -diff --color -rN -u gcc-12.2.0/gcc/config/luna.h build/gcc-12.2.0/gcc/config/luna.h ---- a/dev/null 1970-01-01 01:00:00.000000000 +0100 -+++ b/gcc-12.2.0/gcc/config/luna.h 2022-10-02 11:27:45.663055404 +0200 -@@ -0,0 +1,40 @@ -+#undef TARGET_LUNA -+#define TARGET_LUNA 1 -+ -+/* Default arguments you want when running your -+ i686-luna-gcc/x86_64-luna-gcc toolchain */ -+#undef LIB_SPEC -+#define LIB_SPEC "-lc" /* link against C standard library */ -+ -+/* Files that are linked before user code. -+ The %s tells GCC to look for these files in the library directory. */ -+#undef STARTFILE_SPEC -+#define STARTFILE_SPEC "crt0.o%s crti.o%s crtbegin.o%s" -+ -+/* Files that are linked after user code. */ -+#undef ENDFILE_SPEC -+#define ENDFILE_SPEC "crtend.o%s crtn.o%s" -+ -+#undef PID_TYPE -+#define PID_TYPE "long int" -+ -+#undef SIZE_TYPE -+#define SIZE_TYPE (TARGET_64BIT ? "long unsigned int" : "unsigned int") -+ -+/* Ensure that ptrdiff_t matches the actual pointer size */ -+#undef PTRDIFF_TYPE -+#define PTRDIFF_TYPE (TARGET_64BIT ? "long int" : "int") -+ -+/* Additional predefined macros. */ -+#undef TARGET_OS_CPP_BUILTINS -+#define TARGET_OS_CPP_BUILTINS() \ -+ do { \ -+ builtin_define("__luna__"); \ -+ builtin_define("__unix__"); \ -+ builtin_assert("system=luna"); \ -+ builtin_assert("system=unix"); \ -+ builtin_assert("system=posix"); \ -+ } while (0); -+ -+#undef LINK_SPEC -+#define LINK_SPEC "-z max-page-size=4096" -\ No newline at end of file -diff --color -rN -u gcc-12.2.0/gcc/config.gcc build/gcc-12.2.0/gcc/config.gcc ---- a/gcc-12.2.0/gcc/config.gcc 2022-08-19 10:09:52.552662114 +0200 -+++ b/gcc-12.2.0/gcc/config.gcc 2022-10-02 11:45:18.311797546 +0200 -@@ -895,6 +895,12 @@ - ;; - esac - ;; -+*-*-luna*) -+ gas=yes -+ gnu_ld=yes -+ default_use_cxa_atexit=yes -+ use_gcc_stdint=provide -+ ;; - *-*-netbsd*) - tm_p_file="${tm_p_file} netbsd-protos.h" - tmake_file="t-netbsd t-slibgcc" -@@ -1901,6 +1907,13 @@ - x86_64-*-elf*) - tm_file="${tm_file} i386/unix.h i386/att.h dbxelf.h elfos.h newlib-stdint.h i386/i386elf.h i386/x86-64.h" - ;; -+i[34567]86-*-luna*) -+ tm_file="${tm_file} i386/unix.h i386/att.h dbxelf.h elfos.h newlib-stdint.h i386/i386elf.h luna.h" -+ ;; -+x86_64-*-luna*) -+ tmake_file="${tmake_file} i386/x86_64-luna-kernel" -+ tm_file="${tm_file} i386/unix.h i386/att.h dbxelf.h elfos.h newlib-stdint.h i386/i386elf.h i386/x86-64.h luna.h" -+ ;; - x86_64-*-rtems*) - tm_file="${tm_file} i386/unix.h i386/att.h dbxelf.h elfos.h newlib-stdint.h i386/i386elf.h i386/x86-64.h i386/rtemself.h rtems.h" - ;; -diff --color -rN -u gcc-12.2.0/libgcc/config.host build/gcc-12.2.0/libgcc/config.host ---- a/gcc-12.2.0/libgcc/config.host 2022-08-19 10:09:54.664689148 +0200 -+++ b/gcc-12.2.0/libgcc/config.host 2022-10-02 11:27:45.671055461 +0200 -@@ -783,6 +783,14 @@ - ;; - i[34567]86-*-lynxos*) - ;; -+i[34567]86-*-luna*) -+ extra_parts="$extra_parts crti.o crtbegin.o crtend.o crtn.o" -+ tmake_file="$tmake_file i386/t-crtstuff t-crtstuff-pic t-libgcc-pic" -+ ;; -+x86_64-*-luna*) -+ extra_parts="$extra_parts crti.o crtbegin.o crtend.o crtn.o" -+ tmake_file="$tmake_file i386/t-crtstuff t-crtstuff-pic t-libgcc-pic" -+ ;; - i[34567]86-*-nto-qnx*) - tmake_file="$tmake_file i386/t-nto t-libgcc-pic" - extra_parts=crtbegin.o -diff --color -rN -u gcc-12.2.0/libgcc/libgcov.h build/gcc-12.2.0/libgcc/libgcov.h ---- a/gcc-12.2.0/libgcc/libgcov.h 2022-08-19 10:09:54.728689966 +0200 -+++ b/gcc-12.2.0/libgcc/libgcov.h 2022-10-02 11:41:48.571807335 +0200 -@@ -194,6 +194,7 @@ - #endif - - #include "gcov-io.h" -+#include - - /* Structures embedded in coveraged program. The structures generated - by write_profile must match these. */ diff --git a/tools/generate-symbols.sh b/tools/generate-symbols.sh deleted file mode 100755 index 36bd4369..00000000 --- a/tools/generate-symbols.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/usr/bin/env bash - -set -e - -source $(dirname $0)/env.sh - -cd $LUNA_ROOT - -nm -C -n initrd/boot/moon.elf | grep -vE \\.Lubsan_data | awk '{ if ($2 != "a") print; }' | uniq > initrd/sys/moon.sym \ No newline at end of file diff --git a/tools/install-built-ports.sh b/tools/install-built-ports.sh deleted file mode 100755 index 8e21fbc4..00000000 --- a/tools/install-built-ports.sh +++ /dev/null @@ -1,53 +0,0 @@ -#!/usr/bin/env bash - -set -e - -source $(dirname $0)/env.sh - -cd $LUNA_ROOT/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 - unset islib -} - -if ! [ -f ./ports.list ] -then - echo "No ports built." - exit 0 -fi - -install_port() -{ - unset_vars - cd $LUNA_ROOT/ports - export DESTDIR=${DESTDIR:-"$LUNA_ROOT/initrd"} - export portdir=$PWD/$1 - export workdir=$portdir/workdir - source $portdir/package.sh - if ! [ "$islib" = "1" ] - then - echo "installing port: $pkgname version $pkgver" - mkdir -p $installdir - cd $installdir - port_install | filter-lines $pkgname "install" - fi -} - -while read package; do - install_port $package -done < ./ports.list diff --git a/tools/install-headers.sh b/tools/install-headers.sh deleted file mode 100755 index cbacbd09..00000000 --- a/tools/install-headers.sh +++ /dev/null @@ -1,13 +0,0 @@ -#!/usr/bin/env bash - -set -e -source $(dirname $0)/env.sh - -cd $LUNA_ROOT - -mkdir -p base -mkdir -p base/usr/include -mkdir -p base/usr/include/moon - -cp -RT libs/libc/include base/usr/include -cp -RT kernel/include base/usr/include/moon \ No newline at end of file diff --git a/tools/install-stable.sh b/tools/install-stable.sh new file mode 100644 index 00000000..820ab691 --- /dev/null +++ b/tools/install-stable.sh @@ -0,0 +1,8 @@ +#!/usr/bin/env bash +set -e + +source $(dirname $0)/env.sh + +cd $LUNA_ROOT/moon + +cp target/moon-x86/release/moon $LUNA_ROOT/initrd/boot/moon \ No newline at end of file diff --git a/tools/install.sh b/tools/install.sh index 7b903dc2..6f8a0c4d 100755 --- a/tools/install.sh +++ b/tools/install.sh @@ -3,6 +3,6 @@ set -e source $(dirname $0)/env.sh -cd $LUNA_ROOT +cd $LUNA_ROOT/moon -make install \ No newline at end of file +cp target/moon-x86/debug/moon $LUNA_ROOT/initrd/boot/moon \ No newline at end of file diff --git a/tools/rebuild-iso.sh b/tools/rebuild-iso.sh index fb38d5b3..66571639 100755 --- a/tools/rebuild-iso.sh +++ b/tools/rebuild-iso.sh @@ -5,13 +5,7 @@ source $(dirname $0)/env.sh cd $LUNA_ROOT -tools/setup.sh - -make clean - -tools/install-headers.sh - -make -j$(nproc) -make install +tools/rebuild.sh +tools/install.sh mkbootimg luna.json Luna.iso \ No newline at end of file diff --git a/tools/rebuild.sh b/tools/rebuild.sh index ee3649b0..c95750f4 100755 --- a/tools/rebuild.sh +++ b/tools/rebuild.sh @@ -5,10 +5,5 @@ source $(dirname $0)/env.sh cd $LUNA_ROOT -tools/setup.sh - -tools/install-headers.sh - -make clean - -make -j$(nproc) \ No newline at end of file +tools/clean.sh +tools/build.sh \ No newline at end of file diff --git a/tools/setup-binutils.sh b/tools/setup-binutils.sh deleted file mode 100755 index e7f59b03..00000000 --- a/tools/setup-binutils.sh +++ /dev/null @@ -1,50 +0,0 @@ -#!/usr/bin/env bash -set -e -source $(dirname $0)/setup-env.sh - -cd $LUNA_ROOT - -mkdir -p toolchain/tarballs -mkdir -p toolchain/build - -if [ ! -f toolchain/tarballs/binutils-$LUNA_BINUTILS_VERSION_REQUIRED.tar.xz ]; then - echo Downloading Binutils... - - wget -Otoolchain/tarballs/binutils-$LUNA_BINUTILS_VERSION_REQUIRED.tar.xz https://ftp.gnu.org/gnu/binutils/binutils-$LUNA_BINUTILS_VERSION_REQUIRED.tar.xz -fi - -rm -rf toolchain/build/binutils -rm -rf toolchain/build/binutils-$LUNA_BINUTILS_VERSION_REQUIRED - -echo Extracting Binutils... - -tar xf toolchain/tarballs/binutils-$LUNA_BINUTILS_VERSION_REQUIRED.tar.xz -C toolchain/build/ - -echo Patching Binutils... - -cd toolchain - -patch -u -i $LUNA_ROOT/tools/binutils.patch -p 1 -d build | filter-lines "binutils" "patch" - -cd - - -echo Configuring Binutils... - -mkdir -p toolchain/build/binutils - -cd toolchain/build/binutils - -unset CC -unset CXX -unset LD -unset AR - -../binutils-$LUNA_BINUTILS_VERSION_REQUIRED/configure --prefix="$BUILD_PREFIX" --target=$BUILD_TARGET --disable-nls --with-sysroot=$BUILD_SYSROOT --disable-werror | filter-lines "binutils" "configure" - -echo Building Binutils... - -make -j$(nproc) | filter-lines "binutils" "build" - -echo Installing Binutils... - -make install | filter-lines "binutils" "install" \ No newline at end of file diff --git a/tools/setup-env.sh b/tools/setup-env.sh deleted file mode 100755 index 1d3aa3d0..00000000 --- a/tools/setup-env.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/usr/bin/env bash -source $(dirname $0)/env.sh - -export LUNA_GCC_VERSION_REQUIRED=12.2.0 -export LUNA_BINUTILS_VERSION_REQUIRED=2.38 - -export BUILD_PREFIX=$LUNA_ROOT/toolchain/x86-64-luna -export BUILD_TARGET=x86_64-luna -export BUILD_SYSROOT=$LUNA_ROOT/base \ No newline at end of file diff --git a/tools/setup-gcc.sh b/tools/setup-gcc.sh deleted file mode 100755 index 25cd41eb..00000000 --- a/tools/setup-gcc.sh +++ /dev/null @@ -1,60 +0,0 @@ -#!/usr/bin/env bash -set -e -source $(dirname $0)/setup-env.sh - -cd $LUNA_ROOT - -if [ ! -x $(command -v x86_64-luna-as) ] -then - echo Binutils should be cross-built before GCC. - exit 1 -fi - -tools/install-headers.sh # install the LibC headers before building GCC - -mkdir -p toolchain/tarballs -mkdir -p toolchain/build - -if [ ! -f toolchain/tarballs/gcc-$LUNA_GCC_VERSION_REQUIRED.tar.xz ]; then - echo Downloading GCC... - - wget -Otoolchain/tarballs/gcc-$LUNA_GCC_VERSION_REQUIRED.tar.xz https://ftp.gnu.org/gnu/gcc/gcc-$LUNA_GCC_VERSION_REQUIRED/gcc-$LUNA_GCC_VERSION_REQUIRED.tar.xz -fi - -rm -rf toolchain/build/gcc -rm -rf toolchain/build/gcc-$LUNA_GCC_VERSION_REQUIRED - -echo Extracting GCC... - -tar xf toolchain/tarballs/gcc-$LUNA_GCC_VERSION_REQUIRED.tar.xz -C toolchain/build/ - -echo Patching GCC... - -cd toolchain - -patch -u -i $LUNA_ROOT/tools/gcc.patch -p 1 -d build | filter-lines "gcc" "patch" - -cd - - -echo Configuring GCC... - -mkdir -p toolchain/build/gcc - -cd toolchain/build/gcc - -unset CC -unset CXX -unset LD -unset AR - -../gcc-$LUNA_GCC_VERSION_REQUIRED/configure --prefix="$BUILD_PREFIX" --target=$BUILD_TARGET --disable-nls --with-sysroot=$BUILD_SYSROOT --enable-languages=c,c++ --without-headers | filter-lines "gcc" "configure" - -echo Building GCC... - -make all-gcc -j$(nproc) | filter-lines "gcc" "build" -make all-target-libgcc -j$(nproc) CFLAGS_FOR_TARGET='-g -O2 -mcmodel=large -mno-red-zone' | filter-lines "libgcc" "build" - -echo Installing GCC... - -make install-gcc | filter-lines "gcc" "install" -make install-target-libgcc | filter-lines "libgcc" "install" \ No newline at end of file diff --git a/tools/setup-mkbootimg.sh b/tools/setup-mkbootimg.sh deleted file mode 100755 index 8d3cdf44..00000000 --- a/tools/setup-mkbootimg.sh +++ /dev/null @@ -1,19 +0,0 @@ -#!/usr/bin/env bash - -set -e -source $(dirname $0)/env.sh - -cd $LUNA_ROOT - -mkdir -p toolchain/dist - -cd toolchain - -git clone https://gitlab.com/bztsrc/bootboot.git - -cd bootboot/mkbootimg - -make -j$(nproc) - -cp ./mkbootimg ../../dist/mkbootimg -rm ../mkbootimg-*.zip \ No newline at end of file diff --git a/tools/setup.sh b/tools/setup.sh deleted file mode 100755 index c14ba50c..00000000 --- a/tools/setup.sh +++ /dev/null @@ -1,20 +0,0 @@ -#!/usr/bin/env bash -set -e - -if ! $(dirname $0)/test-binutils.sh -then - echo Building Binutils... - $(dirname $0)/setup-binutils.sh -fi - -if ! $(dirname $0)/test-gcc.sh -then - echo Building GCC.. - $(dirname $0)/setup-gcc.sh -fi - -if ! [ -f $(dirname $0)/../toolchain/dist/mkbootimg ] -then - echo Building mkbootimg... - $(dirname $0)/setup-mkbootimg.sh -fi \ No newline at end of file diff --git a/tools/sync-libc.sh b/tools/sync-libc.sh deleted file mode 100755 index 808bcb04..00000000 --- a/tools/sync-libc.sh +++ /dev/null @@ -1,11 +0,0 @@ -#!/usr/bin/env bash - -set -e -source $(dirname $0)/env.sh - -cd $LUNA_ROOT - -tools/install-headers.sh - -make -C libs/libc build -j$(nproc) -make -C libs/libc install -j$(nproc) \ No newline at end of file diff --git a/tools/test-binutils.sh b/tools/test-binutils.sh deleted file mode 100755 index 4ba6fb3d..00000000 --- a/tools/test-binutils.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/usr/bin/env bash -set -e -source $(dirname $0)/setup-env.sh - -if [ -x "$(command -v x86_64-luna-ar)" ] -then - if [ "$(x86_64-luna-ar --version | head -n 1 | awk '{ print $5 }')" == "$LUNA_BINUTILS_VERSION_REQUIRED" ] - then - exit 0 - else - exit 1 - fi -else -exit 1 -fi \ No newline at end of file diff --git a/tools/test-gcc.sh b/tools/test-gcc.sh deleted file mode 100755 index c5be191f..00000000 --- a/tools/test-gcc.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/usr/bin/env bash -set -e -source $(dirname $0)/setup-env.sh - -if [ -x "$(command -v x86_64-luna-gcc)" ] -then - if [ "$(x86_64-luna-gcc --version | head -n 1 | awk '{ print $3 }')" == "$LUNA_GCC_VERSION_REQUIRED" ] - then - exit 0 - else - exit 1 - fi -else -exit 1 -fi \ No newline at end of file diff --git a/tools/test.sh b/tools/test.sh deleted file mode 100755 index d73fd091..00000000 --- a/tools/test.sh +++ /dev/null @@ -1,10 +0,0 @@ -#!/usr/bin/env bash - -set -e -source $(dirname $0)/env.sh - -cd $LUNA_ROOT - -make -C tests build -make -C tests install -make -C tests test \ No newline at end of file