finished interrupts for now and a basic scheduler for that, start implementation on paging.

This commit is contained in:
Justus Wolff
2026-04-01 16:45:33 +02:00
parent f719733428
commit ef151a8385
10 changed files with 169 additions and 25 deletions

View File

@@ -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/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/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/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 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 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/linked build/grub/boot/kernel # copy kernel over to grub template
cp build/initrd build/grub/boot/JPOS.initrd # copy initrd 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 test: build
qemu-system-i386 \ qemu-system-i386 \
-boot d \ -boot d \
-cdrom build/live.iso -cdrom build/live.iso \
-d int
copygrub: copygrub:
cp grubtemplate -r build/grub cp grubtemplate -r build/grub
prepare: clean prepare: clean

View File

@@ -20,7 +20,7 @@
#define ICW4_BUF_MASTER 0x0C /* Buffered mode/master */ #define ICW4_BUF_MASTER 0x0C /* Buffered mode/master */
#define ICW4_SFNM 0x10 /* Special fully nested (not) */ #define ICW4_SFNM 0x10 /* Special fully nested (not) */
#define CASCADE_IRQ 2 #define CASCADE_IRQ 2
#define IDT_MAX_DESCRIPTORS 32 #define IDT_MAX_DESCRIPTORS 256
typedef struct { typedef struct {
uint16_t isr_low; // The lower 16 bits of the ISR's address uint16_t isr_low; // The lower 16 bits of the ISR's address
@@ -35,9 +35,14 @@ typedef struct {
} __attribute__((packed)) idtr_t; } __attribute__((packed)) idtr_t;
typedef struct { typedef struct {
uint32_t ds; uint32_t ds;
uint32_t edi, esi, ebp, esp, ebx, edx, ecx, eax;
uint32_t eax, ecx, edx, ebx;
uint32_t esp, ebp, esi, edi;
uint32_t int_no, err_code; uint32_t int_no, err_code;
uint32_t eip, cs, eflags, useresp, ss;
//uint32_t eip, cs, eflags;
uint32_t useresp, ss;
} INT_registers_t; } INT_registers_t;
typedef struct { typedef struct {
uint8_t inuse; uint8_t inuse;
@@ -53,7 +58,7 @@ inline void PIC_sendEOI(uint8_t irq) {
void PIC_remap(int offset1, int offset2); void PIC_remap(int offset1, int offset2);
__attribute__((noreturn)) __attribute__((noreturn))
void INT_exhand(INT_registers_t regs); 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_set_descriptor(uint8_t vector, void* isr, uint8_t flags);
void idt_init(); void idt_init();
void IRQ_registerhandler(uint8_t vector, void* callback); void IRQ_registerhandler(uint8_t vector, void* callback);

21
src/headers/keyboard.h Normal file
View File

@@ -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;

0
src/headers/paging.h Normal file
View File

21
src/headers/scheduler.h Normal file
View File

@@ -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);

View File

@@ -4,6 +4,7 @@
#include "../headers/graphics.h" #include "../headers/graphics.h"
#include "../headers/tty.h" #include "../headers/tty.h"
#include "../headers/interrupts.h" #include "../headers/interrupts.h"
#include "../headers/scheduler.h"
struct multiboot_info { struct multiboot_info {
uint32_t total_size; uint32_t total_size;
@@ -55,16 +56,17 @@ void kernel_main(struct multiboot_info* header, uint32_t magic) {
} }
kputstr("OK\n"); kputstr("OK\n");
kputstr("Setting up interrupts: ");
idt_init();
kputstr("OK\n");
kputstr("Setting up IRQs: "); kputstr("Setting up IRQs: ");
for (uint8_t i=0;i<16;i++) { for (uint8_t i=0;i<16;i++) {
idt_set_descriptor(i+0x20, irq_stub_table[i], 0x8E); idt_set_descriptor(i+0x20, irq_stub_table[i], 0x8E);
IRQ_entries[i].inuse = 0;
} }
kputstr("OK\n"); kputstr("OK\n");
kputstr("Setting up interrupts: ");
idt_init();
kputstr("OK\n");
kputstr("Initializing PICs: "); kputstr("Initializing PICs: ");
PIC_remap(0x20,0x28); PIC_remap(0x20,0x28);
kputstr("OK\n"); kputstr("OK\n");
@@ -73,10 +75,8 @@ void kernel_main(struct multiboot_info* header, uint32_t magic) {
asm volatile("sti"); asm volatile("sti");
kputstr("OK\n"); kputstr("OK\n");
while (1) {}
kputstr("Initializing Timer: "); kputstr("Initializing Timer: ");
uint32_t divisor = 1193180 / 1000; uint32_t divisor = 1193180 / SCHED_freq;
uint8_t low = (uint8_t)(divisor & 0xFF); uint8_t low = (uint8_t)(divisor & 0xFF);
uint8_t high = (uint8_t)( (divisor >> 8) & 0xFF); uint8_t high = (uint8_t)( (divisor >> 8) & 0xFF);
outb(0x43, 0x36); outb(0x43, 0x36);
@@ -84,5 +84,9 @@ void kernel_main(struct multiboot_info* header, uint32_t magic) {
outb(0x40, high); outb(0x40, high);
kputstr("OK\n"); kputstr("OK\n");
IRQ_registerhandler(0x00, &tick);
while (1) {} while (1) {}
} }

View File

@@ -72,11 +72,14 @@ void INT_exhand(INT_registers_t regs) {
uitoa32(regs.int_no, temp); uitoa32(regs.int_no, temp);
strcon(msg,temp); strcon(msg,temp);
kpanic(msg); 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) { 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() { void idt_init() {
idtr.base = (uint32_t)&idt[0]; idtr.base = (uint32_t)&idt[0];
@@ -89,6 +92,6 @@ void idt_init() {
__asm__ volatile ("lidt %0" : : "m"(idtr)); // load the new IDT __asm__ volatile ("lidt %0" : : "m"(idtr)); // load the new IDT
} }
void IRQ_registerhandler(uint8_t vector, void* callback) { void IRQ_registerhandler(uint8_t vector, void* callback) {
IRQ_entries[vector].inuse = 1;
IRQ_entries[vector].callback = callback; IRQ_entries[vector].callback = callback;
IRQ_entries[vector].inuse = 1;
} }

77
src/kernel/scheduler.c Normal file
View File

@@ -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;i<SCHED_tasksize;i++) {
if (tasks[i].inUse) {
tasks[i].ticks --;
if (tasks[i].ticks == 0) {
tasks[i].inUse = 0;
if (tasks[i].type == 0) { // callback
((void (*)())tasks[i].callback)();
} else if (tasks[i].type == 1) { // reset
*(uint8_t*)tasks[i].callback = 0;
}
}
}
}
freetasks();
}
size_t schedule_task(size_t tick, void* callback) {
acquiretasks();
for (size_t i=0;i<SCHED_tasksize;i++) {
task_t* task = &tasks[i];
if (!task->inUse) {
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;i<SCHED_tasksize+1;i++) {
if (i == SCHED_tasksize) {
freetasks();
return 0;
}
task_t* task = &tasks[i];
if (!task->inUse) {
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];
}

View File

@@ -34,7 +34,7 @@ void kpanic(char* msg) {
for (uint16_t x=0;x<VGA_sizex;x++) { for (uint16_t x=0;x<VGA_sizex;x++) {
for (uint16_t y=0;y<VGA_sizey;y++) { for (uint16_t y=0;y<VGA_sizey;y++) {
VGA_setpix(x,y,(VGA_pixel){0x00,0xFF,0x00}); VGA_setpix(x,y,(VGA_pixel){(uint32_t)msg+x+(y*VGA_sizex)*3,(uint32_t)msg+x+(y*VGA_sizex)*3+1,(uint32_t)msg+x+(y*VGA_sizex)*3+2});
} }
} }
size_t x=0; size_t x=0;

View File

@@ -3,18 +3,18 @@ extern INT_IRQ
%macro isr_err_stub 1 %macro isr_err_stub 1
isr_stub_%+%1: isr_stub_%+%1:
cli
push 0 push 0
push %1 push %1
pusha pusha
mov ax, ds mov ax, ds
push eax push eax
mov ax, 0x08 mov ax, 0x10
mov ds, ax mov ds, ax
mov es, ax mov es, ax
mov fs, ax mov fs, ax
mov gs, ax mov gs, ax
call INT_exhand call INT_exhand
pop eax pop eax
@@ -24,12 +24,13 @@ isr_stub_%+%1:
mov gs, ax mov gs, ax
popa popa
add esp, 8 add esp, 8
sti
iret iret
%endmacro %endmacro
%macro isr_no_err_stub 1 %macro isr_no_err_stub 1
isr_stub_%+%1: isr_stub_%+%1:
cli
;call INT_exhand ;call INT_exhand
sti sti
iret iret
@@ -37,18 +38,26 @@ isr_stub_%+%1:
%macro irq_stub 1 %macro irq_stub 1
irq_stub_%+%1: irq_stub_%+%1:
cli
push 0 push 0
push %1 push %1
pusha pusha
xor eax, eax
mov ax, ds mov ax, ds
push eax push eax
mov ax, 0x08 mov ax, 0x10
mov ds, ax mov ds, ax
mov es, ax mov es, ax
mov fs, ax mov fs, ax
mov gs, ax mov gs, ax
mov eax, esp
push eax
call INT_IRQ call INT_IRQ
add esp, 4
pop ebx pop ebx
mov ds, bx mov ds, bx
mov es, bx mov es, bx
@@ -56,6 +65,8 @@ irq_stub_%+%1:
mov gs, bx mov gs, bx
popa popa
add esp, 8 add esp, 8
sti
iret
%endmacro %endmacro
isr_no_err_stub 0 isr_no_err_stub 0