diff --git a/src/kernel/boot/kmain.c b/src/kernel/boot/kmain.c index aee9a24..a5890af 100644 --- a/src/kernel/boot/kmain.c +++ b/src/kernel/boot/kmain.c @@ -7,6 +7,7 @@ #include #include #include +#include struct kernel_boot_data_st kernel_boot_data; @@ -29,6 +30,8 @@ void kmain(uint64_t multiboot_magic, void *multiboot_data) debug_info("Boot complete\n"); + start_scheduler(); + PANIC("End of kernel function!"); debug_info("Broke out of panic"); diff --git a/src/kernel/include/proc.h b/src/kernel/include/proc.h new file mode 100644 index 0000000..b1455a2 --- /dev/null +++ b/src/kernel/include/proc.h @@ -0,0 +1,16 @@ +#pragma once +#include + +struct thread +{ + struct thread *q_next; + uint64_t tid; + void *stack; + uint64_t state; +}; + +// proc/swtch.S +void *switch_stack(void *out, void *in); + +// proc/thread.c +void start_scheduler(); \ No newline at end of file diff --git a/src/kernel/proc/swtch.S b/src/kernel/proc/swtch.S new file mode 100644 index 0000000..936bda2 --- /dev/null +++ b/src/kernel/proc/swtch.S @@ -0,0 +1,25 @@ +.intel_syntax noprefix + +.global switch_stack + +switch_stack: + push rbp + mov rbp, rsp + push r15 + push r14 + push r13 + push r12 + push rbx + push rbp + + mov [rdi], rsp + mov rsp, [rsi] + + pop rbp + pop rbx + pop r12 + pop r13 + pop r14 + pop r15 + leaveq + ret \ No newline at end of file diff --git a/src/kernel/proc/thread.c b/src/kernel/proc/thread.c new file mode 100644 index 0000000..9fd9cf6 --- /dev/null +++ b/src/kernel/proc/thread.c @@ -0,0 +1,74 @@ +#include +#include +#include + +struct swtch_stack +{ + uint64_t RBP; + uint64_t RBX; + uint64_t R12; + uint64_t R13; + uint64_t R14; + uint64_t R15; + uint64_t RBP2; + uint64_t ret; +}; + +static uint64_t next_tid = 1; + +static struct thread *run_queue = 0; +static struct thread *current_thread; +static struct thread *scheduler_thread; + +struct thread *new_thread(void (*function)(void)) +{ + struct thread *th = P2V(pmm_calloc()); + th->tid = next_tid++; + th->stack = incptr(th, PAGE_SIZE - sizeof(struct swtch_stack)); + th->q_next = 0; + + struct swtch_stack *stck = th->stack; + stck->RBP = (uint64_t)&stck->RBP2; + stck->ret = (uint64_t)function; + + return th; +} + +struct thread *thread() +{ + return current_thread; +} + +void k_yield() +{ + switch_stack(¤t_thread->stack, &scheduler_thread->stack); +} + +struct thread *scheduler_next() +{ + if(!current_thread) return run_queue; + return current_thread->q_next; +} + +void scheduler() +{ + while(1) + { + struct thread *new = 0; + while(!(new = scheduler_next())); + + current_thread = new; + switch_stack(&scheduler_thread->stack, &new->stack); + + current_thread = 0; + } +} + +void start_scheduler() +{ + scheduler_thread = new_thread(scheduler); + scheduler_thread->tid = (uint64_t)-1; + + uint64_t stack; + switch_stack(&stack, &scheduler_thread->stack); +} \ No newline at end of file