summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/init/main.c1
-rw-r--r--src/init/syscalls.c13
-rw-r--r--src/init/types.h2
-rw-r--r--src/kernel/arch/generic.h5
-rw-r--r--src/kernel/arch/i386/pagedir.c16
-rw-r--r--src/kernel/fd.c9
-rw-r--r--src/kernel/fd.h3
-rw-r--r--src/kernel/main.c4
-rw-r--r--src/kernel/mem.c12
-rw-r--r--src/kernel/mem.h9
-rw-r--r--src/kernel/proc.c6
-rw-r--r--src/kernel/proc.h4
-rw-r--r--src/kernel/syscalls.c31
-rw-r--r--src/kernel/types.h3
-rw-r--r--src/shared/syscalls.h14
15 files changed, 71 insertions, 61 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);