diff options
author | Danny Holman <dholman@gymli.org> | 2025-01-12 01:17:36 -0600 |
---|---|---|
committer | Danny Holman <dholman@gymli.org> | 2025-01-12 01:19:11 -0600 |
commit | 95cd78840f0891e60f5ebecc8a8eb4fbaf3c2ebf (patch) | |
tree | c8c35347b50477929727fa5be9f5d0f55cbe18fd /kernel/core | |
parent | 5e166f3042a8e7b3031aae4da7006f80caa53ecc (diff) |
PROJECT RESTRUCTURING
Move the entire kernel into its own directory. Create new directories
for system commands, libraries and other required essentials for a
complete Unix-like operating system.
Signed-off-by: Danny Holman <dholman@gymli.org>
Diffstat (limited to 'kernel/core')
-rw-r--r-- | kernel/core/interrupt.c | 21 | ||||
-rw-r--r-- | kernel/core/panic.c | 31 | ||||
-rw-r--r-- | kernel/core/sched.c | 74 |
3 files changed, 126 insertions, 0 deletions
diff --git a/kernel/core/interrupt.c b/kernel/core/interrupt.c new file mode 100644 index 0000000..6d9e69d --- /dev/null +++ b/kernel/core/interrupt.c @@ -0,0 +1,21 @@ +#include <kernel/interrupt.h> +#include <kernel/panic.h> +#include <kernel/asm.h> + +static void (*isr_handlers[MAX_ISR])(struct isr_frame *frame); + +void register_isr_handler(unsigned int isr, void (*handler)(struct isr_frame *frame)) { + if (isr > MAX_ISR) + panic("Attempted to set non-existant interrupt vector"); + isr_handlers[isr] = handler; +} + +void clear_isr_handler(unsigned int isr) { + if (isr > MAX_ISR) + panic("Attempted to clear non-existant interrupt vector"); + isr_handlers[isr] = NULL; +} + +void isr_dispatch(struct isr_frame frame) { + (*isr_handlers[frame.isr_vector])(&frame); +} diff --git a/kernel/core/panic.c b/kernel/core/panic.c new file mode 100644 index 0000000..a44a73c --- /dev/null +++ b/kernel/core/panic.c @@ -0,0 +1,31 @@ +#include <kernel/panic.h> +#include <kernel/spinlock.h> +#include <libk/io.h> +#include <stdint.h> +#include <stddef.h> + +static struct spinlock panic_lock = {0}; +static int panicked = 0; + +void walk_stack(uintptr_t *addrs, size_t n); + +void stack_trace(void) { + kprintf("PRINTING STACK TRACE\n"); + uintptr_t strace[32]; + walk_stack(strace, 32); + for (int i = 0; i < 32; i++) { + if (strace[i] == 0) + break; + kprintf("#%d: %x\n", i, strace[i]); + } +} + +void panic(const char *str) { + disable_ints(); + spin_lock(&panic_lock); + panicked = 1; + spin_unlock(&panic_lock); + kprintf("KERNEL PANIC - NOT SYNCING: %s\n", str); + stack_trace(); + while (1); +} diff --git a/kernel/core/sched.c b/kernel/core/sched.c new file mode 100644 index 0000000..b6096da --- /dev/null +++ b/kernel/core/sched.c @@ -0,0 +1,74 @@ +#include <kernel/sched.h> +#include <kernel/kthread.h> +#include <kernel/panic.h> +#include <libk/io.h> +#include <libk/kmalloc.h> +#include <libk/string.h> +#include <stddef.h> + +static struct kthread *run_queue = NULL; +static struct kthread *wait_queue = NULL; +static struct kthread *cur = NULL; + +static int scheduler_enabled = 0; +static struct kmutex scheduler_lock; + +void sched_init(void) { + disable_ints(); + cur = kthread_create(NULL, NULL); + cur->stack = NULL; + switch_thread(cur, cur); + cur->state = THREAD_RUNNING; + scheduler_enabled = 1; + enable_ints(); +} + +void schedule_next(void) { + if (scheduler_enabled == 0) + return; + if (run_queue == NULL) + return; + + struct kthread *thread = cur; + schedule_thread(cur); + cur = run_queue; + run_queue = run_queue->next; + cur->next = NULL; + cur->state = THREAD_RUNNING; + switch_thread(thread, cur); +} + +void schedule_thread(struct kthread *thread) { + if (run_queue == NULL) { + run_queue = thread; + return; + } + + kmutex_lock(&scheduler_lock); + struct kthread *temp = run_queue; + while (temp->next != NULL) + temp = temp->next; + temp->next = thread; + thread->state = THREAD_READY; + kmutex_unlock(&scheduler_lock); +} + +void block_thread(struct kthread *thread) { + kmutex_lock(&scheduler_lock); + thread->next = wait_queue; + wait_queue = thread; + kmutex_unlock(&scheduler_lock); +} + +void unblock_thread(struct kthread *thread) { + kmutex_lock(&scheduler_lock); + struct kthread *temp = wait_queue; + while (temp != NULL) { + if (temp->next == thread) { + temp->next = thread->next; + return; + } + temp = temp->next; + } + kmutex_unlock(&scheduler_lock); +} |