i am genuinely stupid

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
aayanbaig
Posts: 5
Joined: Sat Mar 01, 2025 7:22 am
Libera.chat IRC: aayanbaig26

i am genuinely stupid

Post by aayanbaig »

i decided to try my luck with uefi and see how it is. ive been learning a lot.

however ive run in to a rather abnormal issue.


for any protocol i try to use, locatehandlebuffer, allocate pages, all guids, nothing works. this stuff first started with me not being able to initialize/find the GOP. then when i did a few changes to my code, turns out that the framebuffer exists but GOP is not initialized? what weirdness? whatever i say sounds stupid sometimes because i am not the best at uefi development considering ive only been doing it for 3 or 4 or so months.



So essentially ive tried everything and have ended up making my "bootmanager.c" file into a very minimalistic environment:

Code: Select all

#include <efi_types.h>
#include <efi_table.h>
#include <efi_console.h>
#include <efi_boot_services.h>

EFI_SYSTEM_TABLE* ST;
EFI_BOOT_SERVICES* BS;

#define Print(msg) ST->ConOut->OutputString(ST->ConOut, msg)

// Simple memcpy
void* memcpy(void* dest, const void* src, UINTN n) {
    UINT8* d = (UINT8*)dest;
    const UINT8* s = (const UINT8*)src;
    for (UINTN i = 0; i < n; i++) {
        d[i] = s[i];
    }
    return dest;
}

// Simple hex printer for 64-bit values
void PrintHex(UINT64 val) {
    CHAR16 out[21] = L"0x0000000000000000\r\n";
    for (UINTN i = 0; i < 16; i++) {
        UINT8 nibble = (val >> ((15 - i) * 4)) & 0xF;
        out[2 + i] = (nibble < 10) ? (L'0' + nibble) : (L'A' + nibble - 10);
    }
    Print(out);
}

void PrintGuid(EFI_GUID* g) {
    CHAR16 out[64] = L"GUID: 00000000-0000-0000-0000-000000000000\r\n";
    UINTN idx = 6;
    UINT32 d1 = g->Data1;
    UINT16 d2 = g->Data2;
    UINT16 d3 = g->Data3;
    UINT8* d4 = g->Data4;
    CHAR16 hex[] = L"0123456789ABCDEF";

    #define HEX4(x) hex[(x >> 4) & 0xF], hex[x & 0xF]

    for (int i = 7; i >= 0; --i) {
        out[idx++] = hex[(d1 >> (i * 4)) & 0xF];
    }
    idx++; // '-'
    for (int i = 3; i >= 0; --i) {
        out[idx++] = hex[(d2 >> (i * 4)) & 0xF];
    }
    idx++; // '-'
    for (int i = 3; i >= 0; --i) {
        out[idx++] = hex[(d3 >> (i * 4)) & 0xF];
    }
    idx++; // '-'
    out[idx++] = HEX4(d4[0]);
    out[idx++] = HEX4(d4[1]);
    idx++; // '-'
    for (int i = 2; i < 8; ++i) {
        out[idx++] = HEX4(d4[i]);
    }
    Print(out);
}

EFI_STATUS EFIAPI efi_main(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE* SystemTable) {
    ST = SystemTable;
    BS = ST->BootServices;

    void

    ST->ConOut->Reset(ST->ConOut, TRUE);
    ST->ConOut->SetAttribute(ST->ConOut, 0x0E);
    ST->ConOut->ClearScreen(ST->ConOut);

    Print(L"[debug] Booting EFI GUID dumper...\r\n");

    EFI_HANDLE* handles = NULL;
    UINTN handle_count = 0;

    EFI_STATUS status = BS->LocateHandleBuffer(AllHandles, NULL, NULL, &handle_count, &handles);
    if (EFI_ERROR(status)) {
        Print(L"[error] LocateHandleBuffer failed. Code: ");
        PrintHex(status);
        while (1) __asm__("hlt");
    }

    Print(L"[info] Handles found: ");
    PrintHex((UINT64)handle_count);

    for (UINTN i = 0; i < handle_count; i++) {
        EFI_GUID** guid_array = NULL;
        UINTN guid_count = 0;
        EFI_STATUS res = BS->ProtocolsPerHandle(handles[i], &guid_array, &guid_count);

        if (EFI_ERROR(res)) {
            Print(L"[warn] ProtocolsPerHandle failed for handle: ");
            PrintHex((UINT64)(UINTN)handles[i]);
            continue;
        }

        for (UINTN j = 0; j < guid_count; j++) {
            PrintGuid(guid_array[j]);
        }
    }

    Print(L"[done] GUID scan complete.\r\n");
    while (1) __asm__("hlt");
    return EFI_SUCCESS;
}
essentially just checks for guids because i was trying to do something.


everything fails with 0x800000000000000E (EFI_INVALID_PARAMETER) and its so goddamn annoying - ive tried to fix it for ages to no avail.

everything fails to run. acpi works just fine - im able to get the rsdp structures and hence finding madt, fadt, etc. etc. easily but unfortunately literally nothing works inside efi.

efi_boot_services.h:

Code: Select all

#ifndef EFI_BOOT_SERVICES_H
#define EFI_BOOT_SERVICES_H

#include "efi_types.h"
#include "efi_table_header.h"
#include "efi_memory.h"

typedef enum {
    AllHandles = 0,
    ByRegisterNotify,
    ByProtocol
} EFI_LOCATE_SEARCH_TYPE;

// typedef EFI_STATUS(EFIAPI *EFI_LOCATE_HANDLE_BUFFER)(
//     EFI_LOCATE_SEARCH_TYPE SearchType,
//     EFI_GUID* Protocol,
//     VOID* SearchKey,
//     UINTN* NoHandles,
//     EFI_HANDLE** Buffer
// );


// Task Priority
typedef EFI_TPL (EFIAPI *EFI_RAISE_TPL)(EFI_TPL NewTpl);
typedef VOID (EFIAPI *EFI_RESTORE_TPL)(EFI_TPL OldTpl);

// Memory
typedef EFI_STATUS (EFIAPI *EFI_ALLOCATE_PAGES)(EFI_ALLOCATE_TYPE, EFI_MEMORY_TYPE, UINTN, EFI_PHYSICAL_ADDRESS*);
typedef EFI_STATUS (EFIAPI *EFI_FREE_PAGES)(EFI_PHYSICAL_ADDRESS, UINTN);
typedef EFI_STATUS (EFIAPI *EFI_GET_MEMORY_MAP)(UINTN*, EFI_MEMORY_DESCRIPTOR*, UINTN*, UINTN*, UINT32*);
typedef EFI_STATUS (EFIAPI *EFI_ALLOCATE_POOL)(EFI_MEMORY_TYPE, UINTN, VOID**);
typedef EFI_STATUS (EFIAPI *EFI_FREE_POOL)(VOID*);

// Event & Timer
typedef EFI_STATUS (EFIAPI *EFI_CREATE_EVENT)(UINT32, EFI_TPL, VOID*, VOID*, EFI_EVENT*);
typedef EFI_STATUS (EFIAPI *EFI_SET_TIMER)(EFI_EVENT, UINT32, UINT64);
typedef EFI_STATUS (EFIAPI *EFI_WAIT_FOR_EVENT)(UINTN, EFI_EVENT*, UINTN*);
typedef EFI_STATUS (EFIAPI *EFI_SIGNAL_EVENT)(EFI_EVENT);
typedef EFI_STATUS (EFIAPI *EFI_CLOSE_EVENT)(EFI_EVENT);
typedef EFI_STATUS (EFIAPI *EFI_CHECK_EVENT)(EFI_EVENT);

// Protocol Interface
typedef EFI_STATUS (EFIAPI *EFI_INSTALL_PROTOCOL_INTERFACE)(EFI_HANDLE*, EFI_GUID*, UINT32, VOID*);
typedef EFI_STATUS (EFIAPI *EFI_REINSTALL_PROTOCOL_INTERFACE)(EFI_HANDLE, EFI_GUID*, VOID*, VOID*);
typedef EFI_STATUS (EFIAPI *EFI_UNINSTALL_PROTOCOL_INTERFACE)(EFI_HANDLE, EFI_GUID*, VOID*);
typedef EFI_STATUS (EFIAPI *EFI_HANDLE_PROTOCOL)(EFI_HANDLE, EFI_GUID*, VOID**);
typedef EFI_STATUS (EFIAPI *EFI_REGISTER_PROTOCOL_NOTIFY)(EFI_GUID*, EFI_EVENT, VOID**);
typedef EFI_STATUS (EFIAPI *EFI_LOCATE_HANDLE)(UINT32, EFI_GUID*, VOID*, UINTN*, EFI_HANDLE*);
typedef EFI_STATUS (EFIAPI *EFI_LOCATE_DEVICE_PATH)(EFI_GUID*, VOID**, EFI_HANDLE*);
typedef EFI_STATUS (EFIAPI *EFI_INSTALL_CONFIGURATION_TABLE)(EFI_GUID*, VOID*);

// Image
typedef EFI_STATUS (EFIAPI *EFI_IMAGE_LOAD)(BOOLEAN, EFI_HANDLE, VOID*, VOID*, UINTN, EFI_HANDLE*);
typedef EFI_STATUS (EFIAPI *EFI_IMAGE_START)(EFI_HANDLE, UINTN*, CHAR16**);
typedef EFI_STATUS (EFIAPI *EFI_EXIT)(EFI_HANDLE, EFI_STATUS, UINTN, CHAR16*);
typedef EFI_STATUS (EFIAPI *EFI_IMAGE_UNLOAD)(EFI_HANDLE);
typedef EFI_STATUS (EFIAPI *EFI_EXIT_BOOT_SERVICES)(EFI_HANDLE, UINTN);

// Misc
typedef EFI_STATUS (EFIAPI *EFI_GET_NEXT_MONOTONIC_COUNT)(UINT64*);
typedef EFI_STATUS (EFIAPI *EFI_STALL)(UINTN);
typedef EFI_STATUS (EFIAPI *EFI_SET_WATCHDOG_TIMER)(UINTN, UINT64, UINTN, CHAR16*);

// Driver Support
typedef EFI_STATUS (EFIAPI *EFI_CONNECT_CONTROLLER)(EFI_HANDLE, EFI_HANDLE*, VOID*, BOOLEAN);
typedef EFI_STATUS (EFIAPI *EFI_DISCONNECT_CONTROLLER)(EFI_HANDLE, EFI_HANDLE, VOID*);

// Protocol Locating
typedef EFI_STATUS (EFIAPI *EFI_LOCATE_PROTOCOL)(EFI_GUID*, VOID*, VOID**);
typedef EFI_STATUS (EFIAPI *EFI_LOCATE_PROTOCOL2)(EFI_GUID*, VOID*, VOID**);
typedef EFI_STATUS (EFIAPI *EFI_LOCATE_HANDLE_BUFFER)(EFI_LOCATE_SEARCH_TYPE SearchType, EFI_GUID* Protocol, VOID* SearchKey, UINTN* NoHandles, EFI_HANDLE** Buffer);
typedef EFI_STATUS (EFIAPI *EFI_COPY_MEM)(VOID*, VOID*, UINTN);
typedef EFI_STATUS (EFIAPI *EFI_SET_MEM)(VOID*, UINTN, UINT8);



typedef struct {
    EFI_TABLE_HEADER Hdr;

    // Task Priority
    EFI_RAISE_TPL RaiseTPL;
    EFI_RESTORE_TPL RestoreTPL;

    // Memory
    EFI_ALLOCATE_PAGES AllocatePages;
    EFI_FREE_PAGES FreePages;
    EFI_GET_MEMORY_MAP GetMemoryMap;
    EFI_ALLOCATE_POOL AllocatePool;
    EFI_FREE_POOL FreePool;

    // Event & Timer
    EFI_CREATE_EVENT CreateEvent;
    EFI_SET_TIMER SetTimer;
    EFI_WAIT_FOR_EVENT WaitForEvent;
    EFI_SIGNAL_EVENT SignalEvent;
    EFI_CLOSE_EVENT CloseEvent;
    EFI_CHECK_EVENT CheckEvent;

    // Protocols
    EFI_INSTALL_PROTOCOL_INTERFACE InstallProtocolInterface;
    EFI_REINSTALL_PROTOCOL_INTERFACE ReinstallProtocolInterface;
    EFI_UNINSTALL_PROTOCOL_INTERFACE UninstallProtocolInterface;
    EFI_HANDLE_PROTOCOL HandleProtocol;
    VOID* Reserved; // must be present for alignment!
    EFI_REGISTER_PROTOCOL_NOTIFY RegisterProtocolNotify;
    EFI_LOCATE_HANDLE LocateHandle;
    EFI_LOCATE_DEVICE_PATH LocateDevicePath;
    EFI_INSTALL_CONFIGURATION_TABLE InstallConfigurationTable;

    // Image services
    EFI_IMAGE_LOAD LoadImage;
    EFI_IMAGE_START StartImage;
    EFI_EXIT Exit;
    EFI_IMAGE_UNLOAD UnloadImage;
    EFI_EXIT_BOOT_SERVICES ExitBootServices;

    // Misc
    EFI_GET_NEXT_MONOTONIC_COUNT GetNextMonotonicCount;
    EFI_STALL Stall;
    EFI_SET_WATCHDOG_TIMER SetWatchdogTimer;

    // Driver support
    EFI_CONNECT_CONTROLLER ConnectController;
    EFI_DISCONNECT_CONTROLLER DisconnectController;

    // Protocol locating
    EFI_LOCATE_PROTOCOL LocateProtocol;

    // ✅ This is the only used function i think ;-;
    EFI_STATUS (EFIAPI *ProtocolsPerHandle)(
        EFI_HANDLE Handle,
        EFI_GUID*** ProtocolBuffer,
        UINTN* ProtocolBufferCount
    );

    EFI_LOCATE_HANDLE_BUFFER LocateHandleBuffer;
    EFI_LOCATE_PROTOCOL2 LocateProtocol2;
    EFI_COPY_MEM CopyMem;
    EFI_SET_MEM SetMem;

} EFI_BOOT_SERVICES;


#endif
efi_types.h:

Code: Select all

#ifndef EFI_TYPES_H
#define EFI_TYPES_H

#include <stdint.h>


#define EFIAPI __attribute__((ms_abi))



typedef void            VOID;
typedef uint8_t         BOOLEAN;
typedef uint8_t         UINT8;
typedef uint16_t        UINT16;
typedef uint32_t        UINT32;
typedef uint64_t        UINT64;
typedef int8_t          INT8;
typedef int16_t         INT16;
typedef int32_t         INT32;
typedef int64_t         INT64;

typedef UINT64          UINTN;
typedef INT64           INTN;

typedef char            CHAR8;
typedef uint16_t        CHAR16;

#ifndef NULL
#define NULL ((VOID*)0)
#endif

#ifndef TRUE
#define TRUE ((BOOLEAN)1)
#endif

#ifndef FALSE
#define FALSE ((BOOLEAN)0)
#endif

typedef VOID*           EFI_HANDLE;
typedef VOID*           EFI_EVENT;

typedef UINT64          EFI_LBA;
typedef UINTN           EFI_TPL;

typedef UINT64          EFI_PHYSICAL_ADDRESS;
typedef UINT64          EFI_VIRTUAL_ADDRESS;

typedef struct {
    UINT32  Data1;
    UINT16  Data2;
    UINT16  Data3;
    UINT8   Data4[8];
} EFI_GUID;

typedef UINT64 EFI_STATUS;

#define EFI_SUCCESS               0
#define EFI_LOAD_ERROR            0x8000000000000001
#define EFI_INVALID_PARAMETER     0x8000000000000002
#define EFI_UNSUPPORTED           0x8000000000000003
#define EFI_BAD_BUFFER_SIZE       0x8000000000000004
#define EFI_BUFFER_TOO_SMALL      0x8000000000000005
#define EFI_NOT_FOUND             0x8000000000000014
#define EFI_OUT_OF_RESOURCES      0x8000000000000009

#define EFI_ERROR(Status) (((INTN)(Status)) < 0)

#endif // EFI_TYPES_H
efi_memory.h:

Code: Select all

#ifndef EFI_MEMORY_H
#define EFI_MEMORY_H

#include "efi_types.h"

//
// Memory Type
//
typedef enum {
    EfiReservedMemoryType,
    EfiLoaderCode,
    EfiLoaderData,
    EfiBootServicesCode,
    EfiBootServicesData,
    EfiRuntimeServicesCode,
    EfiRuntimeServicesData,
    EfiConventionalMemory,
    EfiUnusableMemory,
    EfiACPIReclaimMemory,
    EfiACPIMemoryNVS,
    EfiMemoryMappedIO,
    EfiMemoryMappedIOPortSpace,
    EfiPalCode,
    EfiPersistentMemory,
    EfiUnacceptedMemoryType,
    EfiMaxMemoryType
} EFI_MEMORY_TYPE;

typedef enum {
    AllocateAnyPages,
    AllocateMaxAddress,
    AllocateAddress,
    MaxAllocateType
} EFI_ALLOCATE_TYPE;


//
// Memory Attributes (bitfield flags)
//
#define EFI_MEMORY_UC          0x0000000000000001ULL
#define EFI_MEMORY_WC          0x0000000000000002ULL
#define EFI_MEMORY_WT          0x0000000000000004ULL
#define EFI_MEMORY_WB          0x0000000000000008ULL
#define EFI_MEMORY_UCE         0x0000000000000010ULL
#define EFI_MEMORY_WP          0x0000000000001000ULL
#define EFI_MEMORY_RP          0x0000000000002000ULL
#define EFI_MEMORY_XP          0x0000000000004000ULL
#define EFI_MEMORY_NV          0x0000000000008000ULL
#define EFI_MEMORY_MORE_RELIABLE 0x0000000000010000ULL
#define EFI_MEMORY_RO          0x0000000000020000ULL
#define EFI_MEMORY_SP          0x0000000000040000ULL
#define EFI_MEMORY_CPU_CRYPTO  0x0000000000080000ULL
#define EFI_MEMORY_RUNTIME     0x8000000000000000ULL

//
// Memory Descriptor Structure
//
typedef struct {
    UINT32 Type;
    EFI_PHYSICAL_ADDRESS PhysicalStart;
    EFI_VIRTUAL_ADDRESS VirtualStart;
    UINT64 NumberOfPages;
    UINT64 Attribute;
} EFI_MEMORY_DESCRIPTOR;

#endif // EFI_MEMORY_H


i dont know what else do anymore - im in a roadblock :cry:

i would genuinely appreciate it if somebody could help. thanks <3
Octocontrabass
Member
Member
Posts: 5822
Joined: Mon Mar 25, 2013 7:01 pm

Re: i am genuinely stupid

Post by Octocontrabass »

aayanbaig wrote: Wed Jun 04, 2025 1:55 am

Code: Select all

    EFI_DISCONNECT_CONTROLLER DisconnectController;

    // Protocol locating
    EFI_LOCATE_PROTOCOL LocateProtocol;
Your struct is missing a few fields between these two.
aayanbaig
Posts: 5
Joined: Sat Mar 01, 2025 7:22 am
Libera.chat IRC: aayanbaig26

Re: i am genuinely stupid

Post by aayanbaig »

Ill have a look into it. Thanks :D
Post Reply