Begin task refactor
Store state using interrupt stack instead. Looks like `int 0x80` doesn't
work though, which is odd.
diff --git a/.gitignore b/.gitignore
index 2856816..6661bef 100644
--- a/.gitignore
+++ b/.gitignore
@@ -13,6 +13,5 @@
**/Jmk.options
.gitignore
.idea
-.vscode
**/.#*
src/kernel/dri/pci/vendors.c
\ No newline at end of file
diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json
new file mode 100644
index 0000000..1552d82
--- /dev/null
+++ b/.vscode/c_cpp_properties.json
@@ -0,0 +1,23 @@
+{
+ "configurations": [
+ {
+ "name": "Bluejay",
+ "includePath": [
+ "${workspaceFolder}/**",
+ "${workspaceFolder}/include",
+ "${workspaceFolder}/include/kernel",
+ "${workspaceFolder}/src/kernel"
+ ],
+ "defines": [],
+ "compilerPath": "/usr/bin/gcc",
+ "cStandard": "c11",
+ // "cppStandard": "c++14",
+ "intelliSenseMode": "linux-gcc-x86",
+ // "compileCommands": "${workspaceFolder}/compile_commands.json",
+ "compilerArgs": [
+ "-nostdinc -nostdlib -O2 -m32 -g"
+ ]
+ }
+ ],
+ "version": 4
+}
\ No newline at end of file
diff --git a/.vscode/launch.json b/.vscode/launch.json
new file mode 100644
index 0000000..57b1c71
--- /dev/null
+++ b/.vscode/launch.json
@@ -0,0 +1,18 @@
+{
+ // Use IntelliSense to learn about possible attributes.
+ // Hover to view descriptions of existing attributes.
+ // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
+ "version": "0.2.0",
+ "configurations": [
+ {
+ "type": "gdb",
+ "request": "attach",
+ "name": "Attach to QEMU",
+ "executable": "./src/kernel/kernel.elf",
+ "target": ":1234",
+ "remote": true,
+ "cwd": "${workspaceRoot}",
+ "valuesFormatting": "parseText",
+ }
+ ]
+}
\ No newline at end of file
diff --git a/.vscode/tasks.json b/.vscode/tasks.json
new file mode 100644
index 0000000..3ca0ef0
--- /dev/null
+++ b/.vscode/tasks.json
@@ -0,0 +1,17 @@
+{
+ // See https://go.microsoft.com/fwlink/?LinkId=733558
+ // for the documentation about the tasks.json format
+ "version": "2.0.0",
+ "tasks": [
+ {
+ "label": "qemu:build",
+ "type": "shell",
+ "command": "make -C src/kernel/ debug-wait",
+ "problemMatcher": [],
+ "group": {
+ "kind": "build",
+ "isDefault": true
+ }
+ }
+ ],
+}
\ No newline at end of file
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)