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:
2021-04-19 03:40:33 -05:00
parent 086dfe546a
commit 5efc389935
22 changed files with 246 additions and 162 deletions

View File

@@ -13,6 +13,8 @@ quark_kernel_SOURCES += x86/mmgr.c \
x86/isr.c \
x86/msr.c \
x86/context.c \
x86/contextswitch.S \
x86/preempt.S \
x86/quark_x86.c \
x86/entry.S
quark_kernel_LDFLAGS += -T x86/linker.ld

View File

@@ -66,7 +66,7 @@ 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)
{
{
if(prev_state != NULL)
{
kernel->active_process->state = prev_state;
@@ -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);
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_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!");
}

View File

@@ -1,7 +1,7 @@
#include "mmgr.h"
#include "allocator.h"
#include "apic.h"
#include "msr.h"
#include "x86/apic.h"
#include "x86/msr.h"
#include "stdio.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);
printf("MSR_APIC_BASE: %016x\n", *((uint32_t*)&msr));
apic_registers->spurious_iv.value = apic_registers->spurious_iv.value | 0x1FF;
apic_registers->destination_format.value = 0xFFFFFFFF;
}
void apic_eoi()

View File

@@ -1,156 +0,0 @@
#pragma once
#include <stdint.h>
enum apic_delivery_mode_t
{
APIC_DELIVERY_MODE_FIXED = 0b000,
APIC_DELIVERY_MODE_LOWEST_PRIORITY = 0b001,
APIC_DELIVERY_MODE_SMI = 0b010,
APIC_DELIVERY_MODE_NMI = 0b100,
APIC_DELIVERY_MODE_INIT = 0b101,
APIC_DELIVERY_MODE_SIPI = 0b110,
APIV_DELIVERY_MODE_EXTINIT = 0b111
};
enum apic_destination_mode_t
{
APIC_DESTINATION_MODE_PHYSICAL = 0,
APIC_DESTINATION_MODE_LOGICAL = 1
};
enum apic_level_t
{
APIC_LEVEL_DEASSERT = 0,
APIC_LEVEL_ASSERT = 1
};
enum apic_trigger_mode_t
{
APIC_TRIGGER_MODE_EDGE = 0,
APIC_TRIGGER_MODE_LEVEL = 1
};
enum apic_destination_shorthand_t
{
APIC_DEST_SHORTHAND_NONE = 0,
APIC_DEST_SHORTHAND_SELF = 1,
APIC_DEST_SHORTHAND_ALL = 2,
APIC_DEST_SHORTHAND_OTHERS = 3
};
enum apic_divide_mode_t
{
APIC_DIVIDE_1 = 0b1011,
APIC_DIVIDE_2 = 0b0000,
APIC_DIVIDE_4 = 0b0001,
APIC_DIVIDE_8 = 0b0010,
APIC_DIVIDE_16 = 0b0011,
APIC_DIVIDE_32 = 0b1000,
APIC_DIVIDE_64 = 0b1001,
APIC_DIVIDE_128 = 0b1011
};
enum apic_timer_mode_t
{
APIC_TIMER_ONESHOT = 0,
APIC_TIMER_PERIODIC = 1,
APIC_TIMER_TSCDEADLINE = 2
};
struct apic_register_t
{
uint32_t value;
uint32_t padding[3];
};
struct apic_lapic_version_t
{
uint32_t version : 8;
uint32_t reserved_1 : 8;
uint32_t max_lvt_entry : 8;
uint32_t suppress_eoi_broadcast : 1;
uint32_t reserved_2 : 7;
uint32_t padding[3];
};
struct apic_lvt_t
{
uint32_t vector: 8;
uint32_t delivery_mode : 3;
uint32_t reserved_1 : 1;
uint32_t delivery_status : 1;
uint32_t pin_polarity : 1;
uint32_t remote_irr : 1;
uint32_t trigger_mode : 1;
uint32_t mask : 1;
uint32_t timer_mode : 2;
uint32_t reserved_2 : 13;
uint32_t padding[3];
};
struct apic_icr_t
{
uint32_t vector : 8;
uint32_t delivery_mode : 3;
uint32_t destination_mode : 1;
uint32_t delivery_status : 1;
uint32_t reserved_1 : 1;
uint32_t level : 1;
uint32_t trigger_mode : 1;
uint32_t reserved_2 : 2;
uint32_t destination_shorthand : 2;
uint32_t reserved_3 : 12;
uint32_t padding_1[3];
uint32_t reserved : 24;
uint32_t destination : 8;
uint32_t padding_2[3];
};
struct apic_registers_t
{
struct apic_register_t reserved_1[2];
struct apic_register_t lapic_id;
struct apic_lapic_version_t lapic_version;
struct apic_register_t reserved_2[4];
struct apic_register_t task_priority;
struct apic_register_t arbitration_priority;
struct apic_register_t processor_priority;
struct apic_register_t eoi;
struct apic_register_t remote_read;
struct apic_register_t logical_destination;
struct apic_register_t destination_format;
struct apic_register_t spurious_iv;
struct apic_register_t in_service[8];
struct apic_register_t trigger_mode[8];
struct apic_register_t interrupt_request[8];
struct apic_register_t error_status;
struct apic_register_t reserved_3[6];
struct apic_lvt_t lvt_cmci;
struct apic_icr_t interrput_command;
struct apic_lvt_t lvt_timer;
struct apic_lvt_t lvt_thermal_sensor;
struct apic_lvt_t lvt_performance_counters;
struct apic_lvt_t lvt_lint0;
struct apic_lvt_t lvt_lint1;
struct apic_lvt_t lvt_error;
struct apic_register_t initial_count;
struct apic_register_t current_count;
struct apic_register_t reserved_4[4];
struct apic_register_t divide_config;
struct apic_register_t reserved_5;
};
extern struct apic_registers_t volatile *apic_registers;
void apic_enable();
void apic_eoi();
void apic_send_ipi(
uint32_t vector,
enum apic_delivery_mode_t delivery_mode,
enum apic_destination_mode_t destination_mode,
enum apic_level_t level,
enum apic_trigger_mode_t trigger_mode,
enum apic_destination_shorthand_t shorthand,
uint32_t destination);

View File

@@ -2,55 +2,25 @@
#include "pageallocator.h"
#include "mmgr.h"
#include "string.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;
};
#include "x86/processstate.h"
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*)0xFF7FD000, reserve_page(page_stack), PAGE_RW | PAGE_USERMODE);
map_page(page_stack, (void*)NULL, reserve_page(page_stack), PAGE_RW);
map_page(page_stack, (void*)0xFF7FF000, reserve_page(page_stack), PAGE_RW | PAGE_USERMODE);
unmap_page((void*)0xFF7FE000);
unmap_page((void*)0xFF7FC000);
uint32_t flags;
struct process_state_t *stack = (struct process_state_t*)((void*)0xFF800000 - 20 - 8*4);
asm("pushf; "
"mov (%%esp), %0; "
"popf; "
: "=r"(flags));
memset(stack, 0, sizeof(*stack));
stack->eip = (uint32_t)task_entry;
stack->cs = 27;
stack->flags = flags | 0x200;
stack->esp = 0xFF7FE000;
stack->ss = 35;
stack->esp_temp = &stack->eax;
return (void*)stack;
struct process_state_t *state = (struct process_state_t*)PCB_LOCATION;
memset(NULL, 0, page_size);
state->cs = 0x1B;
state->eip = (uint32_t)task_entry;
state->flags = (flags & ~0xFD) | 0x200;
state->ss = 0x23;
state->esp = 0xFF800000;
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
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,18 +97,20 @@ _multibootHeaderEnd:
.section .bss
.align 16
stackBottom:
stack_bottom:
.skip 8192
stackTop:
.global stack_top
stack_top:
.align 4096
_tempPgDir:
.global default_page_dir
default_page_dir:
.skip 4096
_tempIdentityMap:
default_page_table:
.skip 4096
_tempPgTable:
identity_map:
.skip 4096
.section .text
.global _start
.type _start, @function
@@ -121,21 +123,21 @@ _start:
jne .err
# Initialize stack in physical address space
mov $stackTop, %esp
mov $stack_top, %esp
sub $BASE_DIFF, %esp
# Push physical address of identity map
mov $_tempIdentityMap, %eax
mov $identity_map, %eax
sub $BASE_DIFF, %eax
push %eax
# Push physical address of page table
mov $_tempPgTable, %eax
mov $default_page_table, %eax
sub $BASE_DIFF, %eax
push %eax
# Push physical address of page directory
mov $_tempPgDir, %eax
mov $default_page_dir, %eax
sub $BASE_DIFF, %eax
push %eax
@@ -165,7 +167,7 @@ _start:
mov %eax, %cr3
# Initialize stack in virtual memory
mov $stackTop, %esp
mov $stack_top, %esp
# Change EBX to point to the virtual address of the multiboot info
# If the new pointer is out-of-bounds, error

View File

@@ -1,11 +1,14 @@
#include "interrupts.h"
#include "isr.h"
#include "x86/interrupts.h"
#include "x86/isr.h"
#include "string.h"
#include "system.h"
#include <stddef.h>
#define idt_size 256
#define gdt_size 6
extern int default_page_dir;
enum segment_type_t
{
SEGMENT_KERNEL_CODE,
@@ -86,7 +89,7 @@ struct descriptor_table_info_t
void load_gdt(struct gdt_entry_t *gdt)
{
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;
asm("lgdt (%0);"
"jmp $8, $.ldcs;"
@@ -120,11 +123,14 @@ void load_tr(uint16_t 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;
descriptor->offset_2 = (uint32_t) isr >> 16;
descriptor->selector = 8;
if(type != INTERRPUT_TASK32)
{
descriptor->offset_1 = (uint32_t) isr & 0xFFFF;
descriptor->offset_2 = (uint32_t) isr >> 16;
}
descriptor->selector = selector;
descriptor->zero = 0;
descriptor->type = type;
descriptor->storage = 0;
@@ -207,15 +213,26 @@ void initialize_gdt()
{
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);
create_segment_descriptor(&gdt[1], 0, 0xFFFFF, SEGMENT_KERNEL_CODE);
create_segment_descriptor(&gdt[2], 0, 0xFFFFF, SEGMENT_KERNEL_DATA);
create_segment_descriptor(&gdt[3], 0, 0xFFFFF, SEGMENT_USER_CODE);
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[6], (size_t)&double_fault_tss, sizeof(struct tss_entry_t) - 1, SEGMENT_TSS);
memset(&tss, 0, sizeof(tss));
tss.esp0 = 0xFF800000;
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_tr(5 * sizeof(struct gdt_entry_t));
}
@@ -226,15 +243,14 @@ void initialize_idt()
memset(idt, 0, sizeof(struct interrupt_descriptor_t) * idt_size);
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_GPF], (void*)isr_gp_fault, INTERRPUT_TRAP32, 0);
create_interrupt_descriptor(&idt[EXCEPTION_PAGE_FAULT], (void*)isr_page_fault, INTERRPUT_TRAP32, 0);
create_interrupt_descriptor(&idt[EXCEPTION_DOUBLE_FAULT], (void*)isr_double_fault, INTERRPUT_TRAP32, 0);
create_interrupt_descriptor(&idt[ISR_PREEMPT], (void*)isr_preempt, INTERRPUT_INT32, 0);
create_interrupt_descriptor(&idt[ISR_APIC_TIMER], (void*)isr_timer, INTERRPUT_INT32, 0);
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);
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, 8);
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_TASK32, 0, 8 * 6);
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, 8);
create_interrupt_descriptor(&idt[ISR_SYSCALL], (void*)isr_syscall, INTERRPUT_INT32, 0, 8);
load_idt(idt);
}

View File

@@ -1,44 +0,0 @@
#pragma once
#include <stdint.h>
enum interrupt_code_t
{
EXCEPTION_DIV_BY_0 = 0,
EXCEPTION_DEBUG = 1,
EXCEPTION_NMI = 2,
EXCEPTION_BREAKPOINT = 3,
EXCEPTION_OVERFLOW = 4,
EXCEPTION_OUT_OF_BOUNDS = 5,
EXCEPTION_INVALID_OPCODE = 6,
EXCEPTION_DEVICE_NOT_AVAILABLE = 7,
EXCEPTION_DOUBLE_FAULT = 8,
EXCEPTION_INVALID_TSS = 10,
EXCEPTION_SEGMENT_NOT_PRESENT = 11,
EXCEPTION_STACK_SEGMENT_FAULT = 12,
EXCEPTION_GPF = 13,
EXCEPTION_PAGE_FAULT = 14,
EXCEPTION_x87_FLOATING_POINT = 16,
EXCEPTION_ALIGNMENT_CHECK = 17,
EXCEPTION_MACHINE_CHECK = 18,
EXCEPTION_SIMD_FLOATING_POINT = 19,
EXCEPTION_VIRTUALIZATION = 20,
EXCEPTION_SECURITY = 30,
ISR_APIC_TIMER = 64,
ISR_PREEMPT = 65,
ISR_AP_START = 127,
ISR_SYSCALL = 128
};
enum isr_type_t
{
INTERRPUT_TASK32 = 5,
INTERRPUT_TRAP32 = 15,
INTERRPUT_INT32 = 14,
INTERRPUT_TRAP16 = 7,
INTERRPUT_INT16 = 6
};
void initialize_gdt();
void initialize_idt();

View File

@@ -1,32 +1,43 @@
#include "kernel.h"
#include "isr.h"
#include "x86/isr.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");
}
void isr_division_by_zero(void* frame)
void isr_division_by_zero(struct interrupt_frame_t *frame)
{
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("mov $0x10, %%ax; "
"mov %%ax, %%ds; "
"mov %%ax, %%es; "
"mov %%ax, %%fs; "
"mov %%ax, %%gs; "
::: "ax");
"mov %%ax, %%gs; " ::
: "ax");
printf("Exception: GP fault, code %08x\n", error);
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;
asm("mov %%cr2, %0"
@@ -35,53 +46,26 @@ void isr_page_fault(void* frame, unsigned int error)
"mov %%ax, %%ds; "
"mov %%ax, %%es; "
"mov %%ax, %%fs; "
"mov %%ax, %%gs; "
::: "ax");
"mov %%ax, %%gs; " ::
: "ax");
printf("Exception: Page fault, code %08x, linear address %08x\n", error, addr);
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");
printf("Exception: Double fault (!!), code %08x\n", error);
asm("hlt");
}
void isr_timer(void* frame)
void isr_timer(struct interrupt_frame_t *frame)
{
printf("Timer tick.\n");
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)
{
}

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

View File

@@ -1,22 +0,0 @@
#pragma once
#include <stdint.h>
enum msr_id_t
{
MSR_APIC_BASE = 0x1B
};
struct msr_apic_base_t
{
uint64_t reserved_1 : 8;
uint64_t bsp : 1;
uint64_t reserved_2 : 1;
uint64_t x2apic_enable : 1;
uint64_t apic_global_enable : 1;
uint64_t apic_base : 52;
};
void read_msr(enum msr_id_t msr_addr, uint64_t *value);
void write_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 "string.h"

View File

@@ -1,84 +0,0 @@
#pragma once
#include "memorymap.h"
#include "module.h"
#include <stddef.h>
#include <stdint.h>
#define module_limit 8
enum multiboot2_tag_types
{
MB_END_TAG = 0,
MB_BOOT_COMMAND = 1,
MB_BOOTLOADER = 2,
MB_MODULE = 3,
MB_MEMORY_INFO = 4,
MB_BIOS_BOOT_DEVICE = 5,
MB_MEMORY_MAP = 6,
MB_VBE = 7,
MB_FRAMEBUFFER = 8,
MB_ELF_SYMBOLS = 9,
MB_APM = 10,
MB_EFI32_SYSTEM_TABLE = 11,
MB_EFI64_SYSTEM_TABLE = 12,
MB_SMBIOS = 13,
MB_ACPI10_RSDP = 14,
MB_ACPT20_RSDP = 15,
MB_NETOWRK = 16,
MB_EFI_MEMORY_MAP = 17,
MB_EFI_BOOT_SERVICES = 18,
MB_EFI32_IMAGE = 19,
MB_EFI64_IMAGE = 20,
MB_LOAD_ADDRESS = 21
};
enum multiboot2_memory_types
{
MB_AVAILABLE = 1,
MB_ACPI = 3,
MB_DEFECTIVE = 5
};
struct multiboot2_string_t
{
uint32_t type;
uint32_t size;
char str;
};
struct multiboot2_module_t
{
uint32_t type;
uint32_t size;
uint32_t start;
uint32_t end;
char str;
};
struct multiboot2_map_entry_t
{
uint64_t base;
uint64_t length;
uint32_t type;
};
struct multiboot2_memory_map_t
{
uint32_t type;
uint32_t size;
uint32_t entry_size;
uint32_t entry_version;
struct multiboot2_map_entry_t entries;
};
struct boot_info_t
{
char *bootloader;
char *parameters;
size_t module_count;
struct memory_map_t map;
struct module_t modules[module_limit];
};
void *read_multiboot_table(struct boot_info_t *boot_info, void *table);

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

@@ -3,22 +3,18 @@
#include "allocator.h"
#include "mmgr.h"
#include "priorityqueue.h"
#include "multiboot2.h"
#include "x86/multiboot2.h"
#include "memorymap.h"
#include "apic.h"
#include "interrupts.h"
#include "x86/apic.h"
#include "x86/interrupts.h"
#include "stdio.h"
#include "string.h"
#include "module.h"
#include "system.h"
#include "config.h"
#include <stdint.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;
int initialize(void *multiboot_info)
@@ -51,11 +47,11 @@ int initialize(void *multiboot_info)
}
initialize_screen();
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++)
{
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.stack_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]);
}
apic_enable(page_stack);
apic_registers->divide_config.value = APIC_DIVIDE_16;
apic_registers->lvt_timer.vector = ISR_PREEMPT;
/*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*128;
apic_registers->initial_count.value = 1024*1024;*/
asm("sti");
next_process(&kernel_state, NULL);
load_context(next_process(&kernel_state, NULL));
while(1) asm("hlt");
}