But if I try to read memory map and then call ExitBootServices() QEMU crashes for me:
qemu-system-x86_64: Trying to execute code outside RAM or ROM at 0x00000000000b0000
Here is my test-case program that uses GNU-EFI library
Code: Select all
#include "elf.h"
#include <efi.h>
#include <efilib.h>
EFI_STATUS efi_main(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SysTab) {
InitializeLib(ImageHandle, SysTab);
uint8_t buffer[4900];
UINTN msize = sizeof(buffer);
UINTN mkey = 0, dsize = 0;
UINT32 dversion;
SysTab->BootServices->GetMemoryMap(&msize, (EFI_MEMORY_DESCRIPTOR*)buffer, &mkey, &dsize, &dversion);
EFI_STATUS st = SysTab->BootServices->ExitBootServices(ImageHandle, mkey);
// QEMU crashes here ^^^^^^^^^^^^^^^^^^^^^^^^^^
// qemu-system-x86_64: Trying to execute code outside RAM or ROM at 0x00000000000b0000
Print(L"Press any key: %d\n", st);
UINTN index;
EFI_EVENT event = SysTab->ConIn->WaitForKey;
SysTab->BootServices->WaitForEvent(1, &event, &index);
return EFI_SUCCESS;
}
Here is a Makefile for it
Code: Select all
ARCH = x86_64
OBJS = bootloader.o
TARGET = bootloader.efi
EFIINC = /usr/include/efi
EFIINCS = -I$(EFIINC) -I$(EFIINC)/$(ARCH) -I$(EFIINC)/protocol
EFILIB = /usr/lib
EFI_CRT_OBJS = $(EFILIB)/crt0-efi-$(ARCH).o
EFI_LDS = $(EFILIB)/elf_$(ARCH)_efi.lds
CFLAGS = $(EFIINCS) -fno-stack-protector -fPIC -fshort-wchar -mno-red-zone -Wall -std=c11
ifeq ($(ARCH),x86_64)
CFLAGS += -DHAVE_USE_MS_ABI
endif
LDFLAGS = -nostdlib -znocombreloc -T $(EFI_LDS) -shared -Bsymbolic -L $(EFILIB) $(EFI_CRT_OBJS)
all: $(TARGET)
bootloader.so: $(OBJS)
ld $(LDFLAGS) $(OBJS) -o $@ -lefi -lgnuefi
%.efi: %.so
objcopy -j .text -j .sdata -j .data -j .dynamic -j .dynsym -j .rel -j .rela -j .reloc --target=efi-app-$(ARCH) $^ $@
hda/EFI/BOOT/BOOTX64.EFI: bootloader.efi
mkdir -p hda/EFI/BOOT/
cp bootloader.efi hda/EFI/BOOT/BOOTX64.EFI
run: hda/EFI/BOOT/BOOTX64.EFI
qemu-system-x86_64 --bios OVMF_CODE.fd -hda fat:rw:hda -net none
I think I tried everything: GCC vs clang, compiling/running at Arch vs Debian, tried different OVMF version (from Arch, Debian, Fedora). The crash is still here. I am staring at the code and do not see any problems with it.
Does anybody have a clue what is going here and why ExitBootServices() crashes?