Merge into main the new state of the operating system/kernel #1
@ -26,7 +26,7 @@ stack_top:
|
|||||||
.include "./src/kernel/irq_table.s"
|
.include "./src/kernel/irq_table.s"
|
||||||
.include "./src/kernel/idt/idt.s"
|
.include "./src/kernel/idt/idt.s"
|
||||||
.include "./src/kernel/paging.s"
|
.include "./src/kernel/paging.s"
|
||||||
|
.include "./src/kernel/cpu.s"
|
||||||
|
|
||||||
.global _start
|
.global _start
|
||||||
.type _start, @function
|
.type _start, @function
|
||||||
|
@ -1,17 +1,53 @@
|
|||||||
#include <cpuid.h> // NOTE: Only available in GCC
|
#pragma once
|
||||||
// NOT currently usefull!
|
|
||||||
/* static int get_model(){
|
|
||||||
int ebx, unused;
|
|
||||||
__cpuid(0, unused, ebx, unused, unused);
|
|
||||||
return ebx;
|
|
||||||
}
|
|
||||||
|
|
||||||
enum {
|
/*
|
||||||
CPUID_FEAT_EDX_APIC = 1 << 9
|
Based on Intel specifications.
|
||||||
};
|
|
||||||
static int check_apic (){
|
C++ interface for the cpu.s assembly file.
|
||||||
unsigned int eax, unused, edx;
|
|
||||||
__get_cpuid(1, &eax, &unused, &unused, &edx);
|
©Nigel Barink - 2022
|
||||||
return edx & CPUID_FEAT_EDX_APIC;
|
*/
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
/*
|
||||||
|
* 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)
|
25
src/kernel/cpu.s
Normal file
25
src/kernel/cpu.s
Normal file
@ -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
|
@ -2,6 +2,9 @@
|
|||||||
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[1024]__attribute__((aligned(4096)));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#define KERNEL_VRT_MEMORY_BEGIN 0xC0000000
|
#define KERNEL_VRT_MEMORY_BEGIN 0xC0000000
|
||||||
#define KERNEL_VRT_MEMORY_END 0xCFFFFFFF
|
#define KERNEL_VRT_MEMORY_END 0xCFFFFFFF
|
||||||
#define PAGE_SIZE 0xFA0;
|
#define PAGE_SIZE 0xFA0;
|
||||||
@ -105,10 +108,29 @@ void Unmap(VIRTUAL_ADDRESS vaddr, PageDirectoryEntry& page_directory)
|
|||||||
|
|
||||||
|
|
||||||
void Enable()
|
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]));
|
printf("Load into CR3 address: 0x%x\n", (uint32_t)(&kernel_directory[0]));
|
||||||
loadPageDirectory(&kernel_directory[0]);
|
loadPageDirectory(&kernel_directory[0]);
|
||||||
enablePaging();
|
enablePaging();
|
||||||
|
|
||||||
printf("Paging enabled!\n");
|
printf("Paging enabled!\n");
|
||||||
|
|
||||||
|
|
||||||
|
CR0 = GetCR0();
|
||||||
|
printf("PG bit = %d \n" , GET_PG_BIT(CR0) );
|
||||||
|
|
||||||
|
|
||||||
|
uint32_t EFLAGS = GetEFLAGS();
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
#include "./memory.h"
|
#include "./memory.h"
|
||||||
#include "./../tty/kterm.h"
|
#include "./../tty/kterm.h"
|
||||||
#include "paging.definitions.h"
|
#include "paging.definitions.h"
|
||||||
|
#include "../cpu.h"
|
||||||
|
|
||||||
extern "C" void loadPageDirectory (uint32_t* addr );
|
extern "C" void loadPageDirectory (uint32_t* addr );
|
||||||
extern "C" void enablePaging();
|
extern "C" void enablePaging();
|
||||||
@ -16,3 +16,5 @@ void FreePage(VIRTUAL_ADDRESS, PageDirectoryEntry&);
|
|||||||
|
|
||||||
void Map(PHYSICAL_ADDRESS, VIRTUAL_ADDRESS, PageDirectoryEntry&);
|
void Map(PHYSICAL_ADDRESS, VIRTUAL_ADDRESS, PageDirectoryEntry&);
|
||||||
void Unmap (VIRTUAL_ADDRESS, PageDirectoryEntry&);
|
void Unmap (VIRTUAL_ADDRESS, PageDirectoryEntry&);
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,10 +1,17 @@
|
|||||||
|
# NOTE: I wish this wasn't AT&T Syntax its horrible
|
||||||
|
# REMINDER: INSTRUCTION FROM_REGISTER, TO_REGISTER
|
||||||
.globl enablePaging
|
.globl enablePaging
|
||||||
enablePaging:
|
enablePaging:
|
||||||
|
# Create a new call frame
|
||||||
push %ebp
|
push %ebp
|
||||||
mov %esp, %ebp
|
mov %esp, %ebp
|
||||||
|
|
||||||
|
# Set the PG bit of CR0
|
||||||
mov %cr0, %eax
|
mov %cr0, %eax
|
||||||
or $0x80000000, %eax
|
or $0x80000000, %eax
|
||||||
mov %eax, %cr0
|
mov %eax, %cr0
|
||||||
|
|
||||||
|
# Restore to the previous call frame
|
||||||
mov %ebp, %esp
|
mov %ebp, %esp
|
||||||
pop %ebp
|
pop %ebp
|
||||||
ret
|
ret
|
||||||
@ -13,8 +20,25 @@ enablePaging:
|
|||||||
loadPageDirectory:
|
loadPageDirectory:
|
||||||
push %ebp
|
push %ebp
|
||||||
mov %esp, %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
|
mov %ebp, %esp
|
||||||
pop %ebp
|
pop %ebp
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user