Build HELLO page tables from unused memory instead of scratch buffer
This commit is contained in:
parent
0b326e2e36
commit
8aa01ba122
@ -5,7 +5,6 @@ module hello.hello;
|
|||||||
|
|
||||||
import uefi;
|
import uefi;
|
||||||
import hello.console;
|
import hello.console;
|
||||||
import hello.scratch;
|
|
||||||
import hulk.bootinfo;
|
import hulk.bootinfo;
|
||||||
import hulk.header;
|
import hulk.header;
|
||||||
import hulk.pagetable;
|
import hulk.pagetable;
|
||||||
@ -16,6 +15,9 @@ import ldc.llvmasm;
|
|||||||
__gshared EFI_SYSTEM_TABLE * st;
|
__gshared EFI_SYSTEM_TABLE * st;
|
||||||
extern extern(C) __gshared ubyte _hulk_bin_start;
|
extern extern(C) __gshared ubyte _hulk_bin_start;
|
||||||
extern extern(C) __gshared ubyte _hulk_bin_end;
|
extern extern(C) __gshared ubyte _hulk_bin_end;
|
||||||
|
private align(4096) __gshared ubyte[1024 * 1024] scratch_buffer;
|
||||||
|
/** Index to the memory map region being used to allocate page tables. */
|
||||||
|
private __gshared size_t memory_map_page_table_alloc_index;
|
||||||
|
|
||||||
private HulkHeader * hulk_header()
|
private HulkHeader * hulk_header()
|
||||||
{
|
{
|
||||||
@ -87,9 +89,9 @@ private bool in_qemu()
|
|||||||
private bool set_graphics_mode()
|
private bool set_graphics_mode()
|
||||||
{
|
{
|
||||||
uint max_horizontal_resolution = in_qemu() ? 1920u : 0xFFFFFFFFu;
|
uint max_horizontal_resolution = in_qemu() ? 1920u : 0xFFFFFFFFu;
|
||||||
UINTN buffer_size = scratch.free();
|
UINTN buffer_size = scratch_buffer.sizeof;
|
||||||
EFI_GUID gop_guid = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID;
|
EFI_GUID gop_guid = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID;
|
||||||
EFI_HANDLE * handles = cast(EFI_HANDLE *)scratch.current();
|
EFI_HANDLE * handles = cast(EFI_HANDLE *)&scratch_buffer[0];
|
||||||
EFI_STATUS status = st.BootServices.LocateHandle(ByProtocol,
|
EFI_STATUS status = st.BootServices.LocateHandle(ByProtocol,
|
||||||
&gop_guid, null, &buffer_size, handles);
|
&gop_guid, null, &buffer_size, handles);
|
||||||
if (status != EFI_SUCCESS)
|
if (status != EFI_SUCCESS)
|
||||||
@ -148,10 +150,10 @@ private void get_memory_map(ulong * bss_phys, ulong * stack_phys, ulong * physic
|
|||||||
{
|
{
|
||||||
immutable static ubyte[] efi_to_hulk_memory_map_type = [
|
immutable static ubyte[] efi_to_hulk_memory_map_type = [
|
||||||
BootInfo.MemoryRegion.Type.Reserved, // EfiReservedMemoryType
|
BootInfo.MemoryRegion.Type.Reserved, // EfiReservedMemoryType
|
||||||
BootInfo.MemoryRegion.Type.Conventional, // EfiLoaderCode
|
BootInfo.MemoryRegion.Type.Bootloader, // EfiLoaderCode
|
||||||
BootInfo.MemoryRegion.Type.Conventional, // EfiLoaderData
|
BootInfo.MemoryRegion.Type.Bootloader, // EfiLoaderData
|
||||||
BootInfo.MemoryRegion.Type.Conventional, // EfiBootServicesCode
|
BootInfo.MemoryRegion.Type.Bootloader, // EfiBootServicesCode
|
||||||
BootInfo.MemoryRegion.Type.Conventional, // EfiBootServicesData
|
BootInfo.MemoryRegion.Type.Bootloader, // EfiBootServicesData
|
||||||
BootInfo.MemoryRegion.Type.Reserved, // EfiRuntimeServicesCode
|
BootInfo.MemoryRegion.Type.Reserved, // EfiRuntimeServicesCode
|
||||||
BootInfo.MemoryRegion.Type.Reserved, // EfiRuntimeServicesData
|
BootInfo.MemoryRegion.Type.Reserved, // EfiRuntimeServicesData
|
||||||
BootInfo.MemoryRegion.Type.Conventional, // EfiConventionalMemory
|
BootInfo.MemoryRegion.Type.Conventional, // EfiConventionalMemory
|
||||||
@ -163,10 +165,10 @@ private void get_memory_map(ulong * bss_phys, ulong * stack_phys, ulong * physic
|
|||||||
BootInfo.MemoryRegion.Type.PalCode, // EfiPalCode
|
BootInfo.MemoryRegion.Type.PalCode, // EfiPalCode
|
||||||
];
|
];
|
||||||
*physical_address_limit = 0u;
|
*physical_address_limit = 0u;
|
||||||
UINTN memory_map_size = scratch.free();
|
UINTN memory_map_size = scratch_buffer.sizeof;
|
||||||
UINTN descriptor_size;
|
UINTN descriptor_size;
|
||||||
UINT32 descriptor_version;
|
UINT32 descriptor_version;
|
||||||
ubyte * scratch_base = scratch.current();
|
ubyte * scratch_base = cast(ubyte *)&scratch_buffer[0];
|
||||||
UINTN status = st.BootServices.GetMemoryMap(
|
UINTN status = st.BootServices.GetMemoryMap(
|
||||||
&memory_map_size,
|
&memory_map_size,
|
||||||
cast(EFI_MEMORY_DESCRIPTOR *)scratch_base,
|
cast(EFI_MEMORY_DESCRIPTOR *)scratch_base,
|
||||||
@ -235,12 +237,37 @@ private void get_memory_map(ulong * bss_phys, ulong * stack_phys, ulong * physic
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void * alloc_pt_page()
|
||||||
|
{
|
||||||
|
BootInfo.MemoryRegion * regions = &bootinfo().memory_map[0];
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
BootInfo.MemoryRegion * region = &bootinfo().memory_map[memory_map_page_table_alloc_index];
|
||||||
|
if ((region.type == BootInfo.MemoryRegion.Type.Conventional) && (region.size >= PAGE_SIZE))
|
||||||
|
{
|
||||||
|
void * addr = cast(void *)region.base;
|
||||||
|
region.base += PAGE_SIZE;
|
||||||
|
region.size -= PAGE_SIZE;
|
||||||
|
return addr;
|
||||||
|
}
|
||||||
|
memory_map_page_table_alloc_index++;
|
||||||
|
if (memory_map_page_table_alloc_index >= bootinfo().memory_map_count)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Allocate a new page table.
|
* Allocate a new page table.
|
||||||
*/
|
*/
|
||||||
private PageTable * new_page_table()
|
private PageTable * new_page_table()
|
||||||
{
|
{
|
||||||
PageTable * pt = cast(PageTable *)scratch.alloc(1u);
|
PageTable * pt = cast(PageTable *)alloc_pt_page();
|
||||||
|
if (pt == null)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
memset64(pt, 0u, 512);
|
memset64(pt, 0u, 512);
|
||||||
return pt;
|
return pt;
|
||||||
}
|
}
|
||||||
@ -252,7 +279,7 @@ private PageTable * new_page_table()
|
|||||||
* @param dest_page Destination page address.
|
* @param dest_page Destination page address.
|
||||||
* @param pt_base Page table base address.
|
* @param pt_base Page table base address.
|
||||||
*/
|
*/
|
||||||
private void map4k(ulong source_page, ulong dest_page, PageTable * pt_base)
|
private bool map4k(ulong source_page, ulong dest_page, PageTable * pt_base)
|
||||||
{
|
{
|
||||||
PageTable * pt = pt_base;
|
PageTable * pt = pt_base;
|
||||||
for (size_t level = 0; level < 4u; level++)
|
for (size_t level = 0; level < 4u; level++)
|
||||||
@ -270,6 +297,10 @@ private void map4k(ulong source_page, ulong dest_page, PageTable * pt_base)
|
|||||||
if (level < 3u)
|
if (level < 3u)
|
||||||
{
|
{
|
||||||
next_pt = new_page_table();
|
next_pt = new_page_table();
|
||||||
|
if (next_pt == null)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
addr = cast(ulong)next_pt;
|
addr = cast(ulong)next_pt;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -280,6 +311,7 @@ private void map4k(ulong source_page, ulong dest_page, PageTable * pt_base)
|
|||||||
pt = next_pt;
|
pt = next_pt;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -290,15 +322,19 @@ private void map4k(ulong source_page, ulong dest_page, PageTable * pt_base)
|
|||||||
* @param size Region size.
|
* @param size Region size.
|
||||||
* @param pt_base Page table base address.
|
* @param pt_base Page table base address.
|
||||||
*/
|
*/
|
||||||
private void map4kregion(ulong source, ulong dest, size_t size, PageTable * pt_base)
|
private bool map4kregion(ulong source, ulong dest, size_t size, PageTable * pt_base)
|
||||||
{
|
{
|
||||||
ulong end = source + size;
|
ulong end = source + size;
|
||||||
while (source < end)
|
while (source < end)
|
||||||
{
|
{
|
||||||
map4k(source, dest, pt_base);
|
if (!map4k(source, dest, pt_base))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
source += 4096u;
|
source += 4096u;
|
||||||
dest += 4096u;
|
dest += 4096u;
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -308,7 +344,7 @@ private void map4kregion(ulong source, ulong dest, size_t size, PageTable * pt_b
|
|||||||
* @param dest_page Destination page address.
|
* @param dest_page Destination page address.
|
||||||
* @param pt_base Page table base address.
|
* @param pt_base Page table base address.
|
||||||
*/
|
*/
|
||||||
private void map2m(ulong source_page, ulong dest_page, PageTable * pt_base)
|
private bool map2m(ulong source_page, ulong dest_page, PageTable * pt_base)
|
||||||
{
|
{
|
||||||
PageTable * pt = pt_base;
|
PageTable * pt = pt_base;
|
||||||
for (size_t level = 0; level < 3u; level++)
|
for (size_t level = 0; level < 3u; level++)
|
||||||
@ -325,6 +361,10 @@ private void map2m(ulong source_page, ulong dest_page, PageTable * pt_base)
|
|||||||
if (level < 2u)
|
if (level < 2u)
|
||||||
{
|
{
|
||||||
next_pt = new_page_table();
|
next_pt = new_page_table();
|
||||||
|
if (next_pt == null)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
*ppte = PageTableEntry(next_pt, PT_WRITABLE | PT_PRESENT);
|
*ppte = PageTableEntry(next_pt, PT_WRITABLE | PT_PRESENT);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -334,6 +374,7 @@ private void map2m(ulong source_page, ulong dest_page, PageTable * pt_base)
|
|||||||
pt = next_pt;
|
pt = next_pt;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -341,17 +382,27 @@ private void map2m(ulong source_page, ulong dest_page, PageTable * pt_base)
|
|||||||
*
|
*
|
||||||
* @param pt_base Page table base address.
|
* @param pt_base Page table base address.
|
||||||
*/
|
*/
|
||||||
private void map_hulk(PageTable * pt_base, ulong bss_phys, ulong stack_phys)
|
private bool map_hulk(PageTable * pt_base, ulong bss_phys, ulong stack_phys)
|
||||||
{
|
{
|
||||||
/* Map HULK bin region. */
|
/* Map HULK bin region. */
|
||||||
ulong virt = hulk_virt_base_address();
|
ulong virt = hulk_virt_base_address();
|
||||||
map4kregion(virt, hulk_bin_phys(), hulk_bin_size(), pt_base);
|
if (!map4kregion(virt, hulk_bin_phys(), hulk_bin_size(), pt_base))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
/* 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);
|
if (!map4kregion(virt, bss_phys, hulk_bss_size(), pt_base))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
/* Map HULK stack. */
|
/* Map HULK stack. */
|
||||||
virt = hulk_virt_stack_top() - hulk_stack_size();
|
virt = hulk_virt_stack_top() - hulk_stack_size();
|
||||||
map4kregion(virt, stack_phys, hulk_stack_size(), pt_base);
|
if (!map4kregion(virt, stack_phys, hulk_stack_size(), pt_base))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -359,13 +410,20 @@ private void map_hulk(PageTable * pt_base, ulong bss_phys, ulong stack_phys)
|
|||||||
*
|
*
|
||||||
* @param physical_address_limit Maximum physical address to identity map.
|
* @param physical_address_limit Maximum physical address to identity map.
|
||||||
*/
|
*/
|
||||||
private void build_page_tables(ulong physical_address_limit, ulong bss_phys, ulong stack_phys)
|
private bool build_page_tables(ulong physical_address_limit, ulong bss_phys, ulong stack_phys)
|
||||||
{
|
{
|
||||||
PageTable * pt_base = new_page_table();
|
PageTable * pt_base = new_page_table();
|
||||||
|
if (pt_base == null)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
/* Map physical RAM. */
|
/* Map physical RAM. */
|
||||||
for (size_t addr = 0u; addr < physical_address_limit; addr += (2u * 1024u * 1024u))
|
for (size_t addr = 0u; addr < physical_address_limit; addr += (2u * 1024u * 1024u))
|
||||||
{
|
{
|
||||||
map2m(addr, addr, pt_base);
|
if (!map2m(addr, addr, pt_base))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
/* 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++)
|
||||||
@ -373,18 +431,28 @@ private void build_page_tables(ulong physical_address_limit, ulong bss_phys, ulo
|
|||||||
ulong addr = bootinfo().memory_map[i].base;
|
ulong addr = bootinfo().memory_map[i].base;
|
||||||
if (addr >= physical_address_limit)
|
if (addr >= physical_address_limit)
|
||||||
{
|
{
|
||||||
map4kregion(addr, addr, bootinfo().memory_map[i].size, pt_base);
|
if (!map4kregion(addr, addr, bootinfo().memory_map[i].size, pt_base))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* 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;
|
||||||
ulong fb_phys = cast(ulong)bootinfo().fb.buffer;
|
ulong fb_phys = cast(ulong)bootinfo().fb.buffer;
|
||||||
ulong fb_virt = hulk_virt_framebuffer_address();
|
ulong fb_virt = hulk_virt_framebuffer_address();
|
||||||
map4kregion(fb_virt, fb_phys, framebuffer_size, pt_base);
|
if (!map4kregion(fb_virt, fb_phys, framebuffer_size, pt_base))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
/* Map HULK regions. */
|
/* Map HULK regions. */
|
||||||
map_hulk(pt_base, bss_phys, stack_phys);
|
if (!map_hulk(pt_base, bss_phys, stack_phys))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
/* Switch to the new page table. */
|
/* Switch to the new page table. */
|
||||||
write_cr3(cast(ulong)pt_base);
|
write_cr3(cast(ulong)pt_base);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -447,8 +515,6 @@ extern (C) EFI_STATUS efi_main(EFI_HANDLE image_handle, EFI_SYSTEM_TABLE * st)
|
|||||||
return EFI_SUCCESS;
|
return EFI_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
bootinfo().pt_phys = cast(ulong)scratch.current();
|
|
||||||
|
|
||||||
if (!set_graphics_mode())
|
if (!set_graphics_mode())
|
||||||
{
|
{
|
||||||
console.wait_key();
|
console.wait_key();
|
||||||
@ -477,12 +543,14 @@ extern (C) EFI_STATUS efi_main(EFI_HANDLE image_handle, EFI_SYSTEM_TABLE * st)
|
|||||||
return EFI_SUCCESS;
|
return EFI_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
build_page_tables(physical_address_limit, bss_phys, stack_phys);
|
if (!build_page_tables(physical_address_limit, bss_phys, stack_phys))
|
||||||
|
{
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
bootinfo().hulk_phys = hulk_bin_phys();
|
bootinfo().hulk_phys = hulk_bin_phys();
|
||||||
bootinfo().bss_phys = bss_phys;
|
bootinfo().bss_phys = bss_phys;
|
||||||
bootinfo().stack_phys = stack_phys;
|
bootinfo().stack_phys = stack_phys;
|
||||||
bootinfo().pt_size = cast(ulong)scratch.current() - bootinfo().pt_phys;
|
|
||||||
|
|
||||||
jump_to_hulk();
|
jump_to_hulk();
|
||||||
|
|
||||||
|
@ -1,39 +0,0 @@
|
|||||||
/**
|
|
||||||
* HELLO scratch buffer.
|
|
||||||
*/
|
|
||||||
module hello.scratch;
|
|
||||||
|
|
||||||
struct scratch
|
|
||||||
{
|
|
||||||
/* Scratch buffer. */
|
|
||||||
private static align(4096) __gshared ubyte[10 * 1024 * 1024] scratch;
|
|
||||||
|
|
||||||
/* Number of scratch buffer bytes used. */
|
|
||||||
private static __gshared size_t scratch_used;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the number of free bytes in the scratch buffer.
|
|
||||||
*/
|
|
||||||
public static size_t free()
|
|
||||||
{
|
|
||||||
return scratch.sizeof - scratch_used;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the current free scratch buffer address.
|
|
||||||
*/
|
|
||||||
public static ubyte * current()
|
|
||||||
{
|
|
||||||
return &scratch[scratch_used];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Allocate pages from the scratch buffer.
|
|
||||||
*/
|
|
||||||
public static ubyte * alloc(size_t n = 1)
|
|
||||||
{
|
|
||||||
ubyte * address = &scratch[scratch_used];
|
|
||||||
scratch_used += 4096u * n;
|
|
||||||
return address;
|
|
||||||
}
|
|
||||||
}
|
|
@ -33,6 +33,7 @@ struct BootInfo
|
|||||||
enum Type
|
enum Type
|
||||||
{
|
{
|
||||||
Reserved,
|
Reserved,
|
||||||
|
Bootloader,
|
||||||
Conventional,
|
Conventional,
|
||||||
Unusable,
|
Unusable,
|
||||||
ACPIReclaim,
|
ACPIReclaim,
|
||||||
@ -68,12 +69,6 @@ struct BootInfo
|
|||||||
/* Physical address of stack while jumping to HULK. */
|
/* Physical address of stack while jumping to HULK. */
|
||||||
ulong stack_phys;
|
ulong stack_phys;
|
||||||
|
|
||||||
/* Physical address of page tables while jumping to HULK. */
|
|
||||||
ulong pt_phys;
|
|
||||||
|
|
||||||
/* Size of page tables while jumping to HULK. */
|
|
||||||
ulong pt_size;
|
|
||||||
|
|
||||||
/* Physical address of ACPI XSDT table. */
|
/* Physical address of ACPI XSDT table. */
|
||||||
ulong acpi_xsdt_phys;
|
ulong acpi_xsdt_phys;
|
||||||
}
|
}
|
||||||
|
@ -53,12 +53,11 @@ struct hippo
|
|||||||
public static void initialize(HulkHeader * header)
|
public static void initialize(HulkHeader * header)
|
||||||
{
|
{
|
||||||
size_t usable_memory;
|
size_t usable_memory;
|
||||||
ulong[2][5] reserved = [
|
ulong[2][4] reserved = [
|
||||||
[header.bootinfo.hulk_phys, cast(ulong)header.total_size - LinkerAddresses.hulk_bss_size],
|
[header.bootinfo.hulk_phys, cast(ulong)header.total_size - LinkerAddresses.hulk_bss_size],
|
||||||
[header.bootinfo.bss_phys, LinkerAddresses.hulk_bss_size],
|
[header.bootinfo.bss_phys, LinkerAddresses.hulk_bss_size],
|
||||||
[header.bootinfo.stack_phys, header.stack_size],
|
[header.bootinfo.stack_phys, header.stack_size],
|
||||||
[cast(ulong)header.bootinfo.fb.buffer, header.bootinfo.fb.height * header.bootinfo.fb.stride * 4u],
|
[cast(ulong)header.bootinfo.fb.buffer, header.bootinfo.fb.height * header.bootinfo.fb.stride * 4u],
|
||||||
[header.bootinfo.pt_phys, header.bootinfo.pt_size],
|
|
||||||
];
|
];
|
||||||
for (size_t ri = 0u; ri < reserved.length; ri++)
|
for (size_t ri = 0u; ri < reserved.length; ri++)
|
||||||
{
|
{
|
||||||
@ -66,7 +65,8 @@ struct hippo
|
|||||||
}
|
}
|
||||||
for (size_t bii = 0u; bii < header.bootinfo.memory_map_count; bii++)
|
for (size_t bii = 0u; bii < header.bootinfo.memory_map_count; bii++)
|
||||||
{
|
{
|
||||||
if (header.bootinfo.memory_map[bii].type == BootInfo.MemoryRegion.Type.Conventional)
|
if ((header.bootinfo.memory_map[bii].type == BootInfo.MemoryRegion.Type.Bootloader) ||
|
||||||
|
(header.bootinfo.memory_map[bii].type == BootInfo.MemoryRegion.Type.Conventional))
|
||||||
{
|
{
|
||||||
ulong phys = header.bootinfo.memory_map[bii].base;
|
ulong phys = header.bootinfo.memory_map[bii].base;
|
||||||
ulong phys_end = phys + header.bootinfo.memory_map[bii].size;
|
ulong phys_end = phys + header.bootinfo.memory_map[bii].size;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user