Merge pull request #6 from ngiddings/pre-alpha

Pre alpha
This commit is contained in:
Nathan Giddings
2021-04-19 03:42:05 -05:00
committed by GitHub
30 changed files with 401 additions and 157 deletions

View File

@@ -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__((noreturn)); void save_context(struct process_state_t *context, void *ptr);
void load_context(struct process_state_t *context);

View File

@@ -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));

View File

@@ -1,5 +1,6 @@
#pragma once #pragma once
#include "pageallocator.h"
#include "process.h" #include "process.h"
#include <stddef.h> #include <stddef.h>
@@ -28,6 +29,8 @@ struct priority_queue_t
size_t capacity; size_t capacity;
}; };
int construct_priority_queue(struct priority_queue_t *queue, struct page_stack_t *page_stack);
/** /**
* @brief * @brief
* *

View File

@@ -1,5 +1,6 @@
#pragma once #pragma once
#include "pageallocator.h"
#include "process.h" #include "process.h"
#include <stddef.h> #include <stddef.h>
@@ -21,7 +22,9 @@ struct resource_t
struct resource_table_t struct resource_table_t
{ {
struct resource_t *array; struct resource_t *array;
size_t capacity; struct resource_t *limit;
}; };
int find_resource_slot(struct resource_table_t *table); int construct_resource_table(struct resource_table_t *table, struct page_stack_t *page_stack);
int get_free_resource_slot(struct resource_table_t *table, struct page_stack_t *page_stack);

7
include/system.h Normal file
View 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;

View File

@@ -5,5 +5,6 @@ enum status_t
S_OK = 0, S_OK = 0,
S_BAD_SYSCALL, S_BAD_SYSCALL,
S_OUT_OF_MEMORY, S_OUT_OF_MEMORY,
S_OUT_OF_BOUNDS S_OUT_OF_BOUNDS,
S_NULL_POINTER
}; };

View File

@@ -25,6 +25,7 @@ enum interrupt_code_t
EXCEPTION_VIRTUALIZATION = 20, EXCEPTION_VIRTUALIZATION = 20,
EXCEPTION_SECURITY = 30, EXCEPTION_SECURITY = 30,
ISR_APIC_TIMER = 64, ISR_APIC_TIMER = 64,
ISR_PREEMPT = 65,
ISR_AP_START = 127, ISR_AP_START = 127,
ISR_SYSCALL = 128 ISR_SYSCALL = 128
}; };

27
include/x86/isr.h Normal file
View 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);

View 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;
};

View File

@@ -1,3 +1,5 @@
menuentry "Quark OS" { menuentry "Quark OS" {
multiboot2 /apps/quark-kernel multiboot2 /apps/quark-kernel
module2 /apps/quark-testmod
module2 /apps/quark-testmod
} }

View File

@@ -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

View File

@@ -52,7 +52,7 @@ int load_module(struct kernel_t *kernel, struct module_t *module)
} }
load_offset += page_size; load_offset += page_size;
} }
int index = find_resource_slot(kernel); int index = get_free_resource_slot(kernel->resource_table, kernel->page_stack);
if(index < 0) if(index < 0)
{ {
panic("no space left in resource table for module"); panic("no space left in resource table for module");
@@ -73,7 +73,13 @@ struct process_state_t *next_process(struct kernel_t *kernel, struct process_sta
queue_insert(kernel->priority_queue, kernel->active_process); queue_insert(kernel->priority_queue, kernel->active_process);
} }
kernel->active_process = extract_min(kernel->priority_queue); kernel->active_process = extract_min(kernel->priority_queue);
load_context(kernel->active_process->state); if(kernel->active_process != NULL)
{
load_address_space(kernel->active_process->page_table);
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!");
} }
void panic(const char *message) void panic(const char *message)

View File

@@ -34,6 +34,7 @@ int free_page(struct page_stack_t *stack, physaddr_t location)
return S_OUT_OF_BOUNDS; return S_OUT_OF_BOUNDS;
case S_OK: case S_OK:
stack->limit_pointer = new_limit; stack->limit_pointer = new_limit;
return S_OK;
} }
} }
return S_OUT_OF_MEMORY; return S_OUT_OF_MEMORY;

View File

@@ -1,4 +1,6 @@
#include "priorityqueue.h" #include "priorityqueue.h"
#include "allocator.h"
#include "mmgr.h"
#include "types/status.h" #include "types/status.h"
void heapify(struct priority_queue_t *queue, size_t i) void heapify(struct priority_queue_t *queue, size_t i)
@@ -25,6 +27,22 @@ void heapify(struct priority_queue_t *queue, size_t i)
} }
} }
int construct_priority_queue(struct priority_queue_t *queue, struct page_stack_t *page_stack)
{
queue->heap = allocate_from_bottom(page_size);
if(queue->heap == NULL)
{
return S_OUT_OF_MEMORY;
}
int status = map_page(page_stack, queue->heap, reserve_page(page_stack), PAGE_RW);
if(status == S_OK)
{
queue->capacity = page_size / sizeof(struct process_t*);
queue->size = 0;
}
return status;
}
struct process_t *extract_min(struct priority_queue_t *queue) struct process_t *extract_min(struct priority_queue_t *queue)
{ {
if(queue->size == 0) if(queue->size == 0)

View File

@@ -1,13 +1,51 @@
#include "resource.h" #include "resource.h"
#include "mmgr.h"
#include "allocator.h"
#include "types/status.h"
int find_resource_slot(struct resource_table_t *table) int construct_resource_table(struct resource_table_t *table, struct page_stack_t *page_stack)
{ {
for(int i = 0; i < table->capacity; i++) if(table == NULL)
{
return S_NULL_POINTER;
}
void *table_ptr = allocate_from_bottom(page_size);
if(table_ptr == NULL)
{
return S_OUT_OF_MEMORY;
}
int status = map_page(page_stack, table_ptr, reserve_page(page_stack), PAGE_RW);
if(status == S_OK)
{
table->array = (struct resource_t*)table_ptr;
table->limit = (struct resource_t*)(table_ptr + page_size);
}
return status;
}
int get_free_resource_slot(struct resource_table_t *table, struct page_stack_t *page_stack)
{
if(table == NULL)
{
return -1;
}
size_t capacity = table->limit - table->array;
for(int i = 0; i < capacity; i++)
{ {
if(table->array[i].type == RESOURCE_UNAVAILABLE) if(table->array[i].type == RESOURCE_UNAVAILABLE)
{ {
return i; return i;
} }
} }
void *new_limit = allocate_from_bottom(page_size);
if(new_limit != NULL)
{
if(map_page(page_stack, new_limit, reserve_page(page_stack), PAGE_RW) != S_OK)
{
return -1;
}
table->limit = (struct resource_t*)(new_limit + page_size);
return get_free_resource_slot(table, page_stack);
}
return -1; return -1;
} }

View File

@@ -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>
@@ -37,7 +37,8 @@ void apic_enable(struct page_stact_t *page_stack)
apic_registers = (struct apic_registers_t*)allocate_from_bottom(page_size); apic_registers = (struct apic_registers_t*)allocate_from_bottom(page_size);
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 | 0x100; apic_registers->spurious_iv.value = apic_registers->spurious_iv.value | 0x1FF;
apic_registers->destination_format.value = 0xFFFFFFFF;
} }
void apic_eoi() void apic_eoi()

View File

@@ -1,32 +1,26 @@
#include "context.h" #include "context.h"
#include "pageallocator.h" #include "pageallocator.h"
#include "mmgr.h" #include "mmgr.h"
#include "string.h"
#include "x86/processstate.h"
void *initialize_context(void *task_entry, struct page_stack_t *page_stack) void *initialize_context(void *task_entry, struct page_stack_t *page_stack)
{ {
physaddr_t stack0 = reserve_page(page_stack); map_page(page_stack, (void*)NULL, reserve_page(page_stack), PAGE_RW);
map_page(page_stack, (void*)0xFF7FF000, stack0, PAGE_RW); map_page(page_stack, (void*)0xFF7FF000, reserve_page(page_stack), PAGE_RW | PAGE_USERMODE);
map_page(page_stack, (void*)0xFF7FD000, stack0, PAGE_RW | PAGE_USERMODE);
unmap_page((void*)0xFF7FE000); unmap_page((void*)0xFF7FE000);
unmap_page((void*)0xFF7FC000);
uint32_t flags; uint32_t flags;
uint32_t *stack = (uint32_t*)((void*)stack0 - 20);
asm("pushf; " asm("pushf; "
"mov (%%esp), %0; " "mov (%%esp), %0; "
"popf; " "popf; "
: "=r"(flags)); : "=r"(flags));
stack[0] = (uint32_t)task_entry; struct process_state_t *state = (struct process_state_t*)PCB_LOCATION;
stack[1] = 27; memset(NULL, 0, page_size);
stack[2] = flags; state->cs = 0x1B;
stack[3] = 0xFF7FE000; state->eip = (uint32_t)task_entry;
stack[4] = 35; state->flags = (flags & ~0xFD) | 0x200;
return (void*)stack; state->ss = 0x23;
} state->esp = 0xFF800000;
state->ebp = 0xFF800000;
void load_context(struct process_state_t *context) return (void*)state;
{
asm("mov %0, %%esp; "
"popal; "
"iret; "
:: "r"(context));
} }

67
src/x86/contextswitch.S Normal file
View 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

View File

@@ -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

View File

@@ -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,
@@ -30,13 +33,39 @@ struct gdt_entry_t
unsigned int available : 1; unsigned int available : 1;
unsigned int long_mode : 1; unsigned int long_mode : 1;
unsigned int big : 1; unsigned int big : 1;
unsigned int gran : 1; unsigned int granularity : 1;
unsigned int base_high : 8; unsigned int base_high : 8;
} __attribute__ ((packed)); } __attribute__ ((packed));
struct tss_t struct tss_entry_t
{ {
uint32_t prev_tss;
uint32_t esp0;
uint32_t ss0;
uint32_t esp1;
uint32_t ss1;
uint32_t esp2;
uint32_t ss2;
uint32_t cr3;
uint32_t eip;
uint32_t eflags;
uint32_t eax;
uint32_t ecx;
uint32_t edx;
uint32_t ebx;
uint32_t esp;
uint32_t ebp;
uint32_t esi;
uint32_t edi;
uint32_t es;
uint32_t cs;
uint32_t ss;
uint32_t ds;
uint32_t fs;
uint32_t gs;
uint32_t ldt;
uint16_t trap;
uint16_t iomap_base;
}; };
struct interrupt_descriptor_t struct interrupt_descriptor_t
@@ -49,7 +78,7 @@ struct interrupt_descriptor_t
uint16_t dpl : 2; uint16_t dpl : 2;
uint16_t present : 1; uint16_t present : 1;
uint16_t offset_2; uint16_t offset_2;
}; } __attribute__ ((packed));
struct descriptor_table_info_t struct descriptor_table_info_t
{ {
@@ -57,12 +86,10 @@ struct descriptor_table_info_t
void *location; void *location;
} __attribute__ ((packed)); } __attribute__ ((packed));
struct tss_t tss;
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;"
@@ -87,11 +114,23 @@ void load_idt(struct interrupt_descriptor_t *idt)
: "r"(&idt_info)); : "r"(&idt_info));
} }
void create_interrupt_descriptor(struct interrupt_descriptor_t *descriptor, void *isr, enum isr_type_t type, uint32_t privilage) void load_tr(uint16_t gdt_offset)
{
gdt_offset |= 3;
asm("mov %0, %%ax; "
"ltr %%ax; "
:
: "r"(gdt_offset));
}
void create_interrupt_descriptor(struct interrupt_descriptor_t *descriptor, void *isr, enum isr_type_t type, uint32_t privilage, uint32_t selector)
{
if(type != INTERRPUT_TASK32)
{ {
descriptor->offset_1 = (uint32_t) isr & 0xFFFF; descriptor->offset_1 = (uint32_t) isr & 0xFFFF;
descriptor->offset_2 = (uint32_t) isr >> 16; descriptor->offset_2 = (uint32_t) isr >> 16;
descriptor->selector = 8; }
descriptor->selector = selector;
descriptor->zero = 0; descriptor->zero = 0;
descriptor->type = type; descriptor->type = type;
descriptor->storage = 0; descriptor->storage = 0;
@@ -118,7 +157,7 @@ void create_segment_descriptor(struct gdt_entry_t *descriptor, size_t base, size
descriptor->available = 0; descriptor->available = 0;
descriptor->long_mode = 0; descriptor->long_mode = 0;
descriptor->big = 1; descriptor->big = 1;
descriptor->gran = 1; descriptor->granularity = 1;
break; break;
case SEGMENT_KERNEL_DATA: case SEGMENT_KERNEL_DATA:
descriptor->accessed = 0; descriptor->accessed = 0;
@@ -130,7 +169,7 @@ void create_segment_descriptor(struct gdt_entry_t *descriptor, size_t base, size
descriptor->available = 0; descriptor->available = 0;
descriptor->long_mode = 0; descriptor->long_mode = 0;
descriptor->big = 1; descriptor->big = 1;
descriptor->gran = 1; descriptor->granularity = 1;
break; break;
case SEGMENT_USER_CODE: case SEGMENT_USER_CODE:
descriptor->accessed = 0; descriptor->accessed = 0;
@@ -142,7 +181,7 @@ void create_segment_descriptor(struct gdt_entry_t *descriptor, size_t base, size
descriptor->available = 0; descriptor->available = 0;
descriptor->long_mode = 0; descriptor->long_mode = 0;
descriptor->big = 1; descriptor->big = 1;
descriptor->gran = 1; descriptor->granularity = 1;
break; break;
case SEGMENT_USER_DATA: case SEGMENT_USER_DATA:
descriptor->accessed = 0; descriptor->accessed = 0;
@@ -154,7 +193,7 @@ void create_segment_descriptor(struct gdt_entry_t *descriptor, size_t base, size
descriptor->available = 0; descriptor->available = 0;
descriptor->long_mode = 0; descriptor->long_mode = 0;
descriptor->big = 1; descriptor->big = 1;
descriptor->gran = 1; descriptor->granularity = 1;
break; break;
case SEGMENT_TSS: case SEGMENT_TSS:
descriptor->accessed = 1; descriptor->accessed = 1;
@@ -166,20 +205,36 @@ void create_segment_descriptor(struct gdt_entry_t *descriptor, size_t base, size
descriptor->available = 0; descriptor->available = 0;
descriptor->long_mode = 0; descriptor->long_mode = 0;
descriptor->big = 0; descriptor->big = 0;
descriptor->gran = 0; descriptor->granularity = 0;
} }
} }
void initialize_gdt() 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 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_t), 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(&double_fault_tss, 0, sizeof(tss));
tss.esp0 = &stack_top;
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));
} }
void initialize_idt() void initialize_idt()
@@ -188,14 +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_INT32, 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_INT32, 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_INT32, 0); create_interrupt_descriptor(&idt[EXCEPTION_DOUBLE_FAULT], (void*)isr_double_fault, INTERRPUT_TASK32, 0, 8 * 6);
create_interrupt_descriptor(&idt[ISR_APIC_TIMER], (void*)isr_timer, INTERRPUT_INT32, 0); create_interrupt_descriptor(&idt[ISR_PREEMPT], (void*)isr_preempt, INTERRPUT_INT32, 3, 8);
create_interrupt_descriptor(&idt[ISR_AP_START], (void*)isr_ap_start, INTERRPUT_INT32, 0); create_interrupt_descriptor(&idt[ISR_APIC_TIMER], (void*)isr_timer, INTERRPUT_INT32, 0, 8);
create_interrupt_descriptor(&idt[ISR_SYSCALL], (void*)isr_syscall, INTERRPUT_INT32, 0); create_interrupt_descriptor(&idt[ISR_SYSCALL], (void*)isr_syscall, INTERRPUT_INT32, 0, 8);
load_idt(idt); load_idt(idt);
} }

View File

@@ -1,35 +1,58 @@
#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; "
"mov %%ax, %%ds; "
"mov %%ax, %%es; "
"mov %%ax, %%fs; "
"mov %%ax, %%gs; " ::
: "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"
: "=r"(addr)); : "=r"(addr));
asm("mov $0x10, %%ax; "
"mov %%ax, %%ds; "
"mov %%ax, %%es; "
"mov %%ax, %%fs; "
"mov %%ax, %%gs; " ::
: "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");
@@ -37,31 +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");
struct process_state_t *process_state;
asm("mov %%ebp, %0"
: "=r"(process_state));
next_process(&kernel_state, process_state);
}
void isr_ap_start(void* frame)
{
asm(".code16");
//...
asm(".code32");
// do something useful
}
void isr_syscall(void* frame)
{
} }

View File

@@ -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);

View File

@@ -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)
{ {

View File

@@ -1,4 +1,4 @@
#include "multiboot2.h" #include "x86/multiboot2.h"
#include "stdio.h" #include "stdio.h"
#include "string.h" #include "string.h"
@@ -29,7 +29,7 @@ void *read_multiboot_table(struct boot_info_t *boot_info, void *table)
{ {
boot_info->modules[boot_info->module_count].start = ((struct multiboot2_module_t*) table)->start; boot_info->modules[boot_info->module_count].start = ((struct multiboot2_module_t*) table)->start;
boot_info->modules[boot_info->module_count].end = ((struct multiboot2_module_t*) table)->end; boot_info->modules[boot_info->module_count].end = ((struct multiboot2_module_t*) table)->end;
strcpy(boot_info->modules[boot_info->module_count].str, ((struct multiboot2_module_t*) table)->str); strcpy(boot_info->modules[boot_info->module_count].str, &((struct multiboot2_module_t*) table)->str);
insert_region(&boot_info->map, insert_region(&boot_info->map,
((struct multiboot2_module_t*) table)->start, ((struct multiboot2_module_t*) table)->start,
((struct multiboot2_module_t*) table)->end - ((struct multiboot2_module_t*) table)->start, ((struct multiboot2_module_t*) table)->end - ((struct multiboot2_module_t*) table)->start,

17
src/x86/preempt.S Normal file
View 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

View File

@@ -2,22 +2,19 @@
#include "pageallocator.h" #include "pageallocator.h"
#include "allocator.h" #include "allocator.h"
#include "mmgr.h" #include "mmgr.h"
#include "multiboot2.h" #include "priorityqueue.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)
@@ -26,7 +23,7 @@ int initialize(void *multiboot_info)
initialize_idt(); initialize_idt();
initialize_allocator(&_kernel_end, (void*)0xFFC00000); initialize_allocator(&_kernel_end, (void*)0xFFC00000);
static struct page_stack_t page_stack; static struct page_stack_t page_stack;
struct memory_region_t map_array[16]; struct memory_region_t map_array[24];
char bootloader_name[64]; char bootloader_name[64];
char kernel_parameters[64]; char kernel_parameters[64];
struct boot_info_t boot_info = { struct boot_info_t boot_info = {
@@ -36,46 +33,49 @@ int initialize(void *multiboot_info)
.map = { .map = {
.array = map_array, .array = map_array,
.size = 0, .size = 0,
.capacity = 16}}; .capacity = 24}};
void *multiboot_end = multiboot_info + *(uint32_t*)multiboot_info; void *multiboot_end = multiboot_info + *(uint32_t*)multiboot_info;
multiboot_info += 8; multiboot_info += 8;
while (multiboot_info != NULL) while (multiboot_info != NULL)
{ {
multiboot_info = read_multiboot_table(&boot_info, multiboot_info); multiboot_info = read_multiboot_table(&boot_info, multiboot_info);
} }
insert_region(&boot_info.map, (physaddr_t)&_kernel_pstart, (physaddr_t)&_kernel_pend, M_UNAVAILABLE); insert_region(&boot_info.map, (physaddr_t)&_kernel_pstart, (physaddr_t)&_kernel_pend - (physaddr_t)&_kernel_pstart, M_UNAVAILABLE);
for(void *p = (void*)&_kernel_end; p < multiboot_end; p += page_size) for(void *p = (void*)&_kernel_end; p < multiboot_end; p += page_size)
{ {
unmap_page(p); unmap_page(p);
} }
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;
initialize_page_stack(&page_stack, &boot_info.map); initialize_page_stack(&page_stack, &boot_info.map);
apic_enable(page_stack); static struct priority_queue_t priority_queue;
apic_registers->divide_config.value = APIC_DIVIDE_128; construct_priority_queue(&priority_queue, &page_stack);
apic_registers->lvt_timer.vector = ISR_APIC_TIMER; static struct resource_table_t resource_table;
apic_registers->lvt_timer.timer_mode = APIC_TIMER_PERIODIC; construct_resource_table(&resource_table, &page_stack);
apic_registers->initial_count.value = 1024*1024*1024;
apic_registers->lvt_timer.mask = 0;
kernel_state.page_stack = &page_stack; kernel_state.page_stack = &page_stack;
kernel_state.resource_table = &resource_table;
kernel_state.priority_queue = &priority_queue;
kernel_state.active_process = NULL;
for(int i = 0; i < boot_info.module_count; i++) for(int i = 0; i < boot_info.module_count; i++)
{ {
load_module(&kernel_state, &boot_info.modules[i]); load_module(&kernel_state, &boot_info.modules[i]);
} }
apic_enable(page_stack);
/*apic_registers->divide_config.value = APIC_DIVIDE_1;
apic_registers->lvt_timer.timer_mode = APIC_TIMER_PERIODIC;
apic_registers->lvt_timer.vector = ISR_PREEMPT;
apic_registers->lvt_timer.mask = 0;
apic_registers->initial_count.value = 1024*1024;*/
asm("sti"); asm("sti");
while(1) load_context(next_process(&kernel_state, NULL));
{ while(1) asm("hlt");
asm("hlt");
}
// next_process(&kernel_state, NULL);
} }