diff --git a/README.md b/README.md index 1f75391..2368445 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,11 @@ -Yggdrasil x86-64 kernel (+ userspace) +Yggdrasil x86-64 kernel ====================================== (I still need refactoring, huh.) -Yggdrasil is the name for my kernel and userspace development -project which tries to follow the Unix principles (sheesh, yet -another POSIX OS?) and is loosely inspired by stuff like Linux, +Yggdrasil is the name for my kernel development project which +tries to follow the Unix principles (sheesh, yet another POSIX +OS?) and is loosely inspired by stuff like Linux, BSD and other *nixes I've laid my hands on so far. ![alt text](doc/demo0.png "Demo") @@ -19,12 +19,8 @@ Building make ``` -The result is `build/sys/amd64/image.iso` bootable ISO file. You can -burn it on some physical drive or just use qemu. To run qemu, use - -```Shell session - make qemu -``` +The results are build/sys/amd64/loader.elf (32-bit loader and for 64-bit kernel) +and build/sys/amd64/kernel.elf (the kernel itself) What works ---------- diff --git a/etc/make/amd64/conf.mk b/etc/make/amd64/conf.mk index abdafd9..cba0850 100644 --- a/etc/make/amd64/conf.mk +++ b/etc/make/amd64/conf.mk @@ -6,6 +6,8 @@ include etc/make/amd64/config.mk all: +TARGETS+=$(O)/sys/amd64/loader.elf $(O)/sys/amd64/kernel.elf + # add .inc includes for asm HEADERS+=$(shell find include -name "*.inc") @@ -42,7 +44,6 @@ $(O)/sys/font/%.o: etc/%.psfu config -o $@ sys/amd64/incbin.S ### Kernel loader build -TARGETS+=$(O)/sys/amd64/image.iso DIRS+=$(O)/sys/amd64/loader loader_OBJS+=$(O)/sys/amd64/loader/boot.o \ $(O)/sys/amd64/loader/loader.o \ @@ -72,75 +73,3 @@ $(O)/sys/amd64/loader/%.o: sys/amd64/loader/%.S $(HEADERS) config $(O)/sys/amd64/loader/%.o: sys/amd64/loader/%.c $(HEADERS) config @printf " CC\t%s\n" $(@:$(O)/%=%) @$(CC86) $(loader_CFLAGS) $(DEFINES) -c -o $@ $< - -### Initrd building -amd64_mkstage: - @make -sC usr all O=$(O)/usr \ - STAGE=$(O)/stage \ - CC=$(CC64) \ - AR=$(AR64) \ - LD=$(LD64) \ - S=$(abspath .) - -$(O)/sys/amd64/initrd.img: amd64_mkstage - @cd $(O)/stage && tar czf $@ * - @du -sh $@ - -### Debugging and emulation -QEMU_BIN?=qemu-system-x86_64 -# TODO: Uncomment these once I implement this -# This is for playing around with PCI descriptions -#QEMU_DEVS?=-device ich9-usb-uhci1,id=uhci-0 \ -# -device usb-mouse,bus=uhci-0.0 \ -# -device usb-kbd,bus=uhci-0.0 - -QEMU_CHIPSET?=q35 - -ifdef QEMU_HDA -QEMU_DEV_HDA=-drive file=$(QEMU_HDA),format=raw,id=disk_hda -QEMU_DEVS+=$(QEMU_DEV_HDA) -endif - -ifdef QEMU_NET_TAP -QEMU_NETDEV=-netdev type=tap,id=net0 -else -QEMU_NETDEV=-netdev type=user,hostfwd=tcp::5555-:22,hostfwd=udp::5555-:22,id=net0 -endif - -ifdef QEMU_NET -QEMU_DEV_NET=-device $(QEMU_NET),netdev=net0,mac=11:22:33:44:55:66 \ - $(QEMU_NETDEV) \ - -object filter-dump,id=f1,netdev=net0,file=eth_dump.dat -QEMU_DEVS+=$(QEMU_DEV_NET) -endif - -# Use newer (ICH9-based) chipset instead of PIIX4 -QEMU_OPTS?=-m $(QEMU_MEM) \ - -chardev stdio,nowait,id=char0,mux=on \ - -serial chardev:char0 -mon chardev=char0 \ - -M $(QEMU_CHIPSET) \ - -cpu host \ - -enable-kvm \ - -boot d \ - $(QEMU_DEVS) \ - -smp $(QEMU_SMP) - -ifdef QEMU_DEBUG -QEMU_OPTS+=-s -S -endif - -$(O)/sys/amd64/image.iso: $(O)/sys/amd64/kernel.elf \ - $(O)/sys/amd64/loader.elf \ - $(O)/sys/amd64/initrd.img \ - sys/amd64/grub.cfg - @printf " ISO\t%s\n" $(@:$(O)/%=%) - @cp sys/amd64/grub.cfg $(O)/sys/amd64/image/boot/grub/grub.cfg - @cp $(O)/sys/amd64/kernel.elf $(O)/sys/amd64/image/boot/kernel - @cp $(O)/sys/amd64/loader.elf $(O)/sys/amd64/image/boot/loader - @cp $(O)/sys/amd64/initrd.img $(O)/sys/amd64/image/boot/initrd.img - @grub-mkrescue -o $(O)/sys/amd64/image.iso $(O)/sys/amd64/image 2>/dev/null - -qemu: all - @$(QEMU_BIN) \ - -cdrom $(O)/sys/amd64/image.iso \ - $(QEMU_OPTS) diff --git a/usr/Makefile b/usr/Makefile deleted file mode 100644 index 692211a..0000000 --- a/usr/Makefile +++ /dev/null @@ -1,87 +0,0 @@ -# Input parameters: -# O -- build files -# STAGE -- initrd rootfs - -DIRS=$(O) \ - $(O)/libc -HDRS=$(shell find $(S) -type f -name "*.h") -STAGE_BIN=$(STAGE)/init \ - $(STAGE)/bin/hexd \ - $(STAGE)/bin/ls \ - $(STAGE)/bin/reboot - -CFLAGS=-ffreestanding \ - -nostdlib \ - -mno-sse \ - -mno-sse2 \ - -Ilibc/include \ - -ggdb \ - -O0 \ - -I$(S)/include - -usr_LDFLAGS=-nostdlib \ - -lgcc \ - -Tlibc/program.ld -usr_STATIC_LIBS=$(O)/libc.a - -libc_CRTI=$(O)/libc/crti.o -libc_CRTN=$(O)/libc/crtn.o -libc_OBJS=$(O)/libc/crt0.o \ - $(O)/libc/syscall.o \ - $(O)/libc/vsnprintf.o \ - $(O)/libc/printf.o \ - $(O)/libc/string.o \ - $(O)/libc/errno.o \ - $(O)/libc/stdio.o \ - $(O)/libc/init.o \ - $(O)/libc/malloc.o \ - $(O)/libc/dirent.o \ - $(O)/libc/signal.o \ - $(O)/libc/global.o \ - $(O)/libc/time.o - -sys_CRTBEGIN=$(shell $(CC) $(CFLAGS) -print-file-name=crtbegin.o) -sys_CRTEND=$(shell $(CC) $(CFLAGS) -print-file-name=crtend.o) - -all: mkdirs mkstage-etc $(STAGE_BIN) - -mkdirs: - mkdir -p $(DIRS) - -mkstage-etc: - mkdir -p $(STAGE)/dev $(STAGE)/mnt $(STAGE)/bin - cp -r etc $(STAGE) - -# Application building -$(STAGE)/init: init.c $(libc_CRTI) $(libc_CRTN) $(O)/libc.a - @printf " CC\t%s\n" $(@:$(STAGE)/%=/%) - @$(CC) -o $@ $(CFLAGS) $(usr_LDFLAGS) \ - $(libc_CRTI) \ - $(sys_CRTBEGIN) \ - init.c \ - $(sys_CRTEND) \ - $(libc_CRTN) \ - $(usr_STATIC_LIBS) - -$(STAGE)/bin/%: core/bin/%.c $(libc_CRTI) $(libc_CRTN) $(O)/libc.a - @printf " CC\t%s\n" $(@:$(STAGE)/%=/%) - @$(CC) -o $@ $(CFLAGS) $(usr_LDFLAGS) \ - $(libc_CRTI) \ - $(sys_CRTBEGIN) \ - $< \ - $(sys_CRTEND) \ - $(libc_CRTN) \ - $(usr_STATIC_LIBS) - -# libc building -$(O)/libc.a: $(libc_OBJS) - @printf " AR\t%s\n" $(@:$(O)/%=%) - @$(AR) rcs $@ $(libc_OBJS) - -$(O)/libc/%.o: libc/%.c $(HDRS) - @printf " CC\t%s\n" $(@:$(O)/%=%) - @$(CC) -c -o $@ $(CFLAGS) $< - -$(O)/libc/%.o: libc/%.S - @printf " AS\t%s\n" $(@:$(O)/%=%) - @$(CC) -c -o $@ $(CFLAGS) $< diff --git a/usr/core/bin/hexd.c b/usr/core/bin/hexd.c deleted file mode 100644 index 0b74eee..0000000 --- a/usr/core/bin/hexd.c +++ /dev/null @@ -1,95 +0,0 @@ -#include -#include -#include -#include - -#define LINE_LENGTH 16 - -static void line_print(size_t off, const char *line, size_t len) { - printf("%08x: ", off); - for (size_t i = 0; i < LINE_LENGTH; ++i) { - // XXX: This is needed because I didn't implement h/hh modifiers in printf - uint64_t byte = (uint64_t) line[i] & 0xFF; - if (i < len) { - printf("%02x", byte); - } else { - printf(" "); - } - if (i % 2) { - printf(" "); - } - } - printf("| "); - for (size_t i = 0; i < len; ++i) { - // TODO: isprint? - if (line[i] >= ' ') { - printf("%c", line[i]); - } else { - printf("."); - } - } - printf("\n"); -} - -int main(int argc, char **argv) { - int fd; - const char *path; - char buf[512]; - char line[LINE_LENGTH]; - ssize_t bread; - size_t offset; - size_t linel; - size_t n_full_zero; - - if (argc != 2) { - printf("wrong\n"); - return -1; - } - - path = argv[1]; - printf("open file %s\n", path); - - if ((fd = open(path, O_RDONLY, 0)) < 0) { - perror(path); - return -1; - } - - offset = 0; - linel = 0; - n_full_zero = 0; - while ((bread = read(fd, buf, sizeof(buf))) > 0) { - for (size_t i = 0; i < bread; ++i) { - line[linel++] = buf[i]; - if (linel == LINE_LENGTH) { - // Check if the line is all zeros - int all_zeros = 1; - for (size_t j = 0; j < LINE_LENGTH; ++j) { - if (line[j]) { - all_zeros = 0; - break; - } - } - if (all_zeros) { - ++n_full_zero; - } else { - n_full_zero = 0; - } - - if (n_full_zero < 3) { - line_print(offset, line, linel); - } else if (n_full_zero == 3) { - printf(" ... \n"); - } - offset += LINE_LENGTH; - linel = 0; - } - } - } - if (linel) { - line_print(offset, line, linel); - } - - close(fd); - - return 0; -} diff --git a/usr/core/bin/ls.c b/usr/core/bin/ls.c deleted file mode 100644 index f5547f5..0000000 --- a/usr/core/bin/ls.c +++ /dev/null @@ -1,136 +0,0 @@ -#include -#include -#include -#include -#include -#include - -#define LS_COLOR (1 << 0) -#define LS_DETAIL (1 << 1) - -#define COLOR_DIR "\033[36m" -#define COLOR_DEV "\033[33m" -#define COLOR_UNKNOWN "\033[43m" - -#define COLOR_RESET "\033[0m" - -static int ls_dir(const char *path, int flags) { - int res; - DIR *dir; - struct dirent *ent; - struct stat ent_stat; - char ent_path[512]; - char t; - - if (!(dir = opendir(path))) { - perror(path); - return -1; - } - - while ((ent = readdir(dir))) { - if (ent->d_name[0] != '.') { - if (flags & LS_DETAIL) { - snprintf(ent_path, sizeof(ent_path), "%s/%s", - strcmp(path, "") ? path : ".", ent->d_name); - if (stat(ent_path, &ent_stat) != 0) { - printf("?????????? ? ? ? "); - } else { - switch (ent_stat.st_mode & S_IFMT) { - case S_IFDIR: - t = 'd'; - break; - case S_IFREG: - t = '-'; - break; - case S_IFBLK: - t = 'b'; - break; - case S_IFCHR: - t = 'c'; - break; - default: - t = '?'; - break; - } - - printf("%c%c%c%c%c%c%c%c%c%c ", - t, - (ent_stat.st_mode & S_IRUSR) ? 'r' : '-', - (ent_stat.st_mode & S_IWUSR) ? 'w' : '-', - (ent_stat.st_mode & S_IXUSR) ? 'x' : '-', - (ent_stat.st_mode & S_IRGRP) ? 'r' : '-', - (ent_stat.st_mode & S_IWGRP) ? 'w' : '-', - (ent_stat.st_mode & S_IXGRP) ? 'x' : '-', - (ent_stat.st_mode & S_IROTH) ? 'r' : '-', - (ent_stat.st_mode & S_IWOTH) ? 'w' : '-', - (ent_stat.st_mode & S_IXOTH) ? 'x' : '-'); - - printf("%4u %4u %8u ", - ent_stat.st_gid, - ent_stat.st_uid, - ent_stat.st_blocks); - } - } - - if (flags & LS_COLOR) { - switch (ent->d_type) { - case DT_REG: - break; - case DT_BLK: - case DT_CHR: - write(STDOUT_FILENO, COLOR_DEV, 5); - break; - case DT_DIR: - write(STDOUT_FILENO, COLOR_DIR, 5); - break; - default: - write(STDOUT_FILENO, COLOR_UNKNOWN, 5); - break; - } - } - write(STDOUT_FILENO, ent->d_name, strlen(ent->d_name)); - if (flags & LS_COLOR) { - write(STDOUT_FILENO, COLOR_RESET, 4); - } - putchar('\n'); - } - } - - closedir(dir); - - return 0; -} - -int main(int argc, char **argv) { - // Basic getopt-like features - int first = -1; - int flags = 0; - - for (int i = 1; i < argc; ++i) { - if (argv[i][0] != '-') { - first = i; - break; - } else { - if (!strcmp(argv[i], "-c")) { - flags |= LS_COLOR; - } else if (!strcmp(argv[i], "-d")) { - flags |= LS_DETAIL; - } else { - printf("Unknown option: %s\n", argv[i]); - } - } - } - - if (first == -1) { - ls_dir("", flags); - } else { - for (int i = first; i < argc; ++i) { - if (first != argc - 1) { - printf("%s:\n", argv[i]); - } - ls_dir(argv[i], flags); - } - } - - return 0; -} diff --git a/usr/core/bin/reboot.c b/usr/core/bin/reboot.c deleted file mode 100644 index 5d8a09a..0000000 --- a/usr/core/bin/reboot.c +++ /dev/null @@ -1,33 +0,0 @@ -#include -#include -#include -#include -#include - -int main(int argc, char **argv) { - const char *arg = NULL; - - if (argc == 2) { - arg = argv[1]; - } - - int res; - unsigned int cmd = YGG_REBOOT_RESTART; - - if (arg) { - if (!strcmp(arg, "-s")) { - cmd = YGG_REBOOT_POWER_OFF; - } else if (!strcmp(arg, "-h")) { - cmd = YGG_REBOOT_HALT; - } - } - - if ((res = reboot(YGG_REBOOT_MAGIC1, YGG_REBOOT_MAGIC2, cmd, NULL)) < 0) { - perror("reboot()"); - return res; - } - - while (1) { - usleep(1000000); - } -} diff --git a/usr/etc/file.txt b/usr/etc/file.txt deleted file mode 100644 index ff7382d..0000000 --- a/usr/etc/file.txt +++ /dev/null @@ -1 +0,0 @@ -This file is inside the initrd. diff --git a/usr/init.c b/usr/init.c deleted file mode 100644 index 908d145..0000000 --- a/usr/init.c +++ /dev/null @@ -1,410 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -// Cursor helpers - -#define curs_save() \ - write(STDOUT_FILENO, "\033[s", 3) -#define curs_unsave() \ - write(STDOUT_FILENO, "\033[u", 3) -#define curs_set(row, col) \ - printf("\033[%d;%df", row, col) -#define clear() \ - write(STDOUT_FILENO, "\033[2J", 4) - -#define BOX_ANGLE_UL "\332" -#define BOX_ANGLE_UR "\277" -#define BOX_ANGLE_LL "\300" -#define BOX_ANGLE_LR "\331" -#define BOX_HOR "\304" -#define BOX_VERT "\263" - -// - -extern __attribute__((noreturn)) void abort(void); - -#define assert(x) \ - if (!(x)) abort() - -struct builtin { - const char *name; - const char *desc; - int (*run) (const char *arg); -}; - -static int b_cd(const char *path); -static int b_pwd(const char *_); -static int b_cat(const char *path); -static int b_curs(const char *arg); -static int b_sleep(const char *arg); -static int b_help(const char *arg); -static int b_clear(const char *arg); - -static struct builtin builtins[] = { - { - "cd", - "Change working directory", - b_cd, - }, - { - "pwd", - "Print working directory", - b_pwd, - }, - { - "cat", - "Print file contents" /* Concatenate files */, - b_cat - }, - { - "sleep", - "Sleep N seconds", - b_sleep - }, - { - "clear", - "Clear terminal", - b_clear, - }, - { - "help", - "Please help me", - b_help - }, - { NULL, NULL, NULL } -}; - -static int b_cd(const char *arg) { - int res; - if (!arg) { - arg = ""; - } - - if ((res = chdir(arg)) < 0) { - perror(arg); - } - - return res; -} - -static int b_pwd(const char *arg) { - char buf[512]; - if (!getcwd(buf, sizeof(buf))) { - perror("getcwd()"); - return -1; - } else { - puts(buf); - } - return 0; -} - -static int b_cat(const char *arg) { - char buf[512]; - int fd; - ssize_t bread; - - if (!arg) { - return -1; - } - - if ((fd = open(arg, O_RDONLY, 0)) < 0) { - perror(arg); - return fd; - } - - while ((bread = read(fd, buf, sizeof(buf))) > 0) { - write(STDOUT_FILENO, buf, bread); - } - - close(fd); - - return 0; -} - -static int b_curs(const char *arg) { - char c; - - size_t w = 60; - size_t h = 20; - size_t off_y = (25 - h) / 2 + 1; - size_t off_x = (80 - w) / 2; - - const char *lines[18] = { - NULL, - "Demo something", - NULL, - "Slow as hell" - }; - - clear(); - - while (1) { - printf("\033[47;30m"); - - curs_set(off_y, off_x); - printf(BOX_ANGLE_UL); - for (size_t i = 0; i < w; ++i) { - printf(BOX_HOR); - } - printf(BOX_ANGLE_UR); - - for (size_t i = 0; i < h - 2; ++i) { - curs_set(off_y + 1 + i, off_x); - printf(BOX_VERT); - for (size_t j = 0; j < w; ++j) { - printf(" "); - } - if (lines[i]) { - curs_set(off_y + 1 + i, off_x + (w - strlen(lines[i])) / 2); - printf("%s", lines[i]); - } - curs_set(off_y + 1 + i, off_x + w + 1); - printf(BOX_VERT); - } - - curs_set(off_y + h - 3, off_x + (w - 8) / 2); - printf("\033[0m\033[7m[ OK ]\033[47;30m"); - curs_set(off_y + h - 1, off_x); - printf(BOX_ANGLE_LL); - for (size_t i = 0; i < w; ++i) { - printf(BOX_HOR); - } - printf(BOX_ANGLE_LR); - - printf("\033[0m"); - - curs_set(1, 1); - - if (read(STDIN_FILENO, &c, 1) < 0) { - break; - } - - if (c == 'q' || c == '\n') { - break; - } - } - - curs_set(1, 1); - - return 0; -} - -static int b_sleep(const char *arg) { - if (!arg) { - return -1; - } - int seconds = 0; - while (*arg) { - seconds *= 10; - seconds += *arg - '0'; - ++arg; - } - - struct timespec ts = { seconds, 0 }; - if ((seconds = nanosleep(&ts, NULL))) { - perror("nanosleep()"); - return seconds; - } - - return 0; -} - -static int b_clear(const char *arg) { - clear(); - curs_set(1, 1); - return 0; -} - -static int b_help(const char *arg) { - if (arg) { - // Describe a specific command - for (size_t i = 0; builtins[i].run; ++i) { - if (!strcmp(arg, builtins[i].name)) { - printf("%s: %s\n", builtins[i].name, builtins[i].desc); - return 0; - } - } - - printf("%s: Unknown command\n", arg); - return -1; - } else { - for (size_t i = 0; builtins[i].run; ++i) { - printf("%s: %s\n", builtins[i].name, builtins[i].desc); - } - - return 0; - } -} - -static void prompt(void) { - char cwd[512]; - if (!getcwd(cwd, sizeof(cwd))) { - cwd[0] = '?'; - cwd[1] = 0; - } - printf("\033[36mygg\033[0m %s > ", cwd); -} - -static int cmd_subproc_exec(const char *abs_path, const char *cmd, const char *e) { - // Maximum of 8 arguments 64 chars each (63) - // Split input argument into pieces by space - char args[64 * 8] = {0}; - const char *p = e; - const char *t = NULL; - size_t argc = 0; - while (p) { - t = strchr(p, ' '); - if (!t) { - // Last argument - assert(strlen(p) < 64); - strcpy(&args[argc++ * 64], p); - break; - } else { - assert(t - p < 64); - strncpy(&args[argc * 64], p, t - p); - args[(argc++ * 64) + (t - p)] = 0; - p = t + 1; - while (*p == ' ') { - ++p; - } - if (!*p) { - break; - } - } - } - - // Fill arg pointer array - const char *argp[10] = { cmd }; - for (size_t i = 0; i < argc; ++i) { - argp[i + 1] = &args[i * 64]; - } - argp[argc + 1] = NULL; - - int pid = fork(); - int res; - int status; - - switch (pid) { - case -1: - perror("fork()"); - return -1; - case 0: - if (execve(abs_path, argp, NULL) != 0) { - perror("execve()"); - } - exit(-1); - default: - if (waitpid(pid, &status) != 0) { - perror("waitpid()"); - } - return 0; - } -} - -static int cmd_exec(const char *line) { - char cmd[64]; - const char *e = strchr(line, ' '); - - if (!e) { - assert(strlen(line) < 64); - strcpy(cmd, line); - } else { - assert(e - line < 64); - strncpy(cmd, line, e - line); - cmd[e - line] = 0; - ++e; - while (*e == ' ') { - ++e; - } - } - - if (e && !*e) { - e = NULL; - } - - for (size_t i = 0; builtins[i].run; ++i) { - if (!strcmp(cmd, builtins[i].name)) { - return builtins[i].run(e); - } - } - - // If command starts with ./ or /, try to execute it - if (((cmd[0] == '.' && cmd[1] == '/') || cmd[0] == '/') && access(cmd, X_OK) == 0) { - return cmd_subproc_exec(cmd, cmd, e); - } - // Try to execute binary from /bin - char path_buf[512]; - snprintf(path_buf, sizeof(path_buf), "/bin/%s", cmd); - if (access(path_buf, X_OK) == 0) { - return cmd_subproc_exec(path_buf, cmd, e); - } - - printf("%s: Unknown command\n", cmd); - return -1; -} - -int main(int argc, char **argv) { - if (getpid() != 1) { - printf("Won't work if PID is not 1\n"); - return -1; - } - char linebuf[512]; - char c; - size_t l = 0; - int res; - - prompt(); - -#if 0 - if ((res = fork()) < 0) { - perror("fork()"); - return -1; - } else if (res == 0) { - if (execve("/time", NULL, NULL) != 0) { - perror("execve()"); - } - exit(-1); - } -#endif - - while (1) { - if (read(STDIN_FILENO, &c, 1) < 0) { - break; - } - - if (c == '\b') { - if (l) { - linebuf[--l] = 0; - printf("\033[D \033[D"); - } - continue; - } - if (c == '\n') { - write(STDOUT_FILENO, &c, 1); - linebuf[l] = 0; - - if (!strcmp(linebuf, "exit")) { - break; - } - - l = 0; - if ((res = cmd_exec(linebuf)) != 0) { - printf("\033[31m= %d\033[0m\n", res); - } - prompt(); - continue; - } - - linebuf[l++] = c; - write(STDOUT_FILENO, &c, 1); - } - - return -1; -} diff --git a/usr/libc/crt0.S b/usr/libc/crt0.S deleted file mode 100644 index 9d23bfd..0000000 --- a/usr/libc/crt0.S +++ /dev/null @@ -1,25 +0,0 @@ -.section .text -.global _start -.type _start, %function -// Arguments: -// %rdi - argp -_start: - movq $0, %rbp - // For callee linkage - pushq %rbp - pushq %rbp - movq %rsp, %rbp - - push %rdi - call __libc_init - - call _init - - mov __libc_argc, %rdi - pop %rsi - - // exit(main(argc, argv)) - call main - movq %rax, %rdi - call exit -.size _start, . - _start diff --git a/usr/libc/crti.S b/usr/libc/crti.S deleted file mode 100644 index a85782e..0000000 --- a/usr/libc/crti.S +++ /dev/null @@ -1,16 +0,0 @@ -/* x86_64 crti.s */ -.section .init -.global _init -.type _init, @function -_init: - push %rbp - movq %rsp, %rbp - /* gcc will nicely put the contents of crtbegin.o's .init section here. */ - -.section .fini -.global _fini -.type _fini, @function -_fini: - push %rbp - movq %rsp, %rbp - /* gcc will nicely put the contents of crtbegin.o's .fini section here. */ diff --git a/usr/libc/crtn.S b/usr/libc/crtn.S deleted file mode 100644 index b446d9f..0000000 --- a/usr/libc/crtn.S +++ /dev/null @@ -1,10 +0,0 @@ -/* x86_64 crtn.s */ -.section .init - /* gcc will nicely put the contents of crtend.o's .init section here. */ - popq %rbp - ret - -.section .fini - /* gcc will nicely put the contents of crtend.o's .fini section here. */ - popq %rbp - ret diff --git a/usr/libc/dirent.c b/usr/libc/dirent.c deleted file mode 100644 index 73969e7..0000000 --- a/usr/libc/dirent.c +++ /dev/null @@ -1,57 +0,0 @@ -#include "dirent.h" -#include "bits/syscall.h" -#include -#include -#include - -extern void *malloc(size_t count); -extern void free(void *p); - -struct DIR_private { - int fd; - struct dirent buf; -}; - -DIR *opendir(const char *path) { - int fd; - DIR *res; - - if (!(res = malloc(sizeof(struct DIR_private)))) { - errno = ENOMEM; - return NULL; - } - - - if ((fd = open(path, O_DIRECTORY | O_RDONLY, 0)) < 0) { - fd = errno; - free(res); - errno = fd; - // errno is set - return NULL; - } - - res->fd = fd; - memset(&res->buf, 0, sizeof(res->buf)); - - return res; -} - -void closedir(DIR *dirp) { - if (!dirp) { - return; - } - close(dirp->fd); - free(dirp); -} - -struct dirent *readdir(DIR *dirp) { - ssize_t res; - if (!dirp) { - errno = EBADF; - return NULL; - } - if ((res = sys_readdir(dirp->fd, &dirp->buf)) <= 0) { - return NULL; - } - return &dirp->buf; -} diff --git a/usr/libc/errno.c b/usr/libc/errno.c deleted file mode 100644 index 941c59a..0000000 --- a/usr/libc/errno.c +++ /dev/null @@ -1,57 +0,0 @@ -#include -#include - -static const char *err_strings0[35] = { - "Success", - "Operation not permitted", - "No such file or directory", - "No such process", - "Interrupted system call", - "I/O error", - "No such device or address", - "Argument list too long", - "Exec format error", - "Bad file number", - "No child processes", - "Try again", - "Out of memory", - "Permission denied", - "Bad address", - "Block device required", - "Device or resource busy", - "File exists", - "Cross-device link", - "No such device", - "Not a directory", - "Is a directory", - "Invalid argument", - "File table overflow", - "Too many open files", - "Not a typewriter", - "Text file busy", - "File too large", - "No space left on device", - "Illegal seek", - "Read-only file system", - "Too many links", - "Broken pipe", - "Math argument out of domain of func", - "Math result not representable" -}; - -int errno; - -char *strerror(int n) { - if (n >= 0 && n <= 34) { - return (char *) err_strings0[n]; - } - return (char *) "Unknown error"; -} - -void perror(const char *e) { - if (e && *e) { - printf("%s: %s\n", e, strerror(errno)); - } else { - puts(strerror(errno)); - } -} diff --git a/usr/libc/global.c b/usr/libc/global.c deleted file mode 100644 index 1c04fb7..0000000 --- a/usr/libc/global.c +++ /dev/null @@ -1,4 +0,0 @@ -#include "bits/global.h" - -void *__cur_brk; -uint64_t __libc_argc = 0; diff --git a/usr/libc/include/bits/global.h b/usr/libc/include/bits/global.h deleted file mode 100644 index 6b0435b..0000000 --- a/usr/libc/include/bits/global.h +++ /dev/null @@ -1,5 +0,0 @@ -#pragma once -#include - -extern void *__cur_brk; -extern uint64_t __libc_argc; diff --git a/usr/libc/include/bits/printf.h b/usr/libc/include/bits/printf.h deleted file mode 100644 index 68ffd26..0000000 --- a/usr/libc/include/bits/printf.h +++ /dev/null @@ -1,7 +0,0 @@ -#pragma once -#include -#include - -int printf(const char *fmt, ...); -int snprintf(char *buf, size_t size, const char *fmt, ...); -int vsnprintf(char *buf, size_t size, const char *fmt, va_list args); diff --git a/usr/libc/include/bits/syscall.h b/usr/libc/include/bits/syscall.h deleted file mode 100644 index 33d9f72..0000000 --- a/usr/libc/include/bits/syscall.h +++ /dev/null @@ -1,30 +0,0 @@ -#pragma once -#include -#include -#include -#include -#include - -ssize_t read(int fd, void *buf, size_t count); -ssize_t write(int fd, const void *buf, size_t count); -int open(const char *filename, int flags, int mode); -void close(int fd); -int stat(const char *filename, struct stat *st); -void *mmap(void *addr, size_t len, int prot, int flags, int fd, uintptr_t offset); -int fork(void); -int execve(const char *filename, const char *const argv[], const char *const envp[]); -ssize_t sys_readdir(int fd, struct dirent *entp); -int kill(int pid, int signum); -void __kernel_signal(uintptr_t handler); -__attribute__((noreturn)) void __kernel_sigret(void); -int getpid(void); -int chdir(const char *filename); -char *getcwd(char *buf, size_t size); -int nanosleep(const struct timespec *req, struct timespec *rem); -int openpty(int *amaster, int *aslave); -int gettimeofday(struct timeval *tv, struct timezone *tz); -int reboot(int magic1, int magic2, unsigned int cmd, void *arg); -int access(const char *filename, int mode); -int waitpid(int pid, int *status); - -__attribute__((noreturn)) void exit(int code); diff --git a/usr/libc/include/dirent.h b/usr/libc/include/dirent.h deleted file mode 100644 index adb5774..0000000 --- a/usr/libc/include/dirent.h +++ /dev/null @@ -1,8 +0,0 @@ -#pragma once -#include - -typedef struct DIR_private DIR; - -DIR *opendir(const char *path); -void closedir(DIR *dirp); -struct dirent *readdir(DIR *dirp); diff --git a/usr/libc/include/errno.h b/usr/libc/include/errno.h deleted file mode 100644 index d85454b..0000000 --- a/usr/libc/include/errno.h +++ /dev/null @@ -1,7 +0,0 @@ -#pragma once -#include - -extern int errno; - -char *strerror(int errnum); -void perror(const char *s); diff --git a/usr/libc/include/signal.h b/usr/libc/include/signal.h deleted file mode 100644 index 0e1c34f..0000000 --- a/usr/libc/include/signal.h +++ /dev/null @@ -1,8 +0,0 @@ -#pragma once -#include - -typedef void (*sighandler_t) (int); - -sighandler_t signal(int signum, sighandler_t handler); - -int raise(int signum); diff --git a/usr/libc/include/stdio.h b/usr/libc/include/stdio.h deleted file mode 100644 index c89bef8..0000000 --- a/usr/libc/include/stdio.h +++ /dev/null @@ -1,6 +0,0 @@ -#pragma once - -int puts(const char *s); -int putchar(int c); - -#include "bits/printf.h" diff --git a/usr/libc/include/stdlib.h b/usr/libc/include/stdlib.h deleted file mode 100644 index 46de31c..0000000 --- a/usr/libc/include/stdlib.h +++ /dev/null @@ -1,3 +0,0 @@ -#pragma once - -void abort(void); diff --git a/usr/libc/include/string.h b/usr/libc/include/string.h deleted file mode 100644 index 0d57aa0..0000000 --- a/usr/libc/include/string.h +++ /dev/null @@ -1,17 +0,0 @@ -#pragma once -#include - -void *memcpy(void *restrict dst, const void *restrict src, size_t cnt); -void *memmove(void *dst, const void *src, size_t cnt); -void *memset(void *dst, int v, size_t count); -int memcmp(const void *a, const void *b, size_t count); - -size_t strlen(const char *s); -int strncmp(const char *a, const char *b, size_t lim); -int strcmp(const char *a, const char *b); -char *strchr(const char *a, int c); -char *strrchr(const char *a, int c); -char *strcpy(char *dst, const char *src); -char *strncpy(char *dst, const char *src, size_t lim); -char *strcat(char *dst, const char *src); -char *strncat(char *dst, const char *src, size_t lim); diff --git a/usr/libc/include/time.h b/usr/libc/include/time.h deleted file mode 100644 index 2bfead5..0000000 --- a/usr/libc/include/time.h +++ /dev/null @@ -1,4 +0,0 @@ -#pragma once -#include - -int usleep(long us); diff --git a/usr/libc/include/unistd.h b/usr/libc/include/unistd.h deleted file mode 100644 index 5485295..0000000 --- a/usr/libc/include/unistd.h +++ /dev/null @@ -1,10 +0,0 @@ -#pragma once -#include "bits/syscall.h" -#include - -#define STDIN_FILENO 0 -#define STDOUT_FILENO 1 -#define STDERR_FILENO 2 - -void *sbrk(intptr_t diff); -int reboot(int magic1, int magic2, unsigned int cmd, void *arg); diff --git a/usr/libc/init.c b/usr/libc/init.c deleted file mode 100644 index 77cd98c..0000000 --- a/usr/libc/init.c +++ /dev/null @@ -1,18 +0,0 @@ -#include -#include "bits/global.h" - -extern char __heap_start; -extern void __libc_signal_init(void); -static const char *argp_dummy[] = { 0 }; - -void __libc_init(char **argp) { - __libc_signal_init(); - __libc_argc = 0; - if (argp) { - while (argp[__libc_argc]) { - ++__libc_argc; - } - } - __cur_brk = &__heap_start; - errno = 0; -} diff --git a/usr/libc/malloc.c b/usr/libc/malloc.c deleted file mode 100644 index 49c2a9c..0000000 --- a/usr/libc/malloc.c +++ /dev/null @@ -1,15 +0,0 @@ -#include -#include "bits/global.h" - -// XXX: I'll implement a proper heap in the following commits -void *malloc(size_t count) { - void *p = __cur_brk; - if (sbrk(count) == p) { - return NULL; - } - return p; -} - -void free(void *ptr) { - -} diff --git a/usr/libc/printf.c b/usr/libc/printf.c deleted file mode 100644 index 0bcaaec..0000000 --- a/usr/libc/printf.c +++ /dev/null @@ -1,25 +0,0 @@ -#include "bits/printf.h" -#include -#define PRINTF_BUFFER_SIZE 1024 - -int printf(const char *fmt, ...) { - char buf[PRINTF_BUFFER_SIZE]; - va_list args; - va_start(args, fmt); - int res = vsnprintf(buf, PRINTF_BUFFER_SIZE, fmt, args); - va_end(args); - - // TODO: use libc's FILE * instead - return write(STDOUT_FILENO, buf, res); -} - -int snprintf(char *buf, size_t lim, const char *fmt, ...) { - va_list args; - int res; - - va_start(args, fmt); - res = vsnprintf(buf, PRINTF_BUFFER_SIZE, fmt, args); - va_end(args); - - return res; -} diff --git a/usr/libc/program.ld b/usr/libc/program.ld deleted file mode 100644 index f7d68df..0000000 --- a/usr/libc/program.ld +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Userspace program linker script, - * partially derived from GCC's -static one - */ -ENTRY(_start) - -SECTIONS { - . = 0x400000; - - .text : ALIGN(4K) { - KEEP (*(SORT_NONE(.init))) - *(.text) - KEEP (*(SORT_NONE(.fini))) - KEEP (*(SORT(.ctors.*))) - KEEP (*(.ctors)) - KEEP (*(SORT(.dtors.*))) - KEEP (*(.dtors)) - } - - .rodata : { - *(.rodata) - *(.eh_frame) - } - - .data : ALIGN(4K) { - *(.data) - } - - .bss : ALIGN(4K) { - *(.bss) - } - - __program_end = .; - __heap_start = .; -} diff --git a/usr/libc/signal.c b/usr/libc/signal.c deleted file mode 100644 index c42dfb1..0000000 --- a/usr/libc/signal.c +++ /dev/null @@ -1,71 +0,0 @@ -#include -#include -#include - -static sighandler_t signal_handlers[16] = {0}; - -void SIG_IGN(int signum) { - printf("Ignored: %d\n", signum); - - while (1); -} - -void SIG_DFL(int signum) { - int pid = getpid(); - - switch (signum) { - case SIGKILL: - printf("%d: killed\n", pid); - break; - case SIGABRT: - printf("%d: aborted\n", pid); - break; - case SIGSEGV: - printf("%d: segmentation fault\n", pid); - break; - default: - printf("%d: signal %d\n", pid, signum); - break; - } - - exit(1); -} - -static void __libc_signal_handle(int signum) { - if (signum >= 16) { - SIG_DFL(signum); - } else { - signal_handlers[signum](signum); - } - - __kernel_sigret(); -} - -void __libc_signal_init(void) { - for (size_t i = 0; i < 16; ++i) { - signal_handlers[i] = SIG_DFL; - } - - __kernel_signal((uintptr_t) __libc_signal_handle); -} - -sighandler_t signal(int signum, sighandler_t new_handler) { - sighandler_t old_handler; - - if (signum >= 16) { - printf("Fuck\n"); - exit(1); - } - - old_handler = signal_handlers[signum]; - signal_handlers[signum] = new_handler; - return old_handler; -} - -int raise(int signum) { - return kill(getpid(), signum); -} - -void abort(void) { - kill(getpid(), SIGABRT); -} diff --git a/usr/libc/stdio.c b/usr/libc/stdio.c deleted file mode 100644 index e22aaf2..0000000 --- a/usr/libc/stdio.c +++ /dev/null @@ -1,22 +0,0 @@ -#include -#include -#include - -int puts(const char *s) { - size_t l = strlen(s); - int w = write(STDOUT_FILENO, s, l); - char c = '\n'; - - if (w == l) { - write(STDOUT_FILENO, &c, 1); - } - return w; -} - -int putchar(int c) { - int res; - if ((res = write(STDOUT_FILENO, &c, 1)) < 0) { - return res; - } - return c; -} diff --git a/usr/libc/string.c b/usr/libc/string.c deleted file mode 100644 index c4d835d..0000000 --- a/usr/libc/string.c +++ /dev/null @@ -1,167 +0,0 @@ -#include - -char *strcat(char *dst, const char *src) { - size_t l = strlen(dst); - strcpy(dst + l, src); - return dst; -} - -char *strncat(char *dst, const char *src, size_t lim) { - size_t l = strlen(dst); - if (l < lim) { - return dst; - } - size_t r = lim - l; - strncpy(dst + l, src, r); - return dst; -} - -size_t strlen(const char *a) { - size_t s = 0; - while (*a++) { - ++s; - } - return s; -} - -int strncmp(const char *a, const char *b, size_t n) { - size_t c = 0; - for (; c < n && (*a || *b); ++c, ++a, ++b) { - if (*a != *b) { - return -1; - } - } - return 0; -} - -int strcmp(const char *a, const char *b) { - if (a == b) { - return 0; - } - if (a == NULL || b == NULL) { - return -1; - } - for (; *a || *b; ++a, ++b) { - if (*a != *b) { - return 1; - } - } - return 0; -} - -char *strcpy(char *dst, const char *src) { - size_t i; - for (i = 0; src[i]; ++i) { - dst[i] = src[i]; - } - dst[i] = 0; - return dst; -} - -char *strncpy(char *dst, const char *src, size_t lim) { - size_t i = 0; - while (i < lim) { - if (!src[i]) { - dst[i] = 0; - return dst; - } - dst[i] = src[i]; - ++i; - } - return dst; -} - -char *strchr(const char *s, int c) { - while (*s) { - if (*s == (char) c) { - return (char *) s; - } - ++s; - } - return NULL; -} - -char *strrchr(const char *s, int c) { - ssize_t l = (ssize_t) strlen(s); - if (!l) { - return NULL; - } - while (l >= 0) { - if (s[l] == (char) c) { - return (char *) &s[l]; - } - --l; - } - return NULL; -} - -int memcmp(const void *a, const void *b, size_t n) { - const char *l = a; - const char *r = b; - for (; n && *l == *r; --n, ++l, ++r); - return n ? *l - *r : 0; -} - -void *memmove(void *dest, const void *src, size_t n) { - char *d = dest; - const char *s = src; - - if (d == s) { - return d; - } - - if ((s + n) <= d || (d + n) <= s) { - return memcpy(d, s, n); - } - - if (d < s) { - if (((uintptr_t) s) % sizeof(size_t) == ((uintptr_t) d) % sizeof(size_t)) { - while (((uintptr_t) d) % sizeof(size_t)) { - if (!n--) { - return dest; - } - *d++ = *s++; - } - for (; n >= sizeof(size_t); n -= sizeof(size_t), d += sizeof(size_t), s += sizeof(size_t)) { - *((size_t *) d) = *((size_t *) s); - } - } - for (; n; n--) { - *d++ = *s++; - } - } else { - if (((uintptr_t) s) % sizeof(size_t) == ((uintptr_t) d) % sizeof(size_t)) { - while (((uintptr_t) (d + n)) % sizeof(size_t)) { - if (!n--) { - return dest; - } - d[n] = s[n]; - } - while (n >= sizeof(size_t)) { - n -= sizeof(size_t); - *((size_t *) (d + n)) = *((size_t *) (s + n)); - } - } - while (n) { - n--; - d[n] = s[n]; - } - } - - return dest; -} - -void *memset(void *blk, int v, size_t sz) { - for (size_t i = 0; i < sz; ++i) { - ((char *) blk)[i] = v; - } - return blk; -} - -void *memcpy(void *dst, const void *src, size_t sz) { - for (size_t i = 0; i < sz; ++i) { - ((char *) dst)[i] = ((const char *) src)[i]; - } - return dst; -} - diff --git a/usr/libc/syscall.c b/usr/libc/syscall.c deleted file mode 100644 index 2c60c88..0000000 --- a/usr/libc/syscall.c +++ /dev/null @@ -1,179 +0,0 @@ -#include "bits/syscall.h" -#include "bits/global.h" -#include - -#define ASM_REGISTER(name) \ - register uint64_t name asm (#name) - -#define ASM_SYSCALL0(r0) ({ \ - ASM_REGISTER(rax) = (uint64_t) (r0); \ - asm volatile ("syscall":::"memory"); \ - rax; \ - }) - -#define ASM_SYSCALL1(r0, r1) ({ \ - ASM_REGISTER(rdi) = (uint64_t) (r1); \ - /* - * Should be the last one because memory accesses for arguments - * fuck up %rax - */ \ - ASM_REGISTER(rax) = (uint64_t) (r0); \ - asm volatile ("syscall":::"memory"); \ - rax; \ - }) - -#define ASM_SYSCALL2(r0, r1, r2) ({ \ - ASM_REGISTER(rdi) = (uint64_t) (r1); \ - ASM_REGISTER(rsi) = (uint64_t) (r2); \ - /* - * Should be the last one because memory accesses for arguments - * fuck up %rax - */ \ - ASM_REGISTER(rax) = (uint64_t) (r0); \ - asm volatile ("syscall":::"memory", "rax", "rdi", "rsi", "rdx"); \ - rax; \ - }) - -#define ASM_SYSCALL3(r0, r1, r2, r3) ({ \ - ASM_REGISTER(rdi) = (uint64_t) (r1); \ - ASM_REGISTER(rsi) = (uint64_t) (r2); \ - ASM_REGISTER(rdx) = (uint64_t) (r3); \ - /* - * Should be the last one because memory accesses for arguments - * fuck up %rax - */ \ - ASM_REGISTER(rax) = (uint64_t) (r0); \ - asm volatile ("syscall":::"memory", "rax", "rdi", "rsi", "rdx"); \ - rax; \ - }) - -#define ASM_SYSCALL4(r0, r1, r2, r3, r4) ({ \ - ASM_REGISTER(rdi) = (uint64_t) (r1); \ - ASM_REGISTER(rsi) = (uint64_t) (r2); \ - ASM_REGISTER(rdx) = (uint64_t) (r3); \ - ASM_REGISTER(r10) = (uint64_t) (r4); \ - /* - * Should be the last one because memory accesses for arguments - * fuck up %rax - */ \ - ASM_REGISTER(rax) = (uint64_t) (r0); \ - asm volatile ("syscall":::"memory", "rax", "rdi", "rsi", "rdx", "r10"); \ - rax; \ - }) - -#define SET_ERRNO(t, r) ({ \ - t res = (t) r; \ - if (res < 0) { \ - errno = -res; \ - } \ - ((int) res) < 0 ? (t) -1 : res; \ - }) - -ssize_t write(int fd, const void *buf, size_t count) { - return SET_ERRNO(ssize_t, ASM_SYSCALL3(SYSCALL_NR_WRITE, fd, buf, count)); -} - -ssize_t read(int fd, void *buf, size_t count) { - return SET_ERRNO(ssize_t, ASM_SYSCALL3(SYSCALL_NR_READ, fd, buf, count)); -} - -ssize_t sys_readdir(int fd, struct dirent *entp) { - return SET_ERRNO(ssize_t, ASM_SYSCALL2(SYSCALL_NR_READDIR, fd, entp)); -} - -int open(const char *filename, int flags, int mode) { - return SET_ERRNO(int, ASM_SYSCALL3(SYSCALL_NR_OPEN, filename, flags, mode)); -} - -void close(int fd) { - (void) ASM_SYSCALL1(SYSCALL_NR_CLOSE, fd); -} - -int stat(const char *filename, struct stat *st) { - return SET_ERRNO(int, ASM_SYSCALL2(SYSCALL_NR_STAT, filename, st)); -} - -int brk(void *addr) { - return SET_ERRNO(int, ASM_SYSCALL1(SYSCALL_NR_BRK, addr)); -} - -int fork(void) { - return SET_ERRNO(int, ASM_SYSCALL0(SYSCALL_NR_FORK)); -} - -int execve(const char *filename, const char *const argv[], const char *const envp[]) { - return SET_ERRNO(int, ASM_SYSCALL3(SYSCALL_NR_EXECVE, filename, argv, envp)); -} - -__attribute__((noreturn)) void exit(int code) { - (void) ASM_SYSCALL1(SYSCALL_NR_EXIT, code); - while (1); -} - -int kill(int pid, int signum) { - return SET_ERRNO(int, ASM_SYSCALL2(SYSCALL_NR_KILL, pid, signum)); -} - -void __kernel_signal(uintptr_t entry) { - (void) ASM_SYSCALL1(SYSCALL_NRX_SIGNAL, entry); -} - -__attribute__((noreturn)) void __kernel_sigret(void) { - (void) ASM_SYSCALL0(SYSCALL_NRX_SIGRET); - while (1); -} - -int getpid(void) { - return ASM_SYSCALL0(SYSCALL_NR_GETPID); -} - -int chdir(const char *filename) { - return SET_ERRNO(int, ASM_SYSCALL1(SYSCALL_NR_CHDIR, filename)); -} - -char *getcwd(char *buf, size_t lim) { - if (SET_ERRNO(int, ASM_SYSCALL2(SYSCALL_NR_GETCWD, buf, lim)) == 0) { - return buf; - } else { - return NULL; - } -} - -int nanosleep(const struct timespec *req, struct timespec *rem) { - return SET_ERRNO(int, ASM_SYSCALL2(SYSCALL_NR_NANOSLEEP, req, rem)); -} - -int openpty(int *master, int *slave) { - return SET_ERRNO(int, ASM_SYSCALL2(SYSCALL_NRX_OPENPTY, master, slave)); -} - -int gettimeofday(struct timeval *tv, struct timezone *tz) { - return SET_ERRNO(int, ASM_SYSCALL2(SYSCALL_NR_GETTIMEOFDAY, tv, tz)); -} - -int reboot(int magic1, int magic2, unsigned int cmd, void *arg) { - return SET_ERRNO(int, ASM_SYSCALL4(SYSCALL_NR_REBOOT, magic1, magic2, cmd, arg)); -} - -int access(const char *filename, int mode) { - return SET_ERRNO(int, ASM_SYSCALL2(SYSCALL_NR_ACCESS, filename, mode)); -} - -int waitpid(int pid, int *status) { - return SET_ERRNO(int, ASM_SYSCALL2(SYSCALL_NRX_WAITPID, pid, status)); -} - -// Although sbrk() is implemented in userspace, I guess it should also be here -void *sbrk(intptr_t inc) { - if (inc == 0) { - return __cur_brk; - } - - void *new_brk = (void *) ((uintptr_t) __cur_brk + inc); - - if (brk(new_brk) != 0) { - return __cur_brk; - } else { - return __cur_brk = new_brk; - } -} diff --git a/usr/libc/time.c b/usr/libc/time.c deleted file mode 100644 index f75a68a..0000000 --- a/usr/libc/time.c +++ /dev/null @@ -1,7 +0,0 @@ -#include "time.h" -#include "bits/syscall.h" - -int usleep(long us) { - struct timespec tv = { us / 1000000, (us % 1000) * 1000 }; - return nanosleep(&tv, NULL); -} diff --git a/usr/libc/vsnprintf.c b/usr/libc/vsnprintf.c deleted file mode 100644 index 5370763..0000000 --- a/usr/libc/vsnprintf.c +++ /dev/null @@ -1,255 +0,0 @@ -#include "bits/printf.h" -#include -#include - -union printfv { - int value_int; - unsigned int value_uint; - long value_long; - uint32_t value_uint32; - uint64_t value_uint64; - uintptr_t value_ptr; - const char *value_str; -}; - -static const char *s_print_xs_set0 = "0123456789abcdef"; -static const char *s_print_xs_set1 = "0123456789ABCDEF"; - -static int vsnprintf_ds(int64_t x, char *res, int s, int sz) { - if (!x) { - res[0] = '0'; - res[1] = 0; - return 1; - } - - int c; - uint64_t v; - - if (sz) { - if (s && x < 0) { - v = (uint64_t) -x; - } else { - s = 0; - v = (uint64_t) x; - } - } else { - if (s && ((int32_t) x) < 0) { - v = (uint64_t) -((int32_t) x); - } else { - s = 0; - v = (uint64_t) x; - } - } - - c = 0; - - while (v) { - res[c++] = '0' + v % 10; - v /= 10; - } - - if (s) { - res[c++] = '-'; - } - - res[c] = 0; - - for (int i = 0, j = c - 1; i < j; ++i, --j) { - res[i] ^= res[j]; - res[j] ^= res[i]; - res[i] ^= res[j]; - } - - return c; -} - -static int vsnprintf_xs(uint64_t v, char *res, const char *set) { - if (!v) { - res[0] = '0'; - res[1] = 0; - return 1; - } - - int c = 0; - - while (v) { - res[c++] = set[v & 0xF]; - v >>= 4; - } - - res[c] = 0; - - for (int i = 0, j = c - 1; i < j; ++i, --j) { - res[i] ^= res[j]; - res[j] ^= res[i]; - res[i] ^= res[j]; - } - - return c; -} - - - -int vsnprintf(char *buf, size_t len, const char *fmt, va_list args) { - union printfv val; - char cbuf[64]; - size_t p = 0; - // padn > 0: - // --------vvvvv - // padn < 0: - // vvvv---------- - int padn; - char padc; - int pads; - int clen; - char c; - -#define __putc(ch) \ - if (p == len - 1) { \ - goto __end; \ - } else { \ - buf[p++] = ch; \ - } - -#define __puts(s, l) \ - if (padn >= 0) { \ - if (l < padn) { \ - size_t padd = padn - l; \ - if (p + padd < len + 1) { \ - memset(buf + p, padc, padd); \ - p += padd; \ - } else { \ - memset(buf + p, padc, len - 1 - p); \ - p = len - 1; \ - goto __end; \ - } \ - } \ - if (p + l < len + 1) { \ - strncpy(buf + p, s, l); \ - p += l; \ - } else { \ - strncpy(buf + p, s, len - 1 - p); \ - p = len - 1; \ - goto __end; \ - } \ - } else { \ - padn = -padn; \ - if (p + l < len + 1) { \ - strncpy(buf + p, s, l); \ - p += l; \ - } else { \ - strncpy(buf + p, s, len - 1 - p); \ - p = len - 1; \ - goto __end; \ - } \ - if (l < padn) { \ - size_t padd = padn - l; \ - if (p + padd < len + 1) { \ - memset(buf + p, padc, padd); \ - p += padd; \ - } else { \ - memset(buf + p, padc, len - 1 - p); \ - p = len - 1; \ - goto __end; \ - } \ - } \ - } - - while ((c = *fmt)) { - switch (c) { - case '%': - c = *++fmt; - padn = 0; - padc = ' '; - pads = 1; - - if (c == '0') { - padc = c; - c = *++fmt; - } - if (c == '-') { - pads = -1; - c = *++fmt; - } - - while (c >= '0' && c <= '9') { - padn *= 10; - padn += c - '0'; - c = *++fmt; - } - - padn *= pads; - - switch (c) { - case 'l': - // Not supported - return -1; - - case 's': - if ((val.value_str = va_arg(args, const char *))) { - __puts(val.value_str, strlen(val.value_str)); - } else { - __puts("(null)", 6); - } - break; - - case 'p': - val.value_ptr = va_arg(args, uintptr_t); - __putc('0'); - __putc('x'); - padn = sizeof(uintptr_t) * 2; - padc = '0'; - clen = vsnprintf_xs(val.value_ptr, cbuf, s_print_xs_set0); - __puts(cbuf, clen); - break; - - case 'i': - case 'd': - val.value_int = va_arg(args, int); - clen = vsnprintf_ds(val.value_int, cbuf, 1, 1); - __puts(cbuf, clen); - break; - case 'u': - val.value_uint = va_arg(args, unsigned int); - clen = vsnprintf_ds(val.value_uint, cbuf, 0, 1); - __puts(cbuf, clen); - break; - - case 'x': - val.value_uint32 = va_arg(args, uint32_t); - clen = vsnprintf_xs(val.value_uint32, cbuf, s_print_xs_set0); - __puts(cbuf, clen); - break; - case 'X': - val.value_uint32 = va_arg(args, uint32_t); - clen = vsnprintf_xs(val.value_uint32, cbuf, s_print_xs_set1); - __puts(cbuf, clen); - break; - - case 'c': - val.value_int = va_arg(args, int); - __putc(val.value_int); - break; - - default: - __putc('%'); - __putc(c); - break; - } - - break; - default: - __putc(c); - break; - } - - ++fmt; - } - -#undef __puts -#undef __putc - -__end: - buf[p] = 0; - return p; -} diff --git a/usr/time.c b/usr/time.c deleted file mode 100644 index d04801d..0000000 --- a/usr/time.c +++ /dev/null @@ -1,12 +0,0 @@ -#include -#include - -int main() { - struct timeval tv; - while (1) { - usleep(100000); - gettimeofday(&tv, NULL); - - printf("\033[s\033[1;70f%u\033[u", tv.tv_sec); - } -}