From d280aa0584a2334b16df03aab4b831e2644df87f Mon Sep 17 00:00:00 2001 From: Nigel Date: Fri, 19 Aug 2022 00:44:52 +0200 Subject: [PATCH] Page faults and protetion faults will now hang with a helpful message to explain what is going on. I removed previously set barriers from the code to load the kernel further. --- Makefile | 1 + src/kernel/Interrupts/idt/idt.cpp | 80 ++++++++++++++++++++++++++----- src/kernel/Memory/memory.cpp | 2 +- src/kernel/cpu.h | 12 +++++ src/kernel/cpu.s | 26 +++++++++- src/kernel/kernel.cpp | 52 ++++++++++++++------ src/kernel/kernel.h | 2 +- 7 files changed, 145 insertions(+), 30 deletions(-) diff --git a/Makefile b/Makefile index c8a3fa1..8b655ac 100644 --- a/Makefile +++ b/Makefile @@ -37,6 +37,7 @@ run: all $(EMULATOR) -cdrom build/barinkOS.iso -serial stdio -vga std -display gtk -m 2G -cpu core2duo debug: all + objcopy --only-keep-debug build/myos.bin kernel.sym $(EMULATOR) -cdrom build/barinkOS.iso -serial stdio -vga std -display gtk -m 2G -cpu core2duo -s -d int build_kernel: $(OBJ_LINK_LIST) diff --git a/src/kernel/Interrupts/idt/idt.cpp b/src/kernel/Interrupts/idt/idt.cpp index c043c1b..4c5f934 100644 --- a/src/kernel/Interrupts/idt/idt.cpp +++ b/src/kernel/Interrupts/idt/idt.cpp @@ -1,10 +1,11 @@ #include "idt.h" #include "../../Drivers/PIT/pit.h" #include "../../Drivers/PS-2/keyboard.h" - +#include "../../cpu.h" IDT_entry idt_table[256]; IDT_ptr idt_ptr; + void set_id_entry (uint8_t num , uint32_t base, uint16_t sel, uint8_t flags){ idt_table[num].offset_1 = base & 0xFFFF; idt_table[num].selector = sel; @@ -15,7 +16,7 @@ void set_id_entry (uint8_t num , uint32_t base, uint16_t sel, uint8_t flags){ }; void irs_handler (registers regs) { - + uint32_t FaultingAddress; //printf("(IRS) Interrupt number: %d \r", regs.int_no); switch (regs.int_no) { @@ -120,28 +121,83 @@ void irs_handler (registers regs) { case 13: // General Protection Exception #GP printf("#GP\n"); - printf("EIP: 0x%x\n", regs.eip); - printf("EAX: 0x%x\n", regs.eax); - printf("EBP: 0x%x\n", regs.ebp); + + + printf("ERR_CODE: 0x%x", regs.err_code); + + if( regs.err_code & 0x1) + { + printf("Originated externally!"); + } + + if(regs.err_code & 0x3 >> 1 == 0 ){ + printf("Index references GDT"); + } + if(regs.err_code & 0x3 >> 1 == 1 ){ + printf("Index references IDT"); + } + + if(regs.err_code & 0x3 >> 1 == 2 ){ + printf("Index references LDT"); + } + + if(regs.err_code & 0x3 >> 1 == 4 ){ + printf("Index references IDT"); + } + + + printf("Index: ", (regs.err_code >> 3 & 0xFFF ) ); + + __asm__("cli;" "1: hlt;" "jmp 1b;"); + break; case 14: // Page Fault Exception #PF printf("#PF\n"); - printf("EIP: 0x%x\n", regs.eip); // Points to faulting instruction ??? - printf("EAX: 0x%x\n", regs.eax); - printf("EBP: 0x%x\n", regs.ebp); // Base pointer pointing to the bottom of the stack - - + FaultingAddress = GetCR2(); + printf("Faulting instruction adddress: 0x%x\n", FaultingAddress); + // Error code of 32 bits are on the stack - // CR2 register contains the 32-bit linear address that generated the exception + // CR2 register contains the 32-bit linear virtual address that generated the exception // See Intel Software Developers manual Volume 3A Part 1 page 236 for more info - + #define PF_ERR_PRESENT_BIT 0x1 + #define PF_ERR_WRITE_BIT 0x2 + #define PF_ERR_USER_BIT 0x3 + #define PF_ERR_RESERVERD_WRITE_BIT 0x4 + #define PF_ERR_INSTRUCTION_FETCH_BIT 0x5 + #define PF_ERR_PROTECTION_KEY_BIT 0x6 + #define PF_ERR_SHADOW_STACK_BIT 0x7 + #define PF_ERR_SOFTWARE_GUARD_EXTENSION_BIT 0xE + + printf("Determining cause of fault...\n"); + + + if (regs.err_code & PF_ERR_PRESENT_BIT ){ + printf("Page protection violation!\n"); + } else{ + printf("page not-present!\n"); + } + + if(regs.err_code & PF_ERR_WRITE_BIT){ + printf("Write access violation!\n"); + } else{ + printf("Read access violation!\n"); + } + + if(regs.err_code & PF_ERR_USER_BIT){ + printf("Violation from user-space (CPL=3)\n"); + } + + if(regs.err_code & PF_ERR_INSTRUCTION_FETCH_BIT){ + printf("Caused by an instruction fetch. \n"); + } /* Check the error code to figure out what happened here */ + __asm__("cli;" "1: hlt;" "jmp 1b;"); diff --git a/src/kernel/Memory/memory.cpp b/src/kernel/Memory/memory.cpp index b72e786..3106c7c 100644 --- a/src/kernel/Memory/memory.cpp +++ b/src/kernel/Memory/memory.cpp @@ -10,7 +10,7 @@ void PhysicalMemory::setup( MemoryInfo* memory) { used_blocks = 0; - memoryBitMap = (uint32_t*) 0x00a00000; + memoryBitMap = (uint32_t*) 0xCCA00000; printf("Maximum Number of blocks: 0x%x, Number of bytes for memMap: 0x%x\n", max_blocks , (max_blocks/8)); diff --git a/src/kernel/cpu.h b/src/kernel/cpu.h index 97b50ab..94d9485 100644 --- a/src/kernel/cpu.h +++ b/src/kernel/cpu.h @@ -60,3 +60,15 @@ extern "C" uint32_t GetCR4(); #define GET_PSE_BIT(CONTROL_REGISTER_4) (CONTROL_REGISTER_4&0x4) #define GET_PAE_BIT(CONTROL_REGISTER_4) (CONTROL_REGISTER_4&0x5) + +/* +* CONTROL_REGISTER_2 FUNCTIONS +*/ + +extern "C" uint32_t GetCR2(); + +/* +* CONTROL_REGISTER_3 FUNCTIONS +*/ + +extern "C" uint32_t GetCR3(); \ No newline at end of file diff --git a/src/kernel/cpu.s b/src/kernel/cpu.s index 9a40270..2df41db 100644 --- a/src/kernel/cpu.s +++ b/src/kernel/cpu.s @@ -36,4 +36,28 @@ GetEFLAGS: mov %ebp, %esp pop %ebp - ret \ No newline at end of file + ret + +.globl GetCR2 +GetCR2: + push %ebp + mov %esp, %ebp + + xor %eax, %eax + mov %cr2, %eax + + mov %ebp, %esp + pop %ebp + ret + +.globl GetCR3 +GetCR3: + push %ebp + mov %esp, %ebp + + xor %eax, %eax + mov %cr3, %eax + + mov %ebp, %esp + pop %ebp + ret diff --git a/src/kernel/kernel.cpp b/src/kernel/kernel.cpp index 3251521..8409b44 100644 --- a/src/kernel/kernel.cpp +++ b/src/kernel/kernel.cpp @@ -2,8 +2,7 @@ extern "C" void kernel_main (BootInfo* bootinfo) { - init_serial(); - //pit_initialise(); + pit_initialise(); startSuperVisorTerminal(bootinfo); } @@ -17,9 +16,38 @@ extern "C" void early_main(unsigned long magic, unsigned long addr){ initGDT(); kterm_init(); init_serial(); - print_serial("Hello Higher half kernel!"); - printf("DDDDDDDDDDDDDDDD"); - return; + print_serial("Hello Higher half kernel!\n"); + + init_idt(); + // Enable interrupts + asm volatile("STI"); + + // map the multiboot structure into virtual memory + // so we can gather the necessary data from it. + /* const uint32_t KERNEL_BASE_ADDR = 0xC0000000; + + uint32_t pageDirectoryIndex = (addr + KERNEL_BASE_ADDR) >> 22; + printf("pageDirectoryIndex: %d\n", pageDirectoryIndex); + + uint32_t pageTableIndex = (addr + KERNEL_BASE_ADDR >> 12) & 0x1FFF; + printf("PagTableIndex: %d\n", pageTableIndex); + + printf("boot_page_directory addr: 0x%x\n", &boot_page_directory); + printf("boot_page_table addr: 0x%x\n", &boot_page_table); + + uint32_t* pageDirectoryEntry = (uint32_t*) ((uint32_t) &boot_page_directory) + (pageDirectoryIndex * 4); + printf("page_directory_entry addr: 0x%x\n", pageDirectoryEntry); + + *pageDirectoryEntry = ( addr & 0xFFFFF000 ) | 0x003; + + uint32_t* page_table_entry = (uint32_t*) ((uint32_t) &boot_page_table) + ( pageTableIndex * 4); + printf("page_table_entry addr: 0x%x\n" , page_table_entry); + + *page_table_entry = addr | 0x003; + + // Reload CR3 to force a flush + asm("movl %cr3, %ecx;" "movl %ecx, %cr3" ); + */ /** * Check Multiboot magic number * NOTE: Printf call should not be a thing this early on ... @@ -33,8 +61,7 @@ extern "C" void early_main(unsigned long magic, unsigned long addr){ * Show a little banner for cuteness */ printf("|=== BarinkOS ===|\n"); - printf("Kernel Begin AT(0x%x)", kernel_begin); - + /** * Use the address given as an argument as the pointer * to a Multiboot information structure. @@ -111,16 +138,11 @@ extern "C" void early_main(unsigned long magic, unsigned long addr){ //InitializePaging(); //IdentityMap(); //Enable(); + } else{ + printf("memory flag not set!"); } - //initGDT(); - //init_idt(); - // Enable interrupts - //asm volatile("STI"); - - - //CheckMBT( (multiboot_info_t *) addr); - + CheckMBT( (multiboot_info_t *) addr); kernel_main(&bootinfo); diff --git a/src/kernel/kernel.h b/src/kernel/kernel.h index 1f15f6a..d9c6a9c 100644 --- a/src/kernel/kernel.h +++ b/src/kernel/kernel.h @@ -28,7 +28,7 @@ extern "C" #include "time.h" #include "SuperVisorTerminal/superVisorTerminal.h" -#define CHECK_FLAG(flags, bit) ((flags) & (1 <<(bit))) +#define CHECK_FLAG(flag, bit) ( flag & (1 << bit )) #define PANIC(message) {return;}