Rename HEL -> HELLO
This commit is contained in:
1 parent
a855702214
commit
08a35e40d4
3 files changed
+6
-6
No files matched your search
@@ -0,0 +1,156 @@
|
||||
import uefi;
|
||||
import output;
|
||||
import hos.bootinfo;
|
||||
|
||||
__gshared EFI_SYSTEM_TABLE * st;
|
||||
__gshared BootInfo bootinfo;
|
||||
__gshared ubyte[512 * 1024] scratch;
|
||||
__gshared UINTN memory_map_key;
|
||||
|
||||
private void wait_key()
|
||||
{
|
||||
writeln("Press any key...");
|
||||
st.ConIn.Reset(st.ConIn, FALSE);
|
||||
EFI_INPUT_KEY key;
|
||||
while (st.ConIn.ReadKeyStroke(st.ConIn, &key) == EFI_NOT_READY)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
private bool in_qemu()
|
||||
{
|
||||
ulong * firmware_vendor = cast(ulong *) st.FirmwareVendor;
|
||||
ulong fv1 = firmware_vendor[0];
|
||||
return fv1 ==
|
||||
((cast(ulong)'E') |
|
||||
(cast(ulong)'D' << 16) |
|
||||
(cast(ulong)'K' << 32) |
|
||||
(cast(ulong)' ' << 48));
|
||||
}
|
||||
|
||||
private bool set_graphics_mode()
|
||||
{
|
||||
uint max_horizontal_resolution = in_qemu() ? 1920u : 0xFFFFFFFFu;
|
||||
UINTN buffer_size = scratch.sizeof;
|
||||
EFI_GUID gop_guid = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID;
|
||||
EFI_HANDLE * handles = cast(EFI_HANDLE *)&scratch;
|
||||
EFI_STATUS status = st.BootServices.LocateHandle(ByProtocol,
|
||||
&gop_guid, null, &buffer_size, handles);
|
||||
if (status != EFI_SUCCESS)
|
||||
{
|
||||
writeln("LocateHandle: error %x", status);
|
||||
return false;
|
||||
}
|
||||
EFI_HANDLE gop_handle = handles[0];
|
||||
EFI_HANDLE gop_interface;
|
||||
status = st.BootServices.HandleProtocol(gop_handle,
|
||||
&gop_guid, &gop_interface);
|
||||
if (status != EFI_SUCCESS)
|
||||
{
|
||||
writeln("HandleProtocol: error %x", status);
|
||||
return false;
|
||||
}
|
||||
if (gop_interface == null)
|
||||
{
|
||||
writeln("null interface from HandleProtocol");
|
||||
return false;
|
||||
}
|
||||
EFI_GRAPHICS_OUTPUT_PROTOCOL * gop = cast(EFI_GRAPHICS_OUTPUT_PROTOCOL *)gop_interface;
|
||||
UINTN info_size;
|
||||
EFI_GRAPHICS_OUTPUT_MODE_INFORMATION * info;
|
||||
uint best_width;
|
||||
uint best_mode_number;
|
||||
for (uint mode_number = 0u;
|
||||
(status = gop.QueryMode(gop, mode_number, &info_size, &info)) == EFI_SUCCESS;
|
||||
mode_number++)
|
||||
{
|
||||
if ((info.HorizontalResolution > best_width) &&
|
||||
(info.HorizontalResolution <= max_horizontal_resolution))
|
||||
{
|
||||
best_width = info.HorizontalResolution;
|
||||
best_mode_number = mode_number;
|
||||
}
|
||||
st.BootServices.FreePool(info);
|
||||
}
|
||||
if ((status = gop.SetMode(gop, best_mode_number)) != EFI_SUCCESS)
|
||||
{
|
||||
writeln("SetMode: Error %x\n", status);
|
||||
return false;
|
||||
}
|
||||
bootinfo.fb.buffer = cast(uint *)gop.Mode.FrameBufferBase;
|
||||
bootinfo.fb.width = gop.Mode.Info.HorizontalResolution;
|
||||
bootinfo.fb.height = gop.Mode.Info.VerticalResolution;
|
||||
bootinfo.fb.stride = gop.Mode.Info.PixelsPerScanLine;
|
||||
bootinfo.fb.format = gop.Mode.Info.PixelFormat;
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool get_memory_map()
|
||||
{
|
||||
UINTN memory_map_size = scratch.sizeof;
|
||||
UINTN descriptor_size;
|
||||
UINT32 descriptor_version;
|
||||
UINTN status = st.BootServices.GetMemoryMap(
|
||||
&memory_map_size,
|
||||
cast(EFI_MEMORY_DESCRIPTOR *)&scratch,
|
||||
&memory_map_key,
|
||||
&descriptor_size,
|
||||
&descriptor_version);
|
||||
if (status != EFI_SUCCESS)
|
||||
{
|
||||
writeln("GetMemoryMap: Error %x", status);
|
||||
return false;
|
||||
}
|
||||
size_t n_entries = memory_map_size / descriptor_size;
|
||||
size_t di;
|
||||
for (size_t i = 0u; i < n_entries; i++)
|
||||
{
|
||||
EFI_MEMORY_DESCRIPTOR * descriptor = cast(EFI_MEMORY_DESCRIPTOR *)&scratch[i * descriptor_size];
|
||||
if ((descriptor.Type == EfiConventionalMemory) ||
|
||||
(descriptor.Type == EfiBootServicesCode) ||
|
||||
(descriptor.Type == EfiBootServicesData))
|
||||
{
|
||||
bootinfo.memory_map[di].base = cast(void *)descriptor.PhysicalStart;
|
||||
bootinfo.memory_map[di].size = descriptor.NumberOfPages * 4096u;
|
||||
di++;
|
||||
}
|
||||
}
|
||||
bootinfo.memory_map_count = di;
|
||||
return true;
|
||||
}
|
||||
|
||||
extern (C) EFI_STATUS efi_main(EFI_HANDLE image_handle, EFI_SYSTEM_TABLE * st)
|
||||
{
|
||||
.st = st;
|
||||
|
||||
st.ConOut.ClearScreen(st.ConOut);
|
||||
|
||||
writeln("HELLO, HOS EFI Lightweight LOader, v0.1.0");
|
||||
writeln("Firmware vendor: '%S', version: 0x%x", st.FirmwareVendor, st.FirmwareVendor);
|
||||
|
||||
if (!set_graphics_mode())
|
||||
{
|
||||
wait_key();
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
for (;;)
|
||||
{
|
||||
get_memory_map();
|
||||
|
||||
EFI_STATUS status = st.BootServices.ExitBootServices(image_handle, memory_map_key);
|
||||
if (status == EFI_INVALID_PARAMETER)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (status == EFI_SUCCESS)
|
||||
{
|
||||
break;
|
||||
}
|
||||
writeln("ExitBootServices: Error %x", status);
|
||||
wait_key();
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
Reference in new issue
Block a user