sched, interrupts: Now recovers from a userspace exception.

This commit is contained in:
RaphProductions 2025-05-17 11:36:36 +02:00
parent 0652010b1c
commit 30017592ad
5 changed files with 73 additions and 22 deletions

View file

@ -7,6 +7,7 @@
#include <arch/x86_64/idt.h> #include <arch/x86_64/idt.h>
#include <stdbool.h> #include <stdbool.h>
#include <sys/log.h> #include <sys/log.h>
#include <sched/sched.h>
__attribute__((aligned(0x10))) static idt_entry_t idt[256]; __attribute__((aligned(0x10))) static idt_entry_t idt[256];
@ -65,6 +66,17 @@ void idt_int_handler(registers_t *regs) {
// log("kernel - Interrupt %d\n", regs->int_no); // log("kernel - Interrupt %d\n", regs->int_no);
if (regs->int_no < 32) { if (regs->int_no < 32) {
if (regs->cs == 0x43) {
log("ints - Process \"%s\" (pid: %d) caused a CPU fault: %d (err: %d, IP: %p)\n",
curr_proc->name, curr_proc->pid, regs->int_no, regs->err_code, regs->rip);
sched_exit(-144);
return;
//asm("cli");
//while (1)
// asm("hlt");
}
panic_ctx("A CPU exception occured.", regs); panic_ctx("A CPU exception occured.", regs);
} }

View file

@ -4,6 +4,7 @@
#include "mm/memop.h" #include "mm/memop.h"
#include "mm/pmm.h" #include "mm/pmm.h"
#include "mm/vmm.h" #include "mm/vmm.h"
#include "sys/errhnd/panic.h"
#include "sys/log.h" #include "sys/log.h"
#include <lib/string.h> #include <lib/string.h>
#include <mm/liballoc/liballoc.h> #include <mm/liballoc/liballoc.h>
@ -28,6 +29,18 @@ void map_range_to_pagemap(pagemap_t *dest_pagemap, pagemap_t *src_pagemap,
} }
} }
static void __sched_enter_standby() {
standby = 1;
log("sched - As there's nothing "
"to schedule, the scheduler entered standby"
"mode.\n");
}
static void __sched_exit_standby() {
standby = 0;
log("sched - The scheduler exited standby mode.\n");
}
void sched_init() { void sched_init() {
// TODO: It may be good to implement heap memory to save space. // TODO: It may be good to implement heap memory to save space.
@ -41,11 +54,7 @@ void sched_init() {
proc_list->pm = vmm_kernel_pm; proc_list->pm = vmm_kernel_pm;
curr_proc = proc_list; curr_proc = proc_list;
__sched_enter_standby();
standby = 1;
log("sched - As there's nothing "
"to schedule, the scheduler entered standby"
"mode.\n");
} }
sched_process *sched_create(char *name, uint64_t entry_point, pagemap_t *pm, sched_process *sched_create(char *name, uint64_t entry_point, pagemap_t *pm,
@ -107,11 +116,7 @@ sched_process *sched_create(char *name, uint64_t entry_point, pagemap_t *pm,
VMM_PRESENT | VMM_WRITABLE); VMM_PRESENT | VMM_WRITABLE);
if (standby) { if (standby) {
// Disable standby mode as there's actually something to __sched_exit_standby();
// run, now.
standby = 0;
log("sched - Standby mode has been"
"disabled.\n");
} }
log("sched - created process '%s' (pid: %d, rip: %p)\n", proc->name, log("sched - created process '%s' (pid: %d, rip: %p)\n", proc->name,
@ -124,7 +129,7 @@ sched_process *sched_from_program(program_t *prog) {
return sched_create("unknown program", prog->entry, prog->pm, SCHED_USER_PROCESS); return sched_create("unknown program", prog->entry, prog->pm, SCHED_USER_PROCESS);
} }
void sched_exit(int exit_code) { void sched_exit(int exit_code) {
log("sched - Process %d exited with code %d!", curr_proc->pid, exit_code); log("sched - Process %d exited with code %d!\n", curr_proc->pid, exit_code);
curr_proc->type = SCHED_DIED; curr_proc->type = SCHED_DIED;
schedule(&curr_proc->regs); schedule(&curr_proc->regs);
} }
@ -135,30 +140,63 @@ void schedule(registers_t *regs) {
return; return;
} }
memcpy(&curr_proc->regs, regs, sizeof(registers_t)); if (curr_proc->type != SCHED_DIED) {
memcpy(&curr_proc->regs, regs, sizeof(registers_t));
}
if (curr_proc->type == SCHED_DIED) { if (curr_proc->type == SCHED_DIED) {
sched_process *prev_proc = proc_list; sched_process *prev_proc = proc_list;
sched_process *next = curr_proc->next;
if (next == NULL) {
next = proc_list;
}
if (proc_list == curr_proc) {
goto kill_process;
}
while (prev_proc->next != curr_proc) { while (prev_proc->next != curr_proc) {
prev_proc = prev_proc->next; prev_proc = prev_proc->next;
} }
prev_proc->next = curr_proc->next; kill_process:
if (next == NULL) {
next = proc_list;
}
if (proc_list == curr_proc) {
vmm_release_pm(curr_proc->pm);
pmm_free_page(curr_proc->stack_base_physical);
free(curr_proc);
__sched_enter_standby();
return;
}
prev_proc->next = next;
vmm_release_pm(curr_proc->pm); vmm_release_pm(curr_proc->pm);
pmm_free_page(curr_proc->stack_base_physical); pmm_free_page(curr_proc->stack_base_physical);
free(curr_proc);
// R.I.P. process curr_proc = next;
pmm_free_page(curr_proc); } else {
curr_proc = curr_proc->next;
return; if (curr_proc == NULL)
curr_proc = proc_list;
} }
curr_proc = curr_proc->next; if (curr_proc->type == SCHED_RUNNING) {
if (curr_proc == NULL) memcpy(regs, &curr_proc->regs, sizeof(registers_t));
curr_proc = proc_list; } else if (curr_proc->type == SCHED_EMPTY) {
memset(regs, 0, sizeof(registers_t));
memcpy(regs, &curr_proc->regs, sizeof(registers_t)); regs->cs = 0x28;
regs->ss = 0x30;
regs->rflags = 0x202;
regs->rip = 0;
} else {
panic("sched - Tried to schedule a dead process.\n");
}
wrmsr(IA32_GS_KERNEL_MSR, (uint64_t)curr_proc); wrmsr(IA32_GS_KERNEL_MSR, (uint64_t)curr_proc);
// log("sched - proc %d\n", curr_proc->pid); // log("sched - proc %d\n", curr_proc->pid);

Binary file not shown.

View file

@ -8,6 +8,7 @@ _start:
mov rdi, 1 ; stdout file descriptor mov rdi, 1 ; stdout file descriptor
mov rsi, msg ; pointer to message mov rsi, msg ; pointer to message
mov rdx, msg_len ; message length mov rdx, msg_len ; message length
hlt
syscall syscall
.loop: .loop:

Binary file not shown.