aboutsummaryrefslogtreecommitdiff
path: root/kernel/features
diff options
context:
space:
mode:
authorMarvin Borner2021-03-02 23:34:39 +0100
committerMarvin Borner2021-03-02 23:34:39 +0100
commitd47e627d0006e038dcd1c34b9015c3370f7b4b0c (patch)
tree5091e41c0d14f06ee345e7fd965044b2028b4dbb /kernel/features
parent557cb0919118624eacbe4bb95de7bd6b4decab91 (diff)
Getting closer!
Diffstat (limited to 'kernel/features')
-rw-r--r--kernel/features/load.c13
-rw-r--r--kernel/features/mm.c32
-rw-r--r--kernel/features/proc.c11
3 files changed, 42 insertions, 14 deletions
diff --git a/kernel/features/load.c b/kernel/features/load.c
index 610abf8..4b3f8ea 100644
--- a/kernel/features/load.c
+++ b/kernel/features/load.c
@@ -8,16 +8,15 @@
#define PROC_STACK_SIZE 0x4000
-void proc_load(struct proc *proc, void *data)
+void proc_load(struct proc *proc, u32 entry)
{
u32 stack;
memory_alloc(proc->page_dir, PROC_STACK_SIZE, MEMORY_CLEAR, &stack);
- u32 ptr = stack + PROC_STACK_SIZE - 1;
- proc->regs.ebp = (u32)ptr;
- proc->regs.useresp = (u32)ptr;
- proc->regs.eip = (u32)data;
- proc->entry = (u32)data;
+ proc->regs.ebp = stack;
+ proc->regs.useresp = stack;
+ proc->regs.eip = entry;
+ proc->entry = entry;
}
int bin_load(const char *path, struct proc *proc)
@@ -30,7 +29,7 @@ int bin_load(const char *path, struct proc *proc)
return 1;
strcpy(proc->name, path);
- proc_load(proc, (void *)data);
+ proc_load(proc, data);
return 0;
}
diff --git a/kernel/features/mm.c b/kernel/features/mm.c
index ccc2727..ad70685 100644
--- a/kernel/features/mm.c
+++ b/kernel/features/mm.c
@@ -25,6 +25,7 @@ void paging_enable(void)
void paging_switch_dir(u32 dir)
{
+ assert(dir);
cr3_set(dir);
}
@@ -418,7 +419,7 @@ 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?
+ // TODO: Triple fault prevention? Probably bootloader stuff or something
memory_map_identity(&kernel_dir, memory_range_around_address(0x7000, 0x1000), MEMORY_NONE);
// Unmap NULL byte/page
@@ -429,8 +430,37 @@ void memory_initialize(struct mem_info *mem_info)
paging_enable();
}
+static void page_fault(struct regs *r)
+{
+ // Check error code
+ const char *type = (r->err_code & 4) ? "present" : "non-present";
+ const char *operation = (r->err_code & 2) ? "write" : "read";
+ const char *super = (r->err_code & 1) ? "User" : "Super";
+
+ // Check cr2 address
+ u32 vaddr;
+ __asm__ volatile("movl %%cr2, %%eax" : "=a"(vaddr));
+ struct proc *proc = proc_current();
+ struct page_dir *dir = NULL;
+ if (proc && proc->page_dir) {
+ dir = proc->page_dir;
+ printf("Stack is at %x, entry at %x\n", virtual_to_physical(dir, proc->regs.ebp),
+ virtual_to_physical(dir, proc->entry));
+ } else {
+ dir = &kernel_dir;
+ }
+ u32 paddr = virtual_to_physical(dir, vaddr);
+
+ // Print!
+ printf("%s process tried to %s a %s page at [vaddr=%x; paddr=%x]\n", super, operation, type,
+ vaddr, paddr);
+
+ isr_panic(r);
+}
+
void paging_install(struct mem_info *mem_info)
{
memory_initialize(mem_info);
heap_init(HEAP_START);
+ isr_install_handler(14, page_fault);
}
diff --git a/kernel/features/proc.c b/kernel/features/proc.c
index bbe675e..43cedb6 100644
--- a/kernel/features/proc.c
+++ b/kernel/features/proc.c
@@ -20,7 +20,7 @@ struct list *proc_list = NULL;
struct node *idle_proc = NULL;
struct node *current = NULL;
-// TODO: Use less memcpy and only copy relevant registers
+// TODO: Use less memcpy and only copy relevant registers (rewrite for efficiency argh)
// TODO: 20 priority queues (https://www.kernel.org/doc/html/latest/scheduler/sched-nice-design.html)
void scheduler(struct regs *regs)
{
@@ -57,8 +57,8 @@ void scheduler(struct regs *regs)
}
}
- memcpy(regs, &((struct proc *)current->data)->regs, sizeof(struct regs));
memory_dir_switch(((struct proc *)current->data)->page_dir);
+ memcpy(regs, &((struct proc *)current->data)->regs, sizeof(struct regs));
if (regs->cs != GDT_USER_CODE_OFFSET) {
regs->gs = GDT_USER_DATA_OFFSET;
@@ -473,8 +473,7 @@ void proc_init(void)
// Idle proc
struct proc *kernel_proc = proc_make(PROC_PRIV_NONE);
- void (*func)(void) = kernel_idle;
- proc_load(kernel_proc, *(void **)&func);
+ proc_load(kernel_proc, (u32)kernel_idle);
strcpy(kernel_proc->name, "idle");
kernel_proc->state = PROC_SLEEPING;
idle_proc = list_add(proc_list, kernel_proc);
@@ -494,11 +493,11 @@ void proc_init(void)
argv[2] = NULL;
((u32 *)_esp)[0] = argc; // First argument (argc)
- ((u32 *)_esp)[1] = (u32)argv; // Second argument (argv)
+ ((u32 *)_esp)[-1] = (u32)argv; // Second argument (argv)
printf("Jumping to userspace!\n");
- proc_jump_userspace();
memory_dir_switch(((struct proc *)new->data)->page_dir);
+ proc_jump_userspace();
while (1) {
};
}