From 0b0e37b76253195c57100efc827e7bb7178d14ff Mon Sep 17 00:00:00 2001 From: Nigel Date: Wed, 17 Aug 2022 14:17:58 +0200 Subject: [PATCH] Paging cleanup, more cpu testing and psuedo code for higher half kernel --- src/kernel/cpu.h | 11 ++- src/kernel/cpu.s | 14 +++ src/kernel/idt/idt.cpp | 21 ++++- src/kernel/kernel.cpp | 5 +- src/kernel/memory/paging.cpp | 126 ++++++++++++++++--------- src/kernel/memory/paging.definitions.h | 5 +- src/kernel/memory/paging.h | 2 + 7 files changed, 130 insertions(+), 54 deletions(-) diff --git a/src/kernel/cpu.h b/src/kernel/cpu.h index cd241c7..97b50ab 100644 --- a/src/kernel/cpu.h +++ b/src/kernel/cpu.h @@ -50,4 +50,13 @@ extern "C" uint32_t GetCR0(); #define GET_NE_BIT(CONTROL_REGISTER_0) (CONTROL_REGISTER_0&0x6) -#define GET_PG_BIT(CONTROL_REGISTER_0) (CONTROL_REGISTER_0>>31) \ No newline at end of file +#define GET_PG_BIT(CONTROL_REGISTER_0) (CONTROL_REGISTER_0>>31) + +/* +* CONTROL_REGISTER_4 FUNCTIONS +*/ + +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) diff --git a/src/kernel/cpu.s b/src/kernel/cpu.s index aa662dd..9a40270 100644 --- a/src/kernel/cpu.s +++ b/src/kernel/cpu.s @@ -11,6 +11,20 @@ GetCR0: pop %ebp ret +.globl GetCR4 +GetCR4: + push %ebp + mov %esp, %ebp + + xor %eax, %eax + mov %cr4, %eax + + mov %ebp, %esp + pop %ebp + ret + + + .globl GetEFLAGS GetEFLAGS: push %ebp diff --git a/src/kernel/idt/idt.cpp b/src/kernel/idt/idt.cpp index 393902b..cc3db0c 100644 --- a/src/kernel/idt/idt.cpp +++ b/src/kernel/idt/idt.cpp @@ -128,9 +128,24 @@ void irs_handler (registers regs) { case 14: // Page Fault Exception #PF printf("#PF\n"); - printf("EIP: 0x%x\n", regs.eip); - printf("EAX: 0x%x\n", regs.eax); - printf("EBP: 0x%x\n", regs.ebp); + + 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 + + + // Error code of 32 bits are on the stack + // CR2 register contains the 32-bit linear address that generated the exception + // See Intel Software Developers manual Volume 3A Part 1 page 236 for more info + + + /* + Check the error code to figure out what happened here + */ + + + + break; case 16: diff --git a/src/kernel/kernel.cpp b/src/kernel/kernel.cpp index 12d1c79..25666ef 100644 --- a/src/kernel/kernel.cpp +++ b/src/kernel/kernel.cpp @@ -105,8 +105,9 @@ extern "C" void early_main(unsigned long magic, unsigned long addr){ - // memAlloc.free_block((void*) memory); - InitializePaging(); + //memAlloc.free_block((void*) memory); + //InitializePaging(); + IdentityMap(); Enable(); } diff --git a/src/kernel/memory/paging.cpp b/src/kernel/memory/paging.cpp index 70dd0a6..67df499 100644 --- a/src/kernel/memory/paging.cpp +++ b/src/kernel/memory/paging.cpp @@ -1,27 +1,17 @@ #include "paging.h" PageDirectoryEntry kernel_directory[MAX_DIRECTORY_ENTRIES]__attribute__((aligned(4096))); -PageTableEntry first_page_table[1024]__attribute__((aligned(4096))); +PageTableEntry first_page_table[MAX_PAGE_TABLE_ENTRIES]__attribute__((aligned(4096))); - - -#define KERNEL_VRT_MEMORY_BEGIN 0xC0000000 -#define KERNEL_VRT_MEMORY_END 0xCFFFFFFF -#define PAGE_SIZE 0xFA0; - - -void InitializePaging() -{ - - - printf("\nInit paging\n"); +void IdentityMap (){ + printf("\nInit paging\n"); // The basics as explained by wiki.osdev.org // Set all page_directories to not present int i = 0; while ( i < 1024) { - kernel_directory[i] = 0x00000002; + kernel_directory[i] = 0x2; i++; } @@ -31,12 +21,12 @@ void InitializePaging() for( j = 0; j < 1024; j++ ) { first_page_table[j] = (j * 0x1000) | 3 ; - /* - Attributes: - Supervisor Level , - read/write, - present, - */ + + //Attributes: + //Supervisor Level , + //read/write, + //present, + } @@ -45,38 +35,75 @@ void InitializePaging() kernel_directory[0] = ((unsigned int)first_page_table) | 3; printf("Init paging DONE\n"); - // NOTE: Adjust this as needed - - // BIOS Address Identity mapping - // Identity map the first 8MB ... Physical addresses 0x00000000 to 0x007A1200 +} + +void InitializePaging() +{ /* - - PHYSICAL_ADDRESS BIOSAddr = 0x00000000; - PHYSICAL_ADDRESS BIOSAddr_Max = 0x007A1200; - - do + Initial kernel page directory + set all page tables to not present + */ + for (int i = 0; i < MAX_DIRECTORY_ENTRIES; i++) { - Map( BIOSAddr, BIOSAddr, *kernel_directory); - BIOSAddr += PAGE_SIZE - } while(BIOSAddr <= BIOSAddr_Max); + kernel_directory[i] = 0x2; + } - // Identity map the kernel space + // BIOS Address Identity mapping + // Identity map the first 8MiB ... Physical addresses 0x00000000 to 0x007A1200 + PHYSICAL_ADDRESS BIOSAddr = 0x00000000; + PHYSICAL_ADDRESS BIOSAddr_Max = 0x800000; + + // How many PDE's do we need + uint8_t NUM_PDE = BIOSAddr_Max / (4 * 1024 * 1024); + + printf("The first 8MiB require %d Page Directory Entries\n", NUM_PDE); +/* + for( int i = 0; i < NUM_PDE; i++) + { + // setup a page table + PageTableEntry pagetable[MAX_PAGE_TABLE_ENTRIES] = PhysicalMemory::allocate_block(); // TODO :: Physical memory manager functions should be available here. + + for(int j = 0; j < MAX_PAGE_TABLE_ENTRIES; j++) + { + pagetable[j] = ( j * 4096 ) | 3; + } + + // add page table as page directory entry + kernel_directory[i] = ( (unsigned int) pagetable ) | 3; + } +*/ + // map the kernel space VIRTUAL_ADDRESS Vaddr = KERNEL_VRT_MEMORY_BEGIN; PHYSICAL_ADDRESS KernelAddr = kernel_begin; + PHYSICAL_ADDRESS KernelEndAddr = kernel_end; - do + uint32_t KernelSizeInBytes = (KernelEndAddr - KernelAddr); + printf("Kernel is 0x%x bytes\n", KernelSizeInBytes); + NUM_PDE = KernelSizeInBytes / (4 * 1024* 1024); + printf("Kernel requires %d Page Directory Entries\n", NUM_PDE); + +/* + for(int i = 0; i < NUM_PDE; i++) { - Map(KernelAddr, Vaddr , *kernel_directory); + PageTableEntry pageTable [MAX_PAGE_TABLE_ENTRIES] = PhysicalMemory::allocate_block(); + + for(int j = 0; j < MAX_PAGE_TABLE_ENTRIES; j++) + { + pageTable[j] = ( j * 4096) | 3; // NOTE: Check if page is actually supposed to be present + } + + // TODO: Calculate Page Directory index + - Vaddr += PAGE_SIZE; - KernelAddr += PAGE_SIZE } - while(KernelAddr < kernel_end); + */ + + - //TODO: Identity map VGA memory - */ + // Identity map VGA memory + // Calc which PDE adn } @@ -86,13 +113,11 @@ void AllocatePage(VIRTUAL_ADDRESS vaddr, PageDirectoryEntry& page_directory) } - void FreePage(VIRTUAL_ADDRESS vaddr , PageDirectoryEntry& page_directory) { } - void Map ( PHYSICAL_ADDRESS paddr, VIRTUAL_ADDRESS vaddr, PageDirectoryEntry& page_directory) { @@ -106,7 +131,6 @@ void Unmap(VIRTUAL_ADDRESS vaddr, PageDirectoryEntry& page_directory) } - void Enable() { @@ -127,10 +151,20 @@ void Enable() CR0 = GetCR0(); - printf("PG bit = %d \n" , GET_PG_BIT(CR0) ); + uint32_t CR4 = GetCR4(); + printf("PG bit = %d\n" , GET_PG_BIT(CR0) ); + printf("PAE bit = %d\n", GET_PAE_BIT(CR4)); + if(GET_PAE_BIT(CR4) == 0){ + printf("Using 32bit paging\n"); - uint32_t EFLAGS = GetEFLAGS(); - + if(GET_PSE_BIT(CR4) == 0 ){ + printf("Page size is 4KiB\n"); + } else { + printf("Page size is 4MiB\n"); + } + } else { + printf("Using some extended version for paging\n"); + } } diff --git a/src/kernel/memory/paging.definitions.h b/src/kernel/memory/paging.definitions.h index bd9c089..2f771f7 100644 --- a/src/kernel/memory/paging.definitions.h +++ b/src/kernel/memory/paging.definitions.h @@ -6,8 +6,6 @@ also 64 bit mode. */ - - #define MAX_DIRECTORY_ENTRIES 1024 #define MAX_PAGE_TABLE_ENTRIES 1024 #define MAX_PAGES 1024 @@ -19,6 +17,9 @@ #define PageTableEntry uint32_t +#define KERNEL_VRT_MEMORY_BEGIN 0xC0000000 +#define KERNEL_VRT_MEMORY_END 0xCFFFFFFF +#define PAGE_SIZE 4096; // NOTE: FIXME: I am fairly certain these masks are off by one! diff --git a/src/kernel/memory/paging.h b/src/kernel/memory/paging.h index 612c757..0c1979e 100644 --- a/src/kernel/memory/paging.h +++ b/src/kernel/memory/paging.h @@ -7,6 +7,8 @@ extern "C" void loadPageDirectory (uint32_t* addr ); extern "C" void enablePaging(); + +void IdentityMap(); void InitializePaging(); void Enable();