Make addresses more dynamic and flexible

This commit is contained in:
Baptiste Wicht 2016-07-31 14:18:22 +02:00
parent c8c1d914dc
commit f61b9b0e8d
5 changed files with 63 additions and 23 deletions

View File

@ -48,18 +48,18 @@ constexpr const auto pdpt_entries = entries(pdpte_allocations);
constexpr const auto pd_entries = entries(pde_allocations);
constexpr const auto pt_entries = entries(pte_allocations);
//Virtual address where the paging structures are stored
constexpr const size_t virtual_paging_start = 0x101000;
//Compute the start address of each structure
constexpr const size_t virtual_pml4t_start = virtual_paging_start;
constexpr const size_t virtual_pdpt_start = virtual_pml4t_start + paging::PAGE_SIZE;
constexpr const size_t virtual_pd_start = virtual_pdpt_start + pml4_entries * paging::PAGE_SIZE;
constexpr const size_t virtual_pt_start = virtual_pd_start + pdpt_entries * paging::PAGE_SIZE;
//Compute the amount of physical memory pages needed for the paging tables
constexpr const size_t physical_memory_pages = 1 + pml4_entries + pdpt_entries + pd_entries;
//Virtual address where the paging structures are stored
extern size_t virtual_paging_start;
//Compute the start address of each structure
extern size_t virtual_pml4t_start;
extern size_t virtual_pdpt_start;
extern size_t virtual_pd_start;
extern size_t virtual_pt_start;
//Flags
constexpr const uint8_t PRESENT = 0x1;
constexpr const uint8_t WRITE = 0x2;
@ -76,6 +76,7 @@ constexpr size_t page_align(size_t addr){
return (addr / paging::PAGE_SIZE) * paging::PAGE_SIZE;
}
void early_init();
void init();
void finalize();

View File

@ -48,6 +48,9 @@ void kernel_main(){
interrupt::setup_interrupts();
//Compute virtual addresses for paging
paging::early_init();
//Init the virtual allocator
virtual_allocator::init();

View File

@ -19,6 +19,13 @@
#include "fs/sysfs.hpp"
size_t paging::virtual_paging_start;
size_t paging::virtual_pml4t_start;
size_t paging::virtual_pdpt_start;
size_t paging::virtual_pd_start;
size_t paging::virtual_pt_start;
namespace {
typedef uint64_t* page_entry;
@ -49,7 +56,7 @@ constexpr size_t pt_entry(size_t virt){
return (virt >> 12) & 0x1FF;
}
constexpr pml4t_t find_pml4t(){
pml4t_t find_pml4t(){
return reinterpret_cast<pml4t_t>(paging::virtual_pml4t_start);
}
@ -100,6 +107,16 @@ size_t early_map_page_clear(size_t physical){
} //end of anonymous namespace
void paging::early_init(){
paging::virtual_paging_start = 0x101000;
//Compute the start address of each structure
paging::virtual_pml4t_start = virtual_paging_start;
paging::virtual_pdpt_start = virtual_pml4t_start + paging::PAGE_SIZE;
paging::virtual_pd_start = virtual_pdpt_start + pml4_entries * paging::PAGE_SIZE;
paging::virtual_pt_start = virtual_pd_start + pdpt_entries * paging::PAGE_SIZE;
}
void paging::init(){
//Get some physical memory
auto physical_memory = physical_allocator::early_allocate(physical_memory_pages);

View File

@ -11,6 +11,7 @@
#include "buddy_allocator.hpp"
#include "assert.hpp"
#include "logging.hpp"
#include "early_memory.hpp"
#include "fs/sysfs.hpp"
@ -74,22 +75,34 @@ void physical_allocator::early_init(){
k_print_line("e820 failed, no way to allocate memory");
suspend_boot();
}
}
size_t physical_allocator::early_allocate(size_t blocks){
if(!current_mmap_entry){
for(uint64_t i = 0; i < e820::mmap_entry_count(); ++i){
auto& entry = e820::mmap_entry(i);
bool found = false;
if(entry.type == 1 && entry.base >= 0x100000 && entry.size >= 16384){
current_mmap_entry = &entry;
current_mmap_entry_position = entry.base;
for(uint64_t i = 0; i < e820::mmap_entry_count(); ++i){
auto& entry = e820::mmap_entry(i);
if(entry.type == 1 && entry.base == kernel_address){
if(entry.size < kernel_mib() * 0x100000){
break;
}
current_mmap_entry = &entry;
current_mmap_entry_position = entry.base + kernel_mib() * 0x100000;
allocated_memory += kernel_mib() * 0x100000;
found = true;
break;
}
}
if(!found){
k_print_line("did not find any e820 for the kernel itself");
suspend_boot();
}
}
size_t physical_allocator::early_allocate(size_t blocks){
if(!current_mmap_entry){
return 0;
}

View File

@ -21,16 +21,17 @@
namespace {
constexpr const size_t virtual_start = paging::virtual_paging_start + (paging::physical_memory_pages * paging::PAGE_SIZE);
constexpr const size_t first_virtual_address = virtual_start % 0x100000 == 0 ? virtual_start : (virtual_start / 0x100000 + 1) * 0x100000;
constexpr const size_t last_virtual_address = virtual_allocator::kernel_virtual_size;
constexpr const size_t managed_space = last_virtual_address - first_virtual_address;
size_t virtual_start;
size_t first_virtual_address;
size_t last_virtual_address;
size_t managed_space;
constexpr const size_t unit = paging::PAGE_SIZE;
size_t allocated_pages = first_virtual_address / paging::PAGE_SIZE;
constexpr size_t array_size(int block){
return (managed_space / (block * unit) + 1) / (sizeof(uint64_t) * 8) + 1;
return (virtual_allocator::kernel_virtual_size / (block * unit) + 1) / (sizeof(uint64_t) * 8) + 1;
}
std::array<uint64_t, array_size(1)> data_bitmap_1;
@ -60,6 +61,11 @@ std::string sysfs_allocated(){
} //end of anonymous namespace
void virtual_allocator::init(){
virtual_start = paging::virtual_paging_start + (paging::physical_memory_pages * paging::PAGE_SIZE);
first_virtual_address = virtual_start % 0x100000 == 0 ? virtual_start : (virtual_start / 0x100000 + 1) * 0x100000;
last_virtual_address = virtual_allocator::kernel_virtual_size;
managed_space = last_virtual_address - first_virtual_address;
allocator.set_memory_range(first_virtual_address, last_virtual_address);
//Give room to the bitmaps