Paging cleanup, more cpu testing and psuedo code for higher half kernel

dev
Nigel Barink 2022-08-17 14:17:58 +02:00
parent 388ac8e7f9
commit 0b0e37b762
7 changed files with 130 additions and 54 deletions

View File

@ -50,4 +50,13 @@ extern "C" uint32_t GetCR0();
#define GET_NE_BIT(CONTROL_REGISTER_0) (CONTROL_REGISTER_0&0x6) #define GET_NE_BIT(CONTROL_REGISTER_0) (CONTROL_REGISTER_0&0x6)
#define GET_PG_BIT(CONTROL_REGISTER_0) (CONTROL_REGISTER_0>>31) #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)

View File

@ -11,6 +11,20 @@ GetCR0:
pop %ebp pop %ebp
ret ret
.globl GetCR4
GetCR4:
push %ebp
mov %esp, %ebp
xor %eax, %eax
mov %cr4, %eax
mov %ebp, %esp
pop %ebp
ret
.globl GetEFLAGS .globl GetEFLAGS
GetEFLAGS: GetEFLAGS:
push %ebp push %ebp

View File

@ -128,9 +128,24 @@ void irs_handler (registers regs) {
case 14: case 14:
// Page Fault Exception #PF // Page Fault Exception #PF
printf("#PF\n"); printf("#PF\n");
printf("EIP: 0x%x\n", regs.eip);
printf("EAX: 0x%x\n", regs.eax); printf("EIP: 0x%x\n", regs.eip); // Points to faulting instruction ???
printf("EBP: 0x%x\n", regs.ebp); 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; break;
case 16: case 16:

View File

@ -105,8 +105,9 @@ extern "C" void early_main(unsigned long magic, unsigned long addr){
// memAlloc.free_block((void*) memory); //memAlloc.free_block((void*) memory);
InitializePaging(); //InitializePaging();
IdentityMap();
Enable(); Enable();
} }

View File

@ -1,27 +1,17 @@
#include "paging.h" #include "paging.h"
PageDirectoryEntry kernel_directory[MAX_DIRECTORY_ENTRIES]__attribute__((aligned(4096))); 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)));
void IdentityMap (){
printf("\nInit paging\n");
#define KERNEL_VRT_MEMORY_BEGIN 0xC0000000
#define KERNEL_VRT_MEMORY_END 0xCFFFFFFF
#define PAGE_SIZE 0xFA0;
void InitializePaging()
{
printf("\nInit paging\n");
// The basics as explained by wiki.osdev.org // The basics as explained by wiki.osdev.org
// Set all page_directories to not present // Set all page_directories to not present
int i = 0; int i = 0;
while ( i < 1024) while ( i < 1024)
{ {
kernel_directory[i] = 0x00000002; kernel_directory[i] = 0x2;
i++; i++;
} }
@ -31,12 +21,12 @@ void InitializePaging()
for( j = 0; j < 1024; j++ ) for( j = 0; j < 1024; j++ )
{ {
first_page_table[j] = (j * 0x1000) | 3 ; first_page_table[j] = (j * 0x1000) | 3 ;
/*
Attributes: //Attributes:
Supervisor Level , //Supervisor Level ,
read/write, //read/write,
present, //present,
*/
} }
@ -45,38 +35,75 @@ void InitializePaging()
kernel_directory[0] = ((unsigned int)first_page_table) | 3; kernel_directory[0] = ((unsigned int)first_page_table) | 3;
printf("Init paging DONE\n"); printf("Init paging DONE\n");
// NOTE: Adjust this as needed }
// BIOS Address Identity mapping void InitializePaging()
// Identity map the first 8MB ... Physical addresses 0x00000000 to 0x007A1200 {
/* /*
Initial kernel page directory
PHYSICAL_ADDRESS BIOSAddr = 0x00000000; set all page tables to not present
PHYSICAL_ADDRESS BIOSAddr_Max = 0x007A1200; */
for (int i = 0; i < MAX_DIRECTORY_ENTRIES; i++)
do
{ {
Map( BIOSAddr, BIOSAddr, *kernel_directory); kernel_directory[i] = 0x2;
BIOSAddr += PAGE_SIZE }
} while(BIOSAddr <= BIOSAddr_Max);
// 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; VIRTUAL_ADDRESS Vaddr = KERNEL_VRT_MEMORY_BEGIN;
PHYSICAL_ADDRESS KernelAddr = kernel_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 FreePage(VIRTUAL_ADDRESS vaddr , PageDirectoryEntry& page_directory)
{ {
} }
void Map ( PHYSICAL_ADDRESS paddr, 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() void Enable()
{ {
@ -127,10 +151,20 @@ void Enable()
CR0 = GetCR0(); 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");
}
} }

View File

@ -6,8 +6,6 @@
also 64 bit mode. also 64 bit mode.
*/ */
#define MAX_DIRECTORY_ENTRIES 1024 #define MAX_DIRECTORY_ENTRIES 1024
#define MAX_PAGE_TABLE_ENTRIES 1024 #define MAX_PAGE_TABLE_ENTRIES 1024
#define MAX_PAGES 1024 #define MAX_PAGES 1024
@ -19,6 +17,9 @@
#define PageTableEntry uint32_t #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! // NOTE: FIXME: I am fairly certain these masks are off by one!

View File

@ -7,6 +7,8 @@
extern "C" void loadPageDirectory (uint32_t* addr ); extern "C" void loadPageDirectory (uint32_t* addr );
extern "C" void enablePaging(); extern "C" void enablePaging();
void IdentityMap();
void InitializePaging(); void InitializePaging();
void Enable(); void Enable();