2

私は gnu-efi を使用して hello world のようなプログラムを作成しようとしていますが、ExitBootServices の後にブート サービスが使用できなくなるため、ブート サービスはありません。ExitBootServices を呼び出す前にビデオ メモリに直接書き込んでも、何も表示されません。

このため、Mapkey を必要とする ExitBootServices を呼び出す必要があります。MapKey は GetMemoryMap 関数によって提供されます。しかし、それを呼び出すと、アプリケーションがクラッシュします (qemu を使用しています)。

これは私のコードです:

#include <efi.h>
#include <efilib.h>

void write_string( int color, const char *string )
{
    volatile char *video = (volatile char*)0xB8000;
    while( *string != 0 )
    {
        *video++ = *string++;
        *video++ = color;
    }
}

EFI_STATUS
EFIAPI
efi_main (EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
{
    EFI_LOADED_IMAGE *loaded_image = NULL;
    EFI_STATUS status;
    InitializeLib(ImageHandle, SystemTable);

    status = uefi_call_wrapper(SystemTable->BootServices->HandleProtocol,
        3, ImageHandle, &LoadedImageProtocol, (void **)&loaded_image);
    if (EFI_ERROR(status)) {
        Print(L"handleprotocol: %r\n", status);
        return EFI_SUCCESS;
    }

    /* GetMemoryMap */
    UINTN MemoryMapSize = sizeof(EFI_MEMORY_DESCRIPTOR) * 0x10;
    EFI_MEMORY_DESCRIPTOR *MemoryMap = AllocatePool (MemoryMapSize);
    UINTN MapKey = 0;
    UINTN DescriptorSize = 0;
    UINT32 DescriptorVersion = 0;
    status = uefi_call_wrapper(SystemTable->BootServices->GetMemoryMap,
        &MemoryMapSize, MemoryMap, &MapKey, &DescriptorSize, &DescriptorVersion);
    if (EFI_ERROR(status)) {
        Print(L"GetMemoryMap: %r\n", status);
        return EFI_SUCCESS;
    }

    /* ExitBootServices */
    status = uefi_call_wrapper(SystemTable->BootServices->ExitBootServices,
        ImageHandle, MapKey);
    if (EFI_ERROR(status)) {
        Print(L"ExitBootServices: %r\n", status);
        return EFI_SUCCESS;
    }

    write_string(0x07, "example");
}

ExitBootServices qemu を実行する前でも、次のエラーでクラッシュします。

qemu: fatal: Trying to execute code outside RAM or ROM at 0x00000000000b0000

私がやっていることの何が悪いのか誰にもわかりますか?ありがとうございました。

4

1 に答える 1