#include "kernel.h" #include "pageallocator.h" #include "multiboot2.h" #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; int startPaging(uint32_t *directory, uint32_t *table, uint32_t *identityTable) { for (int i = 0; i < 1024; i++) { uint32_t pte = i * 4096 + 3; table[i] = pte; identityTable[i] = pte; } directory[0] = ((uint32_t)identityTable) + 3; directory[1022] = ((uint32_t)table) + 3; directory[1023] = ((uint32_t)directory) + 3; asm("mov %0, %%cr3" : : "r"(directory)); asm("mov %%cr0, %%eax \n" "or $0x80010000, %%eax \n" "mov %%eax, %%cr0" : : : "eax"); return 0; } int initialize(void *multiboot_info) { printf("***%s***\n", PACKAGE_STRING); static struct interrupt_descriptor_t idt[256]; 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]; struct boot_info_t boot_info = { .bootloader = bootloader_name, .parameters = kernel_parameters, .module_count = 0, .map = { .array = map_array, .size = 0, .capacity = 16}}; multiboot_info += 8; while (multiboot_info != NULL) { multiboot_info = read_multiboot_table(&boot_info, multiboot_info); } insert_region(&boot_info.map, 0, 1 << 22, M_UNAVAILABLE); 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*)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]); } memset(idt, 0, sizeof(struct interrupt_descriptor_t) * 256); 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_INT32, 0); create_interrupt_descriptor(&idt[EXCEPTION_PAGE_FAULT], (void*)isr_page_fault, INTERRPUT_INT32, 0); create_interrupt_descriptor(&idt[EXCEPTION_DOUBLE_FAULT], (void*)isr_double_fault, 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); lidt(idt); asm volatile( "mov $0xFF, %%al;" "outb %%al, $0xA1;" "outb %%al, $0x21;" ::: "al" ); apic_enable(page_stack); printf("spurious_interrupt_vector: %08x\n", *((uint32_t*) &apic_registers->spurious_iv)); printf("lvt_timer_vector: %08x\n", *((uint32_t*) &apic_registers->lvt_timer)); 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*512; 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)); asm("sti"); while(1) asm("hlt"); // TODO: enter first process }