[boot] Virtualize memory in the bootloader

Finish updating the page tables, call UEFI's `set_virtual_address_map`
and jump to the kernel!
This commit is contained in:
Justin C. Miller
2020-05-21 23:49:49 -07:00
parent 6a538ad4f3
commit b491a09686
6 changed files with 89 additions and 74 deletions

View File

@@ -1,3 +1,5 @@
#include "kernel_memory.h"
#include "console.h"
#include "error.h"
#include "loader.h"
@@ -123,7 +125,46 @@ private:
};
void allocate_tables(kernel::args::header *args, uefi::boot_services *bs)
static void
add_offset_mappings(page_table *pml4, void *&page_cache, uint32_t &num_pages)
{
uintptr_t phys = 0;
uintptr_t virt = ::memory::page_offset; // Start of offset-mapped area
size_t pages = 64 * 1024; // 64 TiB of 1 GiB pages
constexpr size_t GiB = 0x40000000ull;
page_entry_iterator<2> iterator{
virt, pml4,
page_cache,
num_pages};
while (true) {
*iterator = phys | huge_page_flags;
if (--pages == 0)
break;
iterator.increment();
phys += GiB;
}
}
void
add_current_mappings(page_table *new_pml4)
{
// Get the pointer to the current PML4
page_table *old_pml4 = 0;
asm volatile ( "mov %%cr3, %0" : "=r" (old_pml4) );
// Only copy mappings in the lower half
for (int i = 0; i < 256; ++i) {
uint64_t entry = old_pml4->entries[i];
if (entry & 1)
new_pml4->entries[i] = entry;
}
}
void
allocate_tables(kernel::args::header *args, uefi::boot_services *bs)
{
status_line status(L"Allocating initial page tables");
@@ -151,25 +192,7 @@ void allocate_tables(kernel::args::header *args, uefi::boot_services *bs)
args->page_table_cache = offset_ptr<void>(addr, page_size);
page_table *pml4 = reinterpret_cast<page_table*>(addr);
uintptr_t phys = 0;
uintptr_t virt = 0xffffc00000000000ull; // Start of offset-mapped area
size_t pages = 64 * 1024; // 64 TiB of 1 GiB pages
constexpr size_t GiB = 0x40000000ull;
page_entry_iterator<2> iterator{
virt, pml4,
args->page_table_cache,
args->num_free_tables};
while (true) {
*iterator = phys | huge_page_flags;
if (--pages == 0)
break;
iterator.increment();
phys += GiB;
}
add_offset_mappings(pml4, args->page_table_cache, args->num_free_tables);
console::print(L" Set up initial mappings, %d spare tables.\r\n", args->num_free_tables);
}