summaryrefslogtreecommitdiff
path: root/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'kernel')
-rw-r--r--kernel/cpu/cpu.c62
-rw-r--r--kernel/cpu/idt.S107
-rw-r--r--kernel/cpu/idt.c40
-rw-r--r--kernel/cpu/tss.c7
-rw-r--r--kernel/include/comus/cpu.h7
-rw-r--r--kernel/include/comus/memory.h5
-rw-r--r--kernel/include/comus/procs.h11
-rw-r--r--kernel/memory/memory.c21
-rw-r--r--kernel/memory/physalloc.c1
-rw-r--r--kernel/procs.c83
-rw-r--r--kernel/syscall.c22
-rw-r--r--kernel/user.c40
12 files changed, 272 insertions, 134 deletions
diff --git a/kernel/cpu/cpu.c b/kernel/cpu/cpu.c
index 6ef5ef5..f607b36 100644
--- a/kernel/cpu/cpu.c
+++ b/kernel/cpu/cpu.c
@@ -1,5 +1,6 @@
#include <lib.h>
#include <comus/cpu.h>
+#include <comus/asm.h>
#include "pic.h"
#include "idt.h"
@@ -61,8 +62,10 @@ void cpu_init(void)
struct cpu_feat feats;
cpu_feats(&feats);
- pic_remap();
+ cli();
idt_init();
+ tss_init();
+ pic_remap();
if (feats.fpu)
fpu_init();
if (feats.sse) {
@@ -74,8 +77,6 @@ void cpu_init(void)
if (feats.avx)
avx_init();
}
-
- tss_init();
}
void cpu_report(void)
@@ -181,25 +182,26 @@ void cpu_feats(struct cpu_feat *feats)
void cpu_print_regs(struct cpu_regs *regs)
{
- kprintf("rax: %#016lx (%lu)\n", regs->rax, regs->rax);
- kprintf("rbx: %#016lx (%lu)\n", regs->rbx, regs->rbx);
- kprintf("rcx: %#016lx (%lu)\n", regs->rcx, regs->rcx);
- kprintf("rdx: %#016lx (%lu)\n", regs->rdx, regs->rdx);
- kprintf("rsi: %#016lx (%lu)\n", regs->rsi, regs->rsi);
- kprintf("rdi: %#016lx (%lu)\n", regs->rdi, regs->rdi);
- kprintf("rsp: %#016lx (%lu)\n", regs->rsp, regs->rsp);
- kprintf("rbp: %#016lx (%lu)\n", regs->rbp, regs->rbp);
- kprintf("r8 : %#016lx (%lu)\n", regs->r8, regs->r8);
- kprintf("r9 : %#016lx (%lu)\n", regs->r9, regs->r9);
- kprintf("r10: %#016lx (%lu)\n", regs->r10, regs->r10);
- kprintf("r11: %#016lx (%lu)\n", regs->r11, regs->r11);
- kprintf("r12: %#016lx (%lu)\n", regs->r12, regs->r12);
- kprintf("r13: %#016lx (%lu)\n", regs->r13, regs->r13);
- kprintf("r14: %#016lx (%lu)\n", regs->r14, regs->r14);
- kprintf("r15: %#016lx (%lu)\n", regs->r15, regs->r15);
- kprintf("rip: %#016lx (%lu)\n", regs->rip, regs->rip);
- kprintf("rflags: %#016lx (%lu)\n", regs->rflags, regs->rflags);
- kputs("rflags: ");
+ kprintf("rax:\t%#016lx (%lu)\n", regs->rax, regs->rax);
+ kprintf("rbx:\t%#016lx (%lu)\n", regs->rbx, regs->rbx);
+ kprintf("rcx:\t%#016lx (%lu)\n", regs->rcx, regs->rcx);
+ kprintf("rdx:\t%#016lx (%lu)\n", regs->rdx, regs->rdx);
+ kprintf("rsi:\t%#016lx (%lu)\n", regs->rsi, regs->rsi);
+ kprintf("rdi:\t%#016lx (%lu)\n", regs->rdi, regs->rdi);
+ kprintf("rsp:\t%#016lx (%lu)\n", regs->rsp, regs->rsp);
+ kprintf("rbp:\t%#016lx (%lu)\n", regs->rbp, regs->rbp);
+ kprintf("r8:\t%#016lx (%lu)\n", regs->r8, regs->r8);
+ kprintf("r9:\t%#016lx (%lu)\n", regs->r9, regs->r9);
+ kprintf("r10:\t%#016lx (%lu)\n", regs->r10, regs->r10);
+ kprintf("r11:\t%#016lx (%lu)\n", regs->r11, regs->r11);
+ kprintf("r12:\t%#016lx (%lu)\n", regs->r12, regs->r12);
+ kprintf("r13:\t%#016lx (%lu)\n", regs->r13, regs->r13);
+ kprintf("r14:\t%#016lx (%lu)\n", regs->r14, regs->r14);
+ kprintf("r15:\t%#016lx (%lu)\n", regs->r15, regs->r15);
+ kprintf("rip:\t%#016lx (%lu)\n", regs->rip, regs->rip);
+ kprintf("rflags: %#016lx (%lu) [ ", regs->rflags, regs->rflags);
+ if (regs->rflags & (3 << 12))
+ kprintf("IOPL=%lu ", (regs->rflags >> 12) & 0x3);
if (regs->rflags & (1 << 0))
kputs("CF ");
if (regs->rflags & (1 << 2))
@@ -218,8 +220,6 @@ void cpu_print_regs(struct cpu_regs *regs)
kputs("DF ");
if (regs->rflags & (1 << 11))
kputs("OF ");
- if (regs->rflags & (3 << 12))
- kputs("IOPL ");
if (regs->rflags & (1 << 14))
kputs("NT ");
if (regs->rflags & (1 << 15))
@@ -236,5 +236,19 @@ void cpu_print_regs(struct cpu_regs *regs)
kputs("VIP ");
if (regs->rflags & (1 << 21))
kputs("ID ");
+ kputs("]\n");
+ kprintf("cs:\t%#04lx (%lu) [ DPL=%lu ]\n", regs->cs, regs->cs,
+ regs->cs & 0x3);
+ kprintf("ss:\t%#04lx (%lu) [ DPL=%lu ]\n", regs->ss, regs->ss,
+ regs->ss & 0x3);
+ kprintf("ds:\t%#04hx (%hu) [ DPL=%hu ]\n", regs->ds, regs->ds,
+ regs->ds & 0x3);
+ kprintf("es:\t%#04hx (%hu) [ DPL=%hu ]\n", regs->es, regs->es,
+ regs->es & 0x3);
+ kprintf("fs:\t%#04hx (%hu) [ DPL=%hu ]\n", regs->fs, regs->fs,
+ regs->fs & 0x3);
+ kprintf("gs:\t%#04hx (%hu) [ DPL=%hu ]\n", regs->gs, regs->gs,
+ regs->gs & 0x3);
+ kprintf("cr3:\t%#016lx (%lu)\n", regs->cr3, regs->cr3);
kputs("\n");
}
diff --git a/kernel/cpu/idt.S b/kernel/cpu/idt.S
index 06c70a0..05c34f5 100644
--- a/kernel/cpu/idt.S
+++ b/kernel/cpu/idt.S
@@ -1,6 +1,5 @@
.global isr_stub_table
.global syscall_return
- .global awd
.extern idt_exception_handler
.extern idt_pic_timer
@@ -9,8 +8,10 @@
.extern idt_pic_eoi
.extern syscall_handler
.extern current_pcb
+ .extern isr_save
.macro PUSHALL
+ # regs
pushq %rax
pushq %rbx
pushq %rcx
@@ -26,9 +27,38 @@
pushq %r13
pushq %r14
pushq %r15
+
+ # segments
+ movw %ds, %ax
+ pushw %ax
+ movw %es, %ax
+ pushw %ax
+ movw %fs, %ax
+ pushw %ax
+ movw %gs, %ax
+ pushw %ax
+
+ # pgdir
+ movq %cr3, %rax
+ pushq %rax
.endm
.macro POPALL
+ # pgdir
+ popq %rax
+ movq %rax, %cr3
+
+ # segments
+ popw %ax
+ movw %ax, %gs
+ movw %ax, %fs
+ popw %ax
+ movw %ax, %es
+ popw %ax
+ movw %ax, %ds
+ popw %ax
+
+ # regs
popq %r15
popq %r14
popq %r13
@@ -46,19 +76,28 @@
popq %rax
.endm
+.macro ISRSave
+ PUSHALL
+ cld
+ movq %rsp, %rdi
+ callq isr_save
+.endm
+
+.macro ISRRestore
+ POPALL
+ iretq
+.endm
+
# call the exception handler with the interrupt number
# args: interrupt number
.macro ISRException num
.align 8
isr_stub_\num:
- PUSHALL
- cld
- movq $\num, %rdi # exception number
+ ISRSave
+ movq $\num, %rdi # exception number
movq $0, %rsi # placeholder error code
- movq %rsp, %rdx # top of stack
callq idt_exception_handler
- POPALL
- iretq
+ ISRRestore
.endm
# call the exception handler with the interrupt number
@@ -68,26 +107,21 @@ isr_stub_\num:
.align 8
isr_stub_\num:
# retrieve the error code without corrupting registers
- mov %eax, isr_tmp
+ movq %rax, isr_tmp
popq %rax
- mov %eax, isr_err_code
+ movq %rax, isr_err_code
movq isr_tmp, %rax
- PUSHALL
- cld
+ ISRSave
movq $\num, %rdi # exception number
movq isr_err_code, %rsi # error code
- movq %rsp, %rdx # top of stack
callq idt_exception_handler
- POPALL
- iretq
+ ISRRestore
.endm
.macro SYSCALL num
.align 8
isr_stub_\num:
- PUSHALL
- cld
- movq %rsp, %rdi # top of stack
+ ISRSave
callq syscall_handler
jmp syscall_return
.endm
@@ -95,48 +129,40 @@ isr_stub_\num:
.macro PICGeneric num
.align 8
isr_stub_\num:
- PUSHALL
- cld
+ ISRSave
movq $\num, %rdi
callq idt_pic_eoi
- POPALL
- iretq
+ ISRRestore
.endm
.macro PICTimer num
.align 8
isr_stub_\num:
- PUSHALL
- cld
+ ISRSave
callq idt_pic_timer
movq $\num, %rdi
callq idt_pic_eoi
- POPALL
- iretq
+ ISRRestore
.endm
.macro PICKeyboard num
.align 8
isr_stub_\num:
- PUSHALL
- cld
+ ISRSave
callq idt_pic_keyboard
movq $\num, %rdi
callq idt_pic_eoi
- POPALL
- iretq
+ ISRRestore
.endm
.macro PICMouse num
.align 8
isr_stub_\num:
- PUSHALL
- cld
+ ISRSave
callq idt_pic_mouse
movq $\num, %rdi
callq idt_pic_eoi
- POPALL
- iretq
+ ISRRestore
.endm
# do nothing
@@ -421,18 +447,13 @@ isr_stub_table:
# isr restore
syscall_return:
- movq current_pcb, %rbx // return user stack
- movq 0(%rbx), %rsp // esp
- movq 8(%rbx), %rcx // pml4
- movq (%rcx), %rcx
- movq %rcx, %cr3
+ // get current pcb address
+ movq current_pcb, %rbx
- movw $(0x20 | 3), %ax
- movw %ax, %ds
- movw %ax, %es
- movw %ax, %fs
- movw %ax, %gs
+ // load user stack
+ leaq 8(%rbx), %rsp
+ // return
POPALL
iretq
diff --git a/kernel/cpu/idt.c b/kernel/cpu/idt.c
index 8bddc21..d071d29 100644
--- a/kernel/cpu/idt.c
+++ b/kernel/cpu/idt.c
@@ -3,6 +3,7 @@
#include <comus/asm.h>
#include <comus/cpu.h>
#include <comus/drivers/pit.h>
+#include <comus/procs.h>
#include <comus/memory.h>
#include "idt.h"
@@ -42,8 +43,12 @@ struct idtr {
__attribute__((aligned(0x10))) static struct idt_entry idt[256];
static struct idtr idtr;
-// from idt.S
extern void *isr_stub_table[];
+extern char kern_stack_start[];
+extern char kern_stack_end[];
+
+// current register state on interrupt
+static struct cpu_regs *state;
// initialize and load the IDT
void idt_init(void)
@@ -58,11 +63,10 @@ void idt_init(void)
uint64_t isr = (uint64_t)isr_stub_table[vector];
// interrupts before 0x20 are for cpu exceptions
- uint8_t gate_type = (vector < 0x20) ? GATE_64BIT_TRAP : GATE_64BIT_INT;
entry->kernel_cs = 0x08; // offset of 1 into GDT
entry->ist = 0;
- entry->flags = PRESENT | RING0 | gate_type;
+ entry->flags = PRESENT | RING0 | GATE_64BIT_INT;
entry->isr_low = isr & 0xffff;
entry->isr_mid = (isr >> 16) & 0xffff;
entry->isr_high = (isr >> 32) & 0xffffffff;
@@ -115,14 +119,11 @@ char *EXCEPTIONS[] = {
"Reserved",
};
-void idt_exception_handler(uint64_t exception, uint64_t code,
- struct cpu_regs *state)
+__attribute__((noreturn)) void idt_exception_handler(uint64_t exception,
+ uint64_t code)
{
uint64_t cr2;
- // make sure were in the kernel memory context
- mem_ctx_switch(kernel_mem_ctx);
-
switch (exception) {
case EX_PAGE_FAULT:
// page faults store the offending address in cr2
@@ -151,16 +152,35 @@ void idt_exception_handler(uint64_t exception, uint64_t code,
}
}
+void isr_save(struct cpu_regs *regs)
+{
+ // make sure were in the kernel memory context
+ mem_ctx_switch(kernel_mem_ctx);
+
+ // save pointer to registers
+ state = regs;
+
+ // if we have a kernel stack pointer
+ // we should return to not save kernel context
+ // data to userspace
+ if (regs->rsp >= (size_t)kern_stack_start &&
+ regs->rsp <= (size_t)kern_stack_end)
+ return;
+
+ // save registers in current_pcb
+ if (current_pcb != NULL)
+ current_pcb->regs = *regs;
+}
+
void idt_pic_eoi(uint8_t exception)
{
pic_eoi(exception - PIC_REMAP_OFFSET);
}
-int counter = 0;
-
void idt_pic_timer(void)
{
ticks++;
+ pcb_on_tick();
}
void idt_pic_keyboard(void)
diff --git a/kernel/cpu/tss.c b/kernel/cpu/tss.c
index 184b884..bca979d 100644
--- a/kernel/cpu/tss.c
+++ b/kernel/cpu/tss.c
@@ -1,6 +1,5 @@
-#include "comus/memory.h"
-#include "lib/kstring.h"
-#include <stdint.h>
+#include <comus/memory.h>
+#include <lib.h>
#include "tss.h"
@@ -48,7 +47,7 @@ extern volatile uint8_t GDT[];
static volatile struct sys_seg_descriptor *GDT_TSS;
// kernel stack pointer
-static char interrupt_stack[PAGE_SIZE*2];
+static char interrupt_stack[PAGE_SIZE * 2];
void tss_init(void)
{
diff --git a/kernel/include/comus/cpu.h b/kernel/include/comus/cpu.h
index 3669000..df8f44e 100644
--- a/kernel/include/comus/cpu.h
+++ b/kernel/include/comus/cpu.h
@@ -31,6 +31,13 @@ struct cpu_feat {
};
struct cpu_regs {
+ // pgdir
+ uint64_t cr3;
+ // segments
+ uint16_t gs;
+ uint16_t fs;
+ uint16_t es;
+ uint16_t ds;
// registers
uint64_t r15;
uint64_t r14;
diff --git a/kernel/include/comus/memory.h b/kernel/include/comus/memory.h
index 408521b..47ea103 100644
--- a/kernel/include/comus/memory.h
+++ b/kernel/include/comus/memory.h
@@ -104,6 +104,11 @@ void mem_ctx_free(mem_ctx_t ctx);
void mem_ctx_switch(mem_ctx_t ctx);
/**
+ * @returns the pgdir pointer in the memory ctx
+ */
+volatile void *mem_ctx_pgdir(mem_ctx_t ctx);
+
+/**
* Allocates at least len bytes of memory starting at
* physical address addr. Returned address can be
* any virtural address.
diff --git a/kernel/include/comus/procs.h b/kernel/include/comus/procs.h
index 0150975..eb6c54f 100644
--- a/kernel/include/comus/procs.h
+++ b/kernel/include/comus/procs.h
@@ -15,8 +15,8 @@
#include <lib.h>
#include <elf.h>
-#define PCB_REG(pcb, x) ((pcb)->regs->x)
-#define PCB_RET(pcb) ((pcb)->regs->rax)
+#define PCB_REG(pcb, x) ((pcb)->regs.x)
+#define PCB_RET(pcb) ((pcb)->regs.rax)
#define PCB_ARG1(pcb) PCB_REG((pcb), rdi)
#define PCB_ARG2(pcb) PCB_REG((pcb), rsi)
#define PCB_ARG3(pcb) PCB_REG((pcb), rdx)
@@ -47,8 +47,8 @@ enum proc_state {
/// process control block
struct pcb {
// context
- struct cpu_regs *regs;
mem_ctx_t memctx;
+ struct cpu_regs regs;
// metadata
pid_t pid;
@@ -224,4 +224,9 @@ void schedule(struct pcb *pcb);
*/
__attribute__((noreturn)) void dispatch(void);
+/**
+ * Scheduler function called on every system tick
+ */
+void pcb_on_tick(void);
+
#endif /* procs.h */
diff --git a/kernel/memory/memory.c b/kernel/memory/memory.c
index bd3e06b..ecfd639 100644
--- a/kernel/memory/memory.c
+++ b/kernel/memory/memory.c
@@ -71,7 +71,12 @@ mem_ctx_t mem_ctx_alloc(void)
mem_ctx_t mem_ctx_clone(const mem_ctx_t old, bool cow)
{
- mem_ctx_t new = user_mem_ctx_next;
+ mem_ctx_t new;
+
+ assert(old != NULL, "memory context is null");
+ assert(old->pml4 != NULL, "pgdir is null");
+
+ new = user_mem_ctx_next;
if (new == NULL)
return NULL;
@@ -93,6 +98,9 @@ mem_ctx_t mem_ctx_clone(const mem_ctx_t old, bool cow)
void mem_ctx_free(mem_ctx_t ctx)
{
+ assert(ctx != NULL, "memory context is null");
+ assert(ctx->pml4 != NULL, "pgdir is null");
+
pgdir_free(ctx->pml4);
virtaddr_cleanup(&ctx->virtctx);
@@ -107,9 +115,20 @@ void mem_ctx_free(mem_ctx_t ctx)
void mem_ctx_switch(mem_ctx_t ctx)
{
+ assert(ctx != NULL, "memory context is null");
+ assert(ctx->pml4 != NULL, "pgdir is null");
+
__asm__ volatile("mov %0, %%cr3" ::"r"(ctx->pml4) : "memory");
}
+volatile void *mem_ctx_pgdir(mem_ctx_t ctx)
+{
+ assert(ctx != NULL, "memory context is null");
+ assert(ctx->pml4 != NULL, "pgdir is null");
+
+ return ctx->pml4;
+}
+
void memory_init(void)
{
struct memory_map mmap;
diff --git a/kernel/memory/physalloc.c b/kernel/memory/physalloc.c
index 55ece02..c5a74b7 100644
--- a/kernel/memory/physalloc.c
+++ b/kernel/memory/physalloc.c
@@ -1,4 +1,3 @@
-#include "lib/kio.h"
#include <lib.h>
#include <comus/memory.h>
#include <comus/asm.h>
diff --git a/kernel/procs.c b/kernel/procs.c
index c1bcc4f..f3d855c 100644
--- a/kernel/procs.c
+++ b/kernel/procs.c
@@ -1,3 +1,4 @@
+#include <comus/drivers/pit.h>
#include <comus/procs.h>
#include <comus/error.h>
#include <comus/cpu.h>
@@ -179,45 +180,47 @@ void pcb_zombify(struct pcb *victim)
// schedule init if zombie child found
if (zchild != NULL && init_pcb->state == PROC_STATE_WAITING) {
+ pid_t pid;
+ int *status;
+
assert(pcb_queue_remove(zombie, zchild) == SUCCESS,
"pcb_zombify: cannot remove zombie process from queue");
assert(pcb_queue_remove(waiting, init_pcb) == SUCCESS,
"pcb_zombify: cannot remove waiting process from queue");
- // send exited pid to init
- PCB_RET(init_pcb) = zchild->pid;
- // set &status in init's waitpid call
- int *ptr = (int *)PCB_ARG2(init_pcb);
- if (ptr != NULL) {
- mem_ctx_switch(init_pcb->memctx);
- *ptr = zchild->exit_status;
- mem_ctx_switch(kernel_mem_ctx);
+ pid = (pid_t)PCB_ARG1(init_pcb);
+ status = (int *)PCB_ARG2(init_pcb);
+
+ // set exited pid and exist status in init's waitpid call
+ if (pid == 0 || pid == zchild->pid) {
+ PCB_RET(init_pcb) = zchild->pid;
+ if (status != NULL) {
+ mem_ctx_switch(init_pcb->memctx);
+ *status = zchild->exit_status;
+ mem_ctx_switch(kernel_mem_ctx);
+ }
+ schedule(init_pcb);
}
- // schedule init and cleanup child
- schedule(init_pcb);
pcb_cleanup(zchild);
}
// if the parent is waiting, wake it up and clean the victim,
// otherwise the victim will become a zombie
if (parent->state == PROC_STATE_WAITING) {
- // verify that the parent is either waiting for this process
- // or is waiting for any of its children
- uint64_t target = PCB_ARG1(parent);
+ pid_t pid;
+ int *status;
+
+ pid = (pid_t)PCB_ARG1(parent);
+ status = (int *)PCB_ARG2(parent);
- if (target != 0 || target == victim->pid) {
- // send exited pid to parent
- PCB_RET(parent) = victim->pid;
- // send &status to parent
- int *ptr = (int *)PCB_ARG2(parent);
- if (ptr != NULL) {
+ if (pid == 0 || pid == victim->pid) {
+ PCB_RET(parent) = zchild->pid;
+ if (status != NULL) {
mem_ctx_switch(parent->memctx);
- *ptr = victim->exit_status;
+ *status = victim->exit_status;
mem_ctx_switch(kernel_mem_ctx);
}
-
- // schedule the parent, and clean up the zombie
schedule(parent);
pcb_cleanup(victim);
return;
@@ -476,3 +479,39 @@ __attribute__((noreturn)) void dispatch(void)
syscall_return();
}
+
+void pcb_on_tick(void)
+{
+ // procs not initalized yet
+ if (init_pcb == NULL)
+ return;
+
+ // update on sleeping
+ do {
+ struct pcb *pcb;
+
+ if (pcb_queue_empty(sleeping))
+ break;
+
+ pcb = pcb_queue_peek(sleeping);
+ assert(pcb != NULL, "sleeping queue should not be empty");
+
+ if (pcb->wakeup >= ticks)
+ break;
+
+ if (pcb_queue_remove(sleeping, pcb))
+ panic("failed to wake sleeping process: %d", pcb->pid);
+
+ schedule(pcb);
+ } while (1);
+
+ if (current_pcb) {
+ current_pcb->ticks--;
+ if (current_pcb->ticks < 1) {
+ // schedule another process
+ schedule(current_pcb);
+ current_pcb = NULL;
+ dispatch();
+ }
+ }
+}
diff --git a/kernel/syscall.c b/kernel/syscall.c
index b595b6a..44bfe5f 100644
--- a/kernel/syscall.c
+++ b/kernel/syscall.c
@@ -10,11 +10,11 @@
static struct pcb *pcb;
-#define RET(type, name) type *name = (type *)(&pcb->regs->rax)
-#define ARG1(type, name) type name = (type)(pcb->regs->rdi)
-#define ARG2(type, name) type name = (type)(pcb->regs->rsi)
-#define ARG3(type, name) type name = (type)(pcb->regs->rdx)
-#define ARG4(type, name) type name = (type)(pcb->regs->rcx)
+#define RET(type, name) type *name = (type *)(&pcb->regs.rax)
+#define ARG1(type, name) type name = (type)(pcb->regs.rdi)
+#define ARG2(type, name) type name = (type)(pcb->regs.rsi)
+#define ARG3(type, name) type name = (type)(pcb->regs.rdx)
+#define ARG4(type, name) type name = (type)(pcb->regs.rcx)
__attribute__((noreturn)) static int sys_exit(void)
{
@@ -255,20 +255,16 @@ static int (*syscall_tbl[N_SYSCALLS])(void) = {
[SYS_drm] = sys_drm, [SYS_ticks] = sys_ticks,
};
-void syscall_handler(struct cpu_regs *regs)
+void syscall_handler(void)
{
uint64_t num;
int (*handler)(void);
int ret = 1;
- // make sure were in the kernel memory context
- mem_ctx_switch(kernel_mem_ctx);
-
// update data
pcb = current_pcb;
- pcb->regs = regs;
- num = pcb->regs->rax;
- pcb->regs->rax = 0;
+ num = pcb->regs.rax;
+ pcb->regs.rax = 0;
current_pcb = NULL;
// check for invalid syscall
@@ -287,7 +283,7 @@ void syscall_handler(struct cpu_regs *regs)
// on failure, set rax
if (ret)
- pcb->regs->rax = ret;
+ pcb->regs.rax = ret;
// return to current pcb
current_pcb = pcb;
diff --git a/kernel/user.c b/kernel/user.c
index 9d933e5..ce24b3e 100644
--- a/kernel/user.c
+++ b/kernel/user.c
@@ -16,6 +16,10 @@
#define BLOCK_SIZE (PAGE_SIZE * 1000)
static uint8_t *load_buffer = NULL;
+#define USER_CODE 0x18
+#define USER_DATA 0x20
+#define RING3 3
+
static int user_load_segment(struct pcb *pcb, struct disk *disk, int idx)
{
Elf64_Phdr hdr;
@@ -63,7 +67,7 @@ static int user_load_segment(struct pcb *pcb, struct disk *disk, int idx)
kunmapaddr(mapADDR);
return 1;
}
- memcpyv(mapADDR + total_read, load_buffer, read);
+ memcpy(mapADDR + total_read, load_buffer, read);
total_read += read;
}
@@ -156,16 +160,28 @@ static int user_setup_stack(struct pcb *pcb)
F_WRITEABLE | F_UNPRIVILEGED) == NULL)
return 1;
- // setup initial context save area
- pcb->regs = (struct cpu_regs *)(USER_STACK_TOP - sizeof(struct cpu_regs));
- mem_ctx_switch(pcb->memctx);
- memset(pcb->regs, 0, sizeof(struct cpu_regs));
- pcb->regs->rip = pcb->elf_header.e_entry;
- pcb->regs->cs = 0x18 | 3;
- pcb->regs->rflags = (1 << 9);
- pcb->regs->rsp = USER_STACK_TOP;
- pcb->regs->ss = 0x20 | 3;
- mem_ctx_switch(kernel_mem_ctx);
+ memset(&pcb->regs, 0, sizeof(struct cpu_regs));
+
+ // pgdir
+ pcb->regs.cr3 = (uint64_t)mem_ctx_pgdir(pcb->memctx);
+ // segments
+ pcb->regs.gs = USER_DATA | RING3;
+ pcb->regs.fs = USER_DATA | RING3;
+ pcb->regs.es = USER_DATA | RING3;
+ pcb->regs.ds = USER_DATA | RING3;
+ // registers
+ pcb->regs.rdi = 0; // argc
+ pcb->regs.rsi = 0; // argv
+ // intruction pointer
+ pcb->regs.rip = pcb->elf_header.e_entry;
+ // code segment
+ pcb->regs.cs = 0x18 | 3;
+ // rflags
+ pcb->regs.rflags = (1 << 9);
+ // stack pointer
+ pcb->regs.rsp = USER_STACK_TOP;
+ // stack segment
+ pcb->regs.ss = 0x20 | 3;
return 0;
}
@@ -176,8 +192,6 @@ int user_load(struct pcb *pcb, struct disk *disk)
if (pcb == NULL || disk == NULL)
return 1;
- pcb->regs = NULL;
-
// allocate memory context
pcb->memctx = mem_ctx_alloc();
if (pcb->memctx == NULL)