diff --git a/Makefile b/Makefile index 631447b..b72fd24 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ -USER_PROGRAMS := pedicel.raw apex.raw -USER_FILES := wow.txt +USER_PROGRAMS := pedicel.raw apex.raw doom.raw +USER_FILES := wow.txt doom1.wad BUILDDIR := build ELFFILE := pepperk diff --git a/docs/MANUAL.md b/docs/MANUAL.md index b8dcda2..b126ba4 100644 --- a/docs/MANUAL.md +++ b/docs/MANUAL.md @@ -41,12 +41,4 @@ The recommended hardware to run PepperOS is the following: ## III. Syscall table The syscall interface in the Pepper kernel uses the System V ABI convention for argument order. -It vaguely mimics Unix-like systems. - -Name | Number (%rax) | arg0 (%rdi) | arg1 (%rsi) | arg2 (%rdx) | -|---|---|---|---|---| -| sys_read | 0 | unsigned int fd | char* buf | size_t count | -| sys_write | 1 | unsigned int fd | const char* buf | size_t count | -| sys_open | 2 | const char* filename | int flags | | -| sys_close | 3 | unsigned int fd | | | -| sys_exit | 60 | int error_code | | | \ No newline at end of file +It vaguely mimics Unix-like systems. You will find it in [SYSCALLS.md](SYSCALLS.md). \ No newline at end of file diff --git a/docs/SOFTWARE.md b/docs/SOFTWARE.md index c7e57a0..50c9ace 100644 --- a/docs/SOFTWARE.md +++ b/docs/SOFTWARE.md @@ -6,6 +6,21 @@ Honestly I have no idea. Maybe you have too much free time. Keep in mind that the Pepper kernel is a personal project and it's full of bugs, inconsistencies, weird ways of doing things (and I don't care because it's my toy). Now if you still want to write something for this OS, thank you. Follow along. +## Headers available in userspace + +Of course, all of the freestanding headers are available: +- ``: macros for floating-point types +- ``: macros for integer types +- ``: macros for bitwise and logical operators +- ``: variadic function support +- ``: definitions for `size_t`, `ptrdiff_t`, and others +- ``: definitions for boolean types +- ``: definitions for `int_t` and `uint_t` types + +Also available is the `` header that gives access to low-level system call interface, notably the `syscallX` function family, X being the amount of arguments to use. + +(TODO: put the other headers here once libc is more complete) + ## 1. Write the source code PepperOS is able to run programs written in x86 assembly, and C programs. diff --git a/docs/SYSCALLS.md b/docs/SYSCALLS.md new file mode 100644 index 0000000..1630958 --- /dev/null +++ b/docs/SYSCALLS.md @@ -0,0 +1,15 @@ +# Pepper kernel system call table + +The following table contains all of the system calls supported by PepperOS, as well as their arguments. The explanation for what every system call does is available as a comment above each function in corresponding files in the `src/syscall` folder. + +Name | Number (%rax) | arg0 (%rdi) | arg1 (%rsi) | arg2 (%rdx) | arg3 (%r10) | +|---|---|---|---|---|---| +| sys_read | 0 | unsigned int fd | char* buf | size_t count | | +| sys_write | 1 | unsigned int fd | const char* buf | size_t count | | +| sys_open | 2 | const char* filename | int flags | | | +| sys_close | 3 | unsigned int fd | | | | +| sys_lseek | 8 | unsigned int fd | int offset | int whence | | +| sys_tell | 9 | unsigned int fd | | | | +| sys_eof | 10 | unsigned int fd | | | | +| sys_draw | 11 | const uint8_t* src | int width | int height | int channels | +| sys_exit | 60 | int error_code | | | | \ No newline at end of file diff --git a/include/config.h b/include/config.h index 11c6fe9..55d9c6f 100644 --- a/include/config.h +++ b/include/config.h @@ -44,6 +44,8 @@ #define USER_STACK_TOP 0x80000000 #define USER_STACK_PAGES 16 // 16*4096 = 64kb #define USER_CODE_START 0x400000 // like linux +#define USER_RAW_EXTRA_PAGES 8192 // Extra writable pages after raw image for .bss/heap + // TODO: throw this away and make an ELF loader instead bruh /* paging */ #define PAGING_MAX_PHYS 0x200000000 diff --git a/include/fs/initfs.h b/include/fs/initfs.h index f7a3ca8..0ab4794 100644 --- a/include/fs/initfs.h +++ b/include/fs/initfs.h @@ -15,4 +15,10 @@ int tar_exists(const char* filename); int tar_read(char* filename, char* out, int count, int offset); void tar_list(); +enum Seek { + SEEK_SET, + SEEK_CUR, + SEEK_END +}; + #endif \ No newline at end of file diff --git a/include/kernel.h b/include/kernel.h index 3d8d0b7..0bf2017 100644 --- a/include/kernel.h +++ b/include/kernel.h @@ -9,6 +9,7 @@ #include "limine.h" +// Not in POSIX order. enum ErrorCodes { ENOMEM, // No memory EIO, // Input/output error diff --git a/include/string/string.h b/include/string/string.h index f01dbb9..382cda9 100644 --- a/include/string/string.h +++ b/include/string/string.h @@ -14,5 +14,6 @@ char *strcat(char *dest, const char *src); void strncpy(char* dst, const char* src, size_t n); int strncmp(const char* s1, const char* s2, size_t n); size_t strlen(const char* str); +int atoi(const char* str); #endif \ No newline at end of file diff --git a/src/arch/x86/syscall.c b/src/arch/x86/syscall.c deleted file mode 100644 index 15f9128..0000000 --- a/src/arch/x86/syscall.c +++ /dev/null @@ -1,160 +0,0 @@ -/* - * @author xamidev - * @brief System call handling - * @license GPL-3.0-only - */ - -#include "config.h" -#include "sched/scheduler.h" -#include -#include -#include -#include -#include -#include -#include -#include - -extern struct process* current_process; - -// Return fd on success, -errno on error -int sys_open(const char* filename, int flags) -{ - if (tar_exists(filename) < 0) { - return -ENOENT; // file doesn't exist.. - } - // file exists here! - if (current_process->next_free_fd >= FDT_MAX) { - return -EMFILE; - } - int fd = current_process->next_free_fd++; - current_process->fdt[fd].fd = fd; - current_process->fdt[fd].open = true; - current_process->fdt[fd].cursor = 0; - strncpy(current_process->fdt[fd].filename, filename, PROCESS_NAME_MAX - 1); - return fd; -} - -// Return 0 on success, -EBADFD if invalid FD -int sys_close(int fd) -{ - if (fd < 0 || fd >= FDT_MAX) { - return -EBADFD; - } - - if (!current_process->fdt[fd].open) { - return -EBADFD; // FD not opened in the first place - } - - current_process->fdt[fd].open = false; - current_process->fdt[fd].filename[0] = '\0'; - current_process->fdt[fd].cursor = 0; - return 0; -} - -// Should return the number of bytes read -int sys_read(unsigned int fd, char* buf, size_t count) -{ - size_t i; - switch (fd) { - case 0: //read from stdin (keyboard) - for (i=0; ifdt[fd].open == false) { - return -EBADFD; // File descriptor wasn't open - } - // Here fd refers to a valid opened file.. - int sz = tar_read(current_process->fdt[fd].filename, buf, count, - current_process->fdt[fd].cursor); - if (sz == 0) { - return -ENOENT; - } else { - current_process->fdt[fd].cursor += sz; - return sz; - } - } - - return -EBADFD; -} - -// TODO: Should have a return value: number of bytes written on success, -1 on error (errno set) -int sys_write(unsigned int fd, const char* buf, size_t count) -{ - switch (fd) { - case 1: //stdout - case 2: //stderr - for (size_t i=0; istatus = DEAD; - DEBUG("(pid=%u, name=%s)", current_process->pid, current_process->name); - return error_code; -} - -/* - * syscall_handler - System call dispatcher - * @regs: CPU state - * - * This function is called from the interrupt dispatcher, - * when an interrupt 0x80 is emitted from userland. - * - * It switches control to the syscall number provided - * in %rax. - * - * We try to follow the System V convention here: - * - syscall number in %rax - * - args in %rdi, %rsi, %rdx, %r10, %r8, %r9 - * - return value (if any) in %rax - * - * Return: - * - CPU state after system call - */ -struct cpu_status* syscall_handler(struct cpu_status* regs) -{ - switch (regs->rax) - { - case 0: - DEBUG("sys_read(fd=%u, buf=%p, count=%u)", regs->rdi, regs->rsi, regs->rdx); - regs->rax = sys_read(regs->rdi, (char*)regs->rsi, regs->rdx); - break; - case 1: - DEBUG("sys_write(fd=%u, buf=%p, count=%u)", regs->rdi, regs->rsi, regs->rdx); - regs->rax = sys_write(regs->rdi, (char*)regs->rsi, regs->rdx); - break; - case 2: - DEBUG("sys_open(filename=%s, flags=%u)", regs->rdi, regs->rsi); - regs->rax = sys_open((const char*)regs->rdi, regs->rsi); - break; - case 3: - DEBUG("sys_close(fd=%u)", regs->rdi); - regs->rax = sys_close(regs->rdi); - break; - case 60: - DEBUG("sys_exit(error_code=%d)", regs->rdi); - regs->rax = sys_exit(regs->rdi); - break; - default: - DEBUG("Bad syscall! (rax=%p, rdi=%p, rsi=%p, rdx=%p)", - regs->rax, regs->rdi, regs->rsi, regs->rdx); - regs->rax = 0xbad515ca11; - break; - } - - DEBUG("returned rax=%p (%u)", regs->rax, regs->rax); - - return regs; -} \ No newline at end of file diff --git a/src/io/term/term.c b/src/io/term/term.c index e3bd2ca..e7af50e 100644 --- a/src/io/term/term.c +++ b/src/io/term/term.c @@ -50,9 +50,17 @@ void internal_putc(int c, void *_) if (init.terminal) { if (panic_count == 0) { spinlock_acquire(&term_lock); + if (ch == '\n') { + char cr = '\r'; + flanterm_write(ft_ctx, &cr, 1); + } flanterm_write(ft_ctx, &ch, 1); spinlock_release(&term_lock); } else { + if (ch == '\n') { + char cr = '\r'; + flanterm_write(ft_ctx, &cr, 1); + } flanterm_write(ft_ctx, &ch, 1); } } @@ -82,9 +90,17 @@ void debug_putc(int c, void *_) if (init.terminal && (!init.all || panic_count > 0)) { if (panic_count == 0) { spinlock_acquire(&term_lock); + if (ch == '\n') { + char cr = '\r'; + flanterm_write(ft_ctx, &cr, 1); + } flanterm_write(ft_ctx, &ch, 1); spinlock_release(&term_lock); } else { + if (ch == '\n') { + char cr = '\r'; + flanterm_write(ft_ctx, &cr, 1); + } flanterm_write(ft_ctx, &ch, 1); } } diff --git a/src/kapps/kshell.c b/src/kapps/kshell.c index fa44b51..1da7cb1 100644 --- a/src/kapps/kshell.c +++ b/src/kapps/kshell.c @@ -13,6 +13,7 @@ #include #include