diff options
| author | Arseney300 <Arseney300@gmail.com> | 2026-03-29 02:07:17 +0700 |
|---|---|---|
| committer | Arseney300 <Arseney300@gmail.com> | 2026-04-08 01:19:07 +0700 |
| commit | 4912796d2e88c6eb5d02fbf0fb9c39f8c9f7cd4c (patch) | |
| tree | 9ee8110e2c090c888f23797cda56c7e2df531695 /include/boot/efi.h | |
bastion: initial implementation
ready project skeleton
dual-arch build system with Linux-config style configuration
UEFI EFI stub loader (PE32+) for x86_64 and AArch64
ELF64 kernel parser
Temporary framebuffer console
freestanding string and c++ abi stubs
For now, kernel boots, prints banner, memory map and go halt
Diffstat (limited to 'include/boot/efi.h')
| -rw-r--r-- | include/boot/efi.h | 365 |
1 files changed, 365 insertions, 0 deletions
diff --git a/include/boot/efi.h b/include/boot/efi.h new file mode 100644 index 0000000..bcb8854 --- /dev/null +++ b/include/boot/efi.h @@ -0,0 +1,365 @@ +#pragma once +// ============================================================================ +// efi.h - Minimal UEFI type and protocol definitions +// +// Only what we need for our boot loader. No external dependencies (like gnu-efi). +// Reference: UEFI Specification 2.10, https://uefi.org/specs/UEFI/2.10/ +// I generate it with Cloude, because i don't want to manually rewrite whole spec +// ============================================================================ + +#include <stdint.h> +#include <stddef.h> + +// ── Base types ───────────────────────────────────────────────────────────── + +typedef uint64_t UINTN; +typedef int64_t INTN; +typedef uint64_t EFI_STATUS; +typedef void* EFI_HANDLE; +typedef void* EFI_EVENT; +typedef uint64_t EFI_PHYSICAL_ADDRESS; +typedef uint64_t EFI_VIRTUAL_ADDRESS; +typedef wchar_t CHAR16; // With -fshort-wchar, wchar_t is 16-bit +typedef uint8_t BOOLEAN; + +#define TRUE 1 +#define FALSE 0 +#define IN +#define OUT +#define OPTIONAL +#define EFIAPI + +// ── Status codes ─────────────────────────────────────────────────────────── + +#define EFI_SUCCESS 0ULL +#define EFI_ERROR_BIT (1ULL << 63) +#define EFI_LOAD_ERROR (EFI_ERROR_BIT | 1) +#define EFI_INVALID_PARAMETER (EFI_ERROR_BIT | 2) +#define EFI_UNSUPPORTED (EFI_ERROR_BIT | 3) +#define EFI_BAD_BUFFER_SIZE (EFI_ERROR_BIT | 4) +#define EFI_BUFFER_TOO_SMALL (EFI_ERROR_BIT | 5) +#define EFI_NOT_FOUND (EFI_ERROR_BIT | 14) + +#define EFI_ERROR(status) ((status) & EFI_ERROR_BIT) + +// ── GUIDs ────────────────────────────────────────────────────────────────── + +struct EFI_GUID { + uint32_t Data1; + uint16_t Data2; + uint16_t Data3; + uint8_t Data4[8]; +}; + +#define EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID \ + { 0x9042A9DE, 0x23DC, 0x4A38, { 0x96, 0xFB, 0x7A, 0xDE, 0xD0, 0x80, 0x51, 0x6A } } + +#define EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID \ + { 0x964E5B22, 0x6459, 0x11D2, { 0x8E, 0x39, 0x00, 0xA0, 0xC9, 0x69, 0x72, 0x3B } } + +#define EFI_LOADED_IMAGE_PROTOCOL_GUID \ + { 0x5B1B31A1, 0x9562, 0x11D2, { 0x8E, 0x3F, 0x00, 0xA0, 0xC9, 0x69, 0x72, 0x3B } } + +#define EFI_FILE_INFO_ID \ + { 0x09576E92, 0x6D3F, 0x11D2, { 0x8E, 0x39, 0x00, 0xA0, 0xC9, 0x69, 0x72, 0x3B } } + +#define EFI_ACPI_20_TABLE_GUID \ + { 0x8868E871, 0xE4F1, 0x11D3, { 0xBC, 0x22, 0x00, 0x80, 0xC7, 0x3C, 0x88, 0x81 } } + +#define EFI_DTB_TABLE_GUID \ + { 0xB1B621D5, 0xF19C, 0x41A5, { 0x83, 0x0B, 0xD9, 0x15, 0x2C, 0x69, 0xAA, 0xE0 } } + +// ── Memory types ─────────────────────────────────────────────────────────── + +typedef uint32_t EFI_MEMORY_TYPE; +#define EfiReservedMemoryType 0 +#define EfiLoaderCode 1 +#define EfiLoaderData 2 +#define EfiBootServicesCode 3 +#define EfiBootServicesData 4 +#define EfiRuntimeServicesCode 5 +#define EfiRuntimeServicesData 6 +#define EfiConventionalMemory 7 +#define EfiUnusableMemory 8 +#define EfiACPIReclaimMemory 9 +#define EfiACPIMemoryNVS 10 +#define EfiMemoryMappedIO 11 +#define EfiMemoryMappedIOPortSpace 12 +#define EfiPalCode 13 +#define EfiPersistentMemory 14 +#define EfiMaxMemoryType 15 + +typedef uint32_t EFI_ALLOCATE_TYPE; +#define AllocateAnyPages 0 +#define AllocateMaxAddress 1 +#define AllocateAddress 2 + +struct EFI_MEMORY_DESCRIPTOR { + uint32_t Type; + EFI_PHYSICAL_ADDRESS PhysicalStart; + EFI_VIRTUAL_ADDRESS VirtualStart; + uint64_t NumberOfPages; + uint64_t Attribute; +}; + +// ── Simple Text Output Protocol ──────────────────────────────────────────── + +struct EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL { + void* Reset; + EFI_STATUS (EFIAPI *OutputString)( + EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL* This, + CHAR16* String + ); + void* TestString; + void* QueryMode; + void* SetMode; + void* SetAttribute; + EFI_STATUS (EFIAPI *ClearScreen)( + EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL* This + ); + void* SetCursorPosition; + void* EnableCursor; + void* Mode; +}; + +// ── Graphics Output Protocol ─────────────────────────────────────────────── + +typedef uint32_t EFI_GRAPHICS_PIXEL_FORMAT; +#define PixelRedGreenBlueReserved8BitPerColor 0 +#define PixelBlueGreenRedReserved8BitPerColor 1 +#define PixelBitMask 2 +#define PixelBltOnly 3 + +struct EFI_PIXEL_BITMASK { + uint32_t RedMask; + uint32_t GreenMask; + uint32_t BlueMask; + uint32_t ReservedMask; +}; + +struct EFI_GRAPHICS_OUTPUT_MODE_INFORMATION { + uint32_t Version; + uint32_t HorizontalResolution; + uint32_t VerticalResolution; + EFI_GRAPHICS_PIXEL_FORMAT PixelFormat; + EFI_PIXEL_BITMASK PixelInformation; + uint32_t PixelsPerScanLine; +}; + +struct EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE { + uint32_t MaxMode; + uint32_t Mode; + EFI_GRAPHICS_OUTPUT_MODE_INFORMATION* Info; + UINTN SizeOfInfo; + EFI_PHYSICAL_ADDRESS FrameBufferBase; + UINTN FrameBufferSize; +}; + +struct EFI_GRAPHICS_OUTPUT_PROTOCOL { + void* QueryMode; + void* SetMode; + void* Blt; + EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE* Mode; +}; + +// ── File Protocol ────────────────────────────────────────────────────────── + +#define EFI_FILE_MODE_READ 0x0000000000000001ULL +#define EFI_FILE_READ_ONLY 0x0000000000000001ULL + +struct EFI_FILE_PROTOCOL { + uint64_t Revision; + EFI_STATUS (EFIAPI *Open)( + EFI_FILE_PROTOCOL* This, + EFI_FILE_PROTOCOL** NewHandle, + CHAR16* FileName, + uint64_t OpenMode, + uint64_t Attributes + ); + EFI_STATUS (EFIAPI *Close)( + EFI_FILE_PROTOCOL* This + ); + void* Delete; + EFI_STATUS (EFIAPI *Read)( + EFI_FILE_PROTOCOL* This, + UINTN* BufferSize, + void* Buffer + ); + void* Write; + void* GetPosition; + void* SetPosition; + EFI_STATUS (EFIAPI *GetInfo)( + EFI_FILE_PROTOCOL* This, + EFI_GUID* InformationType, + UINTN* BufferSize, + void* Buffer + ); +}; + +struct EFI_FILE_INFO { + uint64_t Size; + uint64_t FileSize; + uint64_t PhysicalSize; + uint8_t _time_padding[48]; // Skip EFI_TIME fields + uint64_t Attribute; + CHAR16 FileName[1]; // Variable length +}; + +// ── Simple File System Protocol ──────────────────────────────────────────── + +struct EFI_SIMPLE_FILE_SYSTEM_PROTOCOL { + uint64_t Revision; + EFI_STATUS (EFIAPI *OpenVolume)( + EFI_SIMPLE_FILE_SYSTEM_PROTOCOL* This, + EFI_FILE_PROTOCOL** Root + ); +}; + +// ── Loaded Image Protocol ────────────────────────────────────────────────── + +struct EFI_LOADED_IMAGE_PROTOCOL { + uint32_t Revision; + EFI_HANDLE ParentHandle; + void* SystemTable; + EFI_HANDLE DeviceHandle; + void* FilePath; + void* Reserved; + uint32_t LoadOptionsSize; + void* LoadOptions; + void* ImageBase; + uint64_t ImageSize; + EFI_MEMORY_TYPE ImageCodeType; + EFI_MEMORY_TYPE ImageDataType; + void* Unload; +}; + +// ── Boot Services ────────────────────────────────────────────────────────── + +struct EFI_BOOT_SERVICES { + char _hdr[24]; + + // Task Priority (2) + void* RaiseTPL; + void* RestoreTPL; + + // Memory Services + EFI_STATUS (EFIAPI *AllocatePages)( + EFI_ALLOCATE_TYPE Type, + EFI_MEMORY_TYPE MemoryType, + UINTN Pages, + EFI_PHYSICAL_ADDRESS* Memory + ); + EFI_STATUS (EFIAPI *FreePages)( + EFI_PHYSICAL_ADDRESS Memory, + UINTN Pages + ); + EFI_STATUS (EFIAPI *GetMemoryMap)( + UINTN* MemoryMapSize, + EFI_MEMORY_DESCRIPTOR* MemoryMap, + UINTN* MapKey, + UINTN* DescriptorSize, + uint32_t* DescriptorVersion + ); + EFI_STATUS (EFIAPI *AllocatePool)( + EFI_MEMORY_TYPE PoolType, + UINTN Size, + void** Buffer + ); + EFI_STATUS (EFIAPI *FreePool)( + void* Buffer + ); + + // Event & Timer (6) + void* CreateEvent; + void* SetTimer; + void* WaitForEvent; + void* SignalEvent; + void* CloseEvent; + void* CheckEvent; + + // Protocol Handler (6 + 3) + void* InstallProtocolInterface; + void* ReinstallProtocolInterface; + void* UninstallProtocolInterface; + EFI_STATUS (EFIAPI *HandleProtocol)( + EFI_HANDLE Handle, + EFI_GUID* Protocol, + void** Interface + ); + void* Reserved; + void* RegisterProtocolNotify; + void* LocateHandle; + void* LocateDevicePath; + void* InstallConfigurationTable; + + // Image Services (5) + void* LoadImage; + void* StartImage; + void* Exit; + void* UnloadImage; + EFI_STATUS (EFIAPI *ExitBootServices)( + EFI_HANDLE ImageHandle, + UINTN MapKey + ); + + // Misc (3) + void* GetNextMonotonicCount; + void* Stall; + void* SetWatchdogTimer; + + // DriverSupport (2) + void* ConnectController; + void* DisconnectController; + + // Open/Close Protocol (3) + void* OpenProtocol; + void* CloseProtocol; + void* OpenProtocolInformation; + + // Library (3) + void* ProtocolsPerHandle; + void* LocateHandleBuffer; + EFI_STATUS (EFIAPI *LocateProtocol)( + EFI_GUID* Protocol, + void* Registration, + void** Interface + ); +}; + +// ── Configuration Table ──────────────────────────────────────────────────── + +struct EFI_CONFIGURATION_TABLE { + EFI_GUID VendorGuid; + void* VendorTable; +}; + +// ── System Table ─────────────────────────────────────────────────────────── + +struct EFI_SYSTEM_TABLE { + char _hdr[24]; + + CHAR16* FirmwareVendor; + uint32_t FirmwareRevision; + uint32_t _pad; + + EFI_HANDLE ConsoleInHandle; + void* ConIn; + EFI_HANDLE ConsoleOutHandle; + EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL* ConOut; + EFI_HANDLE StandardErrorHandle; + void* StdErr; + void* RuntimeServices; + EFI_BOOT_SERVICES* BootServices; + UINTN NumberOfTableEntries; + EFI_CONFIGURATION_TABLE* ConfigurationTable; +}; + +// ── Utility ──────────────────────────────────────────────────────────────── + +inline bool guid_equal(const EFI_GUID& a, const EFI_GUID& b) { + return a.Data1 == b.Data1 && a.Data2 == b.Data2 && a.Data3 == b.Data3 && + a.Data4[0] == b.Data4[0] && a.Data4[1] == b.Data4[1] && + a.Data4[2] == b.Data4[2] && a.Data4[3] == b.Data4[3] && + a.Data4[4] == b.Data4[4] && a.Data4[5] == b.Data4[5] && + a.Data4[6] == b.Data4[6] && a.Data4[7] == b.Data4[7]; +} |
