Begin task refactor
Store state using interrupt stack instead. Looks like `int 0x80` doesn't
work though, which is odd.
diff --git a/src/kernel/Jmk b/src/kernel/Jmk
index 8300fd8..0ae3053 100644
--- a/src/kernel/Jmk
+++ b/src/kernel/Jmk
@@ -44,6 +44,7 @@
syscall.o \
task.o \
task_api.o \
+ faults.o \
lib(ata_pio) \
lib(pci)
diff --git a/src/kernel/descriptor_tables.c b/src/kernel/descriptor_tables.c
index 916a1ae..94f62df 100644
--- a/src/kernel/descriptor_tables.c
+++ b/src/kernel/descriptor_tables.c
@@ -3,6 +3,7 @@
#include "log.h"
#include "pic.h"
#include "vga.h"
+#include "faults.h"
extern void gdt_flush(uint gdt);
extern void idt_flush(uint idt);
@@ -74,6 +75,8 @@
// Remap PIC
pic_remap();
+ init_faults();
+
vga_set_color(CYAN, BLACK);
for (int i = 0; i < 16; i++)
{
@@ -107,5 +110,4 @@
{
init_gdt();
init_idt();
- memset(interrupt_handlers, 0, sizeof(interrupt_handlers));
}
diff --git a/src/kernel/faults.c b/src/kernel/faults.c
new file mode 100644
index 0000000..ba5a615
--- /dev/null
+++ b/src/kernel/faults.c
@@ -0,0 +1,22 @@
+#include "pic.h"
+#include <log.h>
+
+#define DECLARE_INTERRUPT(sym, name) \
+ static void sym##_h(struct registers *regs) \
+ { \
+ kprintf("Fault " name ": eip = 0x%x, err = 0x%x\n", regs->eip, \
+ regs->error_code); \
+ asm volatile("cli"); \
+ kpanic(name); \
+ }
+
+#define ADD_INTERRUPT(sym, num) add_interrupt_handler(num, sym##_h)
+
+DECLARE_INTERRUPT(gp, "#GP")
+DECLARE_INTERRUPT(pf, "#PF")
+
+void init_faults()
+{
+ ADD_INTERRUPT(gp, 13);
+ ADD_INTERRUPT(pf, 14);
+}
diff --git a/src/kernel/faults.h b/src/kernel/faults.h
new file mode 100644
index 0000000..a85b4ec
--- /dev/null
+++ b/src/kernel/faults.h
@@ -0,0 +1,3 @@
+#pragma once
+
+void init_faults();
\ No newline at end of file
diff --git a/src/kernel/main.c b/src/kernel/main.c
index 55c562a..876c647 100644
--- a/src/kernel/main.c
+++ b/src/kernel/main.c
@@ -74,6 +74,8 @@
}
#endif
+ asm volatile("sti");
+
kprintf("initializing tasks\n");
init_tasks();
kprintf("\ndone initializing tasks\n");
@@ -88,6 +90,7 @@
test_ata_pio();
#endif
+#ifdef TEST_PCI
kprintf("Enumerating PCI devices:\n");
for (int bus = 0; bus < 0xff; bus++)
{
@@ -106,7 +109,8 @@
}
}
}
-
+#endif
+
while (true)
asm volatile("hlt");
diff --git a/src/kernel/pic.c b/src/kernel/pic.c
index 1c96543..a9a06ef 100644
--- a/src/kernel/pic.c
+++ b/src/kernel/pic.c
@@ -14,7 +14,9 @@
#define ICW4_BUF_MASTER 0x0C /* Buffered mode/master */
#define ICW4_SFNM 0x10 /* Special fully nested (not) */
-void (*interrupt_handlers[256])(struct registers *);
+typedef void (*interrupt_handler_t)(struct registers *);
+
+static interrupt_handler_t interrupt_handlers[256];
void pic_send_eoi(uchar interrupt)
{
@@ -60,5 +62,5 @@
outb(0x21, 0x0);
outb(0xA1, 0x0);
- return;
+ memset(interrupt_handlers, 0, sizeof(interrupt_handlers));
}
diff --git a/src/kernel/task.c b/src/kernel/task.c
index 4d740cf..53a31e6 100644
--- a/src/kernel/task.c
+++ b/src/kernel/task.c
@@ -3,14 +3,31 @@
#include "io.h"
#include "log.h"
#include "paging.h"
+#include "pic.h"
struct process processes[1024] = {0};
struct ll_task_i *first_task = NULL, *last_task = NULL, *current_task = NULL;
static uint next_task_id = 0;
+bool tasks_initialized = false;
+
+void _init_tasks(uint kernel_esp, uint kernel_ebp, uint kernel_eip);
+
+void init_tasks()
+{
+ add_interrupt_handler(INIT_TASKS_INTERRUPT, _sys_init_tasks_h);
+
+ asm("int $0x80");
+}
+
+void _sys_init_tasks_h(struct registers *regs)
+{
+ _init_tasks(regs->esp, regs->ebp, regs->eip);
+}
+
void _init_tasks(uint kernel_esp, uint kernel_ebp, uint kernel_eip)
{
- kprintf("_init_tasks\n");
+ kpanic("_init_tasks\n");
processes[0] = (struct process){
.exists = true,
@@ -42,6 +59,8 @@
};
kprintf("Returning from _init_tasks\n");
+
+ tasks_initialized = true;
}
struct process *get_process(uint pid)
diff --git a/src/kernel/task.h b/src/kernel/task.h
index ce5b04c..487c143 100644
--- a/src/kernel/task.h
+++ b/src/kernel/task.h
@@ -3,6 +3,10 @@
#include "kint.h"
#include "registers.h"
+#define INIT_TASKS_INTERRUPT 0x81
+
+extern bool tasks_initialized;
+
struct process
{
bool exists;
@@ -34,7 +38,8 @@
// extern struct process processes[1024];
// extern struct ll_task_i *first_task, *current_task;
-extern void init_tasks();
+// Note: interrupts must be enabled BEFORE this for it to work.
+void init_tasks();
struct process *get_process(uint pid);
int get_process_id();
@@ -47,3 +52,4 @@
void kill_this_thread();
extern void switch_task();
void switch_to_task(struct task *task);
+void _sys_init_tasks_h(struct registers *regs);
diff --git a/src/kernel/task_api.s b/src/kernel/task_api.s
index 1673866..01f3ca4 100644
--- a/src/kernel/task_api.s
+++ b/src/kernel/task_api.s
@@ -30,15 +30,3 @@
mov cr3, ecx ; Set page directory
sti
jmp eax ; Jump back to code
-
- [extern _init_tasks]
- [global init_tasks]
-init_tasks:
- lea eax, [esp + 4] ; Stack pointer before call
- mov ebx, [esp] ; Return address
- push ebx ; eip
- push ebp ; ebp
- push eax ; esp
- call _init_tasks
- add esp, 12
- ret
diff --git a/src/kernel/timer.c b/src/kernel/timer.c
index 8ed0be8..be177f9 100644
--- a/src/kernel/timer.c
+++ b/src/kernel/timer.c
@@ -9,8 +9,11 @@
static void timer_cb(struct registers *regs)
{
- // Preemptive multitasking!
- switch_task();
+ if (tasks_initialized)
+ {
+ // Preemptive multitasking!
+ switch_task();
+ }
}
void init_timer(uint hz)