diff --git a/Makefile b/Makefile index 6a83740c..a703d221 100644 --- a/Makefile +++ b/Makefile @@ -14,7 +14,7 @@ ECHO = `which echo` -e MODULES = $(patsubst %.c,%.o,$(wildcard kernel/core/*.c)) FILESYSTEMS = $(patsubst %.c,%.o,$(wildcard kernel/core/fs/*.c)) VIDEODRIVERS = $(patsubst %.c,%.o,$(wildcard kernel/core/video/*.c)) -BINARIES = initrd/bin/hello initrd/bin/echo initrd/bin/yes initrd/bin/cat initrd/bin/sh +BINARIES = initrd/bin/hello initrd/bin/echo initrd/bin/yes initrd/bin/cat initrd/bin/sh initrd/bin/clear UTILITIES = util/bin/readelf util/bin/typewriter EMU = qemu GENEXT = genext2fs @@ -190,3 +190,8 @@ clean: @-rm -f util/bin/* @-rm -f .passed @${ECHO} "\r\033[31;1m RM Finished cleaning.\033[0m\033[K" + + +# vim:noexpandtab +# vim:tabstop=4 +# vim:shiftwidth=4 diff --git a/initrd/etc/logo.bmp b/initrd/etc/logo.bmp new file mode 120000 index 00000000..2d772b3f --- /dev/null +++ b/initrd/etc/logo.bmp @@ -0,0 +1 @@ +../bs.bmp \ No newline at end of file diff --git a/kernel/core/elf.c b/kernel/core/elf.c index 884c33ee..7fbc5a77 100644 --- a/kernel/core/elf.c +++ b/kernel/core/elf.c @@ -21,7 +21,6 @@ * can be read properly. * * TODO: Environment variables should be loaded somewhere. - * TODO: Keep track of file descriptors so we can do open/read/write/close * * HACK: ELF verification isn't complete. * @@ -88,8 +87,25 @@ exec( free(header); close_fs(file); + for (uintptr_t stack_pointer = 0x10000000; stack_pointer < 0x100F0000; stack_pointer += 0x1000) { + alloc_frame(get_page(stack_pointer, 1, current_directory), 0, 1); + } + + + + uintptr_t heap = current_task->entry + current_task->image_size; + alloc_frame(get_page(heap, 1, current_directory), 0, 1); + char ** argv_ = (char **)heap; + heap += sizeof(char *) * argc; + for (int i = 0; i < argc; ++i) { + alloc_frame(get_page(heap, 1, current_directory), 0, 1); + argv_[i] = (char *)heap; + memcpy((void *)heap, argv[i], strlen(argv[i]) * sizeof(char) + 1); + heap += strlen(argv[i]) + 1; + } + /* Go go go */ - enter_user_jmp(entry, argc, argv); + enter_user_jmp(entry, argc, argv_, 0x100EFFFF); /* We should never reach this code */ return -1; diff --git a/kernel/core/shell.c b/kernel/core/shell.c index ee14f181..aef8fc2f 100644 --- a/kernel/core/shell.c +++ b/kernel/core/shell.c @@ -111,16 +111,6 @@ start_shell() { i++; entry = readdir_fs(node, i); } - } else if (!strcmp(cmd, "info")) { - kprintf("Flags: 0x%x\n", node->flags); - } else if (!strcmp(cmd, "help")) { - kprintf("\033[1;34m"); - kprintf(" - ToAruOS Kernel Debug Shell - \n"); - kprintf("\033[0m"); - kprintf(" This is the ToAruOS kernel debugging environment.\n"); - kprintf(" From here, you have access to the virtual file system layer and \n"); - kprintf(" can read files, list files in directories, dump memory, registers,\n"); - kprintf(" and a few other things.\n"); } else if (!strcmp(cmd, "out")) { if (tokenid < 3) { kprintf("Need a port and a character (both as numbers, please) to write...\n"); @@ -148,8 +138,6 @@ start_shell() { serial_send('\n'); writech('\n'); } - } else if (!strcmp(cmd, "clear")) { - cls(); } else if (!strcmp(cmd, "crash")) { kprintf("Going to dereference some invalid pointers.\n"); int i = 0xFFFFFFFF; @@ -160,8 +148,6 @@ start_shell() { break; } else if (!strcmp(cmd, "cpu-detect")) { detect_cpu(); - } else if (!strcmp(cmd, "scroll")) { - bochs_scroll(); } else if (!strcmp(cmd, "logo")) { if (tokenid < 2) { bochs_draw_logo("/bs.bmp"); @@ -174,12 +160,6 @@ start_shell() { } else { bochs_draw_line(atoi(argv[1]),atoi(argv[2]),atoi(argv[3]),atoi(argv[4]),0xFFFFFF); } - } else if (!strcmp(cmd, "exec")) { - if (tokenid < 2) { - continue; - } - int ret = system(argv[1],tokenid - 1, &argv[1]); - kprintf("Returned %d\n", ret); } else if (!strcmp(cmd, "boredom")) { int x = 30; if (tokenid > 1) { @@ -192,16 +172,41 @@ start_shell() { int y1 = krand() % 768; bochs_draw_line(x0,x1,y0,y1, krand() % 0xFFFFFF); } - } else if (!strcmp(cmd, "test-scroll")) { - bochs_set_y_offset(12 * 20); } else if (!strcmp(cmd, "reset-keyboard")) { /* Reset the shift/alt/ctrl statuses, in case they get messed up */ set_kbd(0,0,0); - } else if (!strcmp(cmd, "test-ansi")) { - ansi_print("This is a \033[32mtest\033[0m of the \033[33mANSI\033[0m driver.\n"); - ansi_print("This is a \033[32;1mte\033[34mst\033[0m of \033[1mthe \033[33mANSI\033[0m driver.\n"); } else if (!strcmp(cmd, "multiboot")) { dump_multiboot(mboot_ptr); + } else if (!strcmp(cmd, "test-alloc")) { + kprintf("Testing the kernel allocator...\n"); + uint32_t sizers[] = { 1, 4, 4, 32, 64, 256, 1024, 795, 2042, 6204, 2525 }; + uint32_t sizes_c = 11; + uint32_t size = krand(); + void ** allocs = (void **)malloc(sizeof(uintptr_t *) * 500); + uint32_t * sizes = (uint32_t *)malloc(sizeof(uint32_t *) * 500); + for (uint32_t i = 0; i < 500; ++i) { + uint32_t s = sizers[size % sizes_c]; + kprintf("[%d] Allocating %d... ",i, s); + allocs[i] = malloc(s); + kprintf("0x%x\n", allocs[i]); + sizes[i] = s; + if (krand() % 2) { + kprintf("[%d] Freeing %d...\n", i, s); + free(allocs[i]); + allocs[i] = NULL; + } + size = krand(); + } + for (uint32_t i = 0; i < 500; ++i) { + if (allocs[i]) { + kprintf("[%d] Freeing %d...\n", i, sizes[i]); + free(allocs[i]); + allocs[i] = NULL; + } + } + free(allocs); + free(sizes); + kprintf("Testing complete.\n"); } else { /* Alright, here we go */ char * filename = malloc(sizeof(char) * 1024); diff --git a/kernel/core/syscall.c b/kernel/core/syscall.c index baaeac93..b479c067 100644 --- a/kernel/core/syscall.c +++ b/kernel/core/syscall.c @@ -10,10 +10,18 @@ * System calls themselves */ +void validate(void * ptr) { + if (ptr && (uintptr_t)ptr < current_task->entry) { + kprintf("SEGFAULT: Invalid pointer passed to syscall. (0x%x)\n", (uintptr_t)ptr); + HALT_AND_CATCH_FIRE("Segmentation fault", NULL); + } +} + /* * print something to the core terminal */ static int print(char * s) { + validate((void *)s); kprintf(s); return 0; } @@ -33,6 +41,7 @@ static int read(int fd, char * ptr, int len) { if (fd >= current_task->next_fd || fd < 0) { return -1; } + validate(ptr); fs_node_t * node = current_task->descriptors[fd]; uint32_t out = read_fs(node, node->offset, len, (uint8_t *)ptr); node->offset += out; @@ -43,6 +52,7 @@ static int write(int fd, char * ptr, int len) { if (fd >= current_task->next_fd || fd < 0) { return -1; } + validate(ptr); fs_node_t * node = current_task->descriptors[fd]; uint32_t out = write_fs(node, node->offset, len, (uint8_t *)ptr); node->offset += out; @@ -50,6 +60,7 @@ static int write(int fd, char * ptr, int len) { } static int open(const char * file, int flags, int mode) { + validate((void *)file); fs_node_t * node = kopen(file, 0); if (!node) { return -1; @@ -68,12 +79,20 @@ static int close(int fd) { } static int execve(const char * filename, char *const argv[], char *const envp[]) { + validate((void *)argv); + validate((void *)filename); + validate((void *)envp); int i = 0; while (argv[i]) { ++i; } + char ** argv_ = malloc(sizeof(char *) * i); + for (int j = 0; j < i; ++j) { + argv_[j] = malloc((strlen(argv[j]) + 1) * sizeof(char)); + memcpy(argv_[j], argv[j], strlen(argv[j]) + 1); + } /* Discard envp */ - exec((char *)filename, i, (char **)argv); + exec((char *)filename, i, (char **)argv_); return -1; } @@ -96,8 +115,9 @@ static uintptr_t syscalls[] = { (uintptr_t)&gettimeofday, (uintptr_t)&execve, (uintptr_t)&sys_fork, + (uintptr_t)&getpid, }; -uint32_t num_syscalls = 9; +uint32_t num_syscalls = 10; void syscalls_install() { diff --git a/kernel/core/task.c b/kernel/core/task.c index a72acabb..1432bb74 100644 --- a/kernel/core/task.c +++ b/kernel/core/task.c @@ -187,32 +187,10 @@ switch_task() { } void -enter_user_mode() { - set_kernel_stack(current_task->stack + KERNEL_STACK_SIZE); - __asm__ __volatile__( - "mov $0x23, %ax\n" - "mov %ax, %ds\n" - "mov %ax, %es\n" - "mov %ax, %fs\n" - "mov %ax, %gs\n" - "mov %esp, %eax\n" - "pushl $0x23\n" - "pushl %eax\n" - "pushf\n" - "popl %eax\n" - "orl $0x200, %eax\n" - "pushl %eax\n" - "pushl $0x1B\n" - "push $1f\n" - "iret\n" - "1:\n" - "mov %ax, %ax\n"); -} - -void -enter_user_jmp(uintptr_t location, int argc, char ** argv) { +enter_user_jmp(uintptr_t location, int argc, char ** argv, uintptr_t stack) { set_kernel_stack(current_task->stack + KERNEL_STACK_SIZE); __asm__ __volatile__( + "mov %3, %%esp\n" "mov $0x23, %%ax\n" "mov %%ax, %%ds\n" "mov %%ax, %%es\n" @@ -229,7 +207,7 @@ enter_user_jmp(uintptr_t location, int argc, char ** argv) { "pushl %2\n" "pushl %1\n" "call *%0\n" - : : "m"(location), "m"(argc), "m"(argv)); + : : "m"(location), "m"(argc), "m"(argv), "r"(stack)); } void task_exit(int retval) { diff --git a/kernel/include/system.h b/kernel/include/system.h index d2046cf7..03d7a4ac 100644 --- a/kernel/include/system.h +++ b/kernel/include/system.h @@ -235,8 +235,7 @@ extern void tasking_install(); extern void switch_task(); extern uint32_t fork(); extern uint32_t getpid(); -extern void enter_user_mode(); -extern void enter_user_jmp(uintptr_t location, int argc, char ** argv); +extern void enter_user_jmp(uintptr_t location, int argc, char ** argv, uintptr_t stack); uintptr_t initial_esp; diff --git a/loader/clear.c b/loader/clear.c new file mode 100644 index 00000000..d97e5be2 --- /dev/null +++ b/loader/clear.c @@ -0,0 +1,6 @@ +#include + +int main(int argc, char ** argv) { + syscall_print("\033[J"); + return 0; +} diff --git a/loader/sh.c b/loader/sh.c index 794c21d1..12579135 100644 --- a/loader/sh.c +++ b/loader/sh.c @@ -2,11 +2,22 @@ int main(int argc, char ** argv) { /* A Simple Shell */ - int i = syscall_fork(); - if (i == 0) { - syscall_print("Herpy derpy!\n"); - } else { - syscall_print("Hello World!\n"); - } + syscall_print("My PID is "); + char x[] = { + '0' + syscall_getpid(), + 0 + }; + syscall_print(x); + syscall_print("\n"); + char * bin = "/bin/echo"; + char * args = "herp"; + char * argv_[] = { + bin, + args, + args, + args, + 0 + }; + syscall_execve(bin, argv_, 0); return 0; } diff --git a/loader/syscall.c b/loader/syscall.c index 5d7831e8..0979d657 100644 --- a/loader/syscall.c +++ b/loader/syscall.c @@ -9,3 +9,4 @@ DEFN_SYSCALL1(close, 5, int) DEFN_SYSCALL2(gettimeofday, 6, void *, void *) DEFN_SYSCALL3(execve, 7, char *, char **, char **) DEFN_SYSCALL0(fork, 8) +DEFN_SYSCALL0(getpid, 9)