Initial commit :)

This commit is contained in:
apio 2022-11-13 10:09:09 +01:00
parent 42efc21110
commit cf758fdfdc
304 changed files with 62 additions and 21552 deletions

14
.gitignore vendored
View File

@ -1,15 +1,5 @@
Luna.iso
toolchain/
.vscode/
**/*.o
initrd/boot/moon
kernel/bin/moon
initrd/sys/moon.sym
initrd/bin/**
apps/bin/**
tests/**/bin/**
base/usr/**
**/*.a
ports/**/workdir/**
ports/ports.list
**/*.pkg.tar.xz
build/
initrd/boot/moon

18
CMakeLists.txt Normal file
View File

@ -0,0 +1,18 @@
cmake_minimum_required(VERSION 3.8..3.22)
set(CMAKE_C_COMPILER_WORKS 1)
set(CMAKE_CXX_COMPILER_WORKS 1)
set(CMAKE_SYSTEM_NAME Luna)
set(CMAKE_CROSSCOMPILING true)
project(Luna LANGUAGES C CXX ASM)
set(LUNA_ROOT ${CMAKE_CURRENT_LIST_DIR})
set(CMAKE_C_COMPILER x86_64-luna-gcc)
set(CMAKE_CXX_COMPILER x86_64-luna-g++)
set(CMAKE_FIND_ROOT_PATH ${LUNA_ROOT}/toolchain/x86-64-luna)
add_subdirectory(kernel)

View File

@ -1,33 +0,0 @@
C_APPS := init sh uname uptime hello ps ls args cat stat su session date mkdir screen touch write
CXX_APPS := hello-cpp
APPS_DIR := $(LUNA_ROOT)/apps
APPS_SRC := $(APPS_DIR)/src
APPS_BIN := $(APPS_DIR)/bin
C_APPS_PATH := $(patsubst %, $(APPS_BIN)/%, $(C_APPS))
CXX_APPS_PATH := $(patsubst %, $(APPS_BIN)/%, $(CXX_APPS))
CFLAGS := -Wall -Wextra -Werror -Os -fno-asynchronous-unwind-tables -ffunction-sections -fdata-sections -Wl,--gc-sections
CXXFLAGS := -fno-exceptions
$(APPS_BIN)/%: $(APPS_SRC)/%.c
@mkdir -p $(@D)
@$(CC) $(CFLAGS) -o $@ $^
@echo " CC $^"
$(APPS_BIN)/%: $(APPS_SRC)/%.cpp
@mkdir -p $(@D)
@$(CXX) $(CFLAGS) $(CXXFLAGS) -o $@ $^
@echo " CXX $^"
build: $(C_APPS_PATH) $(CXX_APPS_PATH)
install: $(C_APPS_PATH) $(CXX_APPS_PATH)
@mkdir -p $(LUNA_ROOT)/initrd/bin
@cp $(C_APPS_PATH) $(CXX_APPS_PATH) $(LUNA_ROOT)/initrd/bin
@echo " INSTALL $(C_APPS) $(CXX_APPS)"
@chmod a+s $(LUNA_ROOT)/initrd/bin/su
clean:
rm -f $(APPS_BIN)/*

View File

@ -1,7 +0,0 @@
#include <stdio.h>
#include <unistd.h>
int main(int argc, char** argv)
{
for (int i = 0; i < argc; i++) puts(argv[i]);
}

View File

@ -1,45 +0,0 @@
#define _GNU_SOURCE // for program_invocation_name
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
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);
}
}
}
}

View File

@ -1,9 +0,0 @@
#include <stdio.h>
#include <time.h>
int main()
{
time_t date = time(NULL);
fputs(ctime(&date), stdout);
}

View File

@ -1,19 +0,0 @@
#include <cstdio>
#include <string>
#include <vector>
int main()
{
std::printf("Well hello world!\n");
std::string str = "this is a c++ string";
str.append(" yay");
std::printf("%s\n", str.c_str());
std::vector<int> vec = {3, 2, 8};
for (int i : vec) { std::printf("%d ", i); }
std::putchar('\n');
}

View File

@ -1,6 +0,0 @@
#include <stdio.h>
int main()
{
puts("Hello, world!");
}

View File

@ -1,77 +0,0 @@
#include <errno.h>
#include <fcntl.h>
#include <luna.h>
#include <stdio.h>
#include <sys/wait.h>
#include <unistd.h>
void show_motd()
{
int fd = open("/etc/motd", O_RDONLY | O_CLOEXEC);
if (fd < 0)
{
if (errno != ENOENT) { perror("open"); }
return;
}
FILE* fp = fdopen(fd, "r");
if (!fp)
{
perror("fopen");
return;
}
char buf[4096];
size_t nread = fread(buf, 1, sizeof(buf) - 1, fp);
if (ferror(fp))
{
perror("fread");
fclose(fp);
return;
}
buf[nread] = 0;
puts(buf);
fclose(fp);
putchar('\n');
}
int main()
{
if (getpid() != 1)
{
fprintf(stderr, "init must be started as PID 1\n");
return 1;
}
if (getuid() != 0)
{
fprintf(stderr, "init must be started as root\n");
return 1;
}
show_motd();
pid_t child = fork();
if (child < 0)
{
perror("fork");
return 1;
}
if (child == 0)
{
char* argv[] = {"/bin/session", NULL};
execv(argv[0], argv);
perror("execv");
return 1;
}
pid_t result;
for (;;)
{
result = wait(NULL);
if (result == child) return 0;
}
}

View File

@ -1,31 +0,0 @@
#include <dirent.h>
#include <fcntl.h>
#include <stdbool.h>
#include <stdio.h>
#include <unistd.h>
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;
}

View File

@ -1,17 +0,0 @@
#include <stdio.h>
#include <sys/stat.h>
int main(int argc, char** argv)
{
if (argc == 1)
{
fprintf(stderr, "Usage: %s [directory]\n", argv[0]);
return 1;
}
if (mkdir(argv[1], 0755) < 0)
{
perror("mkdir");
return 1;
}
}

View File

@ -1,48 +0,0 @@
#include <errno.h>
#include <luna/pstat.h>
#include <pwd.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
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();
}

View File

@ -1,32 +0,0 @@
#include <fcntl.h>
#include <stdio.h>
#include <sys/ioctl.h>
#include <unistd.h>
int main()
{
int fd = open("/dev/fb0", O_WRONLY | O_CLOEXEC);
if (fd < 0)
{
perror("open");
return 1;
}
int fb_width = ioctl(fd, FB_GET_WIDTH);
if (fb_width < 0)
{
perror("ioctl(FB_GET_WIDTH)");
return 1;
}
int fb_height = ioctl(fd, FB_GET_HEIGHT);
if (fb_height < 0)
{
perror("ioctl(FB_GET_HEIGHT)");
return 1;
}
printf("Your screen is %dx%d\n", fb_width, fb_height);
close(fd);
}

View File

@ -1,145 +0,0 @@
#include <errno.h>
#include <pwd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/wait.h>
#include <unistd.h>
static char* echoing_fgets(char* buf, size_t size, FILE* stream)
{
char* s = buf;
memset(buf, 0, size);
size_t oldsize = size;
while (size)
{
int c = fgetc(stream);
if (c == EOF)
{
if (ferror(stream)) return NULL;
if (feof(stream))
{
if (s != buf) return s;
else
return NULL;
};
}
if ((char)c == '\b')
{
if (size != oldsize)
{
buf--;
size++;
putchar('\b');
}
}
else
{
size--;
*buf = (char)c;
buf++;
putchar((char)c);
if ((char)c == '\n') return s;
}
*buf = 0;
}
return s;
}
static void strip_newline(char* str)
{
size_t len = strlen(str);
if (str[len - 1] == '\n') str[len - 1] = 0;
}
static char* collect_password()
{
static char buf[BUFSIZ];
printf("Password: ");
fgets(buf, BUFSIZ, stdin);
strip_newline(buf);
putchar('\n');
char* copy = strdup(
buf); // The password only stays in a caller-controlled heap-allocated buffer, where it can be freed at will.
memset(buf, 0, BUFSIZ);
return copy;
}
static void login_as(struct passwd* user)
{
pid_t child = fork();
if (child < 0)
{
perror("fork");
return;
}
if (child == 0)
{
setgid(user->pw_gid);
setuid(user->pw_uid);
char* argv[] = {user->pw_shell, NULL};
execv(argv[0], argv);
perror("execv");
exit(EXIT_FAILURE);
}
wait(NULL);
}
static int login()
{
printf("Username: ");
char username[BUFSIZ];
echoing_fgets(username, BUFSIZ, stdin);
strip_newline(username);
if (strcmp("exit", username) == 0) return 1;
struct passwd* user = getpwnam(username);
if (!user)
{
if (errno) perror("getpwnam");
else
printf("Unknown user %s\n", username);
return 0;
}
char* password = collect_password();
putchar('\n');
if (strcmp(user->pw_passwd, password) == 0)
{
free(password);
login_as(user);
puts("logout\n");
}
else
{
free(password);
puts("Invalid password.\n");
}
return 0;
}
int main(int argc, char** argv)
{
(void)argc;
if (getuid() != 0)
{
fprintf(stderr,
"%s must be run as root.\nYou are probably looking for the 'su' command, which lets you switch users "
"once logged in.\n",
argv[0]);
return EXIT_FAILURE;
}
for (;;)
{
if (login()) break;
}
endpwent();
return EXIT_SUCCESS;
}

View File

@ -1,364 +0,0 @@
#include <assert.h>
#include <errno.h>
#include <luna.h>
#include <pwd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/wait.h>
#include <unistd.h>
static int status = 0;
static char* username = NULL;
typedef struct
{
char* buffer;
size_t size;
size_t capacity;
int interactive;
} command_t;
char** split_command_into_argv(const char* cmd)
{
size_t argc = 1;
char* ptr = strdup(cmd);
char* endptr;
char** arr = calloc(sizeof(char*), argc);
for (;;)
{
endptr = strchr(ptr, ' ');
arr[argc - 1] = ptr;
if (endptr == NULL) break;
*endptr = 0;
ptr = endptr + 1;
if (*ptr)
{
argc++;
arr = realloc(arr, sizeof(char*) * argc);
}
else
break;
}
argc++;
arr = realloc(arr, sizeof(char*) * argc);
arr[argc - 1] = NULL;
return arr;
}
char* shell_concat_path(const char* dirname, const char* basename)
{
char* buf = malloc(strlen(basename) + strlen(dirname) + 6);
strlcpy(buf, dirname, strlen(dirname) + 1);
strncat(buf, basename, strlen(basename));
return buf;
}
void shell_execvp(char* pathname, char* const argv[])
{
char* new_path;
if (access(pathname, F_OK) == 0)
{
execv(pathname, argv);
return;
}
if (pathname[0] == '/') return; // We do not want to lookup absolute paths
new_path = shell_concat_path("/bin/", pathname);
if (access(new_path, F_OK) == 0)
{
execv(new_path, argv);
return;
}
free(new_path);
new_path = shell_concat_path("/usr/bin/", pathname);
execv(new_path, argv);
int saved = errno;
free(new_path);
errno = saved;
}
void show_prompt()
{
if (WEXITSTATUS(status)) { printf("%d [%s]> ", WEXITSTATUS(status), username); }
else
printf("[%s]> ", username);
}
int command_matches(command_t* cmd, const char* string)
{
if (cmd->size <= strlen(string)) // cmd->size includes null terminator
return 0;
return strncmp(cmd->buffer, string, strlen(string)) == 0;
}
int command_matches_exactly(command_t* cmd, const char* string)
{
if (cmd->size <= strlen(string)) // cmd->size includes null terminator
return 0;
if (cmd->size > (strlen(string) + 1)) return 0;
return strncmp(cmd->buffer, string, strlen(string)) == 0;
}
int command_match_builtins(command_t* cmd)
{
if (command_matches(cmd, "exit ")) { exit(atoi(cmd->buffer + 5)); }
if (command_matches_exactly(cmd, "exit")) { exit(0); }
if (command_matches_exactly(cmd, "id"))
{
printf("pid %ld, ppid %ld, uid %d (%s), gid %d\n", getpid(), getppid(), getuid(), username, getgid());
return 1;
}
if (command_matches(cmd, "sleep"))
{
sleep(atoi(cmd->buffer + 6));
return 1;
}
if (command_matches_exactly(cmd, "clear"))
{
fputs("\033@", stdout); // clear screen. for now, escape sequences in luna are non-standard.
return 1;
}
return 0;
}
void command_expand(command_t* cmd, long new_capacity)
{
char* buffer = realloc(cmd->buffer, new_capacity);
if (!buffer)
{
perror("realloc");
exit(1);
}
cmd->buffer = buffer;
cmd->capacity = new_capacity;
}
void command_push(command_t* cmd, char c)
{
if (cmd->size == cmd->capacity) command_expand(cmd, cmd->capacity + 8);
cmd->buffer[cmd->size] = c;
cmd->size++;
}
void command_pop(command_t* cmd)
{
cmd->size--;
}
void command_init(command_t* cmd)
{
cmd->buffer = malloc(5);
cmd->capacity = 5;
cmd->size = 0;
}
void command_clear(command_t* cmd)
{
free(cmd->buffer);
return command_init(cmd);
}
void process_execute_command(const char* command)
{
char** argv = split_command_into_argv(command);
shell_execvp(argv[0], argv);
perror(argv[0]);
exit(127);
}
void command_execute(command_t* cmd)
{
command_push(cmd, '\0');
if (command_match_builtins(cmd))
{
command_clear(cmd);
if (cmd->interactive) show_prompt();
return;
}
pid_t child = fork();
if (child < 0)
{
perror("fork");
command_clear(cmd);
if (cmd->interactive) show_prompt();
return;
}
if (child == 0) process_execute_command(cmd->buffer);
pid_t result = waitpid(child, &status, 0);
if (result < 0)
{
perror("waitpid");
command_clear(cmd);
if (cmd->interactive) show_prompt();
return;
}
int exit_status = WEXITSTATUS(status);
if (exit_status == -2 || exit_status == -3) printf("(PID %ld) Segmentation fault\n", result);
if (exit_status == -1) printf("(PID %ld) Aborted\n", result);
command_clear(cmd);
if (cmd->interactive) show_prompt();
}
void command_concat_char(command_t* cmd, char c)
{
if (c == '\b')
{
if (cmd->size != 0)
{
if (cmd->interactive) putchar(c);
command_pop(cmd);
}
}
else if (c == '\n')
{
if (cmd->interactive) putchar(c);
if (cmd->size == 0)
{
status = 0;
if (cmd->interactive) show_prompt();
}
else
command_execute(cmd);
}
else
{
if (cmd->interactive) putchar(c);
command_push(cmd, c);
}
}
void command_concat(command_t* cmd, const char* str)
{
while (*str)
{
command_concat_char(cmd, *str);
str++;
}
}
void shell_interactive()
{
show_prompt();
command_t shell_command;
command_init(&shell_command);
shell_command.interactive = 1;
while (1)
{
int c = getchar();
if (c == EOF)
{
if (ferror(stdin))
{
perror("getchar");
exit(EXIT_FAILURE);
}
if (feof(stdin)) exit(EXIT_SUCCESS);
assert(false); // we should never get here
}
command_concat_char(&shell_command, (char)c);
}
}
void shell_read_from_file(const char* pathname)
{
FILE* fp = fopen(pathname, "r");
if (!fp)
{
perror("sh");
exit(EXIT_FAILURE);
}
command_t file_command;
command_init(&file_command);
file_command.interactive = 0;
char buffer[BUFSIZ];
while (fgets(buffer, BUFSIZ, fp))
{
command_concat(&file_command, buffer);
if (feof(fp)) break;
}
if (file_command.size > 0) // last line of file, does not end with newline
{
command_execute(&file_command);
}
fclose(fp);
}
void shell_execute_command(const char* command)
{
command_t cmd;
cmd.buffer = strdup(command);
cmd.size = strlen(command) + 1;
if (command_match_builtins(&cmd)) return;
command_clear(&cmd);
process_execute_command(command);
}
void fetch_username()
{
struct passwd* user = getpwuid(getuid());
if (!user)
{
perror("getpwuid");
exit(EXIT_FAILURE);
}
username = user->pw_name;
endpwent();
}
int main(int argc, char** argv)
{
fetch_username();
if (argc == 1) shell_interactive();
else if (argc == 2)
{
if (!strcmp(argv[1], "-v") || !strcmp(argv[1], "--version"))
{
puts("Luna sh version 0.1"); // FIXME: Store the version somewhere, or use the kernel's version.
return 0;
}
if (!strcmp(argv[1], "-h") || !strcmp(argv[1], "--help"))
{
printf("To use interactively: %s\n", argv[0]);
printf("To run a script: %s [script-name]\n", argv[0]);
printf("To get help: %s --help\n", argv[0]);
printf("To show the version: %s --version\n", argv[0]);
printf("To run a command: %s -c [command]\n", argv[0]);
return 0;
}
if (!strcmp(argv[1], "-c") || !strcmp(argv[1], "--command"))
{
fprintf(stderr, "Usage: %s %s [command]\n", argv[0], argv[1]);
fprintf(stderr, "Use the --help flag for more help.\n");
return 1;
}
shell_read_from_file(argv[1]);
}
else if (argc == 3)
{
if (!strcmp(argv[1], "-c") || !strcmp(argv[1], "--command")) shell_execute_command(argv[2]);
else
{
fprintf(stderr, "%s: too many arguments\n", argv[0]);
fprintf(stderr, "Use the --help flag for more help.\n");
return 1;
}
}
else
{
fprintf(stderr, "%s: too many arguments\n", argv[0]);
fprintf(stderr, "Use the --help flag for more help.\n");
return 1;
}
}

View File

@ -1,66 +0,0 @@
#include <pwd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <time.h>
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;
}

View File

@ -1,88 +0,0 @@
#include <errno.h>
#include <pwd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
void run_program(char** argv)
{
execv(argv[0], argv);
perror("execv");
exit(EXIT_FAILURE);
}
void strip_newline(char* str)
{
size_t len = strlen(str);
if (str[len - 1] == '\n') str[len - 1] = 0;
}
static const char* collect_password()
{
static char buf[BUFSIZ];
printf("Password: ");
fgets(buf, BUFSIZ, stdin);
strip_newline(buf);
putchar('\n');
return buf;
}
int main(int argc, char** argv)
{
const char* username;
if (argc == 1) username = "root";
else
username = argv[1];
if (geteuid() != 0)
{
fprintf(stderr, "%s must be setuid root", argv[0]);
return EXIT_FAILURE;
}
struct passwd* user = getpwnam(username);
endpwent();
if (!user)
{
if (errno) perror("getpwnam");
else
fprintf(stderr, "Unknown user %s\n", username);
return EXIT_FAILURE;
}
if (getuid() != geteuid()) // we were started from a non-root user
{
const char* pw = collect_password();
if (strcmp(pw, user->pw_passwd) != 0)
{
fprintf(stderr, "Invalid password\n");
return EXIT_FAILURE;
}
}
if (setgid(user->pw_gid) < 0)
{
perror("setgid");
return EXIT_FAILURE;
}
if (setuid(user->pw_uid) < 0)
{
perror("setuid");
return EXIT_FAILURE;
}
char* default_argv[] = {user->pw_shell, NULL};
if (argc < 3) run_program(default_argv);
else
run_program(argv + 2);
}

View File

@ -1,22 +0,0 @@
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
int main(int argc, char** argv)
{
if (argc == 1)
{
fprintf(stderr, "Usage: %s [directory]\n", argv[0]);
return 1;
}
int fd = creat(argv[1], 0755);
if (fd < 0)
{
perror("creat");
return 1;
}
close(fd);
}

View File

@ -1,18 +0,0 @@
#include <stdio.h>
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);
}

View File

@ -1,38 +0,0 @@
#include <stdio.h>
#include <time.h>
#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));
}

View File

@ -1,75 +0,0 @@
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
static char* echoing_fgets(char* buf, size_t size, FILE* stream)
{
char* s = buf;
memset(buf, 0, size);
size_t oldsize = size;
while (size)
{
int c = fgetc(stream);
if (c == EOF)
{
if (ferror(stream)) return NULL;
if (feof(stream))
{
if (s != buf) return s;
else
return NULL;
};
}
if ((char)c == '\b')
{
if (size != oldsize)
{
buf--;
size++;
putchar('\b');
}
}
else
{
size--;
*buf = (char)c;
buf++;
putchar((char)c);
if ((char)c == '\n') return s;
}
*buf = 0;
}
return s;
}
int main(int argc, char** argv)
{
if (argc == 1)
{
fprintf(stderr, "Usage: %s [directory]\n", argv[0]);
return 1;
}
int fd = open(argv[1], O_WRONLY | O_CREAT | O_APPEND, 0755);
if (fd < 0)
{
perror("open");
return 1;
}
FILE* fp = fdopen(fd, "a");
char buf[BUFSIZ];
echoing_fgets(buf, BUFSIZ, stdin);
fputs(buf, fp);
if (ferror(fp))
{
perror("fputs");
return 1;
}
fclose(fp);
}

View File

@ -1,3 +0,0 @@
Welcome to Luna!
Tip of the day: Log in as user 'selene' and password 'moon' :)

View File

@ -1,2 +0,0 @@
root:secure:0:0:Administrator:/:/bin/sh
selene:moon:1:1:Default User:/:/bin/sh

View File

@ -1,9 +0,0 @@
mkdir /tmp/1
sleep 1
mkdir /tmp/1/2
sleep 1
mkdir /tmp/1/2/3
sleep 1
mkdir /tmp/1/2/3/4
sleep 1
mkdir /tmp/1/2/3/4/5

View File

@ -1,3 +1,2 @@
screen=1024x768
kernel=boot/moon
verbose=1
kernel=boot/moon

26
kernel/CMakeLists.txt Normal file
View File

@ -0,0 +1,26 @@
set(SOURCES
src/main.cpp
)
add_compile_options(-Os)
add_compile_options(-pedantic -Wall -Wextra -Werror -Wvla)
add_compile_options(-Wdisabled-optimization -Wformat=2 -Winit-self)
add_compile_options(-Wmissing-include-dirs -Wswitch-default -Wcast-qual -Wundef)
add_compile_options(-Wcast-align -Wwrite-strings -Wlogical-op -Wredundant-decls -Wshadow -Wconversion)
add_compile_options(-fno-rtti -ffreestanding -fno-exceptions)
add_compile_options(-fno-asynchronous-unwind-tables -fno-omit-frame-pointer)
add_compile_options(-nostdlib -mcmodel=kernel)
add_compile_options(-mno-red-zone)
add_compile_options(-mno-80387 -mno-mmx -mno-sse -mno-sse2)
add_link_options(-lgcc -Wl,--build-id=none -z max-page-size=0x1000 -mno-red-zone -mcmodel=kernel)
add_executable(moon ${SOURCES})
target_include_directories(moon PUBLIC ${LUNA_ROOT}/luna)
target_link_options(moon PRIVATE LINKER:-T ${CMAKE_CURRENT_LIST_DIR}/moon.ld -nostdlib -nodefaultlibs)
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/moon" DESTINATION ${LUNA_ROOT}/initrd/boot)

View File

@ -1,85 +0,0 @@
MOON_DIR := $(realpath $(dir $(abspath $(lastword $(MAKEFILE_LIST)))))
MOON_SRC := $(MOON_DIR)/src
MOON_OBJ := $(MOON_DIR)/lib
MOON_BIN := $(MOON_DIR)/bin
CFLAGS ?= -Os
CFLAGS := ${CFLAGS} -pedantic -Wall -Wextra -Werror -Wvla -Wfloat-equal -Wdisabled-optimization -Wformat=2 -Winit-self -Wmissing-include-dirs -Wswitch-default -Wcast-qual -Wundef -Wcast-align -Wwrite-strings -Wlogical-op -Wredundant-decls -Wshadow -Wconversion -ffreestanding -fstack-protector-strong -fno-omit-frame-pointer -mno-red-zone -mno-mmx -mno-sse -mno-sse2 -fshort-wchar -mcmodel=kernel -I$(MOON_DIR)/include -isystem $(MOON_DIR)/include/std
CXXFLAGS := -fno-rtti -fno-exceptions -Wsign-promo -Wstrict-null-sentinel -Wctor-dtor-privacy
ASMFLAGS := -felf64
LDFLAGS := -T$(MOON_DIR)/moon.ld -nostdlib -lgcc -Wl,--build-id=none -z max-page-size=0x1000 -mno-red-zone -mcmodel=kernel
ifneq ($(MOON_BUILD_STABLE), 1)
CFLAGS := ${CFLAGS} -D_MOON_SUFFIX=-$(shell git rev-parse --short HEAD)
endif
ifeq ($(MOON_BUILD_DEBUG), 1)
CFLAGS := -ggdb -fsanitize=undefined ${CFLAGS}
endif
rwildcard=$(foreach d,$(wildcard $(1:=/*)),$(call rwildcard,$d,$2) $(filter $(subst *,%,$2),$d))
CXX_SRC = $(call rwildcard,$(MOON_SRC),*.cpp)
C_SRC = $(call rwildcard,$(MOON_SRC),*.c)
NASM_SRC = $(call rwildcard,$(MOON_SRC),*.asm)
OBJS = $(patsubst $(MOON_SRC)/%.cpp, $(MOON_OBJ)/%.cpp.o, $(CXX_SRC))
OBJS += $(patsubst $(MOON_SRC)/%.c, $(MOON_OBJ)/%.c.o, $(C_SRC))
OBJS += $(patsubst $(MOON_SRC)/%.asm, $(MOON_OBJ)/%.asm.o, $(NASM_SRC))
default: $(MOON_BIN)/moon
$(MOON_OBJ)/main.cpp.o: $(MOON_SRC)/main.cpp
@mkdir -p $(@D)
@$(CXX) $(CFLAGS) -fno-stack-protector $(CXXFLAGS) -o $@ -c $^
@echo " CXX $^"
$(MOON_OBJ)/misc/config.cpp.o: $(MOON_SRC)/misc/config.cpp FORCE
@mkdir -p $(@D)
@$(CXX) $(CFLAGS) $(CXXFLAGS) -o $@ -c $(MOON_SRC)/misc/config.cpp
@echo " CXX $^"
$(MOON_OBJ)/init/Init.cpp.o: $(MOON_SRC)/init/Init.cpp
@mkdir -p $(@D)
@$(CXX) $(CFLAGS) -fno-stack-protector $(CXXFLAGS) -o $@ -c $^
@echo " CXX $^"
$(MOON_OBJ)/%.cpp.o: $(MOON_SRC)/%.cpp
@mkdir -p $(@D)
@$(CXX) $(CFLAGS) $(CXXFLAGS) -o $@ -c $^
@echo " CXX $^"
$(MOON_OBJ)/memory/liballoc/liballoc.c.o: $(MOON_SRC)/memory/liballoc/liballoc.c
@mkdir -p $(@D)
@$(CC) $(CFLAGS) -fno-sanitize=undefined -o $@ -c $^
@echo " CC $^"
$(MOON_OBJ)/%.c.o: $(MOON_SRC)/%.c
@mkdir -p $(@D)
@$(CC) $(CFLAGS) -o $@ -c $^
@echo " CC $^"
$(MOON_OBJ)/%.asm.o: $(MOON_SRC)/%.asm
@mkdir -p $(@D)
@$(ASM) $(ASMFLAGS) -o $@ $^
@echo " ASM $^"
build: $(OBJS)
@mkdir -p $(MOON_BIN)
@$(CC) $(OBJS) $(LDFLAGS) -o $(MOON_BIN)/moon
@echo " CCLD $(MOON_BIN)/moon"
clean:
rm -rf $(MOON_OBJ)/*
rm -rf $(MOON_BIN)/*
install: $(MOON_BIN)/moon
@mkdir -p $(LUNA_ROOT)/initrd/boot
@cp $^ $(LUNA_ROOT)/initrd/boot/moon
@echo " INSTALL $^"
@$(LUNA_ROOT)/tools/generate-symbols.sh
@$(STRIP) $(LUNA_ROOT)/initrd/boot/moon
@echo " STRIP $(LUNA_ROOT)/initrd/boot/moon"
.PHONY: build clean install FORCE
FORCE:

View File

@ -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;
};
}

View File

@ -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);
}

View File

@ -1,20 +0,0 @@
#pragma once
#include <stdint.h>
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);
}

View File

@ -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 <stdint.h>
#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

View File

@ -1,7 +0,0 @@
#pragma once
int __moon_version_major();
int __moon_version_minor();
const char* __moon_version_suffix();
const char* moon_version();

View File

@ -1,14 +0,0 @@
#pragma once
#include "cpu/Features.h"
#include <stdint.h>
namespace CPU
{
const char* get_vendor_string();
const char* get_brand_string();
void log_cpu_information();
uint64_t get_feature_bitmask();
uint64_t get_initial_apic_id();
bool has_feature(CPU::Features);
bool has_nx();
}

View File

@ -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,
};
}

View File

@ -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 */};

View File

@ -1,83 +0,0 @@
#pragma once
#include "fs/VFS.h"
#include <stdint.h>
struct Descriptor
{
bool is_open()
{
return m_is_open;
}
bool can_read()
{
return m_can_read && m_is_open;
}
bool can_write()
{
return m_can_write && m_is_open;
}
void close()
{
m_is_open = false;
}
VFS::Node* node()
{
return m_node;
}
ssize_t read(size_t size, char* buffer);
ssize_t write(size_t size, const char* buffer);
ssize_t user_read(size_t size, char* buffer);
ssize_t user_write(size_t size, const char* buffer);
uintptr_t mmap(uintptr_t addr, size_t size, int prot, off_t offset);
long ioctl(int cmd, uintptr_t arg);
void open(VFS::Node* node, bool can_read, bool can_write, bool able_to_block, bool close_on_exec);
int seek(long offset);
long offset()
{
return (long)m_offset;
}
unsigned long length()
{
return m_node->length;
}
bool able_to_block()
{
return m_able_to_block;
}
bool close_on_exec()
{
return m_close_on_exec;
}
void set_close_on_exec(bool value)
{
m_close_on_exec = value;
}
Descriptor(const Descriptor& other);
Descriptor();
const Descriptor& operator=(const Descriptor& other);
private:
bool m_is_open;
bool m_can_read;
bool m_can_write;
bool m_able_to_block;
bool m_close_on_exec;
VFS::Node* m_node;
uint64_t m_offset;
};

View File

@ -1,54 +0,0 @@
#pragma once
#include <stdint.h>
#include <sys/types.h>
#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();
}

View File

@ -1,18 +0,0 @@
#pragma once
#include "fs/VFS.h"
namespace TmpFS
{
VFS::Node* get();
VFS::Node* finddir(VFS::Node* node, const char* filename);
VFS::Node* readdir(VFS::Node* node, long offset);
int mkdir(VFS::Node* node, const char* name, mode_t mode);
ssize_t read(VFS::Node* node, size_t offset, size_t length, char* buffer);
ssize_t write(VFS::Node* node, size_t offset, size_t length, const char* buffer);
VFS::Node* create(VFS::Node* node, const char* name, mode_t mode, uid_t uid, gid_t gid);
}

View File

@ -1,92 +0,0 @@
#pragma once
#include "utils/Result.h"
#include <stddef.h>
#include <stdint.h>
#include <sys/types.h>
typedef long ssize_t;
#define VFS_FILE 0x0
#define VFS_DIRECTORY 0x1
#define VFS_DEVICE 0x2
#define VFS_MOUNTPOINT 0x1
#define NAME_MAX 64
namespace VFS
{
struct Node;
typedef ssize_t (*node_read)(Node*, size_t, size_t, char*);
typedef ssize_t (*node_write)(Node*, size_t, size_t, const char*);
typedef Node* (*node_finddir)(Node*, const char*);
typedef int (*node_mkdir)(Node*, const char*, mode_t);
typedef int (*node_block)(Node*);
typedef Node* (*node_readdir)(Node*, long);
typedef uintptr_t (*node_mmap)(Node*, uintptr_t, size_t, int, off_t);
typedef long (*node_ioctl)(Node*, int, uintptr_t);
typedef Node* (*node_create)(Node*, const char*, mode_t, uid_t, gid_t);
struct Node
{
char name[NAME_MAX];
int type;
int flags;
int tty = 0;
int uid;
int gid;
mode_t mode;
uint64_t impl;
uint64_t atime;
uint64_t ctime;
uint64_t mtime;
uint64_t inode;
uint64_t length;
node_read read_func;
node_finddir find_func;
node_readdir readdir_func;
node_mkdir mkdir_func;
node_write write_func;
node_block block_func;
node_mmap mmap_func;
node_ioctl ioctl_func;
node_create create_func;
Node* link;
};
ssize_t read(Node* node, size_t offset, size_t length, char* buffer);
ssize_t write(Node* node, size_t offset, size_t length, const char* buffer);
int mkdir(const char* path, const char* name);
int mkdir(const char* pathname);
int do_mkdir(const char* path, const char* name, int uid, int gid, mode_t mode);
int do_mkdir(const char* pathname, int uid, int gid, mode_t mode);
Result<Node*> create(const char* pathname, mode_t mode, uid_t uid, gid_t gid);
int would_block(Node* node);
void mount_root(Node* root);
Node* resolve_path(const char* filename, Node* root = nullptr);
Node* resolve_parent(const char* filename, Node* root = nullptr);
bool exists(const char* pathname);
void mount(Node* mountpoint, Node* mounted);
void mount(const char* pathname, Node* mounted);
void unmount(Node* mountpoint);
Node* root();
Node* readdir(Node* dir, long offset);
bool can_execute(Node* node, int uid, int gid);
bool can_read(Node* node, int uid, int gid);
bool can_write(Node* node, int uid, int gid);
bool is_setuid(Node* node);
bool is_setgid(Node* node);
}

View File

@ -1,15 +0,0 @@
#pragma once
#include "fs/VFS.h"
namespace ConsoleDevice
{
VFS::Node* create_new(const char* devname);
ssize_t write(VFS::Node* node, size_t offset, size_t size, const char* buffer);
ssize_t read(VFS::Node* node, size_t offset, size_t size, char* buffer);
int would_block(VFS::Node* node);
void append(char c);
}

View File

@ -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);
}

View File

@ -1,13 +0,0 @@
#pragma once
#include "fs/VFS.h"
namespace FramebufferDevice
{
VFS::Node* create_new(const char* devname);
ssize_t write(VFS::Node* node, size_t offset, size_t size, const char* buffer);
uintptr_t mmap(VFS::Node* node, uintptr_t addr, size_t size, int prot, off_t offset);
long ioctl(VFS::Node* node, int cmd, uintptr_t arg);
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -1,6 +0,0 @@
#pragma once
namespace GDT
{
void load();
}

View File

@ -1,9 +0,0 @@
#pragma once
namespace Init
{
void check_magic();
void disable_smp();
void early_init();
void finish_kernel_boot();
}

View File

@ -1,14 +0,0 @@
#pragma once
#include <stdint.h>
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;
};

View File

@ -1,18 +0,0 @@
#pragma once
#include <stdint.h>
#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();
}

View File

@ -1,7 +0,0 @@
#pragma once
#include "Context.h"
namespace IRQ
{
void interrupt_handler(Context* context);
}

View File

@ -1,7 +0,0 @@
#pragma once
#include <stdint.h>
namespace Interrupts
{
void install();
}

View File

@ -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();
}

View File

@ -1,13 +0,0 @@
#pragma once
#include <stdint.h>
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();
}

View File

@ -1,98 +0,0 @@
#pragma once
#include <stdint.h>
#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&));
}

View File

@ -1,12 +0,0 @@
#pragma once
#include <stdint.h>
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);
}

View File

@ -1,13 +0,0 @@
#pragma once
#include "render/Color.h"
#include <stddef.h>
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();
}

View File

@ -1,41 +0,0 @@
#ifndef _MOON_CLOG_H
#define _MOON_CLOG_H
enum log_level
{
LOG_DEBUG,
LOG_INFO,
LOG_WARN,
LOG_ERROR
};
#define PRINTF_LIKE(n, m) __attribute__((format(printf, n, m)))
#ifdef __cplusplus
extern "C"
{
#endif
void clog_log(const char* function, enum log_level level, const char* message, ...) PRINTF_LIKE(3, 4);
void clog_logln(const char* function, enum log_level level, const char* message, ...) PRINTF_LIKE(3, 4);
#ifdef __cplusplus
}
#endif
#ifndef MODULE
#define kcommonlog(function, level, ...) clog_##function(__FUNCTION__, level, __VA_ARGS__)
#else
#define kcommonlog(function, level, ...) clog_##function(MODULE, level, __VA_ARGS__)
#endif
#define kdbg(...) kcommonlog(log, LOG_DEBUG, __VA_ARGS__)
#define kdbgln(...) kcommonlog(logln, LOG_DEBUG, __VA_ARGS__)
#define kinfo(...) kcommonlog(log, LOG_INFO, __VA_ARGS__)
#define kinfoln(...) kcommonlog(logln, LOG_INFO, __VA_ARGS__)
#define kwarn(...) kcommonlog(log, LOG_WARN, __VA_ARGS__)
#define kwarnln(...) kcommonlog(logln, LOG_WARN, __VA_ARGS__)
#define kerror(...) kcommonlog(log, LOG_ERROR, __VA_ARGS__)
#define kerrorln(...) kcommonlog(logln, LOG_ERROR, __VA_ARGS__)
#endif

View File

@ -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__)

View File

@ -1,22 +0,0 @@
#pragma once
#include "memory/Paging.h"
#include "utils/Result.h"
struct AddressSpace
{
static Result<AddressSpace> create();
void destroy();
void clear();
AddressSpace clone();
PageTable* get_pml4()
{
return m_pml4;
}
private:
PageTable* m_pml4;
};

View File

@ -1,15 +0,0 @@
#pragma once
#include <stdint.h>
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();
}

View File

@ -1,11 +0,0 @@
#pragma once
#include <stdint.h>
namespace Memory
{
uint64_t get_system();
uint64_t get_usable();
bool is_user_address(uintptr_t address);
bool is_kernel_address(uintptr_t address);
}

View File

@ -1,41 +0,0 @@
#pragma once
#include "utils/Result.h"
#include <stdint.h>
#ifndef PAGE_SIZE
#define PAGE_SIZE 4096
#endif
#define MAP_READ_WRITE 1 << 0
#define MAP_USER 1 << 1
#define MAP_EXEC 1 << 2
#define MAP_AS_OWNED_BY_TASK 1 << 3
namespace MemoryManager
{
void init();
void protect_kernel_sections();
Result<void*> get_mapping(void* physicalAddress, int flags = MAP_READ_WRITE);
void release_mapping(void* mapping);
Result<void*> get_unaligned_mapping(void* physicalAddress, int flags = MAP_READ_WRITE);
Result<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);
Result<void*> get_page(int flags = MAP_READ_WRITE);
Result<void*> get_pages(uint64_t count, int flags = MAP_READ_WRITE);
Result<void*> get_page_at(uint64_t addr, int flags = MAP_READ_WRITE);
Result<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);
void map_several_pages(uint64_t physicalAddress, uint64_t virtualAddress, uint64_t count,
int flags = MAP_READ_WRITE);
}

View File

@ -1,6 +0,0 @@
#pragma once
namespace Memory
{
void walk_memory_map();
}

View File

@ -1,25 +0,0 @@
#pragma once
#include "utils/Result.h"
#include <stdint.h>
namespace PMM
{
void init();
Result<void*> request_page();
Result<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();
};

View File

@ -1,34 +0,0 @@
#pragma once
#include <stdint.h>
#ifndef PAGE_SIZE
#define PAGE_SIZE 4096
#endif
struct PageDirectoryEntry
{
bool present : 1;
bool read_write : 1;
bool user : 1;
bool write_through : 1;
bool cache_disabled : 1;
bool accessed : 1;
bool ignore0 : 1;
bool larger_pages : 1;
bool ignore1 : 1;
uint8_t available : 3;
uint64_t address : 48;
bool owned_by_task : 1; // Part of the available for OS use bits.
uint8_t available2 : 2;
bool no_execute : 1;
void set_address(uint64_t addr);
uint64_t get_address();
} __attribute__((packed));
struct PageTable
{
PageDirectoryEntry entries[512];
} __attribute__((aligned(PAGE_SIZE)));
static_assert(sizeof(PageDirectoryEntry) == 8UL);

View File

@ -1,27 +0,0 @@
#pragma once
#include <stdint.h>
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);
};

View File

@ -1,48 +0,0 @@
#pragma once
#include "memory/AddressSpace.h"
#include "memory/Paging.h"
enum Flags
{
ReadWrite = 1 << 0,
User = 1 << 1,
Execute = 1 << 2,
OwnedByTask = 1 << 3,
};
namespace VMM
{
void init(); // Fetch page table from cr3
void switch_to_user_address_space(AddressSpace& space);
void switch_to_previous_user_address_space();
void switch_back_to_kernel_address_space();
void enter_syscall_context();
void exit_syscall_context();
void apply_address_space();
bool is_using_kernel_address_space();
void map(uint64_t vaddr, uint64_t paddr, int flags);
void remap(uint64_t vaddr, int flags);
void unmap(uint64_t vaddr);
uint64_t get_physical(uint64_t vaddr);
uint64_t get_flags(uint64_t vaddr);
PageDirectoryEntry* find_pde(PageTable* root, uint64_t vaddr);
PageDirectoryEntry* create_pde_if_not_exists(PageTable* root, uint64_t vaddr);
void propagate_read_write(PageTable* root, uint64_t vaddr);
void propagate_no_execute(PageTable* root, uint64_t vaddr);
void propagate_user(PageTable* root, uint64_t vaddr);
void flush_tlb(uint64_t addr);
void flush_tlb_full();
void decompose_vaddr(uint64_t vaddr, uint64_t& page_index, uint64_t& pt_index, uint64_t& pd_index,
uint64_t& pdp_index);
uint64_t recompose_vaddr(uint64_t page_index, uint64_t pt_index, uint64_t pd_index, uint64_t pdp_index);
void install_kernel_page_directory_into_address_space(AddressSpace& space);
};

View File

@ -1,75 +0,0 @@
#ifndef _LIBALLOC_H
#define _LIBALLOC_H
#include <stddef.h>
/** \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

View File

@ -1,21 +0,0 @@
#pragma once
#include <stdint.h>
#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;
};

View File

@ -1,4 +0,0 @@
#pragma once
#include "io/PCI.h"
const char* pci_type_name(PCI::DeviceType type);

View File

@ -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);

View File

@ -1,4 +0,0 @@
#pragma once
[[noreturn]] void hang();
void halt();

View File

@ -1,3 +0,0 @@
#pragma once
[[noreturn]] void reboot();

View File

@ -1,3 +0,0 @@
#pragma once
[[noreturn]] void shutdown();

View File

@ -1,10 +0,0 @@
#pragma once
#include <stdint.h>
namespace Utilities
{
inline uint64_t get_blocks_from_size(uint64_t blocksize, uint64_t size)
{
return (size + (blocksize - 1)) / blocksize;
}
}

View File

@ -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)

View File

@ -1,7 +0,0 @@
#pragma once
namespace Mersenne
{
void init();
void reseed();
}

View File

@ -1,8 +0,0 @@
#pragma once
#include <stdint.h>
namespace Mersenne
{
void seed(uint64_t);
uint64_t get();
}

View File

@ -1,22 +0,0 @@
#pragma once
#include <stdint.h>
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)

View File

@ -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;

View File

@ -1,10 +0,0 @@
#pragma once
#include "render/Color.h"
#include <stddef.h>
namespace TextRenderer
{
void putchar(char chr);
void write(const char* str, size_t size);
void reset();
}

View File

@ -1,9 +0,0 @@
#pragma once
#include "panic/Panic.h"
#define STRINGIZE(x) #x
#define STRINGIZE_VALUE_OF(x) STRINGIZE(x)
// clang-format off
#define ensure(expr) (bool)(expr) || panic("Check failed at " __FILE__ ", line " STRINGIZE_VALUE_OF(__LINE__) ": " #expr)
// clang-format on

View File

@ -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

View File

@ -1,7 +0,0 @@
#pragma once
char* basename(char* path);
char* dirname(char* path);
char* better_basename(const char* path);
char* better_dirname(const char* path);

View File

@ -1,14 +0,0 @@
#pragma once
#include <stdarg.h>
#include <stddef.h>
#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);

View File

@ -1,14 +0,0 @@
#pragma once
#include <stdint.h>
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

View File

@ -1,23 +0,0 @@
#pragma once
#include <stddef.h>
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);

View File

@ -1,76 +0,0 @@
#pragma once
#include "interrupts/Context.h"
#include <stddef.h>
#include <sys/types.h>
#define SYS_exit 0
#define SYS_yield 1
#define SYS_sleep 2
#define SYS_write 3
#define SYS_getprocid 4
#define SYS_mmap 5
#define SYS_munmap 6
#define SYS_open 7
#define SYS_read 8
#define SYS_close 9
#define SYS_seek 10
#define SYS_execv 11
#define SYS_fcntl 12
#define SYS_mprotect 13
#define SYS_clock_gettime 14
#define SYS_mkdir 15
#define SYS_fork 16
#define SYS_waitpid 17
#define SYS_access 18
#define SYS_fstat 19
#define SYS_pstat 20
#define SYS_getdents 21
#define SYS_stat 22
#define SYS_dup2 23
#define SYS_setuid 24
#define SYS_setgid 25
#define SYS_umask 26
#define SYS_ioctl 27
#define SYS_seteuid 28
#define SYS_setegid 29
struct stat;
struct pstat;
struct luna_dirent;
struct timespec;
namespace Syscall
{
void entry(Context* context);
}
void sys_exit(Context* context, int status);
void sys_yield(Context* context);
void sys_sleep(Context* context, uint64_t ms);
void sys_write(Context* context, int fd, size_t size, const char* addr);
void sys_getprocid(Context* context, int field);
void sys_mmap(Context* context, void* address, size_t size, int prot, int fd, off_t offset);
void sys_munmap(Context* context, void* address, size_t size);
void sys_open(Context* context, const char* filename, int flags, mode_t mode);
void sys_read(Context* context, int fd, size_t size, char* buffer);
void sys_close(Context* context, int fd);
void sys_seek(Context* context, int fd, long offset, int whence);
void sys_execv(Context* context, const char* pathname, char** argv);
void sys_fcntl(Context* context, int fd, int command, uintptr_t arg);
void sys_mprotect(Context* context, void* address, size_t size, int prot);
void sys_clock_gettime(Context* context, int clock_id, struct timespec* tp);
void sys_mkdir(Context* context, const char* filename, mode_t mode);
void sys_fork(Context* context);
void sys_waitpid(Context* context, long pid, int* wstatus, int options);
void sys_access(Context* context, const char* path, int amode);
void sys_fstat(Context* context, int fd, struct stat* buf);
void sys_pstat(Context* context, long pid, struct pstat* buf);
void sys_getdents(Context* context, int fd, struct luna_dirent* buf, size_t count);
void sys_stat(Context* context, const char* path, struct stat* buf);
void sys_dup2(Context* context, int fd, int fd2);
void sys_setuid(Context* context, uid_t uid);
void sys_setgid(Context* context, gid_t gid);
void sys_umask(Context* context, mode_t cmask);
void sys_ioctl(Context* context, int fd, int request, uintptr_t arg);
void sys_seteuid(Context* context, uid_t euid);
void sys_setegid(Context* context, gid_t egid);

View File

@ -1,30 +0,0 @@
#pragma once
#ifndef MODULE
#define MODULE "mem"
#endif
#include "log/Log.h"
#include "memory/MemoryManager.h"
#include "memory/VMM.h"
#include "misc/utils.h"
#include <stddef.h>
Result<char*> strdup_from_user(const char* user_string);
bool validate_user_readable_page(uintptr_t address);
bool validate_user_writable_page(uintptr_t address);
bool validate_user_read(uintptr_t address, size_t size);
bool validate_user_write(uintptr_t address, size_t size);
bool copy_from_user(const void* user_ptr, void* ptr, size_t size);
bool copy_to_user(void* user_ptr, const void* ptr, size_t size);
template <typename T> bool copy_typed_from_user(const T* user_ptr, T* ptr)
{
return copy_from_user(user_ptr, ptr, sizeof(T));
}
template <typename T> bool copy_typed_to_user(T* user_ptr, const T* ptr)
{
return copy_to_user(user_ptr, ptr, sizeof(T));
}

View File

@ -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 <stdint.h>
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;

View File

@ -1,13 +0,0 @@
#pragma once
#include "fs/VFS.h"
#include "sys/elf/Image.h"
#include <stdint.h>
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);
}

View File

@ -1,15 +0,0 @@
#pragma once
#include <stdint.h>
struct ELFSection
{
uintptr_t base;
uint64_t pages;
};
struct ELFImage
{
uintptr_t entry;
uint64_t section_count;
ELFSection sections[1];
};

View File

@ -1,11 +0,0 @@
#pragma once
#include <stdint.h>
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();
}

View File

@ -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);
}

View File

@ -1,15 +0,0 @@
#pragma once
#include <stdint.h>
struct Spinlock
{
public:
void acquire();
void release();
bool locked();
private:
volatile uint64_t m_lock = 0;
};
void lock(Spinlock& lock, void (*action)(void));

View File

@ -1,123 +0,0 @@
#pragma once
#include "fs/FileDescriptor.h"
#include "interrupts/Context.h"
#include "memory/AddressSpace.h"
#include "memory/UserHeap.h"
#include "sys/elf/Image.h"
#include <sys/types.h>
#define TASK_MAX_FDS 32
enum class BlockReason
{
None,
Reading,
Waiting,
};
// FIXME: To make this struct more C++-styled, maybe we could make a lot of these variables private and add
// getters/setters?
struct Task
{
enum TaskState
{
Idle,
Running,
Sleeping,
Dying,
Blocking,
Exited
};
uint64_t id;
uint64_t ppid;
Context regs;
int64_t task_sleep = 0;
int64_t exit_status;
int64_t task_time = 0;
uid_t uid;
uid_t euid;
gid_t gid;
gid_t egid;
Task* next_task = nullptr;
Task* prev_task = nullptr;
uint64_t allocated_stack = 0;
TaskState state;
uint64_t cpu_time = 0;
char floating_region[512] __attribute__((aligned(16)));
bool floating_saved = false;
bool user_task = true;
bool is_user_task();
ELFImage* image = nullptr; // FIXME: we probably don't need to keep track of this anymore since the ELF sections are
// freed automatically when calling destroy() or clear() on the address space.
Descriptor files[TASK_MAX_FDS];
AddressSpace address_space;
UserHeap allocator;
int alloc_fd();
int alloc_fd_greater_than_or_equal(int base_fd);
void save_context(Context* context);
void restore_context(Context* context);
void save_floating();
void restore_floating();
void switch_to_address_space();
bool has_died();
char name[128];
mode_t umask;
BlockReason block_reason;
union {
struct
{
size_t size;
int fd;
char* buf;
} blocking_read_info;
struct
{
int64_t pid;
int* wstatus;
} blocking_wait_info;
};
void resume();
bool is_still_blocking();
// FIXME: These two functions are a bit clunky.
Descriptor* open_descriptor_from_fd(int fd, int& error);
Descriptor* descriptor_from_fd(int fd, int& error);
bool is_superuser();
private:
void resume_read();
void resume_wait();
bool is_read_still_blocking();
bool is_wait_still_blocking();
};

View File

@ -1,5 +0,0 @@
#pragma once
#include <stddef.h>
#include <stdint.h>
void get_symbol_name(uintptr_t address, char* buffer, size_t size);

View File

@ -1,15 +0,0 @@
#pragma once
#include <stdint.h>
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);

Some files were not shown because too many files have changed in this diff Show More