diff --git a/src/kernel/boot/kmain.c b/src/kernel/boot/kmain.c index fe2b320..bbd10a8 100644 --- a/src/kernel/boot/kmain.c +++ b/src/kernel/boot/kmain.c @@ -8,16 +8,9 @@ #include #include -int *pid = (int *)0x20000; void thread_function() { - *pid = process()->pid; - - while(1) - { - debug("Process %d\n", *pid); - yield(); - } + while(1); } @@ -35,16 +28,12 @@ void kmain(uint64_t multiboot_magic, void *multiboot_data) cpu_init(); - struct process *p1 = new_process(thread_function); - vmm_set_page(p1->P4, 0x20000, pmm_alloc(), PAGE_WRITE | PAGE_PRESENT); - struct process *p2 = new_process(thread_function); - vmm_set_page(p2->P4, 0x20000, pmm_alloc(), PAGE_WRITE | PAGE_PRESENT); - struct process *p3 = new_process(thread_function); - vmm_set_page(p3->P4, 0x20000, pmm_alloc(), PAGE_WRITE | PAGE_PRESENT); + struct process *p1 = new_process((void (*)(void))0x10000); + uint64_t page = pmm_alloc(); + vmm_set_page(p1->P4, 0x10000, page, PAGE_WRITE | PAGE_PRESENT | PAGE_USER); + memcpy(P2V(page), (void *)(uintptr_t)thread_function, PAGE_SIZE); ready(p1); - ready(p2); - ready(p3); debug_ok("Boot \"Complete\"\n"); diff --git a/src/kernel/cpu/cpu.c b/src/kernel/cpu/cpu.c index 1970cae..da598c5 100644 --- a/src/kernel/cpu/cpu.c +++ b/src/kernel/cpu/cpu.c @@ -1,7 +1,7 @@ #include #include -uint64_t gdt[5]; +uint64_t gdt[6]; uint8_t tss[104]; void gdt_init(uint64_t *, void *); diff --git a/src/kernel/cpu/gdt.c b/src/kernel/cpu/gdt.c index ed89f7f..7962337 100644 --- a/src/kernel/cpu/gdt.c +++ b/src/kernel/cpu/gdt.c @@ -6,7 +6,7 @@ #define GDT_DPL(lvl) ((lvl)<<13) #define GDT_PRESENT (1<<15) #define GDT_LONG (1<<21) -#define GDT_TSS (1<<8) +#define GDT_TSS (9<<8) struct gdt { @@ -44,6 +44,7 @@ struct gdt BootGDT[] = { {0, 0}, {0, GDT_PRESENT | GDT_DPL(0) | GDT_CODE | GDT_LONG}, {0, GDT_PRESENT | GDT_DPL(3) | GDT_CODE | GDT_LONG}, + {0, GDT_PRESENT | GDT_DPL(3) | (1<<12) | (1<<9)}, {0, 0}, {0, 0}, }; @@ -56,18 +57,27 @@ void gdt_init(uint64_t *_gdt, void *_tss) struct gdt *gdt = (struct gdt *)_gdt; memcpy(gdt, BootGDT, sizeof(BootGDT)); + struct tss *tss = _tss; + tss->io_mba = sizeof(struct tss); + uint32_t tss_limit = sizeof(struct tss); uint64_t tss_base = (uint64_t)_tss; - gdt[3].flags = GDT_PRESENT | GDT_TSS; - gdt[3].flags |= (((tss_base >> 24) & 0xFF) << 24); - gdt[3].flags |= ((tss_base >> 16) & 0xFF); - gdt[3].flags |= (((tss_limit >> 16) & 0xF) << 16); - gdt[3].addr = ((tss_base & 0xFFFF) << 16) | (tss_limit & 0xFFFF); - gdt[4].flags = 0; - gdt[4].addr = ((tss_base >> 32) & 0xFFFF); + gdt[4].flags = GDT_PRESENT | GDT_TSS; + gdt[4].flags |= (((tss_base >> 24) & 0xFF) << 24); + gdt[4].flags |= ((tss_base >> 16) & 0xFF); + gdt[4].flags |= (((tss_limit >> 16) & 0xF) << 16); + gdt[4].addr = ((tss_base & 0xFFFF) << 16) | (tss_limit & 0xFFFF); + gdt[5].flags = 0; + gdt[5].addr = ((tss_base >> 32) & 0xFFFFFFFF); - GDTp.len = 5*8 - 1; + GDTp.len = 6*8 - 1; GDTp.gdt = gdt; load_gdt(&GDTp); } + +void set_tss_rsp0(void *_tss, void *rsp0) +{ + struct tss *tss = _tss; + tss->rsp0 = (uint64_t)rsp0; +} diff --git a/src/kernel/cpu/registers.S b/src/kernel/cpu/registers.S index 6d75804..f99166d 100644 --- a/src/kernel/cpu/registers.S +++ b/src/kernel/cpu/registers.S @@ -17,7 +17,7 @@ load_gdt: push rax retfq .load_gdt: - mov rax, 0x18 + mov rax, 0x20 ltr ax ret diff --git a/src/kernel/include/cpu.h b/src/kernel/include/cpu.h index 9cf84a4..beba505 100644 --- a/src/kernel/include/cpu.h +++ b/src/kernel/include/cpu.h @@ -3,6 +3,8 @@ void cpu_init(); +extern uint8_t tss[]; +void set_tss_rsp0(void *tss, void *rsp0); void load_idt(void *); diff --git a/src/kernel/include/memory.h b/src/kernel/include/memory.h index e4ae958..13e8035 100644 --- a/src/kernel/include/memory.h +++ b/src/kernel/include/memory.h @@ -18,6 +18,7 @@ #define PAGE_PRESENT 0x001 #define PAGE_WRITE 0x002 +#define PAGE_USER 0x004 #define PAGE_HUGE 0x080 #define PAGE_GLOBAL 0x100 diff --git a/src/kernel/include/process.h b/src/kernel/include/process.h index c375907..5473bb6 100644 --- a/src/kernel/include/process.h +++ b/src/kernel/include/process.h @@ -2,6 +2,7 @@ #include #include #include +#include struct process { diff --git a/src/kernel/proc/process.c b/src/kernel/proc/process.c index ff2b57d..a52ea18 100644 --- a/src/kernel/proc/process.c +++ b/src/kernel/proc/process.c @@ -11,8 +11,10 @@ struct swtch_stack uint64_t R13; uint64_t R14; uint64_t R15; + uint64_t isr_return_arg; uint64_t RBP2; uint64_t ret; + registers r; }__attribute__((packed)); struct process *sched_proc = 0; @@ -28,7 +30,15 @@ struct process *new_process(void (*function)(void)) struct swtch_stack *stk = proc->stack_ptr; stk->RBP = (uint64_t)&stk->RBP2; - stk->ret = (uint64_t)function; + + stk->ret = (uint64_t)isr_return; + stk->isr_return_arg = (uint64_t)&stk->r; + + stk->r.rip = (uint64_t)function; + stk->r.cs = 0x10 | 3; + stk->r.ss = 0x18 | 3; + stk->r.rflags = 3<<12; + stk->r.rsp = 0x10FFF; return proc; } @@ -52,6 +62,7 @@ void scheduler() _proc = new; write_cr3(new->P4); + set_tss_rsp0(tss, new + PAGE_SIZE); switch_stack(&sched_proc->stack_ptr, &new->stack_ptr); ready(_proc); @@ -61,8 +72,15 @@ void scheduler() void start_scheduler() { - sched_proc = new_process(scheduler); + sched_proc = P2V(pmm_calloc()); sched_proc->pid = (uint64_t)-1; + sched_proc->stack_ptr = incptr(sched_proc, PAGE_SIZE - sizeof(struct swtch_stack) + sizeof(registers)); + sched_proc->P4 = kernel_P4; + + struct swtch_stack *stk = sched_proc->stack_ptr; + stk->RBP = (uint64_t)&stk->RBP2; + + stk->ret = (uint64_t)scheduler; uint64_t stack; switch_stack(&stack, &sched_proc->stack_ptr); diff --git a/src/kernel/proc/swtch.S b/src/kernel/proc/swtch.S index 097e8ec..5ee6574 100644 --- a/src/kernel/proc/swtch.S +++ b/src/kernel/proc/swtch.S @@ -5,6 +5,7 @@ switch_stack: push rbp mov rbp, rsp + push rdi push r15 push r14 push r13 @@ -21,5 +22,6 @@ switch_stack: pop r13 pop r14 pop r15 + pop rdi leaveq ret