From 15559b0a565a185f96dd4da35dcc23737f744992 Mon Sep 17 00:00:00 2001 From: Josh Holtrop Date: Mon, 21 Mar 2022 16:31:01 -0400 Subject: [PATCH] Add HULK header; map virtual memory for HULK bss section --- Rsconscript | 14 ++++++++++---- src/hello/hello.d | 17 ++++++++++------- src/hulk/header.d | 23 +++++++++++++++++++++++ src/hulk/hulk.d | 10 +++++++++- src/hulk/hulk.ld | 15 +++++++-------- 5 files changed, 59 insertions(+), 20 deletions(-) create mode 100644 src/hulk/header.d diff --git a/Rsconscript b/Rsconscript index 28a721a..1c1ec15 100644 --- a/Rsconscript +++ b/Rsconscript @@ -19,15 +19,16 @@ KFONT_SIZE = 15 class HulkBinObj < Builder def run(options) + FileUtils.mkdir_p(File.dirname(@target)) File.write(@target, <#{@target}", nil) @@ -86,6 +87,11 @@ hulk_env = env "hulk", use: %w[ldc2 x86_64-elf-gcc] do |env| env.Command("^/hulk.bin", "^/hulk.elf", "CMD" => %W[${OBJCOPY} -O binary ${_SOURCES} ${_TARGET}], "CMD_DESC" => "Convert ELF to binary:") + env.add_build_hook do |builder| + if builder.target.end_with?(".o") + env.Disassemble("#{builder.target}.txt", builder.target) + end + end end hello_env = env "hello", use: %w[ldc2 x86_64-w64-mingw32-gcc] do |env| diff --git a/src/hello/hello.d b/src/hello/hello.d index d1ac80f..62bebbf 100644 --- a/src/hello/hello.d +++ b/src/hello/hello.d @@ -7,6 +7,7 @@ import uefi; import console = hello.console; import scratch = hello.scratch; import hulk.bootinfo; +import hulk.header : HulkHeader = Header; import hos.page_table; import hos.cpu; import hos.memory; @@ -14,8 +15,7 @@ import hos.memory; __gshared EFI_SYSTEM_TABLE * st; private __gshared BootInfo bootinfo; private __gshared UINTN memory_map_key; -extern extern(C) __gshared ubyte hulk_start; -extern extern(C) __gshared ubyte hulk_end; +extern extern(C) __gshared ubyte hulk_bin_start; /** * Detect if we're running in QEMU. @@ -237,8 +237,10 @@ private void map2m(ulong source_page, ulong dest_page, PageTableEntry * pt_base) private void map_hulk(PageTableEntry * pt_base) { ulong virt = HULK_VIRTUAL_START; - ulong phys = cast(ulong)&hulk_start; - while (phys < cast(ulong)&hulk_end) + ulong phys = cast(ulong)&hulk_bin_start; + HulkHeader * hulk_header = cast(HulkHeader *)&hulk_bin_start; + size_t end_phys = phys + cast(size_t)hulk_header.total_size; + while (phys < end_phys) { map4k(virt, phys, pt_base); virt += 4096u; @@ -272,8 +274,8 @@ private void build_page_tables(ulong max_physical_address) } } /* Map graphics framebuffer. */ - ulong framebuffer_size = bootinfo.fb.height * bootinfo.fb.stride; - for (size_t offset = 0u; offset < framebuffer_size; offset++) + 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); @@ -289,7 +291,8 @@ private void build_page_tables(ulong max_physical_address) */ private void jump_to_hulk() { - void function(BootInfo *) hulk_start = cast(void function(BootInfo *))HULK_VIRTUAL_START; + HulkHeader * hulk_header = cast(HulkHeader *)&hulk_bin_start; + void function(BootInfo *) hulk_start = cast(void function(BootInfo *))hulk_header.entry; hulk_start(&bootinfo); } diff --git a/src/hulk/header.d b/src/hulk/header.d new file mode 100644 index 0000000..c8ad5a8 --- /dev/null +++ b/src/hulk/header.d @@ -0,0 +1,23 @@ +/** + * HULK image header. + */ +module hulk.header; + +/** + * Header describing the HULK image. + */ +struct Header +{ + /** + * Total size of memory to be mapped. + * + * The OS loader must ensure that virtual memory is mapped for this entire + * size. + * This value is really an integer, but is stored as a pointer because it + * is provided by the linker and LDC does not like us to cast it. + */ + void * total_size; + + /** Entry point. */ + void * entry; +} diff --git a/src/hulk/hulk.d b/src/hulk/hulk.d index 3fc4984..cbb5510 100644 --- a/src/hulk/hulk.d +++ b/src/hulk/hulk.d @@ -3,16 +3,24 @@ */ module hulk.hulk; +import hulk.header; import hulk.bootinfo; import hos.memory; import ldc.attributes; +extern extern(C) __gshared ubyte _hulk_total_size; + +@(ldc.attributes.section(".hulk_header")) +private __gshared Header hulk_header = { + &_hulk_total_size, + &hulk_start, +}; + /** * HULK entry point. * * @param bootinfo Pointer to HULK boot information structure. */ -@(ldc.attributes.section(".hulk_start")) extern(C) void hulk_start(ulong rdi, ulong rsi, ulong rdx, BootInfo * bootinfo) { for (size_t y = 100u; y < 120u; y++) diff --git a/src/hulk/hulk.ld b/src/hulk/hulk.ld index 686df43..8c19cdb 100644 --- a/src/hulk/hulk.ld +++ b/src/hulk/hulk.ld @@ -1,21 +1,19 @@ -ENTRY(hulk_start) - SECTIONS { . = 0x0000400000000000; _hulk_mem_start = .; - .text BLOCK(4K) : ALIGN(4K) - { - *(.hulk_start) - *(.text) - } - .rodata BLOCK(4K) : ALIGN(4K) { + *(.hulk_header) *(.rodata) } + .text BLOCK(4K) : ALIGN(4K) + { + *(.text) + } + .data BLOCK(4K) : ALIGN(4K) { *(.data) @@ -30,4 +28,5 @@ SECTIONS . = ALIGN(4K); _hulk_mem_end = .; + _hulk_total_size = _hulk_mem_end - _hulk_mem_start; }