getting there...

This commit is contained in:
2026-07-04 00:26:20 -05:00
parent ab5a1ecb6b
commit 0b98ac0273
6 changed files with 49 additions and 61 deletions

View File

@@ -46,27 +46,11 @@ isr32:
cli cli
pushal pushal
xorl %eax, %eax
movw %ds, %ax
pushl %eax
movw $0x10, %ax # Load Kernel Data Segment descriptor
movw %ax, %ds
movw %ax, %es
movw %ax, %fs
movw %ax, %gs
call send_eoi_master
pushl %esp pushl %esp
call switch_context call switch_context
movl %eax, %esp movl %eax, %esp
popl %eax call send_eoi_master
movw %ax, %ds
movw %ax, %es
movw %ax, %fs
movw %ax, %gs
popal popal
sti sti

View File

@@ -2,8 +2,11 @@
#include <lib/print.h> #include <lib/print.h>
#include "process.h"
#include "scheduler.h"
#include "syscall.h" #include "syscall.h"
#include "common.h" #include "common.h"
#include "gdt.h"
#include <drivers/pic/pic.h> #include <drivers/pic/pic.h>
#include <drivers/ps2/ps2.h> #include <drivers/ps2/ps2.h>
@@ -27,13 +30,13 @@ typedef struct __attribute__((packed)) {
} idt_ptr; } idt_ptr;
typedef struct __attribute__((packed)) { typedef struct __attribute__((packed)) {
uint32_t edi, esi, ebp, esp_dummy, ebx, edx, ecx, eax; uint32_t edi, esi, ebp, dummy, ebx, edx, ecx, eax;
uint32_t int_no; uint32_t int_no;
uint32_t error_code; uint32_t error_code;
uint32_t eip, cs, eflags, useresp, ss; uint32_t eip, cs, eflags, u_esp, u_ss;
} registers; } intr_regs_t;
// (interrupts.S) // (interrupts.S)
extern void load_idt(void); extern void load_idt(void);
@@ -57,7 +60,9 @@ static void* isr_stub_table[256] = {
static const char* err_messages[32] = { static const char* err_messages[32] = {
[0] = "Divide by 0", [0] = "Divide by 0",
[1] = "", [1] = "Debug",
[4] = "Overflow",
[6] = "Undefined Opcode",
[8] = "", [8] = "",
[13] = "General Protection Fault", [13] = "General Protection Fault",
[14] = "Page Fault", [14] = "Page Fault",
@@ -93,7 +98,7 @@ void init_idt() {
load_idt(); load_idt();
} }
void common_interrupt_handler(registers *args) { void common_interrupt_handler(intr_regs_t *args) {
switch (args->int_no) { switch (args->int_no) {
case 0: case 0:
case 1: case 1:
@@ -111,14 +116,20 @@ void common_interrupt_handler(registers *args) {
case 13: case 13:
case 15: case 15:
case 16: case 16:
kprintf("CPU Error: [%d]%s\n", args->int_no, err_messages[args->int_no]); asm volatile("cli");
kprintf("\n--- CPU Exception ---\n");
kprintf("Error: [%d] %s\n", args->int_no, err_messages[args->int_no]);
kprintf("Error Code: 0x%x\n", args->error_code); kprintf("Error Code: 0x%x\n", args->error_code);
kprintf("Instruction Pointer: 0x%x\n", args->eip); kprintf("Instruction Pointer: 0x%x\n", args->eip);
kprintf("Stack Pointer: 0x%x\n", args->useresp); kprintf("Current Stack Pointer: 0x%x\n", (void*)args);
kprintf("EAX: 0x%x\n", args->eax); kprintf("EAX: 0x%x\n", args->eax);
kprintf("EFLAGS: 0x%x\n", args->eflags); kprintf("EFLAGS: 0x%x\n", args->eflags);
kprintf("cr3: 0x%x\n", fetch_cr3()); kprintf("Code Segment: 0x%x\n", args->cs);
while(1); kprintf("Current cr3: 0x%x\n", fetch_cr3());
kprintf("tss.esp0: 0x%x\n", tss.esp0);
process_t* task = current_task();
kprintf("Task kstack_top: 0x%x\n", task->kstack_top);
asm volatile("hlt");
break; break;
case 14:{ case 14:{
uint32_t faulting_address; uint32_t faulting_address;
@@ -127,14 +138,20 @@ void common_interrupt_handler(registers *args) {
kprintf("Faulted Virtual Address: 0x%x\n", faulting_address); kprintf("Faulted Virtual Address: 0x%x\n", faulting_address);
kprintf("Error Code: 0x%x\n", args->error_code); kprintf("Error Code: 0x%x\n", args->error_code);
kprintf("Instruction Pointer: 0x%x\n", args->eip); kprintf("Instruction Pointer: 0x%x\n", args->eip);
kprintf("Stack Pointer: 0x%x\n", args->useresp); kprintf("Current Stack Pointer: 0x%x\n", (void*)args);
kprintf("EAX: 0x%x\n", args->eax); kprintf("EAX: 0x%x\n", args->eax);
kprintf("EFLAGS: 0x%x\n", args->eflags); kprintf("EFLAGS: 0x%x\n", args->eflags);
kprintf("Code Segment: 0x%x\n", args->cs);
kprintf("Current cr3: 0x%x\n", fetch_cr3());
if (args->cs == 0x1b) {
kprintf("User ESP: 0x%x\n", args->u_esp);
kprintf("User SS: 0x%x\n", args->u_ss);
}
kprintf("Caused by: %s, %s, running in %s mode\n", kprintf("Caused by: %s, %s, running in %s mode\n",
(args->error_code & 0x01) ? "Protection Violation" : "Page Not Present", (args->error_code & 0x01) ? "Protection Violation" : "Page Not Present",
(args->error_code & 0x02) ? "Write" : "Read", (args->error_code & 0x02) ? "Write" : "Read",
(args->error_code & 0x04) ? "User" : "Supervisor"); (args->error_code & 0x04) ? "User" : "Supervisor");
while(1); asm volatile("hlt");
break; break;
} }
case 33: { case 33: {

View File

@@ -59,7 +59,6 @@ vfs_node_t* load_initrd() {
void load_root_program(const char* path) { void load_root_program(const char* path) {
uint32_t kernel_cr3 = fetch_cr3(); uint32_t kernel_cr3 = fetch_cr3();
void* cr3 = create_task_pd(); void* cr3 = create_task_pd();
kprintf("new task cr3 0x%x\n", cr3);
load_pd(cr3); load_pd(cr3);
flush_tlb(); flush_tlb();
@@ -170,7 +169,7 @@ void kmain(uint32_t magic, multiboot_info* mbi) {
disable_interrupts(); disable_interrupts();
init_scheduler(); init_scheduler();
enable_interrupts();
load_root_program("/origin.elf"); load_root_program("/origin.elf");
kprintf("done loading origin program\n");
enable_interrupts();
} }

View File

@@ -4,10 +4,10 @@
#include <stdint.h> #include <stdint.h>
typedef enum { typedef enum {
STATE_READY, STATE_READY = 1,
STATE_SLEEPING, STATE_SLEEPING = 2,
STATE_BLOCKED, STATE_BLOCKED = 3,
STATE_DEAD STATE_DEAD = 4,
} process_state_t; } process_state_t;
typedef enum { typedef enum {

View File

@@ -67,19 +67,25 @@ uint32_t switch_context(uint32_t current_esp) {
current_process = next_process; current_process = next_process;
uint32_t current_cr3 = fetch_cr3();
if (current_cr3 != process_table[current_process].cr3) {
kprintf("switching cr3 | old: 0x%x | new: 0x%x\n", current_cr3, process_table[current_process].cr3);
load_pd((void*)process_table[current_process].cr3);
}
if (process_table[current_process].flags & PROCESS_FLAG_USER) { if (process_table[current_process].flags & PROCESS_FLAG_USER) {
tss.esp0 = process_table[current_process].kstack_top; tss.esp0 = process_table[current_process].kstack_top;
} }
if (fetch_cr3() != process_table[current_process].cr3) { if (found_ready) {
load_pd((void*)process_table[current_process].cr3); kprintf("found ready task %d | cr3: 0x%x\n", current_process, process_table[current_process].cr3);
} }
return process_table[current_process].esp; return process_table[current_process].esp;
} }
void init_scheduler() { void init_scheduler() {
process_table = kalloc(16 * sizeof(process_t)); process_table = kalloc(16 * sizeof(process_t));
memset((void*)process_table, 0, 16 * sizeof(process_t));
total_processes = 0; total_processes = 0;
process_t* process = &process_table[total_processes]; process_t* process = &process_table[total_processes];
@@ -99,25 +105,15 @@ int create_task(uint32_t entry_point, uint32_t cr3, int user, uint32_t u_esp) {
return 0; return 0;
} }
lock_scheduler();
// default to a new task, but if we find a dead one, re use it // default to a new task, but if we find a dead one, re use it
int reuse = 0;
process_t* process = &process_table[total_processes]; process_t* process = &process_table[total_processes];
uint32_t pid = total_processes; uint32_t pid = total_processes;
for (uint32_t i = 0; i < total_processes; i++) {
if (process_table[i].state == STATE_DEAD) {
process = &process_table[i];
pid = i;
reuse = 1;
}
}
process->pid = pid; process->pid = pid;
process->cr3 = cr3; process->cr3 = cr3;
process->state = STATE_READY; process->state = STATE_READY;
process->sleep = 0; process->sleep = 0;
process->flags = user ? PROCESS_FLAG_USER : PROCESS_FLAG_KERNEL; process->flags = user ? PROCESS_FLAG_USER : PROCESS_FLAG_KERNEL;
total_processes++;
void* kstack_bottom = kalloc(PAGE_SIZE); void* kstack_bottom = kalloc(PAGE_SIZE);
uint32_t kstack_top = (uint32_t)kstack_bottom + PAGE_SIZE; uint32_t kstack_top = (uint32_t)kstack_bottom + PAGE_SIZE;
@@ -130,13 +126,11 @@ int create_task(uint32_t entry_point, uint32_t cr3, int user, uint32_t u_esp) {
*(--esp) = 0x0202; // EFLAGS (Interrupts enabled) *(--esp) = 0x0202; // EFLAGS (Interrupts enabled)
*(--esp) = 0x1B; // User Code Segment (CS) with RPL 3 (0x18 | 3) *(--esp) = 0x1B; // User Code Segment (CS) with RPL 3 (0x18 | 3)
*(--esp) = entry_point; // EIP *(--esp) = entry_point; // EIP
*(--esp) = 0x23;
} else { } else {
// IRET values for Ring 0 // IRET values for Ring 0
*(--esp) = 0x0202; // EFLAGS *(--esp) = 0x0202; // EFLAGS
*(--esp) = 0x08; // Kernel Code Segment (CS) *(--esp) = 0x08; // Kernel Code Segment (CS)
*(--esp) = entry_point; // EIP *(--esp) = entry_point; // EIP
*(--esp) = 0x10;
} }
*(--esp) = 0; // EAX *(--esp) = 0; // EAX
@@ -149,17 +143,11 @@ int create_task(uint32_t entry_point, uint32_t cr3, int user, uint32_t u_esp) {
*(--esp) = 0; // EDI *(--esp) = 0; // EDI
process->esp = (uint32_t)esp; process->esp = (uint32_t)esp;
if (!reuse) {
total_processes++;
}
unlock_scheduler();
return 1; return 1;
} }
process_t* current_task() { process_t* current_task() {
lock_scheduler();
process_t* rtn = &process_table[current_process]; process_t* rtn = &process_table[current_process];
unlock_scheduler();
return rtn; return rtn;
} }

View File

@@ -13,7 +13,7 @@ _start:
push %ecx push %ecx
push %ebx push %ebx
push %eax push %eax
1: jmp 1b
call main call main
push %eax push %eax