diff options
-rw-r--r-- | src/init/main.c | 1 | ||||
-rw-r--r-- | src/init/syscalls.c | 13 | ||||
-rw-r--r-- | src/init/types.h | 2 | ||||
-rw-r--r-- | src/kernel/arch/generic.h | 5 | ||||
-rw-r--r-- | src/kernel/arch/i386/pagedir.c | 16 | ||||
-rw-r--r-- | src/kernel/fd.c | 9 | ||||
-rw-r--r-- | src/kernel/fd.h | 3 | ||||
-rw-r--r-- | src/kernel/main.c | 4 | ||||
-rw-r--r-- | src/kernel/mem.c | 12 | ||||
-rw-r--r-- | src/kernel/mem.h | 9 | ||||
-rw-r--r-- | src/kernel/proc.c | 6 | ||||
-rw-r--r-- | src/kernel/proc.h | 4 | ||||
-rw-r--r-- | src/kernel/syscalls.c | 31 | ||||
-rw-r--r-- | src/kernel/types.h | 3 | ||||
-rw-r--r-- | src/shared/syscalls.h | 14 | ||||
-rw-r--r-- | todo.txt | 1 |
16 files changed, 71 insertions, 62 deletions
diff --git a/src/init/main.c b/src/init/main.c index d24dda0..4f99c8b 100644 --- a/src/init/main.c +++ b/src/init/main.c @@ -1,3 +1,4 @@ +#include <init/types.h> #include <shared/magic.h> #include <shared/syscalls.h> #include <stdint.h> diff --git a/src/init/syscalls.c b/src/init/syscalls.c index 01dda51..8c747e4 100644 --- a/src/init/syscalls.c +++ b/src/init/syscalls.c @@ -1,9 +1,10 @@ // this file could probably just get generated by a script +#include <init/types.h> #include <shared/syscalls.h> int _syscall(int, int, int, int); -_Noreturn void _syscall_exit(const char *msg, size_t len) { +_Noreturn void _syscall_exit(const user_ptr msg, size_t len) { _syscall(_SYSCALL_EXIT, (int)msg, len, 0); __builtin_unreachable(); } @@ -12,23 +13,23 @@ int _syscall_fork(void) { return _syscall(_SYSCALL_FORK, 0, 0, 0); } -int _syscall_await(char *buf, int len) { +int _syscall_await(user_ptr buf, int len) { return _syscall(_SYSCALL_AWAIT, (int)buf, (int)len, 0); } -fd_t _syscall_fs_open(const char *path, int len) { +fd_t _syscall_fs_open(const user_ptr path, int len) { return _syscall(_SYSCALL_FS_OPEN, (int)path, len, 0); } -int _syscall_mount(const char *path, int len, fd_t fd) { +int _syscall_mount(const user_ptr path, int len, fd_t fd) { return _syscall(_SYSCALL_MOUNT, (int)path, len, fd); } -int _syscall_fd_read(fd_t fd, char *buf, int len) { +int _syscall_fd_read(fd_t fd, user_ptr buf, int len) { return _syscall(_SYSCALL_FD_READ, fd, (int)buf, len); } -int _syscall_fd_write(fd_t fd, char *buf, int len) { +int _syscall_fd_write(fd_t fd, user_ptr buf, int len) { return _syscall(_SYSCALL_FD_WRITE, fd, (int)buf, len); } diff --git a/src/init/types.h b/src/init/types.h new file mode 100644 index 0000000..d06d171 --- /dev/null +++ b/src/init/types.h @@ -0,0 +1,2 @@ +#pragma once +typedef char* user_ptr; diff --git a/src/kernel/arch/generic.h b/src/kernel/arch/generic.h index 1fa716b..e7afeff 100644 --- a/src/kernel/arch/generic.h +++ b/src/kernel/arch/generic.h @@ -1,5 +1,6 @@ #pragma once +#include <kernel/types.h> #include <kernel/arch/i386/registers.h> #include <kernel/arch/log.h> #include <stdbool.h> @@ -22,11 +23,11 @@ int syscall_handler(int, int, int, int); // all of those can allocate memory struct pagedir *pagedir_new(void); struct pagedir *pagedir_copy(const struct pagedir *orig); -void pagedir_map(struct pagedir *dir, void *virt, void *phys, +void pagedir_map(struct pagedir *dir, user_ptr virt, void *phys, bool user, bool writeable); void pagedir_switch(struct pagedir *); // return 0 on failure -void *pagedir_virt2phys(struct pagedir *dir, const void *virt, +void *pagedir_virt2phys(struct pagedir *dir, const user_ptr virt, bool user, bool writeable); diff --git a/src/kernel/arch/i386/pagedir.c b/src/kernel/arch/i386/pagedir.c index 486d2a2..8f62a45 100644 --- a/src/kernel/arch/i386/pagedir.c +++ b/src/kernel/arch/i386/pagedir.c @@ -46,12 +46,11 @@ struct pagedir *pagedir_new(void) { return dir; } -void pagedir_map(struct pagedir *dir, void *virt, void *phys, +void pagedir_map(struct pagedir *dir, user_ptr virt, void *phys, bool user, bool writeable) { - uintptr_t virt_casted = (uintptr_t) virt; - uint32_t pd_idx = virt_casted >> 22; - uint32_t pt_idx = virt_casted >> 12 & 0x03FF; + uint32_t pd_idx = virt >> 22; + uint32_t pt_idx = virt >> 12 & 0x03FF; struct pagetable_entry *pagetable; if (dir->e[pd_idx].present) { @@ -125,13 +124,12 @@ struct pagedir *pagedir_copy(const struct pagedir *orig) { return clone; } -void *pagedir_virt2phys(struct pagedir *dir, const void *virt, +void *pagedir_virt2phys(struct pagedir *dir, const user_ptr virt, bool user, bool writeable) { - uintptr_t virt_casted = (uintptr_t) virt; uintptr_t phys; - uint32_t pd_idx = virt_casted >> 22; - uint32_t pt_idx = virt_casted >> 12 & 0x03FF; + uint32_t pd_idx = virt >> 22; + uint32_t pt_idx = virt >> 12 & 0x03FF; struct pagetable_entry *pagetable, page; /* DOESN'T CHECK PERMISSIONS ON PAGE DIRS, TODO @@ -148,6 +146,6 @@ void *pagedir_virt2phys(struct pagedir *dir, const void *virt, if (writeable && !page.writeable) return 0; phys = page.address << 11; - phys |= (uintptr_t)virt & 0xFFF; + phys |= virt & 0xFFF; return (void*)phys; } diff --git a/src/kernel/fd.c b/src/kernel/fd.c index e99fb7d..c495c8c 100644 --- a/src/kernel/fd.c +++ b/src/kernel/fd.c @@ -3,9 +3,9 @@ #include <kernel/panic.h> #include <kernel/proc.h> -static int fdop_special_tty(enum fdop fdop, struct fd *fd, void *ptr, size_t len); +static int fdop_special_tty(enum fdop fdop, struct fd *fd, user_ptr ptr, size_t len); -int fdop_dispatch(enum fdop fdop, struct fd *fd, void *ptr, size_t len) { +int fdop_dispatch(enum fdop fdop, struct fd *fd, user_ptr ptr, size_t len) { switch(fd->type) { case FD_EMPTY: return -1; @@ -16,15 +16,14 @@ int fdop_dispatch(enum fdop fdop, struct fd *fd, void *ptr, size_t len) { } } -static int fdop_special_tty(enum fdop fdop, struct fd *fd, void *ptr, size_t len) { +static int fdop_special_tty(enum fdop fdop, struct fd *fd, user_ptr ptr, size_t len) { switch(fdop) { case FDOP_READ: return -1; // input not implemented yet case FDOP_WRITE: { struct virt_iter iter; - virt_iter_new(&iter, (void*)ptr, len, - process_current->pages, true, false); + virt_iter_new(&iter, ptr, len, process_current->pages, true, false); while (virt_iter_next(&iter)) tty_write(iter.frag, iter.frag_len); return iter.prior; diff --git a/src/kernel/fd.h b/src/kernel/fd.h index 6950b9b..90ce717 100644 --- a/src/kernel/fd.h +++ b/src/kernel/fd.h @@ -1,4 +1,5 @@ #pragma once +#include <kernel/types.h> #include <stddef.h> #define FD_MAX 16 @@ -21,4 +22,4 @@ enum fdop { // describes the operations which can be done on file descriptors FDOP_CLOSE, }; -int fdop_dispatch(enum fdop fdop, struct fd *fd, void *ptr, size_t len); +int fdop_dispatch(enum fdop fdop, struct fd *fd, user_ptr ptr, size_t len); diff --git a/src/kernel/main.c b/src/kernel/main.c index 7796c44..cc8e10d 100644 --- a/src/kernel/main.c +++ b/src/kernel/main.c @@ -9,13 +9,13 @@ static void run_init(struct kmain_info *info) { struct process *proc = process_seed(); - void *init_base = (void*) 0x200000; + user_ptr init_base = 0x200000; // map the module as rw for (uintptr_t off = 0; off < info->init.size; off += PAGE_SIZE) pagedir_map(proc->pages, init_base + off, info->init.at + off, true, true); - proc->regs.eip = (int) init_base; + proc->regs.eip = init_base; tty_const("switching..."); process_switch(proc); diff --git a/src/kernel/mem.c b/src/kernel/mem.c index aed2ff9..55b0361 100644 --- a/src/kernel/mem.c +++ b/src/kernel/mem.c @@ -40,7 +40,7 @@ void kfree(void *ptr) { // TODO move to some shared file in kernel/arch/ void virt_iter_new( - struct virt_iter *iter, void *virt, size_t length, + struct virt_iter *iter, user_ptr virt, size_t length, struct pagedir *pages, bool user, bool writeable) { iter->frag = 0; @@ -60,7 +60,7 @@ bool virt_iter_next(struct virt_iter *iter) { * virtual and physical memory, which might not always be the case. * TODO test this */ - uintptr_t virt = (uintptr_t) iter->_virt; + user_ptr virt = iter->_virt; size_t partial = iter->_remaining; iter->prior += iter->frag_len; if (partial <= 0) return false; @@ -84,14 +84,14 @@ bool virt_iter_next(struct virt_iter *iter) { } bool virt_user_cpy( - struct pagedir *dest_pages, void *dest, - struct pagedir *src_pages, const void *src, size_t length) + struct pagedir *dest_pages, user_ptr dest, + struct pagedir *src_pages, const user_ptr src, size_t length) { struct virt_iter dest_iter, src_iter; size_t min; - virt_iter_new(&dest_iter, dest, length, dest_pages, true, true); - virt_iter_new( &src_iter, (void*)src, length, src_pages, true, false); + virt_iter_new(&dest_iter, dest, length, dest_pages, true, true); + virt_iter_new( &src_iter, src, length, src_pages, true, false); dest_iter.frag_len = 0; src_iter.frag_len = 0; diff --git a/src/kernel/mem.h b/src/kernel/mem.h index c8192fd..5184ec5 100644 --- a/src/kernel/mem.h +++ b/src/kernel/mem.h @@ -1,6 +1,7 @@ #pragma once #include <kernel/arch/generic.h> #include <kernel/main.h> +#include <kernel/types.h> #include <stddef.h> void mem_init(struct kmain_info *); @@ -22,7 +23,7 @@ struct virt_iter { size_t prior; // sum of all prior frag_lens bool error; - void *_virt; + user_ptr _virt; size_t _remaining; struct pagedir *_pages; bool _user; @@ -30,11 +31,11 @@ struct virt_iter { }; void virt_iter_new( - struct virt_iter *iter, void *virt, size_t length, + struct virt_iter *iter, user_ptr virt, size_t length, struct pagedir *pages, bool user, bool writeable); bool virt_iter_next(struct virt_iter *); bool virt_user_cpy( - struct pagedir *dest_pages, void *dest, - struct pagedir *src_pages, const void *src, size_t length); + struct pagedir *dest_pages, user_ptr dest, + struct pagedir *src_pages, const user_ptr src, size_t length); diff --git a/src/kernel/proc.c b/src/kernel/proc.c index cc6e599..c7963f0 100644 --- a/src/kernel/proc.c +++ b/src/kernel/proc.c @@ -27,14 +27,14 @@ struct process *process_seed(void) { proc->fds[FD_STDOUT].type = FD_SPECIAL_TTY; // map the stack to the last page in memory - pagedir_map(proc->pages, (void*)~PAGE_MASK, page_alloc(1), true, true); - proc->stack_top = (void*) (proc->regs.esp = ~0xF); + pagedir_map(proc->pages, ~PAGE_MASK, page_alloc(1), true, true); + proc->stack_top = proc->regs.esp = ~0xF; // map the kernel // yup, .text is writeable too. the plan is to not map the kernel // into user memory at all, but i'll implement that later. TODO for (size_t p = 0x100000; p < (size_t)&_bss_end; p += PAGE_SIZE) - pagedir_map(proc->pages, (void*)p, (void*)p, false, true); + pagedir_map(proc->pages, p, (void*)p, false, true); // the kernel still has to load the executable code and set EIP return proc; diff --git a/src/kernel/proc.h b/src/kernel/proc.h index 87fed14..6de270b 100644 --- a/src/kernel/proc.h +++ b/src/kernel/proc.h @@ -11,7 +11,7 @@ enum process_state { }; struct process { - void *stack_top; + user_ptr stack_top; struct pagedir *pages; struct registers regs; enum process_state state; @@ -25,7 +25,7 @@ struct process { // meaning changes depending on the state // PS_DEAD - death message // PS_WAITS4CHILDDEATH - buffer for said message - void *saved_addr; + user_ptr saved_addr; size_t saved_len; struct vfs_mount *mount; diff --git a/src/kernel/syscalls.c b/src/kernel/syscalls.c index 3383a13..533ebca 100644 --- a/src/kernel/syscalls.c +++ b/src/kernel/syscalls.c @@ -2,6 +2,7 @@ #include <kernel/mem.h> #include <kernel/panic.h> #include <kernel/proc.h> +#include <kernel/types.h> #include <kernel/vfs/path.h> #include <shared/syscalls.h> #include <stdint.h> @@ -25,9 +26,9 @@ _Noreturn static void await_finish(struct process *dead, struct process *listene } -_Noreturn void _syscall_exit(const char *msg, size_t len) { +_Noreturn void _syscall_exit(const user_ptr msg, size_t len) { process_current->state = PS_DEAD; - process_current->saved_addr = (void*)msg; // discard const + process_current->saved_addr = msg; process_current->saved_len = len; if (process_current->parent->state == PS_WAITS4CHILDDEATH) @@ -40,7 +41,7 @@ _Noreturn void _syscall_exit(const char *msg, size_t len) { process_switch_any(); } -int _syscall_await(char *buf, int len) { +int _syscall_await(user_ptr buf, int len) { process_current->state = PS_WAITS4CHILDDEATH; process_current->saved_addr = buf; process_current->saved_len = len; @@ -65,7 +66,7 @@ int _syscall_fork(void) { return 1; } -fd_t _syscall_fs_open(const char *path, int len) { +fd_t _syscall_fs_open(const user_ptr path, int len) { struct virt_iter iter; struct vfs_mount *mount = process_current->mount; static char buffer[PATH_MAX]; // holds the path @@ -73,7 +74,7 @@ fd_t _syscall_fs_open(const char *path, int len) { if (len > PATH_MAX) return -1; // copy the path to the kernel - virt_iter_new(&iter, (void*)path, len, process_current->pages, true, false); + virt_iter_new(&iter, path, len, process_current->pages, true, false); while (virt_iter_next(&iter)) memcpy(buffer + iter.prior, iter.frag, iter.frag_len); if (iter.error) return -1; @@ -99,7 +100,7 @@ fd_t _syscall_fs_open(const char *path, int len) { return -1; } -int _syscall_mount(const char *path, int len, fd_t fd) { +int _syscall_mount(const user_ptr path, int len, fd_t fd) { struct virt_iter iter; struct vfs_mount *mount; char *path_buf; @@ -108,7 +109,7 @@ int _syscall_mount(const char *path, int len, fd_t fd) { // copy the path to the kernel path_buf = kmalloc(len); - virt_iter_new(&iter, (void*)path, len, process_current->pages, true, false); + virt_iter_new(&iter, path, len, process_current->pages, true, false); while (virt_iter_next(&iter)) memcpy(path_buf + iter.prior, iter.frag, iter.frag_len); if (iter.error) goto fail; @@ -130,12 +131,12 @@ fail: return -1; } -int _syscall_fd_read(fd_t fd, char *buf, int len) { +int _syscall_fd_read(fd_t fd, user_ptr buf, int len) { if (fd < 0 || fd >= FD_MAX) return -1; return fdop_dispatch(FDOP_READ, &process_current->fds[fd], buf, len); } -int _syscall_fd_write(fd_t fd, char *buf, int len) { +int _syscall_fd_write(fd_t fd, user_ptr buf, int len) { if (fd < 0 || fd >= FD_MAX) return -1; return fdop_dispatch(FDOP_WRITE, &process_current->fds[fd], buf, len); } @@ -148,19 +149,19 @@ int _syscall_fd_close(fd_t fd) { int syscall_handler(int num, int a, int b, int c) { switch (num) { case _SYSCALL_EXIT: - _syscall_exit((void*)a, b); + _syscall_exit(a, b); case _SYSCALL_AWAIT: - return _syscall_await((void*)a, b); + return _syscall_await(a, b); case _SYSCALL_FORK: return _syscall_fork(); case _SYSCALL_FS_OPEN: - return _syscall_fs_open((void*)a, b); + return _syscall_fs_open(a, b); case _SYSCALL_MOUNT: - return _syscall_mount((void*)a, b, c); + return _syscall_mount(a, b, c); case _SYSCALL_FD_READ: - return _syscall_fd_read(a, (void*)b, c); + return _syscall_fd_read(a, b, c); case _SYSCALL_FD_WRITE: - return _syscall_fd_write(a, (void*)b, c); + return _syscall_fd_write(a, b, c); case _SYSCALL_FD_CLOSE: return _syscall_fd_close(a); default: diff --git a/src/kernel/types.h b/src/kernel/types.h new file mode 100644 index 0000000..eb12f08 --- /dev/null +++ b/src/kernel/types.h @@ -0,0 +1,3 @@ +#pragma once +#include <stdint.h> +typedef uintptr_t user_ptr; diff --git a/src/shared/syscalls.h b/src/shared/syscalls.h index 9eb3fa5..d0c6640 100644 --- a/src/shared/syscalls.h +++ b/src/shared/syscalls.h @@ -1,3 +1,5 @@ +// requires the user_ptr type from kernel/types.h or init/types.h + #pragma once #include <stddef.h> @@ -21,12 +23,12 @@ enum { /** Kills the current process. * TODO: what happens to the children? */ -_Noreturn void _syscall_exit(const char *msg, size_t len); +_Noreturn void _syscall_exit(const user_ptr msg, size_t len); /** Waits for a child to exit, putting its exit message into *buf. * @return the length of the message */ -int _syscall_await(char *buf, int len); +int _syscall_await(user_ptr buf, int len); /** Creates a copy of the current process, and executes it. * All user memory pages get copied too. @@ -34,9 +36,9 @@ int _syscall_await(char *buf, int len); */ int _syscall_fork(void); -fd_t _syscall_fs_open(const char *path, int len); -int _syscall_mount(const char *path, int len, fd_t fd); +fd_t _syscall_fs_open(const user_ptr path, int len); +int _syscall_mount(const user_ptr path, int len, fd_t fd); -int _syscall_fd_read(fd_t fd, char *buf, int len); -int _syscall_fd_write(fd_t fd, char *buf, int len); +int _syscall_fd_read(fd_t fd, user_ptr buf, int len); +int _syscall_fd_write(fd_t fd, user_ptr buf, int len); int _syscall_fd_close(fd_t fd); @@ -1 +0,0 @@ -don't use pointer types for useland pointers |