Finished basic task switching mechansim
PCB is local to a process's address space. Context switches are written in assembly. Moved x86 headers to include/x86
This commit is contained in:
@@ -5,4 +5,6 @@
|
|||||||
|
|
||||||
void *initialize_context(void *task_entry, struct page_stack_t *page_stack);
|
void *initialize_context(void *task_entry, struct page_stack_t *page_stack);
|
||||||
|
|
||||||
void load_context(struct process_state_t *context) __attribute__((naked));
|
void save_context(struct process_state_t *context, void *ptr);
|
||||||
|
|
||||||
|
void load_context(struct process_state_t *context);
|
||||||
|
|||||||
@@ -26,6 +26,6 @@ size_t do_syscall(struct kernel_t *kernel, enum syscall_id_t id, size_t arg1, si
|
|||||||
|
|
||||||
int load_module(struct kernel_t *kernel, struct module_t *module);
|
int load_module(struct kernel_t *kernel, struct module_t *module);
|
||||||
|
|
||||||
struct process_state_t *next_process(struct kernel_t *kernel, struct process_state_t *prev_state) __attribute__((noreturn));
|
struct process_state_t *next_process(struct kernel_t *kernel, struct process_state_t *prev_state);
|
||||||
|
|
||||||
void panic(const char *message) __attribute__ ((noreturn));
|
void panic(const char *message) __attribute__ ((noreturn));
|
||||||
|
|||||||
7
include/system.h
Normal file
7
include/system.h
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
extern int stack_top;
|
||||||
|
extern int _kernel_pstart;
|
||||||
|
extern int _kernel_pend;
|
||||||
|
extern int _kernel_start;
|
||||||
|
extern int _kernel_end;
|
||||||
27
include/x86/isr.h
Normal file
27
include/x86/isr.h
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
struct interrupt_frame_t;
|
||||||
|
|
||||||
|
__attribute__ ((interrupt))
|
||||||
|
void isr_generic(struct interrupt_frame_t *frame);
|
||||||
|
|
||||||
|
__attribute__ ((interrupt))
|
||||||
|
void isr_division_by_zero(struct interrupt_frame_t *frame);
|
||||||
|
|
||||||
|
__attribute__ ((interrupt))
|
||||||
|
void isr_gp_fault(struct interrupt_frame_t *frame, unsigned int error);
|
||||||
|
|
||||||
|
__attribute__ ((interrupt))
|
||||||
|
void isr_page_fault(struct interrupt_frame_t *frame, unsigned int error);
|
||||||
|
|
||||||
|
__attribute__ ((interrupt))
|
||||||
|
void isr_double_fault(struct interrupt_frame_t *frame, unsigned int error);
|
||||||
|
|
||||||
|
__attribute__ ((interrupt))
|
||||||
|
void isr_timer(struct interrupt_frame_t *frame);
|
||||||
|
|
||||||
|
__attribute__ ((naked))
|
||||||
|
void isr_preempt(struct interrupt_frame_t *frame);
|
||||||
|
|
||||||
|
__attribute__ ((interrupt))
|
||||||
|
void isr_syscall(struct interrupt_frame_t *frame);
|
||||||
21
include/x86/processstate.h
Normal file
21
include/x86/processstate.h
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#define PCB_LOCATION 0x800
|
||||||
|
|
||||||
|
struct process_state_t
|
||||||
|
{
|
||||||
|
uint32_t eax;
|
||||||
|
uint32_t ebx;
|
||||||
|
uint32_t ecx;
|
||||||
|
uint32_t edx;
|
||||||
|
uint32_t edi;
|
||||||
|
uint32_t esi;
|
||||||
|
uint32_t ebp;
|
||||||
|
uint32_t ss;
|
||||||
|
uint32_t esp;
|
||||||
|
uint32_t cs;
|
||||||
|
uint32_t eip;
|
||||||
|
uint32_t flags;
|
||||||
|
};
|
||||||
@@ -13,6 +13,8 @@ quark_kernel_SOURCES += x86/mmgr.c \
|
|||||||
x86/isr.c \
|
x86/isr.c \
|
||||||
x86/msr.c \
|
x86/msr.c \
|
||||||
x86/context.c \
|
x86/context.c \
|
||||||
|
x86/contextswitch.S \
|
||||||
|
x86/preempt.S \
|
||||||
x86/quark_x86.c \
|
x86/quark_x86.c \
|
||||||
x86/entry.S
|
x86/entry.S
|
||||||
quark_kernel_LDFLAGS += -T x86/linker.ld
|
quark_kernel_LDFLAGS += -T x86/linker.ld
|
||||||
|
|||||||
@@ -75,9 +75,9 @@ struct process_state_t *next_process(struct kernel_t *kernel, struct process_sta
|
|||||||
kernel->active_process = extract_min(kernel->priority_queue);
|
kernel->active_process = extract_min(kernel->priority_queue);
|
||||||
if(kernel->active_process != NULL)
|
if(kernel->active_process != NULL)
|
||||||
{
|
{
|
||||||
printf("entering process %08x\n\tcr3=%08x state=%08x.\n", kernel->active_process, kernel->active_process->page_table, kernel->active_process->state);
|
|
||||||
load_address_space(kernel->active_process->page_table);
|
load_address_space(kernel->active_process->page_table);
|
||||||
load_context(kernel->active_process->state);
|
printf("entering process %08x cr3=%08x state=%08x.\n", kernel->active_process, kernel->active_process->page_table, kernel->active_process->state);
|
||||||
|
return kernel->active_process->state;
|
||||||
}
|
}
|
||||||
panic("no processes available to enter!");
|
panic("no processes available to enter!");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#include "mmgr.h"
|
#include "mmgr.h"
|
||||||
#include "allocator.h"
|
#include "allocator.h"
|
||||||
#include "apic.h"
|
#include "x86/apic.h"
|
||||||
#include "msr.h"
|
#include "x86/msr.h"
|
||||||
#include "stdio.h"
|
#include "stdio.h"
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
@@ -38,6 +38,7 @@ void apic_enable(struct page_stact_t *page_stack)
|
|||||||
map_page(page_stack, apic_registers, msr.apic_base << 12, PAGE_RW);
|
map_page(page_stack, apic_registers, msr.apic_base << 12, PAGE_RW);
|
||||||
printf("MSR_APIC_BASE: %016x\n", *((uint32_t*)&msr));
|
printf("MSR_APIC_BASE: %016x\n", *((uint32_t*)&msr));
|
||||||
apic_registers->spurious_iv.value = apic_registers->spurious_iv.value | 0x1FF;
|
apic_registers->spurious_iv.value = apic_registers->spurious_iv.value | 0x1FF;
|
||||||
|
apic_registers->destination_format.value = 0xFFFFFFFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
void apic_eoi()
|
void apic_eoi()
|
||||||
|
|||||||
@@ -2,55 +2,25 @@
|
|||||||
#include "pageallocator.h"
|
#include "pageallocator.h"
|
||||||
#include "mmgr.h"
|
#include "mmgr.h"
|
||||||
#include "string.h"
|
#include "string.h"
|
||||||
|
#include "x86/processstate.h"
|
||||||
struct process_state_t
|
|
||||||
{
|
|
||||||
uint32_t edi;
|
|
||||||
uint32_t esi;
|
|
||||||
uint32_t ebp;
|
|
||||||
uint32_t esp_temp;
|
|
||||||
uint32_t ebx;
|
|
||||||
uint32_t edx;
|
|
||||||
uint32_t ecx;
|
|
||||||
uint32_t eax;
|
|
||||||
uint32_t eip;
|
|
||||||
uint32_t cs;
|
|
||||||
uint32_t flags;
|
|
||||||
uint32_t esp;
|
|
||||||
uint32_t ss;
|
|
||||||
};
|
|
||||||
|
|
||||||
void *initialize_context(void *task_entry, struct page_stack_t *page_stack)
|
void *initialize_context(void *task_entry, struct page_stack_t *page_stack)
|
||||||
{
|
{
|
||||||
map_page(page_stack, (void*)0xFF7FF000, reserve_page(page_stack), PAGE_RW);
|
map_page(page_stack, (void*)NULL, reserve_page(page_stack), PAGE_RW);
|
||||||
map_page(page_stack, (void*)0xFF7FD000, reserve_page(page_stack), PAGE_RW | PAGE_USERMODE);
|
map_page(page_stack, (void*)0xFF7FF000, reserve_page(page_stack), PAGE_RW | PAGE_USERMODE);
|
||||||
unmap_page((void*)0xFF7FE000);
|
unmap_page((void*)0xFF7FE000);
|
||||||
unmap_page((void*)0xFF7FC000);
|
|
||||||
uint32_t flags;
|
uint32_t flags;
|
||||||
struct process_state_t *stack = (struct process_state_t*)((void*)0xFF800000 - 20 - 8*4);
|
|
||||||
asm("pushf; "
|
asm("pushf; "
|
||||||
"mov (%%esp), %0; "
|
"mov (%%esp), %0; "
|
||||||
"popf; "
|
"popf; "
|
||||||
: "=r"(flags));
|
: "=r"(flags));
|
||||||
memset(stack, 0, sizeof(*stack));
|
struct process_state_t *state = (struct process_state_t*)PCB_LOCATION;
|
||||||
stack->eip = (uint32_t)task_entry;
|
memset(NULL, 0, page_size);
|
||||||
stack->cs = 27;
|
state->cs = 0x1B;
|
||||||
stack->flags = flags | 0x200;
|
state->eip = (uint32_t)task_entry;
|
||||||
stack->esp = 0xFF7FE000;
|
state->flags = (flags & ~0xFD) | 0x200;
|
||||||
stack->ss = 35;
|
state->ss = 0x23;
|
||||||
stack->esp_temp = &stack->eax;
|
state->esp = 0xFF800000;
|
||||||
return (void*)stack;
|
state->ebp = 0xFF800000;
|
||||||
}
|
return (void*)state;
|
||||||
|
|
||||||
void load_context(struct process_state_t *context)
|
|
||||||
{
|
|
||||||
asm("mov $0x10, %%ax; "
|
|
||||||
"mov %%ax, %%ds; "
|
|
||||||
"mov %%ax, %%es; "
|
|
||||||
"mov %%ax, %%fs; "
|
|
||||||
"mov %%ax, %%gs; "
|
|
||||||
::: "ax");
|
|
||||||
asm("mov 4(%esp), %esp; "
|
|
||||||
"popal; "
|
|
||||||
"iret; ");
|
|
||||||
}
|
}
|
||||||
67
src/x86/contextswitch.S
Normal file
67
src/x86/contextswitch.S
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
.section .text
|
||||||
|
|
||||||
|
/*
|
||||||
|
* save_context(struct process_state_t *context, struct interrupt_frame_t *frame)
|
||||||
|
*/
|
||||||
|
.global save_context
|
||||||
|
.type save_context, @function
|
||||||
|
save_context:
|
||||||
|
push %edi
|
||||||
|
push %esi
|
||||||
|
push %eax
|
||||||
|
mov $0x10, %ax
|
||||||
|
mov %ax, %ds
|
||||||
|
mov %ax, %es
|
||||||
|
mov %ax, %fs
|
||||||
|
mov %ax, %gs
|
||||||
|
mov 16(%esp), %eax
|
||||||
|
mov %ebx, 0x04(%eax)
|
||||||
|
mov %ecx, 0x08(%eax)
|
||||||
|
mov %edx, 0x0C(%eax)
|
||||||
|
mov %edi, 0x10(%eax)
|
||||||
|
mov %esi, 0x14(%eax)
|
||||||
|
mov %ebp, 0x18(%eax)
|
||||||
|
mov %eax, %edi
|
||||||
|
pop %eax
|
||||||
|
mov %eax, 0x00(%edi)
|
||||||
|
mov 16(%esp), %esi
|
||||||
|
mov 0x10(%esi), %eax
|
||||||
|
mov %eax, 0x1C(%edi)
|
||||||
|
mov 0x0C(%esi), %eax
|
||||||
|
mov %eax, 0x20(%edi)
|
||||||
|
mov 0x08(%esi), %eax
|
||||||
|
mov %eax, 0x2C(%edi)
|
||||||
|
mov 0x04(%esi), %eax
|
||||||
|
mov %eax, 0x24(%edi)
|
||||||
|
mov 0x00(%esi), %eax
|
||||||
|
mov %eax, 0x28(%edi)
|
||||||
|
pop %esi
|
||||||
|
pop %edi
|
||||||
|
ret
|
||||||
|
|
||||||
|
/*
|
||||||
|
* load_context(struct process_state_t *context)
|
||||||
|
*/
|
||||||
|
.global load_context
|
||||||
|
.type load_context, @function
|
||||||
|
load_context:
|
||||||
|
mov 4(%esp), %eax
|
||||||
|
push 0x1C(%eax)
|
||||||
|
push 0x20(%eax)
|
||||||
|
push 0x2C(%eax)
|
||||||
|
push 0x24(%eax)
|
||||||
|
push 0x28(%eax)
|
||||||
|
push 0x00(%eax)
|
||||||
|
mov 0x04(%eax), %ebx
|
||||||
|
mov 0x08(%eax), %ecx
|
||||||
|
mov 0x0C(%eax), %edx
|
||||||
|
mov 0x10(%eax), %edi
|
||||||
|
mov 0x14(%eax), %esi
|
||||||
|
mov 0x18(%eax), %ebp
|
||||||
|
mov 0x1C(%eax), %ax
|
||||||
|
mov %ax, %ds
|
||||||
|
mov %ax, %es
|
||||||
|
mov %ax, %fs
|
||||||
|
mov %ax, %gs
|
||||||
|
pop %eax
|
||||||
|
iret
|
||||||
@@ -97,16 +97,18 @@ _multibootHeaderEnd:
|
|||||||
.section .bss
|
.section .bss
|
||||||
|
|
||||||
.align 16
|
.align 16
|
||||||
stackBottom:
|
stack_bottom:
|
||||||
.skip 8192
|
.skip 8192
|
||||||
stackTop:
|
.global stack_top
|
||||||
|
stack_top:
|
||||||
|
|
||||||
.align 4096
|
.align 4096
|
||||||
_tempPgDir:
|
.global default_page_dir
|
||||||
|
default_page_dir:
|
||||||
.skip 4096
|
.skip 4096
|
||||||
_tempIdentityMap:
|
default_page_table:
|
||||||
.skip 4096
|
.skip 4096
|
||||||
_tempPgTable:
|
identity_map:
|
||||||
.skip 4096
|
.skip 4096
|
||||||
|
|
||||||
.section .text
|
.section .text
|
||||||
@@ -121,21 +123,21 @@ _start:
|
|||||||
jne .err
|
jne .err
|
||||||
|
|
||||||
# Initialize stack in physical address space
|
# Initialize stack in physical address space
|
||||||
mov $stackTop, %esp
|
mov $stack_top, %esp
|
||||||
sub $BASE_DIFF, %esp
|
sub $BASE_DIFF, %esp
|
||||||
|
|
||||||
# Push physical address of identity map
|
# Push physical address of identity map
|
||||||
mov $_tempIdentityMap, %eax
|
mov $identity_map, %eax
|
||||||
sub $BASE_DIFF, %eax
|
sub $BASE_DIFF, %eax
|
||||||
push %eax
|
push %eax
|
||||||
|
|
||||||
# Push physical address of page table
|
# Push physical address of page table
|
||||||
mov $_tempPgTable, %eax
|
mov $default_page_table, %eax
|
||||||
sub $BASE_DIFF, %eax
|
sub $BASE_DIFF, %eax
|
||||||
push %eax
|
push %eax
|
||||||
|
|
||||||
# Push physical address of page directory
|
# Push physical address of page directory
|
||||||
mov $_tempPgDir, %eax
|
mov $default_page_dir, %eax
|
||||||
sub $BASE_DIFF, %eax
|
sub $BASE_DIFF, %eax
|
||||||
push %eax
|
push %eax
|
||||||
|
|
||||||
@@ -165,7 +167,7 @@ _start:
|
|||||||
mov %eax, %cr3
|
mov %eax, %cr3
|
||||||
|
|
||||||
# Initialize stack in virtual memory
|
# Initialize stack in virtual memory
|
||||||
mov $stackTop, %esp
|
mov $stack_top, %esp
|
||||||
|
|
||||||
# Change EBX to point to the virtual address of the multiboot info
|
# Change EBX to point to the virtual address of the multiboot info
|
||||||
# If the new pointer is out-of-bounds, error
|
# If the new pointer is out-of-bounds, error
|
||||||
|
|||||||
@@ -1,11 +1,14 @@
|
|||||||
#include "interrupts.h"
|
#include "x86/interrupts.h"
|
||||||
#include "isr.h"
|
#include "x86/isr.h"
|
||||||
#include "string.h"
|
#include "string.h"
|
||||||
|
#include "system.h"
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
#define idt_size 256
|
#define idt_size 256
|
||||||
#define gdt_size 6
|
#define gdt_size 6
|
||||||
|
|
||||||
|
extern int default_page_dir;
|
||||||
|
|
||||||
enum segment_type_t
|
enum segment_type_t
|
||||||
{
|
{
|
||||||
SEGMENT_KERNEL_CODE,
|
SEGMENT_KERNEL_CODE,
|
||||||
@@ -86,7 +89,7 @@ struct descriptor_table_info_t
|
|||||||
void load_gdt(struct gdt_entry_t *gdt)
|
void load_gdt(struct gdt_entry_t *gdt)
|
||||||
{
|
{
|
||||||
struct descriptor_table_info_t gdt_info;
|
struct descriptor_table_info_t gdt_info;
|
||||||
gdt_info.size = sizeof(struct gdt_entry_t) * 6 - 1;
|
gdt_info.size = sizeof(struct gdt_entry_t) * 7 - 1;
|
||||||
gdt_info.location = (void *)gdt;
|
gdt_info.location = (void *)gdt;
|
||||||
asm("lgdt (%0);"
|
asm("lgdt (%0);"
|
||||||
"jmp $8, $.ldcs;"
|
"jmp $8, $.ldcs;"
|
||||||
@@ -120,11 +123,14 @@ void load_tr(uint16_t gdt_offset)
|
|||||||
: "r"(gdt_offset));
|
: "r"(gdt_offset));
|
||||||
}
|
}
|
||||||
|
|
||||||
void create_interrupt_descriptor(struct interrupt_descriptor_t *descriptor, void *isr, enum isr_type_t type, uint32_t privilage)
|
void create_interrupt_descriptor(struct interrupt_descriptor_t *descriptor, void *isr, enum isr_type_t type, uint32_t privilage, uint32_t selector)
|
||||||
{
|
{
|
||||||
descriptor->offset_1 = (uint32_t) isr & 0xFFFF;
|
if(type != INTERRPUT_TASK32)
|
||||||
descriptor->offset_2 = (uint32_t) isr >> 16;
|
{
|
||||||
descriptor->selector = 8;
|
descriptor->offset_1 = (uint32_t) isr & 0xFFFF;
|
||||||
|
descriptor->offset_2 = (uint32_t) isr >> 16;
|
||||||
|
}
|
||||||
|
descriptor->selector = selector;
|
||||||
descriptor->zero = 0;
|
descriptor->zero = 0;
|
||||||
descriptor->type = type;
|
descriptor->type = type;
|
||||||
descriptor->storage = 0;
|
descriptor->storage = 0;
|
||||||
@@ -207,15 +213,26 @@ void initialize_gdt()
|
|||||||
{
|
{
|
||||||
static struct gdt_entry_t gdt[gdt_size];
|
static struct gdt_entry_t gdt[gdt_size];
|
||||||
static struct tss_entry_t tss;
|
static struct tss_entry_t tss;
|
||||||
|
static struct tss_entry_t double_fault_tss;
|
||||||
memset(gdt, 0, sizeof(struct gdt_entry_t) * gdt_size);
|
memset(gdt, 0, sizeof(struct gdt_entry_t) * gdt_size);
|
||||||
create_segment_descriptor(&gdt[1], 0, 0xFFFFF, SEGMENT_KERNEL_CODE);
|
create_segment_descriptor(&gdt[1], 0, 0xFFFFF, SEGMENT_KERNEL_CODE);
|
||||||
create_segment_descriptor(&gdt[2], 0, 0xFFFFF, SEGMENT_KERNEL_DATA);
|
create_segment_descriptor(&gdt[2], 0, 0xFFFFF, SEGMENT_KERNEL_DATA);
|
||||||
create_segment_descriptor(&gdt[3], 0, 0xFFFFF, SEGMENT_USER_CODE);
|
create_segment_descriptor(&gdt[3], 0, 0xFFFFF, SEGMENT_USER_CODE);
|
||||||
create_segment_descriptor(&gdt[4], 0, 0xFFFFF, SEGMENT_USER_DATA);
|
create_segment_descriptor(&gdt[4], 0, 0xFFFFF, SEGMENT_USER_DATA);
|
||||||
create_segment_descriptor(&gdt[5], (size_t)&tss, sizeof(struct tss_entry_t) - 1, SEGMENT_TSS);
|
create_segment_descriptor(&gdt[5], (size_t)&tss, sizeof(struct tss_entry_t) - 1, SEGMENT_TSS);
|
||||||
|
create_segment_descriptor(&gdt[6], (size_t)&double_fault_tss, sizeof(struct tss_entry_t) - 1, SEGMENT_TSS);
|
||||||
memset(&tss, 0, sizeof(tss));
|
memset(&tss, 0, sizeof(tss));
|
||||||
tss.esp0 = 0xFF800000;
|
memset(&double_fault_tss, 0, sizeof(tss));
|
||||||
|
tss.esp0 = &stack_top;
|
||||||
tss.ss0 = 0x10;
|
tss.ss0 = 0x10;
|
||||||
|
double_fault_tss.esp0 = &stack_top;
|
||||||
|
double_fault_tss.ss0 = 0x10;
|
||||||
|
double_fault_tss.esp = &stack_top;
|
||||||
|
double_fault_tss.cs = 0x08;
|
||||||
|
double_fault_tss.ds = 0x10;
|
||||||
|
double_fault_tss.ss = 0x10;
|
||||||
|
double_fault_tss.cr3 = &default_page_dir;
|
||||||
|
double_fault_tss.eip = (void*)isr_double_fault;
|
||||||
load_gdt(gdt);
|
load_gdt(gdt);
|
||||||
load_tr(5 * sizeof(struct gdt_entry_t));
|
load_tr(5 * sizeof(struct gdt_entry_t));
|
||||||
}
|
}
|
||||||
@@ -226,15 +243,14 @@ void initialize_idt()
|
|||||||
memset(idt, 0, sizeof(struct interrupt_descriptor_t) * idt_size);
|
memset(idt, 0, sizeof(struct interrupt_descriptor_t) * idt_size);
|
||||||
for(int i = 0; i < idt_size; i++)
|
for(int i = 0; i < idt_size; i++)
|
||||||
{
|
{
|
||||||
create_interrupt_descriptor(&idt[i], (void*)isr_generic, INTERRPUT_INT32, 0);
|
create_interrupt_descriptor(&idt[i], (void*)isr_generic, INTERRPUT_INT32, 0, 8);
|
||||||
}
|
}
|
||||||
create_interrupt_descriptor(&idt[EXCEPTION_DIV_BY_0], (void*)isr_division_by_zero, INTERRPUT_INT32, 0);
|
create_interrupt_descriptor(&idt[EXCEPTION_DIV_BY_0], (void*)isr_division_by_zero, INTERRPUT_INT32, 0, 8);
|
||||||
create_interrupt_descriptor(&idt[EXCEPTION_GPF], (void*)isr_gp_fault, INTERRPUT_TRAP32, 0);
|
create_interrupt_descriptor(&idt[EXCEPTION_GPF], (void*)isr_gp_fault, INTERRPUT_TRAP32, 0, 8);
|
||||||
create_interrupt_descriptor(&idt[EXCEPTION_PAGE_FAULT], (void*)isr_page_fault, INTERRPUT_TRAP32, 0);
|
create_interrupt_descriptor(&idt[EXCEPTION_PAGE_FAULT], (void*)isr_page_fault, INTERRPUT_TRAP32, 0, 8);
|
||||||
create_interrupt_descriptor(&idt[EXCEPTION_DOUBLE_FAULT], (void*)isr_double_fault, INTERRPUT_TRAP32, 0);
|
create_interrupt_descriptor(&idt[EXCEPTION_DOUBLE_FAULT], (void*)isr_double_fault, INTERRPUT_TASK32, 0, 8 * 6);
|
||||||
create_interrupt_descriptor(&idt[ISR_PREEMPT], (void*)isr_preempt, INTERRPUT_INT32, 0);
|
create_interrupt_descriptor(&idt[ISR_PREEMPT], (void*)isr_preempt, INTERRPUT_INT32, 3, 8);
|
||||||
create_interrupt_descriptor(&idt[ISR_APIC_TIMER], (void*)isr_timer, INTERRPUT_INT32, 0);
|
create_interrupt_descriptor(&idt[ISR_APIC_TIMER], (void*)isr_timer, INTERRPUT_INT32, 0, 8);
|
||||||
create_interrupt_descriptor(&idt[ISR_AP_START], (void*)isr_ap_start, INTERRPUT_INT32, 0);
|
create_interrupt_descriptor(&idt[ISR_SYSCALL], (void*)isr_syscall, INTERRPUT_INT32, 0, 8);
|
||||||
create_interrupt_descriptor(&idt[ISR_SYSCALL], (void*)isr_syscall, INTERRPUT_INT32, 0);
|
|
||||||
load_idt(idt);
|
load_idt(idt);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,32 +1,43 @@
|
|||||||
#include "kernel.h"
|
#include "kernel.h"
|
||||||
#include "isr.h"
|
#include "x86/isr.h"
|
||||||
#include "stdio.h"
|
#include "stdio.h"
|
||||||
#include "apic.h"
|
#include "x86/apic.h"
|
||||||
|
#include "x86/processstate.h"
|
||||||
|
#include "context.h"
|
||||||
|
|
||||||
void isr_generic(void* frame)
|
struct interrupt_frame_t
|
||||||
|
{
|
||||||
|
size_t eip;
|
||||||
|
size_t cs;
|
||||||
|
size_t eflags;
|
||||||
|
size_t esp;
|
||||||
|
size_t ss;
|
||||||
|
};
|
||||||
|
|
||||||
|
void isr_generic(struct interrupt_frame_t *frame)
|
||||||
{
|
{
|
||||||
printf("Generic interrupt.\n");
|
printf("Generic interrupt.\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void isr_division_by_zero(void* frame)
|
void isr_division_by_zero(struct interrupt_frame_t *frame)
|
||||||
{
|
{
|
||||||
printf("Exception: Division by zero\n");
|
printf("Exception: Division by zero\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void isr_gp_fault(void* frame, unsigned int error)
|
void isr_gp_fault(struct interrupt_frame_t *frame, unsigned int error)
|
||||||
{
|
{
|
||||||
asm("cli");
|
asm("cli");
|
||||||
asm("mov $0x10, %%ax; "
|
asm("mov $0x10, %%ax; "
|
||||||
"mov %%ax, %%ds; "
|
"mov %%ax, %%ds; "
|
||||||
"mov %%ax, %%es; "
|
"mov %%ax, %%es; "
|
||||||
"mov %%ax, %%fs; "
|
"mov %%ax, %%fs; "
|
||||||
"mov %%ax, %%gs; "
|
"mov %%ax, %%gs; " ::
|
||||||
::: "ax");
|
: "ax");
|
||||||
printf("Exception: GP fault, code %08x\n", error);
|
printf("Exception: GP fault, code %08x\n", error);
|
||||||
asm("hlt");
|
asm("hlt");
|
||||||
}
|
}
|
||||||
|
|
||||||
void isr_page_fault(void* frame, unsigned int error)
|
void isr_page_fault(struct interrupt_frame_t *frame, unsigned int error)
|
||||||
{
|
{
|
||||||
size_t addr;
|
size_t addr;
|
||||||
asm("mov %%cr2, %0"
|
asm("mov %%cr2, %0"
|
||||||
@@ -35,13 +46,13 @@ void isr_page_fault(void* frame, unsigned int error)
|
|||||||
"mov %%ax, %%ds; "
|
"mov %%ax, %%ds; "
|
||||||
"mov %%ax, %%es; "
|
"mov %%ax, %%es; "
|
||||||
"mov %%ax, %%fs; "
|
"mov %%ax, %%fs; "
|
||||||
"mov %%ax, %%gs; "
|
"mov %%ax, %%gs; " ::
|
||||||
::: "ax");
|
: "ax");
|
||||||
printf("Exception: Page fault, code %08x, linear address %08x\n", error, addr);
|
printf("Exception: Page fault, code %08x, linear address %08x\n", error, addr);
|
||||||
asm("hlt");
|
asm("hlt");
|
||||||
}
|
}
|
||||||
|
|
||||||
void isr_double_fault(void* frame, unsigned int error)
|
void isr_double_fault(struct interrupt_frame_t *frame, unsigned int error)
|
||||||
{
|
{
|
||||||
asm("cli");
|
asm("cli");
|
||||||
|
|
||||||
@@ -49,39 +60,12 @@ void isr_double_fault(void* frame, unsigned int error)
|
|||||||
asm("hlt");
|
asm("hlt");
|
||||||
}
|
}
|
||||||
|
|
||||||
void isr_timer(void* frame)
|
void isr_timer(struct interrupt_frame_t *frame)
|
||||||
{
|
{
|
||||||
printf("Timer tick.\n");
|
printf("Timer tick.\n");
|
||||||
apic_eoi();
|
apic_eoi();
|
||||||
}
|
}
|
||||||
|
|
||||||
void isr_preempt(void* frame)
|
void isr_syscall(struct interrupt_frame_t *frame)
|
||||||
{
|
{
|
||||||
asm("pushal; "
|
|
||||||
"mov %esp, %ebp; ");
|
|
||||||
asm("mov $0x10, %%ax; "
|
|
||||||
"mov %%ax, %%ds; "
|
|
||||||
"mov %%ax, %%es; "
|
|
||||||
"mov %%ax, %%fs; "
|
|
||||||
"mov %%ax, %%gs; "
|
|
||||||
::: "ax");
|
|
||||||
struct process_state_t *process_state;
|
|
||||||
asm("mov %%ebp, %0"
|
|
||||||
: "=r"(process_state));
|
|
||||||
printf("Preempted process %08x.\n", kernel_state.active_process);
|
|
||||||
apic_eoi();
|
|
||||||
next_process(&kernel_state, process_state);
|
|
||||||
}
|
|
||||||
|
|
||||||
void isr_ap_start(void* frame)
|
|
||||||
{
|
|
||||||
asm(".code16");
|
|
||||||
//...
|
|
||||||
asm(".code32");
|
|
||||||
// do something useful
|
|
||||||
}
|
|
||||||
|
|
||||||
void isr_syscall(void* frame)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
__attribute__ ((interrupt))
|
|
||||||
void isr_generic(void* frame);
|
|
||||||
|
|
||||||
__attribute__ ((interrupt))
|
|
||||||
void isr_division_by_zero(void* frame);
|
|
||||||
|
|
||||||
__attribute__ ((interrupt))
|
|
||||||
void isr_gp_fault(void* frame, unsigned int error);
|
|
||||||
|
|
||||||
__attribute__ ((interrupt))
|
|
||||||
void isr_page_fault(void* frame, unsigned int error);
|
|
||||||
|
|
||||||
__attribute__ ((interrupt))
|
|
||||||
void isr_double_fault(void* frame, unsigned int error);
|
|
||||||
|
|
||||||
__attribute__ ((interrupt))
|
|
||||||
void isr_timer(void* frame);
|
|
||||||
|
|
||||||
__attribute__ ((naked))
|
|
||||||
void isr_preempt(void* frame);
|
|
||||||
|
|
||||||
__attribute__ ((naked))
|
|
||||||
void isr_ap_start(void* frame);
|
|
||||||
|
|
||||||
__attribute__ ((interrupt))
|
|
||||||
void isr_syscall(void* frame);
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
#include "msr.h"
|
#include "x86/msr.h"
|
||||||
|
|
||||||
void read_msr(enum msr_id_t msr_addr, uint64_t *value)
|
void read_msr(enum msr_id_t msr_addr, uint64_t *value)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#include "multiboot2.h"
|
#include "x86/multiboot2.h"
|
||||||
#include "stdio.h"
|
#include "stdio.h"
|
||||||
#include "string.h"
|
#include "string.h"
|
||||||
|
|
||||||
|
|||||||
17
src/x86/preempt.S
Normal file
17
src/x86/preempt.S
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
.section .text
|
||||||
|
|
||||||
|
.global isr_preempt
|
||||||
|
.type isr_preempt, @function
|
||||||
|
isr_preempt:
|
||||||
|
cli
|
||||||
|
push %esp
|
||||||
|
push $0x800
|
||||||
|
call save_context
|
||||||
|
sub $8, %esp
|
||||||
|
push $0x800
|
||||||
|
push $kernel_state
|
||||||
|
call next_process
|
||||||
|
sub $8, %esp
|
||||||
|
push %eax
|
||||||
|
call load_context
|
||||||
|
|
||||||
@@ -3,22 +3,18 @@
|
|||||||
#include "allocator.h"
|
#include "allocator.h"
|
||||||
#include "mmgr.h"
|
#include "mmgr.h"
|
||||||
#include "priorityqueue.h"
|
#include "priorityqueue.h"
|
||||||
#include "multiboot2.h"
|
#include "x86/multiboot2.h"
|
||||||
#include "memorymap.h"
|
#include "memorymap.h"
|
||||||
#include "apic.h"
|
#include "x86/apic.h"
|
||||||
#include "interrupts.h"
|
#include "x86/interrupts.h"
|
||||||
#include "stdio.h"
|
#include "stdio.h"
|
||||||
#include "string.h"
|
#include "string.h"
|
||||||
#include "module.h"
|
#include "module.h"
|
||||||
|
#include "system.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
extern int _kernel_pstart;
|
|
||||||
extern int _kernel_pend;
|
|
||||||
extern int _kernel_start;
|
|
||||||
extern int _kernel_end;
|
|
||||||
|
|
||||||
struct kernel_t kernel_state;
|
struct kernel_t kernel_state;
|
||||||
|
|
||||||
int initialize(void *multiboot_info)
|
int initialize(void *multiboot_info)
|
||||||
@@ -51,11 +47,11 @@ int initialize(void *multiboot_info)
|
|||||||
}
|
}
|
||||||
initialize_screen();
|
initialize_screen();
|
||||||
printf("***%s***\n", PACKAGE_STRING);
|
printf("***%s***\n", PACKAGE_STRING);
|
||||||
printf("Type\t\tLocation\t\tSize\n");
|
/*printf("Type\t\tLocation\t\tSize\n");
|
||||||
for (size_t i = 0; i < boot_info.map.size && boot_info.map.array[i].size > 0; i++)
|
for (size_t i = 0; i < boot_info.map.size && boot_info.map.array[i].size > 0; i++)
|
||||||
{
|
{
|
||||||
printf("%i\t\t\t%08x\t\t%u\n", boot_info.map.array[i].type, boot_info.map.array[i].location, boot_info.map.array[i].size);
|
printf("%i\t\t\t%08x\t\t%u\n", boot_info.map.array[i].type, boot_info.map.array[i].location, boot_info.map.array[i].size);
|
||||||
}
|
}*/
|
||||||
page_stack.base_pointer = (physaddr_t*)0xFFC00000;
|
page_stack.base_pointer = (physaddr_t*)0xFFC00000;
|
||||||
page_stack.stack_pointer = (physaddr_t*)0xFFC00000;
|
page_stack.stack_pointer = (physaddr_t*)0xFFC00000;
|
||||||
page_stack.limit_pointer = (physaddr_t*)0xFFC00000;
|
page_stack.limit_pointer = (physaddr_t*)0xFFC00000;
|
||||||
@@ -73,13 +69,13 @@ int initialize(void *multiboot_info)
|
|||||||
load_module(&kernel_state, &boot_info.modules[i]);
|
load_module(&kernel_state, &boot_info.modules[i]);
|
||||||
}
|
}
|
||||||
apic_enable(page_stack);
|
apic_enable(page_stack);
|
||||||
apic_registers->divide_config.value = APIC_DIVIDE_16;
|
/*apic_registers->divide_config.value = APIC_DIVIDE_1;
|
||||||
apic_registers->lvt_timer.vector = ISR_PREEMPT;
|
|
||||||
apic_registers->lvt_timer.timer_mode = APIC_TIMER_PERIODIC;
|
apic_registers->lvt_timer.timer_mode = APIC_TIMER_PERIODIC;
|
||||||
|
apic_registers->lvt_timer.vector = ISR_PREEMPT;
|
||||||
apic_registers->lvt_timer.mask = 0;
|
apic_registers->lvt_timer.mask = 0;
|
||||||
apic_registers->initial_count.value = 1024*1024*128;
|
apic_registers->initial_count.value = 1024*1024;*/
|
||||||
asm("sti");
|
asm("sti");
|
||||||
next_process(&kernel_state, NULL);
|
load_context(next_process(&kernel_state, NULL));
|
||||||
while(1) asm("hlt");
|
while(1) asm("hlt");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user