From 9c3495c98a342269f1c546b77684321659287c83 Mon Sep 17 00:00:00 2001 From: Jezura777 Date: Tue, 1 Apr 2025 13:03:46 +0200 Subject: [PATCH] Makefile + fixed GetMemMap + updated readme --- Makefile | 8 ++ README | 13 +++ README.md | 3 - bootefi.asm | 22 +++- uefi.inc | 326 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 367 insertions(+), 5 deletions(-) create mode 100644 Makefile create mode 100644 README delete mode 100644 README.md create mode 100644 uefi.inc diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..e748b4b --- /dev/null +++ b/Makefile @@ -0,0 +1,8 @@ +bootefi.efi: bootefi.asm uefi.inc + fasm bootefi.asm + +run: bootefi.efi + uefi-run bootefi.efi -b /usr/share/ovmf/x64/OVMF.4m.fd + +clean: bootefi.efi + rm bootefi.efi diff --git a/README b/README new file mode 100644 index 0000000..9cc2599 --- /dev/null +++ b/README @@ -0,0 +1,13 @@ +FlatEFILoader +============= + +FEFIL is a simple EFI bootloader written in flatassembler. It tries to be +understandable by mere mortals + +TODO +==== + - [X] Make GetMemoryMap and ExitBootServices work + - [ ] Get GOP frame buffer and load it to arbitrary memory space + - [ ] Indicate boot success with frame buffer + - [ ] EDID multiple screens and their resolution + diff --git a/README.md b/README.md deleted file mode 100644 index e2dac40..0000000 --- a/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# FlatEFILoader - -FEFIL is a EFI bootloader written in flatassembler \ No newline at end of file diff --git a/bootefi.asm b/bootefi.asm index aeb05b6..bfff717 100644 --- a/bootefi.asm +++ b/bootefi.asm @@ -60,7 +60,21 @@ main: mov rdx, BootMsg call print +;.GetGOP: +; mov rcx, EFI_GRAPHICS_OUTPUT_UUID +; mov rdx, 3 +; mov r8, Video +; +; mov rax, [BootSrvc] +; call_safe [rax + EFI_BOOT_SERVICES_TABLE.LocateProtocol] +; +; cmp rax, EFI_SUCCES +; jne .error +; +; mov rax, [Video] +; mov rbx, [rax + EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE.MaxMode] +; jmp . ; TODO: Get and store framebuffer ; Getting the memory map is kind of harder (not in this case), normally @@ -76,6 +90,8 @@ main: ; *MemMapDescSize, ; *MemMapDescVer) .GetMemMap: + mov rax, [BootSrvc] + lea rcx, [MemMapSize] mov rdx, [MemMapBuff] lea r8, [MemMapKey] @@ -85,7 +101,7 @@ main: lea r10, [MemMapDescVer] mov [rsp+32], r10 - call [BootSrvc + EFI_BOOT_SERVICES_TABLE.GetMemoryMap] + call [rax + EFI_BOOT_SERVICES_TABLE.GetMemoryMap] ; if it returns buffer too small run the function again as it filled out ; the needed buffer length @@ -106,7 +122,8 @@ main: mov rcx, [ImgHdl] mov rdx, [MemMapKey] - call_safe [BootSrvc + EFI_BOOT_SERVICES_TABLE.ExitBootServices] + mov rax, [BootSrvc] + call_safe [rax + EFI_BOOT_SERVICES_TABLE.ExitBootServices] cmp rax, EFI_SUCCESS jne .error @@ -138,6 +155,7 @@ ImgHdl dq ? SysTbl dq ? BootSrvc dq ? Output dq ? +Video dq ? MemMapSize dq 32768 MemMapKey dq ? diff --git a/uefi.inc b/uefi.inc new file mode 100644 index 0000000..30dd9bd --- /dev/null +++ b/uefi.inc @@ -0,0 +1,326 @@ +;********************************************************************* +;* * +;* UEFI library for fasm by bzt, Public Domain * +;* * +;********************************************************************* + +; include x86asm.net's efi.inc +;include 'efi.inc' +struc int8 { + . db ? +} +struc int16 { + align 2 + . dw ? +} +struc int32 { + align 4 + . dd ? +} +struc int64 { + align 8 + . dq ? +} +struc intn { + align 8 + . dq ? +} +struc dptr { + align 8 + . dq ? +} + +;symbols + +; EFIERR = 0x8000000000000000 +EFI_SUCCESS = 0 +EFI_LOAD_ERROR = 1 ;or EFIERR +EFI_INVALID_PARAMETER = 2 ;or EFIERR +EFI_UNSUPPORTED = 3;or EFIERR +EFI_BAD_BUFFER_SIZE = 4;or EFIERR +EFI_BUFFER_TOO_SMALL = 5;or EFIERR +EFI_NOT_READY = 6;or EFIERR +EFI_DEVICE_ERROR = 7;or EFIERR +EFI_WRITE_PROTECTED = 8;or EFIERR +EFI_OUT_OF_RESOURCES = 9;or EFIERR +EFI_VOLUME_CORRUPTED = 10;or EFIERR +EFI_VOLUME_FULL = 11;or EFIERR +EFI_NO_MEDIA = 12;or EFIERR +EFI_MEDIA_CHANGED = 13;or EFIERR +EFI_NOT_FOUND = 14;or EFIERR +EFI_ACCESS_DENIED = 15;or EFIERR +EFI_NO_RESPONSE = 16;or EFIERR +EFI_NO_MAPPING = 17;or EFIERR +EFI_TIMEOUT = 18;or EFIERR +EFI_NOT_STARTED = 19;or EFIERR +EFI_ALREADY_STARTED = 20;or EFIERR +EFI_ABORTED = 21;or EFIERR +EFI_ICMP_ERROR = 22;or EFIERR +EFI_TFTP_ERROR = 23;or EFIERR +EFI_PROTOCOL_ERROR = 24;or EFIERR + +; ConOut Colors :) +EFI_BLACK = 0x00 +EFI_BLUE = 0x01 +EFI_GREEN = 0x02 +EFI_CYAN = 0x03 +EFI_RED = 0x04 +EFI_MAGENTA = 0x05 +EFI_BROWN = 0x06 +EFI_LIGHTGRAY = 0x07 +EFI_BRIGHT = 0x08 +EFI_DARKGRAY = 0x08 +EFI_LIGHTBLUE = 0x09 +EFI_LIGHTGREEN = 0x0A +EFI_LIGHTCYAN = 0x0B +EFI_LIGHTRED = 0x0C +EFI_LIGHTMAGENTA = 0x0D +EFI_YELLOW = 0x0E +EFI_WHITE = 0x0F + +EFI_BACKGROUND_BLACK = 0x00 +EFI_BACKGROUND_BLUE = 0x10 +EFI_BACKGROUND_GREEN = 0x20 +EFI_BACKGROUND_CYAN = 0x30 +EFI_BACKGROUND_RED = 0x40 +EFI_BACKGROUND_MAGENTA = 0x50 +EFI_BACKGROUND_BROWN = 0x60 +EFI_BACKGROUND_LIGHTGRAY = 0x70 + +;helper macro for definition of relative structure member offsets + +macro struct name +{ + virtual at 0 + name name + end virtual +} + +;structures +EFI_SYSTEM_TABLE_SIGNATURE equ 49h,42h,49h,20h,53h,59h,53h,54h +struc EFI_TABLE_HEADER { + .Signature int64 + .Revision int32 + .HeaderSize int32 + .CRC32 int32 + .Reserved int32 +} +struct EFI_TABLE_HEADER + +struc EFI_SYSTEM_TABLE { + .Hdr EFI_TABLE_HEADER + .FirmwareVendor dptr + .FirmwareRevision int32 + .ConsoleInHandle dptr + .ConIn dptr + .ConsoleOutHandle dptr + .ConOut dptr + .StandardErrorHandle dptr + .StdErr dptr + .RuntimeServices dptr + .BootServices dptr + .NumberOfTableEntries intn + .ConfigurationTable dptr +} +struct EFI_SYSTEM_TABLE + +struc SIMPLE_TEXT_OUTPUT_INTERFACE { + .Reset dptr + .OutputString dptr + .TestString dptr + .QueryMode dptr + .SetMode dptr + .SetAttribute dptr + .ClearScreen dptr + .SetCursorPosition dptr + .EnableCursor dptr + .Mode dptr +} +struct SIMPLE_TEXT_OUTPUT_INTERFACE + +;---include ends + +struc SIMPLE_INPUT_INTERFACE { + .Reset dptr + .ReadKeyStroke dptr + .WaitForKey dptr +} +struct SIMPLE_INPUT_INTERFACE + +struc EFI_BOOT_SERVICES_TABLE { + .Hdr EFI_TABLE_HEADER + .RaisePriority dptr + .RestorePriority dptr + .AllocatePages dptr + .FreePages dptr + .GetMemoryMap dptr + .AllocatePool dptr + .FreePool dptr + .CreateEvent dptr + .SetTimer dptr + .WaitForEvent dptr + .SignalEvent dptr + .CloseEvent dptr + .CheckEvent dptr + .InstallProtocolInterface dptr + .ReInstallProtocolInterface dptr + .UnInstallProtocolInterface dptr + .HandleProtocol dptr + .Void dptr + .RegisterProtocolNotify dptr + .LocateHandle dptr + .LocateDevicePath dptr + .InstallConfigurationTable dptr + .ImageLoad dptr + .ImageStart dptr + .Exit dptr + .ImageUnLoad dptr + .ExitBootServices dptr + .GetNextMonotonicCount dptr + .Stall dptr + .SetWatchdogTimer dptr + .ConnectController dptr + .DisConnectController dptr + .OpenProtocol dptr + .CloseProtocol dptr + .OpenProtocolInformation dptr + .ProtocolsPerHandle dptr + .LocateHandleBuffer dptr + .LocateProtocol dptr + .InstallMultipleProtocolInterfaces dptr + .UnInstallMultipleProtocolInterfaces dptr + .CalculateCrc32 dptr + .CopyMem dptr + .SetMem dptr +} +struct EFI_BOOT_SERVICES_TABLE + +struc EFI_RUNTIME_SERVICES_TABLE { + .Hdr EFI_TABLE_HEADER + .GetTime dptr + .SetTime dptr + .GetWakeUpTime dptr + .SetWakeUpTime dptr + .SetVirtualAddressMap dptr + .ConvertPointer dptr + .GetVariable dptr + .GetNextVariableName dptr + .SetVariable dptr + .GetNextHighMonoCount dptr + .ResetSystem dptr +} +struct EFI_RUNTIME_SERVICES_TABLE + +struc EFI_TIME { + .Year int16 + .Month int8 + .Day int8 + .Hour int8 + .Minute int8 + .Second int8 + .Pad1 int8 + .Nanosecond int32 + .TimeZone int16 + .Daylight int8 + .Pad2 int8 + .sizeof rb 1 +} +struct EFI_TIME + +EFI_LOADED_IMAGE_PROTOCOL_UUID equ 0A1h,31h,1bh,5bh,62h,95h,0d2h,11h,8Eh,3Fh,0h,0A0h,0C9h,69h,72h,3Bh +struc EFI_LOADED_IMAGE_PROTOCOL { + .Revision int32 + .ParentHandle int64 + .SystemTable dptr + .DeviceHandle int64 + .FilePath dptr + .Reserved int64 + .LoadOptionsSize int32 + .ImageBase dptr + .ImageSize int64 + .ImageCodeType int32 + .ImageDataType int32 + .UnLoad dptr +} +struct EFI_LOADED_IMAGE_PROTOCOL + +EFI_BLOCK_IO_PROTOCOL_UUID equ 21h,5bh,4eh,96h,59h,64h,0d2h,11h,8eh,39h,00h,0a0h,0c9h,69h,72h,3bh +struc EFI_BLOCK_IO_PROTOCOL { + .Revision int64 + .Media dptr + .Reset dptr + .ReadBlocks dptr + .WriteBlocks dptr + .FlushBlocks dptr +} +struct EFI_BLOCK_IO_PROTOCOL + +struc EFI_BLOCK_IO_MEDIA { + .MediaId int32 + .RemovableMedia int8 + .MediaPresent int8 + .LogicalPartition int8 + .ReadOnly int8 + .WriteCaching int8 + .BlockSize int32 + .IoAlign int32 + .LastBlock int64 +} +struct EFI_BLOCK_IO_MEDIA + +EFI_GRAPHICS_OUTPUT_PROTOCOL_UUID equ 0deh, 0a9h, 42h,90h,0dch,023h,38h,04ah,96h,0fbh,7ah,0deh,0d0h,80h,51h,6ah +struc EFI_GRAPHICS_OUTPUT_PROTOCOL { + .QueryMode dptr + .SetMode dptr + .Blt dptr + .Mode dptr +} +struct EFI_GRAPHICS_OUTPUT_PROTOCOL + +struc EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE { + .MaxMode int32 + .CurrentMode int32 + .ModeInfo dptr + .SizeOfModeInfo intn + .FrameBufferBase dptr + .FrameBufferSize intn +} +struct EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE + +struc EFI_GRAPHICS_OUTPUT_MODE_INFORMATION { + .Version int32 + .HorizontalResolution int32 + .VerticalResolution int32 + .PixelFormat int32 + .RedMask int32 + .GreenMask int32 + .BlueMask int32 + .Reserved int32 + .PixelsPerScanline int32 +} +struct EFI_GRAPHICS_OUTPUT_MODE_INFORMATION +;---macros to make life easier--- +;call it early, after entry point is the best +macro InitializeLib +{ + clc + or rdx, rdx + jz .badout + cmp dword [rdx], 20494249h + je @f +.badout: xor rcx, rcx + xor rdx, rdx + stc +@@: mov [efi_handler], rcx ; ImageHandle + mov [efi_ptr], rdx ; pointer to SystemTable +} + + +;********************************************************************* +;* Library functions * +;********************************************************************* + +section '.data' data readable writeable +efi_handler: dq 0 +efi_ptr: dq 0 +uefi_rsptmp: dq 0