Start review of memory

This commit is contained in:
Baptiste Wicht 2014-01-21 22:31:19 +01:00
parent 2ca91fd085
commit a1c4e56a56
6 changed files with 70 additions and 22 deletions

View File

@ -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);

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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;