[boot] Do address virtualization in the bootloader

More and more places in the kernel init code are taking addresses from
the bootloader and translating them to offset-mapped addresses. The
bootloader can do this, so it should.
This commit is contained in:
Justin C. Miller
2021-02-10 01:23:50 -08:00
parent 2d4a65c654
commit 793bba95b5
3 changed files with 26 additions and 11 deletions

View File

@@ -93,6 +93,8 @@ add_module(args::header *args, args::mod_type type, buffer &data)
m.type = type;
m.location = data.data;
m.size = data.size;
change_pointer(m.location);
}
/// Check that all required cpu features are supported
@@ -198,12 +200,15 @@ efi_main(uefi::handle image, uefi::system_table *st)
reinterpret_cast<kernel::entrypoint>(kernel.entrypoint);
status.next();
hw::setup_control_regs();
memory::virtualize(args->pml4, map, st->runtime_services);
status.next();
change_pointer(args);
change_pointer(args->pml4);
change_pointer(args->modules);
change_pointer(args->programs);
status.next();
kentry(args);

View File

@@ -105,7 +105,7 @@ kernel_main(args::header *header)
bool has_video = false;
if (header->video.size > 0) {
has_video = true;
fb = memory::to_virtual<args::framebuffer>(reinterpret_cast<uintptr_t>(&header->video));
fb = &header->video;
const args::framebuffer &video = header->video;
log::debug(logs::boot, "Framebuffer: %dx%d[%d] type %d @ %llx size %llx",
@@ -143,11 +143,10 @@ kernel_main(args::header *header)
for (size_t i = 0; i < header->num_modules; ++i) {
args::module &mod = header->modules[i];
void *virt = memory::to_virtual<void>(mod.location);
switch (mod.type) {
case args::mod_type::symbol_table:
new symbol_table {virt, mod.size};
new symbol_table {mod.location, mod.size};
break;
default:

View File

@@ -58,15 +58,18 @@ namespace kutil {
void kfree(void *p) { return g_kernel_heap.free(p); }
}
template <typename T>
uintptr_t
get_physical_page(T *p) {
return memory::page_align_down(reinterpret_cast<uintptr_t>(p));
}
void
memory_initialize_pre_ctors(args::header &kargs)
{
using kernel::args::frame_block;
// Clean out any remaning bootloader page table entries
page_table *kpml4 = static_cast<page_table*>(kargs.pml4);
for (unsigned i = 0; i < memory::pml4e_kernel; ++i)
kpml4->entries[i] = 0;
new (&g_kernel_heap) kutil::heap_allocator {heap_start, kernel_max_heap};
@@ -75,17 +78,21 @@ memory_initialize_pre_ctors(args::header &kargs)
// Mark all the things the bootloader allocated for us as used
g_frame_allocator.used(
reinterpret_cast<uintptr_t>(kargs.frame_blocks),
get_physical_page(&kargs),
memory::page_count(sizeof(kargs)));
g_frame_allocator.used(
get_physical_page(kargs.frame_blocks),
kargs.frame_block_pages);
g_frame_allocator.used(
reinterpret_cast<uintptr_t>(kargs.pml4),
get_physical_page(kargs.pml4),
kargs.table_pages);
for (unsigned i = 0; i < kargs.num_modules; ++i) {
const kernel::args::module &mod = kargs.modules[i];
g_frame_allocator.used(
reinterpret_cast<uintptr_t>(mod.location),
get_physical_page(mod.location),
memory::page_count(mod.size));
}
@@ -113,6 +120,10 @@ memory_initialize_pre_ctors(args::header &kargs)
memory::kernel_max_stacks,
vm_flags::write};
vm.add(memory::stacks_start, &g_kernel_stacks);
// Clean out any remaning bootloader page table entries
for (unsigned i = 0; i < memory::pml4e_kernel; ++i)
kpml4->entries[i] = 0;
}
void
@@ -122,7 +133,7 @@ memory_initialize_post_ctors(args::header &kargs)
vm.add(memory::buffers_start, &g_kernel_buffers);
g_frame_allocator.free(
reinterpret_cast<uintptr_t>(kargs.page_tables),
get_physical_page(kargs.page_tables),
kargs.table_count);
}