diff options
Diffstat (limited to 'include/boot')
| -rw-r--r-- | include/boot/boot_info.h | 76 | ||||
| -rw-r--r-- | include/boot/efi.h | 365 |
2 files changed, 441 insertions, 0 deletions
diff --git a/include/boot/boot_info.h b/include/boot/boot_info.h new file mode 100644 index 0000000..cc02ae8 --- /dev/null +++ b/include/boot/boot_info.h @@ -0,0 +1,76 @@ +#pragma once +// ============================================================================ +// boot_info.h - Boot handoff struct +// Shared between the UEFI loader and the kernel. +// The loader fills it, the kernel consumes it. Simple. +// In future i will expand this struct +// ============================================================================ + +#include <stdint.h> + +// ── Boot Magic Number─────────────────────────────────────────────────────── +inline constexpr uint64_t BOOT_INFO_MAGIC = 0xDEADDEADDEADDEADULL; + +// ── Framebuffer (GOP) ─────────────────────────────────────────────────────── +// TODO: remove Framebuffer to driver +enum class PixelFormat : uint32_t { + RGB = 0, // PixelRedGreenBlueReserved8BitPerColor + BGR = 1, // PixelBlueGreenRedReserved8BitPerColor + Mask = 2, // PixelBitMask — need to check masks +}; + +struct FramebufferInfo { + uint64_t base; // Physical address of framebuffer + uint32_t width; // Horizontal resolution in pixels + uint32_t height; // Vertical resolution in pixels + uint32_t pitch; // Bytes per scanline (>= width * 4) + PixelFormat format; +}; + +// ── Memory map ───────────────────────────────────────────────────────────── +//TODO: remove FrameBuffer +enum class MemoryRegionType : uint32_t { + Usable = 0, // Free RAM - kernel can use + Reserved = 1, // Firmware/hardware reserved + AcpiReclaimable = 2, // ACPI tables - free after parsing + AcpiNvs = 3, // ACPI non-volatile storage + BootloaderReclaimable = 4, // Loader code/data - free after kernel init + KernelAndModules = 5, // Kernel image + any loaded modules + Framebuffer = 6, // Framebuffer memory - do not use as RAM +}; + +struct MemoryRegion { + uint64_t base; + uint64_t length; + MemoryRegionType type; + uint32_t _reserved; // Padding to 24 bytes +}; + +// ── Boot info structure ──────────────────────────────────────────────────── + +struct BootInfo { + uint64_t magic; // Must be BOOT_INFO_MAGIC + + // Framebuffer + // Todo: remove + FramebufferInfo framebuffer; + + // Memory map (array of MemoryRegion) + MemoryRegion* memory_map; + uint64_t memory_map_count; + + // Platform-specific firmware tables (both always present to keep layout uniform) + uint64_t rsdp_address; // ACPI RSDP (x86_64), 0 if absent + uint64_t fdt_address; // Flattened Device Tree (aarch64), 0 if absent + + // Kernel load info + uint64_t kernel_phys_base; // Where the kernel was loaded physically + uint64_t kernel_virt_base; // Kernel's virtual base (from ELF) + uint64_t kernel_size; // Total size of kernel in memory + + // Kernel entry point (virtual address from ELF e_entry) + uint64_t kernel_entry_point; + + // Higher-half direct map base (if set up by loader) + uint64_t hhdm_base; // e.g., 0xFFFF800000000000 +}; 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]; +} |
