aboutsummaryrefslogtreecommitdiff
path: root/kernel/features
diff options
context:
space:
mode:
authorMarvin Borner2021-03-02 19:04:53 +0100
committerMarvin Borner2021-03-02 19:04:53 +0100
commitacc4b7ccc133b64312e7ab1da3225b7945b1e13d (patch)
tree933d772ec33472cdcc3015d04d2afefab3ab5014 /kernel/features
parent20b1a8e22301877a0cc311efa069eb3f491f7a42 (diff)
very good this is
Diffstat (limited to 'kernel/features')
-rw-r--r--kernel/features/load.c18
-rw-r--r--kernel/features/mm.c (renamed from kernel/features/memory.c)10
-rw-r--r--kernel/features/proc.c20
-rw-r--r--kernel/features/syscall.c2
4 files changed, 36 insertions, 14 deletions
diff --git a/kernel/features/load.c b/kernel/features/load.c
index 8a4aae3..610abf8 100644
--- a/kernel/features/load.c
+++ b/kernel/features/load.c
@@ -3,14 +3,19 @@
#include <fs.h>
#include <load.h>
#include <mem.h>
+#include <mm.h>
#include <str.h>
+#define PROC_STACK_SIZE 0x4000
+
void proc_load(struct proc *proc, void *data)
{
- u32 stack = (u32)malloc(0x2000) + 0x1000;
+ u32 stack;
+ memory_alloc(proc->page_dir, PROC_STACK_SIZE, MEMORY_CLEAR, &stack);
+ u32 ptr = stack + PROC_STACK_SIZE - 1;
- proc->regs.ebp = (u32)stack;
- proc->regs.useresp = (u32)stack;
+ proc->regs.ebp = (u32)ptr;
+ proc->regs.useresp = (u32)ptr;
proc->regs.eip = (u32)data;
proc->entry = (u32)data;
}
@@ -19,12 +24,13 @@ int bin_load(const char *path, struct proc *proc)
{
struct stat s = { 0 };
vfs_stat(path, &s);
- char *data = malloc(s.size);
- if (!vfs_read(path, data, 0, s.size))
+ u32 data;
+ memory_alloc(proc->page_dir, PAGE_ALIGN_UP(s.size), MEMORY_CLEAR, &data);
+ if (!vfs_read(path, (void *)data, 0, s.size))
return 1;
strcpy(proc->name, path);
- proc_load(proc, data);
+ proc_load(proc, (void *)data);
return 0;
}
diff --git a/kernel/features/memory.c b/kernel/features/mm.c
index 7813c56..ccc2727 100644
--- a/kernel/features/memory.c
+++ b/kernel/features/mm.c
@@ -5,7 +5,7 @@
#include <cpu.h>
#include <def.h>
#include <mem.h>
-#include <memory.h>
+#include <mm.h>
#include <print.h>
@@ -369,6 +369,11 @@ void memory_dir_switch(struct page_dir *dir)
paging_switch_dir(virtual_to_physical(&kernel_dir, (u32)dir));
}
+struct page_dir *memory_kernel_dir(void)
+{
+ return &kernel_dir;
+}
+
void memory_initialize(struct mem_info *mem_info)
{
for (u32 i = 0; i < 256; i++) {
@@ -413,6 +418,9 @@ void memory_initialize(struct mem_info *mem_info)
memory_map_identity(&kernel_dir, memory_range_around_address(HEAP_START, HEAP_INIT_SIZE),
MEMORY_NONE);
+ // TODO: Map something, idk? Triple fault prevention?
+ memory_map_identity(&kernel_dir, memory_range_around_address(0x7000, 0x1000), MEMORY_NONE);
+
// Unmap NULL byte/page
virtual_free(&kernel_dir, memory_range(0, PAGE_SIZE));
physical_set_used(0, 1);
diff --git a/kernel/features/proc.c b/kernel/features/proc.c
index cdbe8b1..bbe675e 100644
--- a/kernel/features/proc.c
+++ b/kernel/features/proc.c
@@ -6,6 +6,7 @@
#include <fs.h>
#include <load.h>
#include <mem.h>
+#include <mm.h>
#include <print.h>
#include <proc.h>
#include <stack.h>
@@ -57,6 +58,7 @@ void scheduler(struct regs *regs)
}
memcpy(regs, &((struct proc *)current->data)->regs, sizeof(struct regs));
+ memory_dir_switch(((struct proc *)current->data)->page_dir);
if (regs->cs != GDT_USER_CODE_OFFSET) {
regs->gs = GDT_USER_DATA_OFFSET;
@@ -103,7 +105,7 @@ u8 proc_super(void)
{
struct proc *proc = proc_current();
if (proc)
- return proc->super;
+ return proc->priv == PROC_PRIV_ROOT || proc->priv == PROC_PRIV_KERNEL;
else if (current_pid == 0)
return 1; // Kernel has super permissions
else
@@ -237,14 +239,19 @@ end:
p->state = PROC_SLEEPING;
}
-struct proc *proc_make(void)
+struct proc *proc_make(enum proc_priv priv)
{
struct proc *proc = zalloc(sizeof(*proc));
proc->pid = current_pid++;
- proc->super = 0;
+ proc->priv = priv;
proc->messages = stack_new();
proc->state = PROC_RUNNING;
+ if (priv == PROC_PRIV_KERNEL)
+ proc->page_dir = memory_kernel_dir();
+ else
+ proc->page_dir = memory_dir_create();
+
if (current)
list_add(proc_list, proc);
@@ -465,20 +472,20 @@ void proc_init(void)
vfs_mount(dev, "/proc/");
// Idle proc
- struct proc *kernel_proc = proc_make();
+ struct proc *kernel_proc = proc_make(PROC_PRIV_NONE);
void (*func)(void) = kernel_idle;
proc_load(kernel_proc, *(void **)&func);
strcpy(kernel_proc->name, "idle");
kernel_proc->state = PROC_SLEEPING;
idle_proc = list_add(proc_list, kernel_proc);
- struct node *new = list_add(proc_list, proc_make());
+ // Init proc (root)
+ struct node *new = list_add(proc_list, proc_make(PROC_PRIV_ROOT));
bin_load("/bin/init", new->data);
current = new;
_eip = ((struct proc *)new->data)->regs.eip;
_esp = ((struct proc *)new->data)->regs.useresp;
- ((struct proc *)new->data)->super = 1;
u32 argc = 2;
char **argv = malloc(sizeof(*argv) * (argc + 1));
@@ -491,6 +498,7 @@ void proc_init(void)
printf("Jumping to userspace!\n");
proc_jump_userspace();
+ memory_dir_switch(((struct proc *)new->data)->page_dir);
while (1) {
};
}
diff --git a/kernel/features/syscall.c b/kernel/features/syscall.c
index 61c7479..b3e69e0 100644
--- a/kernel/features/syscall.c
+++ b/kernel/features/syscall.c
@@ -62,7 +62,7 @@ static void syscall_handler(struct regs *r)
}
case SYS_EXEC: {
char *path = (char *)r->ebx;
- struct proc *proc = proc_make();
+ struct proc *proc = proc_make(PROC_PRIV_NONE);
r->eax = (u32)bin_load(path, proc);
u32 argc = 3; // TODO: Add argc evaluator
char **argv = malloc(sizeof(*argv) * (argc + 1));