diff --git a/src/kernel/boot.s b/src/kernel/boot.s index 4b38316..4e4ba36 100644 --- a/src/kernel/boot.s +++ b/src/kernel/boot.s @@ -26,7 +26,7 @@ stack_top: .include "./src/kernel/irq_table.s" .include "./src/kernel/idt/idt.s" .include "./src/kernel/paging.s" - +.include "./src/kernel/cpu.s" .global _start .type _start, @function diff --git a/src/kernel/cpu.h b/src/kernel/cpu.h index 6e9f95a..cd241c7 100644 --- a/src/kernel/cpu.h +++ b/src/kernel/cpu.h @@ -1,17 +1,53 @@ -#include // NOTE: Only available in GCC -// NOT currently usefull! -/* static int get_model(){ - int ebx, unused; - __cpuid(0, unused, ebx, unused, unused); - return ebx; - } +#pragma once - enum { - CPUID_FEAT_EDX_APIC = 1 << 9 - }; - static int check_apic (){ - unsigned int eax, unused, edx; - __get_cpuid(1, &eax, &unused, &unused, &edx); - return edx & CPUID_FEAT_EDX_APIC; - } -*/ \ No newline at end of file +/* +Based on Intel specifications. + +C++ interface for the cpu.s assembly file. + +©Nigel Barink - 2022 +*/ + + +/* +* EFLAGS FUNCTIONS +*/ + +extern "C" uint32_t GetEFLAGS(); + + + +/* +* CONTROL_REGISTER_0 FUNCTIONS +*/ +extern "C" uint32_t GetCR0(); + +/* + struct CR0_Register { + uint8_t PE :1; // Protection Mode Enabled 0 + uint8_t MP :1; // Monitor co-processor 1 + uint8_t EM :1; // Emulation 2 + uint8_t TS :1; // Task switched 3 + uint8_t ET :1; // Extension Type 4 + uint8_t NE :1; // Numeric error 5 + uint16_t Reserved :10; // 6,7,8,9,10,11,12,13,14,15 + uint8_t WP :1; // Write Protect 16 + uint8_t Reserved :1; // 17 + uint8_t AM :1; // Alligment Task 18 + uint16_t Reserved :10; // 19,20,21,22,23,24,25,26,27,28 + uint8_t NW :1; // Not-write through 29 + uint8_t CD :1; // Cache disable 30 + uint8_t PG :1; // Paging 31 + };*/ + + + +#define GET_PE_BIT(CONTROL_REGISTER_0) (CONTROL_REGISTER_0&0x1) +#define GET_MP_BIT(CONTROL_REGISTER_0) (CONTROL_REGISTER_0&0x2) +#define GET_EM_BIT(CONTROL_REGISTER_0) (CONTROL_REGISTER_0&0x3) +#define GET_TS_BIT(CONTROL_REGISTER_0) (CONTROL_REGISTER_0&0x4) +#define GET_ET_BIT(CONTROL_REGISTER_0) (CONTROL_REGISTER_0&0x5) +#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 diff --git a/src/kernel/cpu.s b/src/kernel/cpu.s new file mode 100644 index 0000000..aa662dd --- /dev/null +++ b/src/kernel/cpu.s @@ -0,0 +1,25 @@ +# Basic cpu functions +.globl GetCR0 +GetCR0: + push %ebp # save the base pointer on the stack + mov %esp, %ebp # Set the base pointer to the current stack pointer + + xor %eax, %eax # Clear EAX to make sure no weird stuff is going on + mov %cr0, %eax # Copy the value of the CR0 register into EAX + + mov %ebp, %esp # restore the base pointer + pop %ebp + ret + +.globl GetEFLAGS +GetEFLAGS: + push %ebp + mov %esp, %ebp + + xor %eax, %eax + pushfl # Push the EFLAGS register content onto the stack, should be pushfd but GAS apparently doesn't agree + mov 4(%esp) , %eax + + mov %ebp, %esp + pop %ebp + ret \ No newline at end of file diff --git a/src/kernel/memory/paging.cpp b/src/kernel/memory/paging.cpp index 9ea4859..70dd0a6 100644 --- a/src/kernel/memory/paging.cpp +++ b/src/kernel/memory/paging.cpp @@ -2,6 +2,9 @@ PageDirectoryEntry kernel_directory[MAX_DIRECTORY_ENTRIES]__attribute__((aligned(4096))); PageTableEntry first_page_table[1024]__attribute__((aligned(4096))); + + + #define KERNEL_VRT_MEMORY_BEGIN 0xC0000000 #define KERNEL_VRT_MEMORY_END 0xCFFFFFFF #define PAGE_SIZE 0xFA0; @@ -105,10 +108,29 @@ void Unmap(VIRTUAL_ADDRESS vaddr, PageDirectoryEntry& page_directory) void Enable() -{ +{ + + //TODO: Write protect will not be turned on + // for the moment altough according to the intel + // developer manual this should happen. + + uint32_t CR0; + + CR0 = GetCR0(); + printf("PG bit = %d \n" , GET_PG_BIT(CR0)); + printf("Load into CR3 address: 0x%x\n", (uint32_t)(&kernel_directory[0])); loadPageDirectory(&kernel_directory[0]); enablePaging(); printf("Paging enabled!\n"); + + + CR0 = GetCR0(); + printf("PG bit = %d \n" , GET_PG_BIT(CR0) ); + + + uint32_t EFLAGS = GetEFLAGS(); + + } diff --git a/src/kernel/memory/paging.h b/src/kernel/memory/paging.h index 789574e..612c757 100644 --- a/src/kernel/memory/paging.h +++ b/src/kernel/memory/paging.h @@ -2,7 +2,7 @@ #include "./memory.h" #include "./../tty/kterm.h" #include "paging.definitions.h" - +#include "../cpu.h" extern "C" void loadPageDirectory (uint32_t* addr ); extern "C" void enablePaging(); @@ -16,3 +16,5 @@ void FreePage(VIRTUAL_ADDRESS, PageDirectoryEntry&); void Map(PHYSICAL_ADDRESS, VIRTUAL_ADDRESS, PageDirectoryEntry&); void Unmap (VIRTUAL_ADDRESS, PageDirectoryEntry&); + + diff --git a/src/kernel/paging.s b/src/kernel/paging.s index fa25003..ca25a7d 100644 --- a/src/kernel/paging.s +++ b/src/kernel/paging.s @@ -1,10 +1,17 @@ +# NOTE: I wish this wasn't AT&T Syntax its horrible +# REMINDER: INSTRUCTION FROM_REGISTER, TO_REGISTER .globl enablePaging enablePaging: + # Create a new call frame push %ebp mov %esp, %ebp + + # Set the PG bit of CR0 mov %cr0, %eax or $0x80000000, %eax mov %eax, %cr0 + + # Restore to the previous call frame mov %ebp, %esp pop %ebp ret @@ -13,8 +20,25 @@ enablePaging: loadPageDirectory: push %ebp mov %esp, %ebp - mov 8(%esp), %eax - mov %eax, %cr3 + + /* NOTE: We should probably check if paging is already enabled. + Changing the CR3 register whilst paging is enabled might + result in unwanted behaviour (in the worst case) or cause a + fault (in the best case). + */ + + mov 8(%esp), %eax # Move the first argument in the eax register + + mov %eax, %cr3 # Move the value of eax into the CR3 register + + /* + Moving the value of the argument passed to this function + into the CR3 register will allow the MMU to access the paging + structure we setup in memory once we enable paging + */ + mov %ebp, %esp pop %ebp ret + +