Add HULK header; map virtual memory for HULK bss section

This commit is contained in:
Josh Holtrop 2022-03-21 16:31:01 -04:00
parent c58284761a
commit 15559b0a56
5 changed files with 59 additions and 20 deletions

View File

@ -19,15 +19,16 @@ KFONT_SIZE = 15
class HulkBinObj < Builder class HulkBinObj < Builder
def run(options) def run(options)
FileUtils.mkdir_p(File.dirname(@target))
File.write(@target, <<EOF) File.write(@target, <<EOF)
.section ".rodata" .section ".rodata"
.balign 4096 .balign 4096
.global hulk_start .global hulk_bin_start
hulk_start: hulk_bin_start:
.incbin "#{@sources.first}" .incbin "#{@sources.first}"
.balign 4096 .balign 4096
.global hulk_end .global hulk_bin_end
hulk_end: hulk_bin_end:
EOF EOF
unless @cache.up_to_date?(@target, nil, @sources, @env) unless @cache.up_to_date?(@target, nil, @sources, @env)
print_run_message("Creating HULK binary object <target>#{@target}<reset>", nil) print_run_message("Creating HULK binary object <target>#{@target}<reset>", nil)
@ -86,6 +87,11 @@ hulk_env = env "hulk", use: %w[ldc2 x86_64-elf-gcc] do |env|
env.Command("^/hulk.bin", "^/hulk.elf", env.Command("^/hulk.bin", "^/hulk.elf",
"CMD" => %W[${OBJCOPY} -O binary ${_SOURCES} ${_TARGET}], "CMD" => %W[${OBJCOPY} -O binary ${_SOURCES} ${_TARGET}],
"CMD_DESC" => "Convert ELF to binary:") "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 end
hello_env = env "hello", use: %w[ldc2 x86_64-w64-mingw32-gcc] do |env| hello_env = env "hello", use: %w[ldc2 x86_64-w64-mingw32-gcc] do |env|

View File

@ -7,6 +7,7 @@ import uefi;
import console = hello.console; import console = hello.console;
import scratch = hello.scratch; import scratch = hello.scratch;
import hulk.bootinfo; import hulk.bootinfo;
import hulk.header : HulkHeader = Header;
import hos.page_table; import hos.page_table;
import hos.cpu; import hos.cpu;
import hos.memory; import hos.memory;
@ -14,8 +15,7 @@ import hos.memory;
__gshared EFI_SYSTEM_TABLE * st; __gshared EFI_SYSTEM_TABLE * st;
private __gshared BootInfo bootinfo; private __gshared BootInfo bootinfo;
private __gshared UINTN memory_map_key; private __gshared UINTN memory_map_key;
extern extern(C) __gshared ubyte hulk_start; extern extern(C) __gshared ubyte hulk_bin_start;
extern extern(C) __gshared ubyte hulk_end;
/** /**
* Detect if we're running in QEMU. * 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) private void map_hulk(PageTableEntry * pt_base)
{ {
ulong virt = HULK_VIRTUAL_START; ulong virt = HULK_VIRTUAL_START;
ulong phys = cast(ulong)&hulk_start; ulong phys = cast(ulong)&hulk_bin_start;
while (phys < cast(ulong)&hulk_end) 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); map4k(virt, phys, pt_base);
virt += 4096u; virt += 4096u;
@ -272,8 +274,8 @@ private void build_page_tables(ulong max_physical_address)
} }
} }
/* Map graphics framebuffer. */ /* Map graphics framebuffer. */
ulong framebuffer_size = bootinfo.fb.height * bootinfo.fb.stride; ulong framebuffer_size = bootinfo.fb.height * bootinfo.fb.stride * 4u;
for (size_t offset = 0u; offset < framebuffer_size; offset++) for (size_t offset = 0u; offset < framebuffer_size; offset += 4096u)
{ {
ulong addr = cast(ulong)bootinfo.fb.buffer + offset; ulong addr = cast(ulong)bootinfo.fb.buffer + offset;
map4k(addr, addr, pt_base); map4k(addr, addr, pt_base);
@ -289,7 +291,8 @@ private void build_page_tables(ulong max_physical_address)
*/ */
private void jump_to_hulk() 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); hulk_start(&bootinfo);
} }

23
src/hulk/header.d Normal file
View File

@ -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;
}

View File

@ -3,16 +3,24 @@
*/ */
module hulk.hulk; module hulk.hulk;
import hulk.header;
import hulk.bootinfo; import hulk.bootinfo;
import hos.memory; import hos.memory;
import ldc.attributes; 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. * HULK entry point.
* *
* @param bootinfo Pointer to HULK boot information structure. * @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) extern(C) void hulk_start(ulong rdi, ulong rsi, ulong rdx, BootInfo * bootinfo)
{ {
for (size_t y = 100u; y < 120u; y++) for (size_t y = 100u; y < 120u; y++)

View File

@ -1,21 +1,19 @@
ENTRY(hulk_start)
SECTIONS SECTIONS
{ {
. = 0x0000400000000000; . = 0x0000400000000000;
_hulk_mem_start = .; _hulk_mem_start = .;
.text BLOCK(4K) : ALIGN(4K)
{
*(.hulk_start)
*(.text)
}
.rodata BLOCK(4K) : ALIGN(4K) .rodata BLOCK(4K) : ALIGN(4K)
{ {
*(.hulk_header)
*(.rodata) *(.rodata)
} }
.text BLOCK(4K) : ALIGN(4K)
{
*(.text)
}
.data BLOCK(4K) : ALIGN(4K) .data BLOCK(4K) : ALIGN(4K)
{ {
*(.data) *(.data)
@ -30,4 +28,5 @@ SECTIONS
. = ALIGN(4K); . = ALIGN(4K);
_hulk_mem_end = .; _hulk_mem_end = .;
_hulk_total_size = _hulk_mem_end - _hulk_mem_start;
} }