diff --git a/src/hello/hello.d b/src/hello/hello.d index 7dd2f5c..a1e2f99 100644 --- a/src/hello/hello.d +++ b/src/hello/hello.d @@ -48,6 +48,21 @@ private ulong hulk_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. */ @@ -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) { /* 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); /* Map HULK bss region. */ virt += hulk_bin_size(); map4kregion(virt, bss_phys, hulk_bss_size(), pt_base); /* Map HULK stack. */ - virt += hulk_bss_size(); + virt = hulk_virt_stack_top() - hulk_stack_size(); 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. */ 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) - { - ulong addr = bootinfo.memory_map[i].base + offset; - map4k(addr, addr, pt_base); - } + map4kregion(addr, addr, bootinfo.memory_map[i].size, pt_base); } } /* Map graphics framebuffer. */ ulong framebuffer_size = bootinfo.fb.height * bootinfo.fb.stride * 4u; - for (size_t offset = 0u; offset < framebuffer_size; offset += 4096u) - { - ulong addr = cast(ulong)bootinfo.fb.buffer + offset; - map4k(addr, addr, pt_base); - } - /* Map HULK to its requested starting virtual address. */ + ulong fb_phys = cast(ulong)bootinfo.fb.buffer; + ulong fb_virt = hulk_virt_framebuffer_address(); + map4kregion(fb_virt, fb_phys, framebuffer_size, pt_base); + /* Map HULK regions. */ map_hulk(pt_base, bss_phys, stack_phys); /* Switch to the new page table. */ 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. */ -private void jump_to_hulk(ulong stack_end) +private void jump_to_hulk() { __asm( "jmpq *$0", "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.stack_phys = stack_phys; - jump_to_hulk(stack_phys + hulk_stack_size()); + jump_to_hulk(); return EFI_SUCCESS; } diff --git a/src/hulk/bootinfo.d b/src/hulk/bootinfo.d index 8f610d4..bf3c237 100644 --- a/src/hulk/bootinfo.d +++ b/src/hulk/bootinfo.d @@ -13,7 +13,7 @@ struct BootInfo */ struct Framebuffer { - /** Framebuffer base address. */ + /** Framebuffer physical base address. */ uint * buffer; /** Horizontal resolution. */ uint width; @@ -68,6 +68,3 @@ struct BootInfo /* Physical address of stack while jumping to HULK. */ ulong stack_phys; } - -/** HULK base virtual address. */ -enum ulong HULK_VIRTUAL_START = 0x0000_4000_0000_0000u; diff --git a/src/hulk/header.d b/src/hulk/header.d index 1bbef17..639270d 100644 --- a/src/hulk/header.d +++ b/src/hulk/header.d @@ -23,4 +23,13 @@ struct Header /** 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; } diff --git a/src/hulk/hulk.d b/src/hulk/hulk.d index a63178f..947edc7 100644 --- a/src/hulk/hulk.d +++ b/src/hulk/hulk.d @@ -11,14 +11,18 @@ import hos.memory; import ldc.attributes; import hulk.kfont; import hulk.klog; +import hulk.hurl; extern extern(C) __gshared ubyte _hulk_total_size; @(ldc.attributes.section(".hulk_header")) private __gshared Header hulk_header = { - &_hulk_total_size, - &hulk_start, - 16u * 1024u, + &_hulk_total_size, /* total_size */ + &hulk_start, /* entry */ + 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) { - 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.clear(); klog.initialize(); diff --git a/src/hulk/hulk.ld b/src/hulk/hulk.ld index 8c19cdb..8674f46 100644 --- a/src/hulk/hulk.ld +++ b/src/hulk/hulk.ld @@ -1,6 +1,6 @@ SECTIONS { - . = 0x0000400000000000; + . = 0xFFFF800000000000; _hulk_mem_start = .; .rodata BLOCK(4K) : ALIGN(4K) diff --git a/src/hulk/hurl.d b/src/hulk/hurl.d new file mode 100644 index 0000000..89c5ef7 --- /dev/null +++ b/src/hulk/hurl.d @@ -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;