getting there...
This commit is contained in:
@@ -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
|
||||||
|
|||||||
@@ -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: {
|
||||||
|
|||||||
@@ -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();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user