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