gnu-efi undefined reference to WaitForSingleEvent

Programming, for all ages and all languages.
Post Reply
Rhodez
Member
Member
Posts: 33
Joined: Tue Jun 30, 2020 2:09 pm
Location: Langeskov, Denmark

gnu-efi undefined reference to WaitForSingleEvent

Post by Rhodez »

Hi, I need some help.

I have followed this https://wiki.osdev.org/UEFI_Bare_Bones and I have the hello world example
running in both QEMU and on hardware form a USB, so that is very good.

I would like to extend the example, as suggested, with the WaitForKey.

If I have understood correct the code should look somthing like this:

Code: Select all

    
/* Now wait until a key becomes available.  This is a simple
    polling implementation.  You could try and use the WaitForKey
    event instead if you like */
    
/* while(Status = ST->ConIn->ReadKeyStroke(ST->ConIn, &Key) == EFI_NOT_READY); */ 
    
while (Key.UnicodeChar != 'q')
{
        
    WaitForSingleEvent(ST->ConIn->WaitForKey, 0);
    ST->ConIn->ReadKeyStroke(ST->ConIn, &Key);
    ST->ConOut->OutputString(ST->ConOut, &Key.UnicodeChar );
}
But when I try to compile I get an undefined reference to `WaitForSingleEvent'

Code: Select all

/usr/lib/gcc/x86_64-w64-mingw32/10.1.0/../../../../x86_64-w64-mingw32/bin/ld: hello.o:hello.c:(.text+0xca): undefined reference to `WaitForSingleEvent'
collect2: error: ld returned 1 exit status
It is my first time cross compiling, so maybe it is just a small thing that I'm not aware of.
Anyone who can help?
User avatar
iansjack
Member
Member
Posts: 4685
Joined: Sat Mar 31, 2012 3:07 am
Location: Chichester, UK

Re: gnu-efi undefined reference to WaitForSingleEvent

Post by iansjack »

What command are you using to link the files?
User avatar
bzt
Member
Member
Posts: 1584
Joined: Thu Oct 13, 2016 4:55 pm
Contact:

Re: gnu-efi undefined reference to WaitForSingleEvent

Post by bzt »

Hi,
Rhodez wrote:It is my first time cross compiling, so maybe it is just a small thing that I'm not aware of.
Anyone who can help?
Your problem is not cross-compilation related. As the error message says, there's no such function "WaitForSingleEvent". Either you implement it yourself, or you rewrite your code to use BS->WaitForEvent with one event in parameter.

Cheers,
bzt
Rhodez
Member
Member
Posts: 33
Joined: Tue Jun 30, 2020 2:09 pm
Location: Langeskov, Denmark

Re: gnu-efi undefined reference to WaitForSingleEvent

Post by Rhodez »

iansjack wrote:What command are you using to link the files?
Just like the wiki says.

Code: Select all

x86_64-w64-mingw32-gcc -nostdlib -Wl,-dll -shared -Wl,--subsystem,10 -e efi_main -o BOOTX64.EFI hello.o data.o -lgcc
@bzt:
This was it! At least it compiles now, but it seems that no events occur.
I have both tried my own example here, but also the one from the link.

From the link example it only writes the first "wait" but then it just freezes.
Do you have any more suggestions here?
User avatar
bzt
Member
Member
Posts: 1584
Joined: Thu Oct 13, 2016 4:55 pm
Contact:

Re: gnu-efi undefined reference to WaitForSingleEvent

Post by bzt »

Rhodez wrote:@bzt:
This was it! At least it compiles now, but it seems that no events occur.
I have both tried my own example here, but also the one from the link.

From the link example it only writes the first "wait" but then it just freezes.
Do you have any more suggestions here?
Set up a timer to implement timeout maybe? Then you'd have to wait for two events, one for WaitForKey, and one for TimerEvent (not entirely sure about this, but it seems all examples on the net do this).

My other suggestion would be that you need to somehow "acknowledge" the event, my guess would be to read the keystroke before you enter the WaitForEvent cycle again. But you probably have tried this already.

I'd recommend to take a look at some FOSS UEFI boot manager, I'm pretty sure you can find a working example somewhere. Such as elilo, rEFInd, etc. Last resort GRUB (it's code is terrible, hard to read compared to the others, but has the answer for sure).

Cheers,
bzt
Rhodez
Member
Member
Posts: 33
Joined: Tue Jun 30, 2020 2:09 pm
Location: Langeskov, Denmark

Re: gnu-efi undefined reference to WaitForSingleEvent

Post by Rhodez »

I have basically copy/pasted the example from the link, which I assume should work, but at least it does not on my machine.
I will try to examine more source code and see if I can figure it out.

But thanks for the BS->xxx tip, I hadn't figured out how to access the EFI_BOOT_SERVICES until that.

By chance, do you know the difference of using BS->xxx and gBS->xxx as he does in the example.
Both things works for me.

Cheers
User avatar
bzt
Member
Member
Posts: 1584
Joined: Thu Oct 13, 2016 4:55 pm
Contact:

Re: gnu-efi undefined reference to WaitForSingleEvent

Post by bzt »

Rhodez wrote:By chance, do you know the difference of using BS->xxx and gBS->xxx as he does in the example.
Different examples use different variable names, that's all. Both should be a pointer to the EFI Boot Time Services table. Most SDKs and libs set these up for you, but you could use your own pointer and read the address yourself from EFI_SYSTEM_TABLE*. I believe the "g" prefix most likely supposed to refer to "global" variable. To keep compatibility, it is not uncommon for EFI libs to set both. Here's the relevant code from gnu-efi's InitializeLib, and here's the EDK2 counterpart. As you can see, both initialized with SystemTable->BootServices.

For example, elilo is using the gnu-efi library that sets up BS, while shim prefers gBS and gRT (primarily uses EDK2, but also gnu-efi too for some reason).

Cheers,
bzt
Rhodez
Member
Member
Posts: 33
Joined: Tue Jun 30, 2020 2:09 pm
Location: Langeskov, Denmark

Re: gnu-efi undefined reference to WaitForSingleEvent

Post by Rhodez »

Nice, thanks for the valuable information.
My initial understanding is much better now.

I will look at some more source code, and hopefully figure out what I need to do to get the WaitForEvent to work.
Rhodez
Member
Member
Posts: 33
Joined: Tue Jun 30, 2020 2:09 pm
Location: Langeskov, Denmark

Re: gnu-efi undefined reference to WaitForSingleEvent

Post by Rhodez »

Of course it was a stupid mistake.
I had not set BS to be ST->BootServices so it has been an invalid pointer during my tests.

I have attached a complete example of an UEFI application which just waits and writes keystrokes and exits on ESC.

Code: Select all

#include <efi.h>
#include <efilib.h>
 
EFI_STATUS
efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *systemTable)
{

  ST = systemTable;
  BS = ST->BootServices;

  UINTN index;
  EFI_INPUT_KEY Key;
  EFI_EVENT event = ST->ConIn->WaitForKey;

  SIMPLE_INPUT_INTERFACE* conIn = ST->ConIn;
  SIMPLE_TEXT_OUTPUT_INTERFACE* conOut = ST->ConOut;
  conOut->OutputString(conOut, L"Hello UEFI");

while(Key.ScanCode != SCAN_ESC)
{
  BS->WaitForEvent(1, &event, &index);
  ST->ConIn->ReadKeyStroke(conIn, &Key);
  ST->ConOut->OutputString(conOut, &Key.UnicodeChar );

}

  return EFI_SUCCESS;
}
Post Reply