Merge into main the new state of the operating system/kernel #1
@ -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)
 | 
			
		||||
#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)
 | 
			
		||||
 | 
			
		||||
@ -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 
 | 
			
		||||
 | 
			
		||||
@ -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:
 | 
			
		||||
 | 
			
		||||
@ -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();
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
@ -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");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -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!
 | 
			
		||||
 | 
			
		||||
@ -7,6 +7,8 @@
 | 
			
		||||
extern "C" void loadPageDirectory (uint32_t* addr );
 | 
			
		||||
extern "C" void enablePaging();
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void IdentityMap();
 | 
			
		||||
void InitializePaging();
 | 
			
		||||
 | 
			
		||||
void Enable();
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user