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
_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel

Reply via email to