aboutsummaryrefslogtreecommitdiff
path: root/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'kernel')
-rw-r--r--kernel/Makefile2
-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
-rw-r--r--kernel/inc/mm.h (renamed from kernel/inc/memory.h)7
-rw-r--r--kernel/inc/proc.h8
-rw-r--r--kernel/main.c2
8 files changed, 50 insertions, 19 deletions
diff --git a/kernel/Makefile b/kernel/Makefile
index 6763185..2db201b 100644
--- a/kernel/Makefile
+++ b/kernel/Makefile
@@ -10,7 +10,7 @@ COBJS = main.o \
drivers/ide.o \
drivers/timer.o \
drivers/rtl8139.o \
- features/memory.o \
+ features/mm.o \
features/fs.o \
features/load.o \
features/proc.o \
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));
diff --git a/kernel/inc/memory.h b/kernel/inc/mm.h
index 812b052..00d9e4b 100644
--- a/kernel/inc/memory.h
+++ b/kernel/inc/mm.h
@@ -18,6 +18,8 @@
#define PAGE_COUNT 1024
#define PAGE_ALIGN(x) ((x) + PAGE_SIZE - ((x) % PAGE_SIZE))
#define PAGE_ALIGNED(x) ((x) % PAGE_SIZE == 0)
+#define PAGE_ALIGN_UP(x) (((x) % PAGE_SIZE == 0) ? (x) : (x) + PAGE_SIZE - ((x) % PAGE_SIZE))
+#define PAGE_ALIGN_DOWN(x) ((x) - ((x) % PAGE_SIZE))
union page_table_entry {
struct PACKED {
@@ -77,4 +79,9 @@ struct memory_range {
u32 size;
};
+struct page_dir *memory_dir_create(void);
+void memory_dir_switch(struct page_dir *dir);
+void memory_alloc(struct page_dir *dir, u32 size, u32 flags, u32 *out);
+struct page_dir *memory_kernel_dir(void);
+
#endif
diff --git a/kernel/inc/proc.h b/kernel/inc/proc.h
index 272a3ac..de4eb84 100644
--- a/kernel/inc/proc.h
+++ b/kernel/inc/proc.h
@@ -9,7 +9,7 @@
#include <stack.h>
#include <sys.h>
-#define PROC_QUANTUM 10 // Milliseconds or something // TODO
+#define PROC_QUANTUM 42 // Milliseconds or something // TODO
#define EFLAGS_ALWAYS 0x2 // Always one
#define EFLAGS_INTERRUPTS 0x200 // Enable interrupts
@@ -23,6 +23,7 @@
#define STREAM_MAX_SIZE 4096
enum stream_defaults { STREAM_IN, STREAM_OUT, STREAM_ERR, STREAM_LOG, STREAM_UNKNOWN = -1 };
+enum proc_priv { PROC_PRIV_NONE, PROC_PRIV_ROOT, PROC_PRIV_KERNEL };
enum proc_state { PROC_RUNNING, PROC_SLEEPING };
enum proc_wait_type { PROC_WAIT_DEV, PROC_WAIT_MSG };
@@ -47,9 +48,10 @@ struct stream {
struct proc {
u32 pid;
u32 entry;
- u8 super;
+ u8 priv;
char name[32];
struct stream streams[4];
+ struct page_dir *page_dir;
struct regs regs;
struct proc_wait wait; // dev_id
enum proc_state state;
@@ -67,6 +69,6 @@ void proc_yield(struct regs *r);
void proc_clear_quantum(void);
void proc_enable_waiting(u32 id, enum proc_wait_type type);
void proc_wait_for(u32 id, enum proc_wait_type type, u32 func_ptr);
-struct proc *proc_make(void);
+struct proc *proc_make(enum proc_priv priv);
#endif
diff --git a/kernel/main.c b/kernel/main.c
index 16ae619..b46db0d 100644
--- a/kernel/main.c
+++ b/kernel/main.c
@@ -7,7 +7,7 @@
#include <interrupts.h>
#include <keyboard.h>
#include <load.h>
-#include <memory.h>
+#include <mm.h>
#include <mouse.h>
#include <net.h>
#include <pci.h>