mirror of
https://github.com/wichtounet/thor-os.git
synced 2025-09-12 14:10:36 -04:00
Start review of memory
This commit is contained in:
parent
2ca91fd085
commit
a1c4e56a56
@ -32,6 +32,8 @@ constexpr T* page_align(T* addr){
|
||||
return reinterpret_cast<T*>((reinterpret_cast<uintptr_t>(addr) / paging::PAGE_SIZE) * paging::PAGE_SIZE);
|
||||
}
|
||||
|
||||
void init();
|
||||
|
||||
void* physical_address(void* virt);
|
||||
bool page_present(void* virt);
|
||||
bool page_free_or_set(void* virt, void* physical);
|
||||
|
@ -59,7 +59,7 @@ void setup_paging(){
|
||||
//PDPT[0] -> PDT
|
||||
*reinterpret_cast<uint32_t*>(PML4T + 1 * paging::PAGE_SIZE) = PML4T + 2 * paging::PAGE_SIZE + 0x7;
|
||||
|
||||
//PDT[0] -> PD
|
||||
//PD[0] -> PT
|
||||
*reinterpret_cast<uint32_t*>(PML4T + 2 * paging::PAGE_SIZE) = PML4T + 3 * paging::PAGE_SIZE + 0x7;
|
||||
|
||||
//Map the first MiB
|
||||
|
@ -64,12 +64,10 @@ create_irq_dummy 30
|
||||
create_irq_dummy 31
|
||||
|
||||
isr_common_handler:
|
||||
restore_kernel_segments
|
||||
//TODO Kernel segments should be restored
|
||||
|
||||
call _fault_handler
|
||||
|
||||
restore_user_segments
|
||||
|
||||
// TODO At this point, it is absolutely not safe to return since most
|
||||
// registers will get trashed the fault handler must hang
|
||||
|
||||
|
@ -6,6 +6,8 @@
|
||||
//=======================================================================
|
||||
|
||||
#include "kernel.hpp"
|
||||
#include "physical_allocator.hpp"
|
||||
#include "paging.hpp"
|
||||
#include "memory.hpp"
|
||||
#include "timer.hpp"
|
||||
#include "shell.hpp"
|
||||
@ -18,7 +20,6 @@
|
||||
#include "vesa.hpp"
|
||||
#include "console.hpp"
|
||||
#include "gdt.hpp"
|
||||
#include "physical_allocator.hpp"
|
||||
|
||||
extern "C" {
|
||||
|
||||
@ -31,15 +32,19 @@ void kernel_main(){
|
||||
|
||||
interrupt::setup_interrupts();
|
||||
|
||||
//Prepare memory
|
||||
init_physical_allocator();
|
||||
paging::init();
|
||||
init_memory_manager();
|
||||
|
||||
//Install drivers
|
||||
install_timer();
|
||||
//acpi::init();
|
||||
keyboard::install_driver();
|
||||
disks::detect_disks();
|
||||
vesa::init();
|
||||
|
||||
//Only install system calls when everything else is ready
|
||||
install_system_calls();
|
||||
|
||||
//Call global constructors
|
||||
|
@ -103,6 +103,8 @@ malloc_header_chunk* malloc_head = 0;
|
||||
uintptr_t min_address; //Address of the first block being allocated
|
||||
uintptr_t max_address; //Address of the next block being allocated
|
||||
|
||||
uintptr_t current_virtual = 0x400000;
|
||||
|
||||
uint64_t* allocate_block(uint64_t blocks){
|
||||
auto memory = allocate_physical_memory(blocks);
|
||||
|
||||
@ -116,9 +118,10 @@ uint64_t* allocate_block(uint64_t blocks){
|
||||
|
||||
max_address = memory;
|
||||
|
||||
auto block = reinterpret_cast<uint64_t*>(memory);
|
||||
paging::map_pages(reinterpret_cast<void*>(current_virtual), reinterpret_cast<void*>(memory), blocks);
|
||||
|
||||
paging::identity_map_pages(block, blocks);
|
||||
auto block = reinterpret_cast<uint64_t*>(current_virtual);
|
||||
current_virtual += blocks * BLOCK_SIZE;
|
||||
|
||||
_allocated_memory += blocks * BLOCK_SIZE;
|
||||
|
||||
|
@ -6,6 +6,7 @@
|
||||
//=======================================================================
|
||||
|
||||
#include "paging.hpp"
|
||||
#include "physical_allocator.hpp"
|
||||
|
||||
#include "stl/types.hpp"
|
||||
#include "stl/algorithms.hpp"
|
||||
@ -14,8 +15,8 @@ namespace {
|
||||
|
||||
typedef uint64_t* page_entry;
|
||||
typedef page_entry* pt_t;
|
||||
typedef pt_t* pdt_t;
|
||||
typedef pdt_t* pdpt_t;
|
||||
typedef pt_t* pd_t;
|
||||
typedef pd_t* pdpt_t;
|
||||
typedef pdpt_t* pml4t_t;
|
||||
|
||||
//Memory from 0x70000 can be used for pages
|
||||
@ -38,6 +39,45 @@ inline void flush_tlb(void* page){
|
||||
|
||||
} //end of anonymous namespace
|
||||
|
||||
void paging::init(){
|
||||
//PD[0] already points to a valid PT (0x73000)
|
||||
auto pt = reinterpret_cast<pt_t>(0x73000);
|
||||
|
||||
auto pd = reinterpret_cast<pd_t>(0x72000);
|
||||
|
||||
auto physical = allocate_physical_memory(1);
|
||||
|
||||
pt[256] = reinterpret_cast<page_entry>(physical | PRESENT | WRITE | USER);
|
||||
flush_tlb(reinterpret_cast<void*>(0x100000));
|
||||
|
||||
auto it = reinterpret_cast<size_t*>(0x100000);
|
||||
std::fill(it, it + paging::PAGE_SIZE / sizeof(size_t), 0);
|
||||
|
||||
pd[1] = reinterpret_cast<pt_t>(physical | PRESENT | WRITE | USER);
|
||||
|
||||
//Use PD[1] as pt
|
||||
pt = reinterpret_cast<pt_t>(0x100000);
|
||||
|
||||
for(size_t pd_index = 2; pd_index < 512; ++pd_index){
|
||||
//1. Allocate space for the new Page Table
|
||||
physical = allocate_physical_memory(1);
|
||||
|
||||
//2. Compute logical address
|
||||
uint64_t logical = 0x200000 + (pd_index - 2) * paging::PAGE_SIZE;
|
||||
|
||||
//2. Map it using the valid entries in the first PT
|
||||
pt[pd_index - 2] = reinterpret_cast<page_entry>(physical | PRESENT | WRITE | USER);
|
||||
flush_tlb(reinterpret_cast<void*>(logical));
|
||||
|
||||
//3. Clear the new PT
|
||||
it = reinterpret_cast<size_t*>(logical);
|
||||
std::fill(it, it + paging::PAGE_SIZE / sizeof(size_t), 0);
|
||||
|
||||
//4. Set it in PD
|
||||
pd[pd_index] = reinterpret_cast<pt_t>(physical | PRESENT | WRITE | USER);
|
||||
}
|
||||
}
|
||||
|
||||
//TODO Update to support offsets at the end of virt
|
||||
//TODO Improve to support a status
|
||||
void* paging::physical_address(void* virt){
|
||||
@ -54,8 +94,8 @@ void* paging::physical_address(void* virt){
|
||||
pml4t_t pml4t = reinterpret_cast<pml4t_t>(0x70000);
|
||||
|
||||
auto pdpt = reinterpret_cast<pdpt_t>(reinterpret_cast<uintptr_t>(pml4t[pml4]) & ~0xFFF);
|
||||
auto pdt = reinterpret_cast<pdt_t>(reinterpret_cast<uintptr_t>(pdpt[directory_ptr]) & ~0xFFF);
|
||||
auto pt = reinterpret_cast<pt_t>(reinterpret_cast<uintptr_t>(pdt[directory]) & ~0xFFF);
|
||||
auto pd = reinterpret_cast<pd_t>(reinterpret_cast<uintptr_t>(pdpt[directory_ptr]) & ~0xFFF);
|
||||
auto pt = reinterpret_cast<pt_t>(reinterpret_cast<uintptr_t>(pd[directory]) & ~0xFFF);
|
||||
return reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(pt[table]) & ~0xFFF);
|
||||
}
|
||||
|
||||
@ -76,12 +116,12 @@ bool paging::page_present(void* virt){
|
||||
return false;
|
||||
}
|
||||
|
||||
auto pdt = reinterpret_cast<pdt_t>(reinterpret_cast<uintptr_t>(pdpt[directory_ptr]) & ~0xFFF);
|
||||
if(!(reinterpret_cast<uintptr_t>(pdt[directory]) & PRESENT)){
|
||||
auto pd = reinterpret_cast<pd_t>(reinterpret_cast<uintptr_t>(pdpt[directory_ptr]) & ~0xFFF);
|
||||
if(!(reinterpret_cast<uintptr_t>(pd[directory]) & PRESENT)){
|
||||
return false;
|
||||
}
|
||||
|
||||
auto pt = reinterpret_cast<pt_t>(reinterpret_cast<uintptr_t>(pdt[directory]) & ~0xFFF);
|
||||
auto pt = reinterpret_cast<pt_t>(reinterpret_cast<uintptr_t>(pd[directory]) & ~0xFFF);
|
||||
return reinterpret_cast<uintptr_t>(pt[table]) & PRESENT;
|
||||
}
|
||||
|
||||
@ -120,17 +160,17 @@ bool paging::map(void* virt, void* physical, uint8_t flags){
|
||||
|
||||
//Init new page if necessary
|
||||
if(!(reinterpret_cast<uintptr_t>(pdpt[directory_ptr]) & PRESENT)){
|
||||
pdpt[directory_ptr] = reinterpret_cast<pdt_t>(init_new_page() | USER | WRITE | PRESENT);
|
||||
pdpt[directory_ptr] = reinterpret_cast<pd_t>(init_new_page() | USER | WRITE | PRESENT);
|
||||
}
|
||||
|
||||
auto pdt = reinterpret_cast<pdt_t>(reinterpret_cast<uintptr_t>(pdpt[directory_ptr]) & ~0xFFF);
|
||||
auto pd = reinterpret_cast<pd_t>(reinterpret_cast<uintptr_t>(pdpt[directory_ptr]) & ~0xFFF);
|
||||
|
||||
//Init new page if necessary
|
||||
if(!(reinterpret_cast<uintptr_t>(pdt[directory]) & PRESENT)){
|
||||
pdt[directory] = reinterpret_cast<pt_t>(init_new_page() | USER | WRITE | PRESENT);
|
||||
if(!(reinterpret_cast<uintptr_t>(pd[directory]) & PRESENT)){
|
||||
pd[directory] = reinterpret_cast<pt_t>(init_new_page() | USER | WRITE | PRESENT);
|
||||
}
|
||||
|
||||
auto pt = reinterpret_cast<pt_t>(reinterpret_cast<uintptr_t>(pdt[directory]) & ~0xFFF);
|
||||
auto pt = reinterpret_cast<pt_t>(reinterpret_cast<uintptr_t>(pd[directory]) & ~0xFFF);
|
||||
|
||||
//Check if the page is already present
|
||||
if(reinterpret_cast<uintptr_t>(pt[table]) & PRESENT){
|
||||
@ -204,14 +244,14 @@ bool paging::unmap(void* virt){
|
||||
return true;
|
||||
}
|
||||
|
||||
auto pdt = reinterpret_cast<pdt_t>(reinterpret_cast<uintptr_t>(pdpt[directory_ptr]) & ~0xFFF);
|
||||
auto pd = reinterpret_cast<pd_t>(reinterpret_cast<uintptr_t>(pdpt[directory_ptr]) & ~0xFFF);
|
||||
|
||||
//If not present, returns directly
|
||||
if(!(reinterpret_cast<uintptr_t>(pdt[directory]) & PRESENT)){
|
||||
if(!(reinterpret_cast<uintptr_t>(pd[directory]) & PRESENT)){
|
||||
return true;
|
||||
}
|
||||
|
||||
auto pt = reinterpret_cast<pt_t>(reinterpret_cast<uintptr_t>(pdt[directory]) & ~0xFFF);
|
||||
auto pt = reinterpret_cast<pt_t>(reinterpret_cast<uintptr_t>(pd[directory]) & ~0xFFF);
|
||||
|
||||
//Unmap the virtual address
|
||||
pt[table] = 0x0;
|
||||
|
Loading…
x
Reference in New Issue
Block a user