From ef151a8385557fb67191dff5ab916ac71eb3e8ca Mon Sep 17 00:00:00 2001 From: Justus Wolff Date: Wed, 1 Apr 2026 16:45:33 +0200 Subject: [PATCH] finished interrupts for now and a basic scheduler for that, start implementation on paging. --- makefile | 6 ++-- src/headers/interrupts.h | 17 +++++---- src/headers/keyboard.h | 21 +++++++++++ src/headers/paging.h | 0 src/headers/scheduler.h | 21 +++++++++++ src/kernel/entry.c | 18 ++++++---- src/kernel/interrupts.c | 9 +++-- src/kernel/scheduler.c | 77 ++++++++++++++++++++++++++++++++++++++++ src/kernel/stdlib.c | 2 +- src/misc/interrupts.asm | 23 ++++++++---- 10 files changed, 169 insertions(+), 25 deletions(-) create mode 100644 src/headers/keyboard.h create mode 100644 src/headers/paging.h create mode 100644 src/headers/scheduler.h create mode 100644 src/kernel/scheduler.c diff --git a/makefile b/makefile index 954fa00..5110aa1 100644 --- a/makefile +++ b/makefile @@ -8,11 +8,12 @@ build: prepare copygrub gcc -c src/kernel/graphics.c -o build/graphics.o -ffreestanding -O2 -Wall -Wextra -m32 # VGA graphics gcc -c src/kernel/tty.c -o build/tty.o -ffreestanding -O2 -Wall -Wextra -m32 # tty gcc -c src/kernel/interrupts.c -o build/interrupts.o -ffreestanding -O2 -Wall -Wextra -m32 # interrupts, C side + gcc -c src/kernel/scheduler.c -o build/scheduler.o -ffreestanding -O2 -Wall -Wextra -m32 # scheduler gcc -c initrd/vga/main.c -o build/initrddir/vga_graph -ffreestanding -O2 -Wall -Wextra -m32 # initrd/vga driver tar -czf build/initrd build/initrddir/* # build initrd - gcc -z noexecstack -m32 -T linker.ld -o build/linked -ffreestanding -O2 -nostdlib build/interrupts.o build/intasm.o build/tty.o build/graphics.o build/boot.o build/kernel.o build/stdlib.o -fno-pie -fno-pic -no-pie # link + gcc -z noexecstack -m32 -T linker.ld -o build/linked -ffreestanding -O2 -nostdlib build/scheduler.o build/interrupts.o build/intasm.o build/tty.o build/graphics.o build/boot.o build/kernel.o build/stdlib.o -fno-pie -fno-pic -no-pie # link cp build/linked build/grub/boot/kernel # copy kernel over to grub template cp build/initrd build/grub/boot/JPOS.initrd # copy initrd to grub template @@ -21,7 +22,8 @@ build: prepare copygrub test: build qemu-system-i386 \ -boot d \ - -cdrom build/live.iso + -cdrom build/live.iso \ + -d int copygrub: cp grubtemplate -r build/grub prepare: clean diff --git a/src/headers/interrupts.h b/src/headers/interrupts.h index 334a2db..c118260 100644 --- a/src/headers/interrupts.h +++ b/src/headers/interrupts.h @@ -20,7 +20,7 @@ #define ICW4_BUF_MASTER 0x0C /* Buffered mode/master */ #define ICW4_SFNM 0x10 /* Special fully nested (not) */ #define CASCADE_IRQ 2 -#define IDT_MAX_DESCRIPTORS 32 +#define IDT_MAX_DESCRIPTORS 256 typedef struct { uint16_t isr_low; // The lower 16 bits of the ISR's address @@ -34,10 +34,15 @@ typedef struct { uint32_t base; } __attribute__((packed)) idtr_t; typedef struct { - uint32_t ds; - uint32_t edi, esi, ebp, esp, ebx, edx, ecx, eax; - uint32_t int_no, err_code; - uint32_t eip, cs, eflags, useresp, ss; + uint32_t ds; + + uint32_t eax, ecx, edx, ebx; + uint32_t esp, ebp, esi, edi; + + uint32_t int_no, err_code; + + //uint32_t eip, cs, eflags; + uint32_t useresp, ss; } INT_registers_t; typedef struct { uint8_t inuse; @@ -53,7 +58,7 @@ inline void PIC_sendEOI(uint8_t irq) { void PIC_remap(int offset1, int offset2); __attribute__((noreturn)) void INT_exhand(INT_registers_t regs); -void INT_IRQ(uint8_t IRQ, INT_registers_t regs); +void INT_IRQ(INT_registers_t* regs); void idt_set_descriptor(uint8_t vector, void* isr, uint8_t flags); void idt_init(); void IRQ_registerhandler(uint8_t vector, void* callback); diff --git a/src/headers/keyboard.h b/src/headers/keyboard.h new file mode 100644 index 0000000..c0f997d --- /dev/null +++ b/src/headers/keyboard.h @@ -0,0 +1,21 @@ +#include "stddef.h" +#include "stdlib.h" + +#define KEYBOARD_cmd_setled 0xED +#define KEYBOARD_cmd_echo 0xEE +#define KEYBOARD_cmd_setscanset 0xF0 +#define KEYBOARD_cmd_enable 0xF4 +#define KEYBOARD_cmd_disable 0xF5 +#define KEYBOARD_cmd_reset 0xFF +#define KEYBOARD_resp_ACK 0xFA +#define KEYBOARD_resp_resend 0xFE +#define KEYBOARD_resp_err 0x00 +#define KEYBOARD_resp_selftestpass 0xAA +#define KEYBOARD_resp_echo 0xEE +#define KEYBOARD_resp_testfail1 0xFC +#define KEYBOARD_resp_testfail2 0xFD +#define KEYBOARD_resp_err2 0xFF +#define KEYBOARD_cqsize 128 + +extern uint8_t KEYBOARD_cmdqueue[KEYBOARD_cqsize]; +extern size_t KEYBOARD_cmdqueuesize; diff --git a/src/headers/paging.h b/src/headers/paging.h new file mode 100644 index 0000000..e69de29 diff --git a/src/headers/scheduler.h b/src/headers/scheduler.h new file mode 100644 index 0000000..a88864e --- /dev/null +++ b/src/headers/scheduler.h @@ -0,0 +1,21 @@ +#include "stddef.h" +#include "stdlib.h" + +#define SCHED_tasksize 128 +#define SCHED_freq 1000 + +typedef struct { + uint8_t inUse; + uint8_t type; + size_t ticks; + void* callback; +} task_t; + +extern task_t tasks[SCHED_tasksize]; + +void tick(); +size_t schedule_task(size_t tick, void* callback); +uint8_t schedule_sleep(size_t tick); +size_t schedule_task_fl(double time, void* callback); +uint8_t schedule_sleep_fl(double time); +task_t* schedule_getTask(size_t index); \ No newline at end of file diff --git a/src/kernel/entry.c b/src/kernel/entry.c index 491711b..1649da7 100644 --- a/src/kernel/entry.c +++ b/src/kernel/entry.c @@ -4,6 +4,7 @@ #include "../headers/graphics.h" #include "../headers/tty.h" #include "../headers/interrupts.h" +#include "../headers/scheduler.h" struct multiboot_info { uint32_t total_size; @@ -55,16 +56,17 @@ void kernel_main(struct multiboot_info* header, uint32_t magic) { } kputstr("OK\n"); - kputstr("Setting up interrupts: "); - idt_init(); - kputstr("OK\n"); - kputstr("Setting up IRQs: "); for (uint8_t i=0;i<16;i++) { idt_set_descriptor(i+0x20, irq_stub_table[i], 0x8E); + IRQ_entries[i].inuse = 0; } kputstr("OK\n"); + kputstr("Setting up interrupts: "); + idt_init(); + kputstr("OK\n"); + kputstr("Initializing PICs: "); PIC_remap(0x20,0x28); kputstr("OK\n"); @@ -73,10 +75,8 @@ void kernel_main(struct multiboot_info* header, uint32_t magic) { asm volatile("sti"); kputstr("OK\n"); - while (1) {} - kputstr("Initializing Timer: "); - uint32_t divisor = 1193180 / 1000; + uint32_t divisor = 1193180 / SCHED_freq; uint8_t low = (uint8_t)(divisor & 0xFF); uint8_t high = (uint8_t)( (divisor >> 8) & 0xFF); outb(0x43, 0x36); @@ -84,5 +84,9 @@ void kernel_main(struct multiboot_info* header, uint32_t magic) { outb(0x40, high); kputstr("OK\n"); + IRQ_registerhandler(0x00, &tick); + + + while (1) {} } \ No newline at end of file diff --git a/src/kernel/interrupts.c b/src/kernel/interrupts.c index 6a751d5..2f9c23f 100644 --- a/src/kernel/interrupts.c +++ b/src/kernel/interrupts.c @@ -72,11 +72,14 @@ void INT_exhand(INT_registers_t regs) { uitoa32(regs.int_no, temp); strcon(msg,temp); kpanic(msg); + PIC_sendEOI(regs.int_no); } -void INT_IRQ(INT_registers_t regs) { +void INT_IRQ(INT_registers_t* _regs) { + INT_registers_t regs = *_regs; if (IRQ_entries[regs.int_no].inuse) { - (void (*)(INT_registers_t))IRQ_entries[regs.int_no].callback(regs); + ((void (*)(INT_registers_t))IRQ_entries[regs.int_no].callback)(regs); } + PIC_sendEOI(regs.int_no); } void idt_init() { idtr.base = (uint32_t)&idt[0]; @@ -89,6 +92,6 @@ void idt_init() { __asm__ volatile ("lidt %0" : : "m"(idtr)); // load the new IDT } void IRQ_registerhandler(uint8_t vector, void* callback) { - IRQ_entries[vector].inuse = 1; IRQ_entries[vector].callback = callback; + IRQ_entries[vector].inuse = 1; } \ No newline at end of file diff --git a/src/kernel/scheduler.c b/src/kernel/scheduler.c new file mode 100644 index 0000000..874b0f6 --- /dev/null +++ b/src/kernel/scheduler.c @@ -0,0 +1,77 @@ +#include "../headers/scheduler.h" + +task_t tasks[SCHED_tasksize]; +uint8_t tasksbusy = 0; + +void acquiretasks() { + while (tasksbusy) {} + tasksbusy = 1; +} +void freetasks() { + tasksbusy = 0; +} +void tick() { + if (tasksbusy) {return;} + acquiretasks(); + for (size_t i=0;iinUse) { + task->inUse = 1; + task->ticks = tick; + task->callback = callback; + task->type = 0; + freetasks(); + return i+1; + } + } + freetasks(); + return 0; +} +uint8_t schedule_sleep(size_t tick) { + volatile uint8_t wait = 1; + acquiretasks(); + for (size_t i=0;iinUse) { + task->inUse = 1; + task->ticks = tick; + task->callback = &wait; + task->type = 1; + break; + } + } + freetasks(); + while (wait) {} + return 1; +} +size_t schedule_task_fl(double time, void* callback) { + return schedule_task(time*SCHED_freq, callback); +} +uint8_t schedule_sleep_fl(double time) { + return schedule_sleep(time*SCHED_freq); +} +task_t* schedule_getTask(size_t index) { + if (index == 0) {return 0x00;} + return &tasks[index-1]; +} \ No newline at end of file diff --git a/src/kernel/stdlib.c b/src/kernel/stdlib.c index e3f5182..4d61f45 100644 --- a/src/kernel/stdlib.c +++ b/src/kernel/stdlib.c @@ -34,7 +34,7 @@ void kpanic(char* msg) { for (uint16_t x=0;x