public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
* EFI ExitBootServices() function crashes in QEMU
@ 2018-03-13 23:28 Anatol Pomozov
  2018-03-14  8:18 ` Laszlo Ersek
  0 siblings, 1 reply; 2+ messages in thread
From: Anatol Pomozov @ 2018-03-13 23:28 UTC (permalink / raw)
  To: edk2-devel

Hello

I am implementing a simple UEFI bootloader. Most EFI functions that I
tried work me - I can clear Console, print text, successfully read
files from system partition, allocate memory pages.

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

I tried to enable QEMU cpu debugging and I see that at some point flow
jumps to address 0 then executes "00" operations until it reaches
0xb0000 (video memory?) that contains non-zero data and crashes.

Here is my bootloader code (this one is based on GNU-EFI but I also
tried one based on xefi from Fuchsia).



EFI_STATUS efi_main(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SysTab) {
    InitializeLib(ImageHandle, SysTab);

    UINTN mkey = 0, dsize = 0;
    UINT32 dversion = 0;
    UINTN msize = 32768;
    EFI_MEMORY_DESCRIPTOR *mmap = AllocatePool(msize);
    if (!mmap) {
        Print(L"AllocatePool failed\n");
        goto error;
    }

    SysTab->BootServices->GetMemoryMap(&msize, mmap, &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
error:
    return EFI_SUCCESS;
}



And here is my Makefile:



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



The sourcecode is simple and clear, I think the problem either in the
Makefile (CFLAGS/LDFLAGS) or OVMF.

So my questions: in what cases ExitBootServices() can cause execution
of NULL pointer? How to debug this issue with OVMF?

Or maybe you see something wrong with my CFLAGS/LDFLAGS?


^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: EFI ExitBootServices() function crashes in QEMU
  2018-03-13 23:28 EFI ExitBootServices() function crashes in QEMU Anatol Pomozov
@ 2018-03-14  8:18 ` Laszlo Ersek
  0 siblings, 0 replies; 2+ messages in thread
From: Laszlo Ersek @ 2018-03-14  8:18 UTC (permalink / raw)
  To: Anatol Pomozov, edk2-devel

On 03/14/18 00:28, Anatol Pomozov wrote:
> Hello
> 
> I am implementing a simple UEFI bootloader. Most EFI functions that I
> tried work me - I can clear Console, print text, successfully read
> files from system partition, allocate memory pages.
> 
> 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
> 
> I tried to enable QEMU cpu debugging and I see that at some point flow
> jumps to address 0 then executes "00" operations until it reaches
> 0xb0000 (video memory?) that contains non-zero data and crashes.
> 
> Here is my bootloader code (this one is based on GNU-EFI but I also
> tried one based on xefi from Fuchsia).
> 
> 
> 
> EFI_STATUS efi_main(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SysTab) {
>     InitializeLib(ImageHandle, SysTab);
> 
>     UINTN mkey = 0, dsize = 0;
>     UINT32 dversion = 0;
>     UINTN msize = 32768;
>     EFI_MEMORY_DESCRIPTOR *mmap = AllocatePool(msize);
>     if (!mmap) {
>         Print(L"AllocatePool failed\n");
>         goto error;
>     }
> 
>     SysTab->BootServices->GetMemoryMap(&msize, mmap, &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
> error:
>     return EFI_SUCCESS;
> }
> 
> 
> 
> And here is my Makefile:
> 
> 
> 
> 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
> 
> 
> 
> The sourcecode is simple and clear, I think the problem either in the
> Makefile (CFLAGS/LDFLAGS) or OVMF.
> 
> So my questions: in what cases ExitBootServices() can cause execution
> of NULL pointer? How to debug this issue with OVMF?
> 
> Or maybe you see something wrong with my CFLAGS/LDFLAGS?

I suggest asking this question on a gnu-efi development list or forum.

Alternatively, you could check how grub2-efi is built with gnu-efi in a
Linux distribution -- for example, Fedora's build logs are saved in
Koji:
https://kojipkgs.fedoraproject.org//packages/grub2/2.02/27.fc29/data/logs/x86_64/build.log

I think it very unlikely that the issue is with the ExitBootServices()
boot service itself. No UEFI OS can be booted without that service; if
it was broken in OVMF, we'd be inundated with bug reports.

Laszlo


^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2018-03-14  8:12 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2018-03-13 23:28 EFI ExitBootServices() function crashes in QEMU Anatol Pomozov
2018-03-14  8:18 ` Laszlo Ersek

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox