Add HURL; relocate kernel virtual regions

This commit is contained in:
Josh Holtrop 2022-03-26 10:41:53 -04:00
parent f761d0a445
commit 8498de6b62
6 changed files with 61 additions and 26 deletions

View File

@ -48,6 +48,21 @@ private ulong hulk_stack_size()
return hulk_header().stack_size; return hulk_header().stack_size;
} }
private ulong hulk_virt_base_address()
{
return hulk_header().virt_base;
}
private ulong hulk_virt_stack_top()
{
return hulk_header().virt_stack_top;
}
private ulong hulk_virt_framebuffer_address()
{
return hulk_header().virt_fb_buffer;
}
/** /**
* Detect if we're running in QEMU. * Detect if we're running in QEMU.
*/ */
@ -326,13 +341,13 @@ private void map2m(ulong source_page, ulong dest_page, PageTableEntry * pt_base)
private void map_hulk(PageTableEntry * pt_base, ulong bss_phys, ulong stack_phys) private void map_hulk(PageTableEntry * pt_base, ulong bss_phys, ulong stack_phys)
{ {
/* Map HULK bin region. */ /* Map HULK bin region. */
ulong virt = HULK_VIRTUAL_START; ulong virt = hulk_virt_base_address();
map4kregion(virt, hulk_bin_phys(), hulk_bin_size(), pt_base); map4kregion(virt, hulk_bin_phys(), hulk_bin_size(), pt_base);
/* Map HULK bss region. */ /* Map HULK bss region. */
virt += hulk_bin_size(); virt += hulk_bin_size();
map4kregion(virt, bss_phys, hulk_bss_size(), pt_base); map4kregion(virt, bss_phys, hulk_bss_size(), pt_base);
/* Map HULK stack. */ /* Map HULK stack. */
virt += hulk_bss_size(); virt = hulk_virt_stack_top() - hulk_stack_size();
map4kregion(virt, stack_phys, hulk_stack_size(), pt_base); map4kregion(virt, stack_phys, hulk_stack_size(), pt_base);
} }
@ -352,23 +367,18 @@ private void build_page_tables(ulong max_physical_address, ulong bss_phys, ulong
/* Map any memory regions that are outside physical RAM. */ /* Map any memory regions that are outside physical RAM. */
for (size_t i = 0u; i < bootinfo.memory_map_count; i++) for (size_t i = 0u; i < bootinfo.memory_map_count; i++)
{ {
if (bootinfo.memory_map[i].base > max_physical_address) ulong addr = bootinfo.memory_map[i].base;
if (addr >= max_physical_address)
{ {
for (size_t offset = 0u; offset < bootinfo.memory_map[i].size; offset += 4096u) map4kregion(addr, addr, bootinfo.memory_map[i].size, pt_base);
{
ulong addr = bootinfo.memory_map[i].base + offset;
map4k(addr, addr, pt_base);
}
} }
} }
/* Map graphics framebuffer. */ /* Map graphics framebuffer. */
ulong framebuffer_size = bootinfo.fb.height * bootinfo.fb.stride * 4u; ulong framebuffer_size = bootinfo.fb.height * bootinfo.fb.stride * 4u;
for (size_t offset = 0u; offset < framebuffer_size; offset += 4096u) ulong fb_phys = cast(ulong)bootinfo.fb.buffer;
{ ulong fb_virt = hulk_virt_framebuffer_address();
ulong addr = cast(ulong)bootinfo.fb.buffer + offset; map4kregion(fb_virt, fb_phys, framebuffer_size, pt_base);
map4k(addr, addr, pt_base); /* Map HULK regions. */
}
/* Map HULK to its requested starting virtual address. */
map_hulk(pt_base, bss_phys, stack_phys); map_hulk(pt_base, bss_phys, stack_phys);
/* Switch to the new page table. */ /* Switch to the new page table. */
write_cr3(cast(ulong)pt_base); write_cr3(cast(ulong)pt_base);
@ -377,12 +387,12 @@ private void build_page_tables(ulong max_physical_address, ulong bss_phys, ulong
/** /**
* Jump to HULK entry point. * Jump to HULK entry point.
*/ */
private void jump_to_hulk(ulong stack_end) private void jump_to_hulk()
{ {
__asm( __asm(
"jmpq *$0", "jmpq *$0",
"r,{rdi},{rsp}", "r,{rdi},{rsp}",
hulk_header().entry, &bootinfo, stack_end); hulk_header().entry, &bootinfo, hulk_virt_stack_top());
} }
/** /**
@ -434,7 +444,7 @@ extern (C) EFI_STATUS efi_main(EFI_HANDLE image_handle, EFI_SYSTEM_TABLE * st)
bootinfo.bss_phys = bss_phys; bootinfo.bss_phys = bss_phys;
bootinfo.stack_phys = stack_phys; bootinfo.stack_phys = stack_phys;
jump_to_hulk(stack_phys + hulk_stack_size()); jump_to_hulk();
return EFI_SUCCESS; return EFI_SUCCESS;
} }

View File

@ -13,7 +13,7 @@ struct BootInfo
*/ */
struct Framebuffer struct Framebuffer
{ {
/** Framebuffer base address. */ /** Framebuffer physical base address. */
uint * buffer; uint * buffer;
/** Horizontal resolution. */ /** Horizontal resolution. */
uint width; uint width;
@ -68,6 +68,3 @@ struct BootInfo
/* Physical address of stack while jumping to HULK. */ /* Physical address of stack while jumping to HULK. */
ulong stack_phys; ulong stack_phys;
} }
/** HULK base virtual address. */
enum ulong HULK_VIRTUAL_START = 0x0000_4000_0000_0000u;

View File

@ -23,4 +23,13 @@ struct Header
/** Stack size. */ /** Stack size. */
ulong stack_size; ulong stack_size;
/** Virtual base address. */
ulong virt_base;
/** Stack top virtual address. */
ulong virt_stack_top;
/** Framebuffer virtual address. */
ulong virt_fb_buffer;
} }

View File

@ -11,14 +11,18 @@ import hos.memory;
import ldc.attributes; import ldc.attributes;
import hulk.kfont; import hulk.kfont;
import hulk.klog; import hulk.klog;
import hulk.hurl;
extern extern(C) __gshared ubyte _hulk_total_size; extern extern(C) __gshared ubyte _hulk_total_size;
@(ldc.attributes.section(".hulk_header")) @(ldc.attributes.section(".hulk_header"))
private __gshared Header hulk_header = { private __gshared Header hulk_header = {
&_hulk_total_size, &_hulk_total_size, /* total_size */
&hulk_start, &hulk_start, /* entry */
16u * 1024u, 16u * 1024u, /* stack_size */
HULK_VIRTUAL_BASE_ADDRESS, /* virt_base */
HULK_VIRTUAL_STACK_TOP_ADDRESS, /* virt_stack_top */
HULK_VIRTUAL_FRAMEBUFFER_ADDRESS, /* virt_fb_buffer */
}; };
/** /**
@ -28,7 +32,7 @@ private __gshared Header hulk_header = {
*/ */
void hulk_start(BootInfo * bootinfo) void hulk_start(BootInfo * bootinfo)
{ {
fb.initialize(bootinfo.fb.buffer, bootinfo.fb.width, bootinfo.fb.height, bootinfo.fb.stride); fb.initialize(cast(uint *)HULK_VIRTUAL_FRAMEBUFFER_ADDRESS, bootinfo.fb.width, bootinfo.fb.height, bootinfo.fb.stride);
console.initialize(); console.initialize();
console.clear(); console.clear();
klog.initialize(); klog.initialize();

View File

@ -1,6 +1,6 @@
SECTIONS SECTIONS
{ {
. = 0x0000400000000000; . = 0xFFFF800000000000;
_hulk_mem_start = .; _hulk_mem_start = .;
.rodata BLOCK(4K) : ALIGN(4K) .rodata BLOCK(4K) : ALIGN(4K)

15
src/hulk/hurl.d Normal file
View File

@ -0,0 +1,15 @@
/**
* HURL, the HOS Unreal Region Locator.
*
* HURL provides virtual memory management for HULK.
*/
module hulk.hurl;
/** HULK virtual base address. */
enum ulong HULK_VIRTUAL_BASE_ADDRESS = 0xFFFF_8000_0000_0000u;
/** HULK virtual stack top address. */
enum ulong HULK_VIRTUAL_STACK_TOP_ADDRESS = 0xFFFF_A000_0000_0000u;
/** HULK virtual framebuffer address. */
enum ulong HULK_VIRTUAL_FRAMEBUFFER_ADDRESS = 0xFFFF_A000_0000_0000u;