From b582c39ff84df873d23807cc41bcc9ac39c0376d Mon Sep 17 00:00:00 2001 From: ngiddings Date: Sat, 17 Apr 2021 01:00:28 -0500 Subject: [PATCH] Started work on process management --- include/kernel.h | 17 +++++++-- include/priorityqueue.h | 4 +-- src/kernel.c | 77 +++++++++++++++++++++++++++++++++++++++-- src/priorityqueue.c | 4 +-- src/x86/apic.c | 4 ++- src/x86/quark_x86.c | 20 +++++------ 6 files changed, 106 insertions(+), 20 deletions(-) diff --git a/include/kernel.h b/include/kernel.h index 9f6da99..be6095d 100644 --- a/include/kernel.h +++ b/include/kernel.h @@ -1,18 +1,31 @@ #pragma once +#include "pageallocator.h" #include "priorityqueue.h" +#include "resource.h" #include "module.h" +#include "process.h" #include +enum syscall_id_t +{ + SYSCALL_YIELD = 1 +}; + struct kernel_t { + struct page_stack_t *page_stack; struct priority_queue_t *priority_queue; + struct process_t *active_process; + struct resource_table_t *resource_table; }; -extern struct kernel_t kernel; +extern struct kernel_t kernel_state; -int do_syscall(struct kernel_t *kernel, size_t id, size_t arg1, size_t arg2, size_t arg3); +size_t do_syscall(struct kernel_t *kernel, enum syscall_id_t id, size_t arg1, size_t arg2, size_t arg3); 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)); + void panic(const char *message) __attribute__ ((noreturn)); diff --git a/include/priorityqueue.h b/include/priorityqueue.h index 85aed7a..d259ef6 100644 --- a/include/priorityqueue.h +++ b/include/priorityqueue.h @@ -43,7 +43,7 @@ struct process_t *extract_min(struct priority_queue_t *queue); * @param process * @return int */ -int insert(struct priority_queue_t *queue, struct process_t *process); +int queue_insert(struct priority_queue_t *queue, struct process_t *process); /** * @brief @@ -52,4 +52,4 @@ int insert(struct priority_queue_t *queue, struct process_t *process); * @param process * @return int */ -int remove(struct priority_queue_t *queue, struct process_t *process); +int queue_remove(struct priority_queue_t *queue, struct process_t *process); diff --git a/src/kernel.c b/src/kernel.c index cf049dc..a4755d5 100644 --- a/src/kernel.c +++ b/src/kernel.c @@ -1,11 +1,84 @@ #include "kernel.h" +#include "mmgr.h" +#include "stdio.h" +#include "elf.h" +#include "context.h" +#include "types/status.h" -int do_syscall(struct kernel_t *kernel, size_t id, size_t arg1, size_t arg2, size_t arg3) +size_t do_syscall(struct kernel_t *kernel, enum syscall_id_t id, size_t arg1, size_t arg2, size_t arg3) { } int load_module(struct kernel_t *kernel, struct module_t *module) { + physaddr_t module_address_space = create_address_space(kernel->page_stack); + load_address_space(module_address_space); + void *const load_base = (void*)0x80000000; + size_t load_offset = 0; + for(physaddr_t p = module->start & ~(page_size - 1); p < module->end; p += page_size) + { + int status = map_page(kernel->page_stack, load_base + load_offset, p, PAGE_RW); + switch(status) + { + case S_OUT_OF_MEMORY: + panic("ran out of memory while mapping module"); + case S_OUT_OF_BOUNDS: + panic("got out-of-bounds error while mapping module"); + } + load_offset += page_size; + } + int status = load_program(load_base, kernel->page_stack); + switch(status) + { + case S_OUT_OF_MEMORY: + panic("ran out of memory while reading ELF file"); + case S_OUT_OF_BOUNDS: + panic("got out-of-bounds error while reading ELF file"); + } + void *module_entry = ((struct elf_file_header_t*)load_base)->entry; + void *module_context = initialize_context(module_entry, kernel->page_stack); + printf("loaded module with entry point %08x\n", (unsigned int)module_entry); + load_offset = 0; + for(physaddr_t p = module->start & ~(page_size - 1); p < module->end; p += page_size) + { + int status = unmap_page(load_base + load_offset); + switch(status) + { + case S_OUT_OF_MEMORY: + panic("ran out of memory while unmapping module"); + case S_OUT_OF_BOUNDS: + panic("got out-of-bounds error while unmapping module"); + } + load_offset += page_size; + } + int index = find_resource_slot(kernel); + if(index < 0) + { + panic("no space left in resource table for module"); + } + kernel->resource_table->array[index].type = RESOURCE_PROCESS; + kernel->resource_table->array[index].process.priority = 1; + kernel->resource_table->array[index].process.state = module_context; + kernel->resource_table->array[index].process.page_table = current_address_space(); + queue_insert(kernel->priority_queue, &kernel->resource_table->array[index].process); + return S_OK; +} -} \ No newline at end of file +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; + queue_insert(kernel->priority_queue, kernel->active_process); + } + kernel->active_process = extract_min(kernel->priority_queue); + load_context(kernel->active_process->state); +} + +void panic(const char *message) +{ + printf("panic: %s", message); + asm("cli"); + while(1) asm("hlt"); +} diff --git a/src/priorityqueue.c b/src/priorityqueue.c index 5ab2873..66a4960 100644 --- a/src/priorityqueue.c +++ b/src/priorityqueue.c @@ -36,7 +36,7 @@ struct process_t *extract_min(struct priority_queue_t *queue) return p; } -int insert(struct priority_queue_t *queue, struct process_t *process) +int queue_insert(struct priority_queue_t *queue, struct process_t *process) { if(queue->size == queue->capacity) return S_OUT_OF_MEMORY; @@ -51,7 +51,7 @@ int insert(struct priority_queue_t *queue, struct process_t *process) return S_OK; } -int remove(struct priority_queue_t *queue, struct process_t *process) +int queue_remove(struct priority_queue_t *queue, struct process_t *process) { for(size_t i = 0; i < queue->size; i++) { diff --git a/src/x86/apic.c b/src/x86/apic.c index 399ab41..32d6b84 100644 --- a/src/x86/apic.c +++ b/src/x86/apic.c @@ -6,6 +6,8 @@ extern int _kernel_end; +struct apic_registers_t volatile *apic_registers; + void apic_enable(struct page_stact_t *page_stack) { // Remap and mask 8259 PIC @@ -31,7 +33,7 @@ void apic_enable(struct page_stact_t *page_stack) ); struct msr_apic_base_t msr; read_msr(MSR_APIC_BASE, (uint64_t*)&msr); - map_page(page_stack, &_kernel_end, msr.apic_base << 12, 0); + map_page(page_stack, &_kernel_end, msr.apic_base << 12, PAGE_RW); printf("MSR_APIC_BASE: %016x\n", *((uint32_t*)&msr)); apic_registers = (struct apic_registers_t*)&_kernel_end; apic_registers->spurious_iv.value = apic_registers->spurious_iv.value | 0x100; diff --git a/src/x86/quark_x86.c b/src/x86/quark_x86.c index 474fa5e..31fb801 100644 --- a/src/x86/quark_x86.c +++ b/src/x86/quark_x86.c @@ -4,18 +4,16 @@ #include "memorymap.h" #include "apic.h" #include "interrupts.h" -#include "msr.h" #include "stdio.h" #include "string.h" #include "module.h" -#include "isr.h" #include "config.h" #include #include extern int _kernel_end; -struct apic_registers_t volatile *apic_registers; +struct kernel_t kernel_state; int start_paging(uint32_t *directory, uint32_t *table, uint32_t *identityTable) { @@ -46,7 +44,6 @@ int initialize(void *multiboot_info) initialize_idt(); printf("***%s***\n", PACKAGE_STRING); static struct page_stack_t page_stack; - static struct kernel_t kernel; struct memory_region_t map_array[16]; char bootloader_name[64]; char kernel_parameters[64]; @@ -73,22 +70,23 @@ int initialize(void *multiboot_info) page_stack.stack_pointer = (physaddr_t*)0xFFC00000; page_stack.limit_pointer = (physaddr_t*)0xFF900000; initialize_page_stack(&page_stack, &boot_info.map, 4096); - for(int i = 0; i < boot_info.module_count; i++) - { - load_module(&kernel, &boot_info.modules[i]); - } apic_enable(page_stack); apic_registers->divide_config.value = APIC_DIVIDE_128; apic_registers->lvt_timer.vector = ISR_APIC_TIMER; apic_registers->lvt_timer.timer_mode = APIC_TIMER_PERIODIC; apic_registers->initial_count.value = 1024*1024*1024; apic_registers->lvt_timer.mask = 0; - printf("spurious_interrupt_vector: %08x\n", *((uint32_t*) &apic_registers->spurious_iv)); - printf("lvt_timer_vector: %08x\n", *((uint32_t*) &apic_registers->lvt_timer)); + + kernel_state.page_stack = &page_stack; + for(int i = 0; i < boot_info.module_count; i++) + { + load_module(&kernel_state, &boot_info.modules[i]); + } + asm("sti"); while(1) { asm("hlt"); } - // TODO: enter first process + // next_process(&kernel_state, NULL); }