diff --git a/kernel/interrupts.S b/kernel/interrupts.S index 145fcdd..e8336e8 100644 --- a/kernel/interrupts.S +++ b/kernel/interrupts.S @@ -45,28 +45,12 @@ ISR_ERRCODE 14 # Page Fault (Has Error Code!) isr32: cli 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 call switch_context movl %eax, %esp - popl %eax - movw %ax, %ds - movw %ax, %es - movw %ax, %fs - movw %ax, %gs + call send_eoi_master popal sti diff --git a/kernel/interrupts.c b/kernel/interrupts.c index 7f7d78d..57e4805 100644 --- a/kernel/interrupts.c +++ b/kernel/interrupts.c @@ -2,8 +2,11 @@ #include +#include "process.h" +#include "scheduler.h" #include "syscall.h" #include "common.h" +#include "gdt.h" #include #include @@ -27,13 +30,13 @@ typedef struct __attribute__((packed)) { } idt_ptr; 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 error_code; - uint32_t eip, cs, eflags, useresp, ss; -} registers; + uint32_t eip, cs, eflags, u_esp, u_ss; +} intr_regs_t; // (interrupts.S) extern void load_idt(void); @@ -57,7 +60,9 @@ static void* isr_stub_table[256] = { static const char* err_messages[32] = { [0] = "Divide by 0", - [1] = "", + [1] = "Debug", + [4] = "Overflow", + [6] = "Undefined Opcode", [8] = "", [13] = "General Protection Fault", [14] = "Page Fault", @@ -93,7 +98,7 @@ void init_idt() { load_idt(); } -void common_interrupt_handler(registers *args) { +void common_interrupt_handler(intr_regs_t *args) { switch (args->int_no) { case 0: case 1: @@ -111,14 +116,20 @@ void common_interrupt_handler(registers *args) { case 13: case 15: 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("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("EFLAGS: 0x%x\n", args->eflags); - kprintf("cr3: 0x%x\n", fetch_cr3()); - while(1); + kprintf("Code Segment: 0x%x\n", args->cs); + 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; case 14:{ uint32_t faulting_address; @@ -127,14 +138,20 @@ void common_interrupt_handler(registers *args) { kprintf("Faulted Virtual Address: 0x%x\n", faulting_address); kprintf("Error Code: 0x%x\n", args->error_code); 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("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", (args->error_code & 0x01) ? "Protection Violation" : "Page Not Present", (args->error_code & 0x02) ? "Write" : "Read", (args->error_code & 0x04) ? "User" : "Supervisor"); - while(1); + asm volatile("hlt"); break; } case 33: { diff --git a/kernel/kmain.c b/kernel/kmain.c index 1d08ffa..3f558df 100644 --- a/kernel/kmain.c +++ b/kernel/kmain.c @@ -59,7 +59,6 @@ vfs_node_t* load_initrd() { void load_root_program(const char* path) { uint32_t kernel_cr3 = fetch_cr3(); void* cr3 = create_task_pd(); - kprintf("new task cr3 0x%x\n", cr3); load_pd(cr3); flush_tlb(); @@ -130,7 +129,7 @@ void load_root_program(const char* path) { *(--u_esp) = 0; // argc = 0 create_task(e_hdr->e_entry, (uint32_t)cr3, 1, (uint32_t)u_esp); - + load_pd((void*)kernel_cr3); flush_tlb(); } @@ -170,7 +169,7 @@ void kmain(uint32_t magic, multiboot_info* mbi) { disable_interrupts(); init_scheduler(); - enable_interrupts(); - load_root_program("/origin.elf"); + kprintf("done loading origin program\n"); + enable_interrupts(); } diff --git a/kernel/process.h b/kernel/process.h index 3dd028e..95e58e5 100644 --- a/kernel/process.h +++ b/kernel/process.h @@ -4,10 +4,10 @@ #include typedef enum { - STATE_READY, - STATE_SLEEPING, - STATE_BLOCKED, - STATE_DEAD + STATE_READY = 1, + STATE_SLEEPING = 2, + STATE_BLOCKED = 3, + STATE_DEAD = 4, } process_state_t; typedef enum { diff --git a/kernel/scheduler.c b/kernel/scheduler.c index 37634bd..4e36e49 100644 --- a/kernel/scheduler.c +++ b/kernel/scheduler.c @@ -67,19 +67,25 @@ uint32_t switch_context(uint32_t current_esp) { current_process = next_process; - if (process_table[current_process].flags & PROCESS_FLAG_USER ) { - tss.esp0 = process_table[current_process].kstack_top; - } - - if (fetch_cr3() != process_table[current_process].cr3) { + 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) { + tss.esp0 = process_table[current_process].kstack_top; + } + + if (found_ready) { + kprintf("found ready task %d | cr3: 0x%x\n", current_process, process_table[current_process].cr3); + } return process_table[current_process].esp; } void init_scheduler() { process_table = kalloc(16 * sizeof(process_t)); + memset((void*)process_table, 0, 16 * sizeof(process_t)); total_processes = 0; 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; } - lock_scheduler(); - // 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]; 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->cr3 = cr3; process->state = STATE_READY; process->sleep = 0; process->flags = user ? PROCESS_FLAG_USER : PROCESS_FLAG_KERNEL; + total_processes++; void* kstack_bottom = kalloc(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) = 0x1B; // User Code Segment (CS) with RPL 3 (0x18 | 3) *(--esp) = entry_point; // EIP - *(--esp) = 0x23; } else { // IRET values for Ring 0 *(--esp) = 0x0202; // EFLAGS *(--esp) = 0x08; // Kernel Code Segment (CS) *(--esp) = entry_point; // EIP - *(--esp) = 0x10; } *(--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 process->esp = (uint32_t)esp; - if (!reuse) { - total_processes++; - } - unlock_scheduler(); return 1; } process_t* current_task() { - lock_scheduler(); process_t* rtn = &process_table[current_process]; - unlock_scheduler(); return rtn; } diff --git a/programs/crt0.S b/programs/crt0.S index 655f862..b2f3d65 100644 --- a/programs/crt0.S +++ b/programs/crt0.S @@ -13,7 +13,7 @@ _start: push %ecx push %ebx push %eax - +1: jmp 1b call main push %eax