PeterX wrote:
1. I'm at the very start of learning UEFI (as you can see by my code and by my questions.) I'm not aware of needing any UEFI library. Can you point me to info about this in the UEFI specifications?
OK, technically you could write an UEFI app without any library, but you'd need to define a ton of function signatures, structs and GUIDs
in your code, following strictly the specification. This is error-prone and a very mechanical thing to do: there's not much to learn
from doing it from scratch. That's why we use a libraries like gnu-efi.
PeterX wrote:
2. There are several things but I don't remember details. One thing I DO remember is the need to prefix UEFI calls with EFI_ABI or uefi_call_wrapper or something like that.
Yes, the EFI library has to prefix the functions with EFIAPI, but that's totally transparent to you: if you build your
code with -DGNU_EFI_USE_MS_ABI, you won't need to use the uefi_call_wrapper() at all.
Let me show how your code will look like:
Code: Select all
EFI_STATUS
efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *__ST)
{
EFI_STATUS status;
InitializeLib(image, __ST);
status = BS->OpenProtocol(image,
&LoadedImageProtocol,
(void**) &gLoadedImage,
image,
NULL,
EFI_OPEN_PROTOCOL_GET_PROTOCOL);
if (EFI_ERROR(status)) {
Print(L"Error: %r\n", status);
}
return status;
}
No weird wrappers, nothing. That's because even the regular GCC compiled for Linux supports MS_ABI as well,
no need for MINGW for that. The only difference is that MINGW uses MS_ABI
by default, while the Linux GCC
requires the __attribute__((ms_abi)) attribute,
in the efi library, not in your code.
In conclusion, I see no real advantages in using MINGW for compiling a UEFI application. Actually, I see more potential
troubles in that scenario.
If you want an even cleaner solution (avoiding the objcopy hack), you can build your EFI application with
clang. It not only supports the MS ABI as gcc does, but it supports natively the PE shared library (DLL) as target:
Code: Select all
CFLAGS+= \
--target x86_64-unknown-windows \
-ffreestanding \
-fshort-wchar \
-mno-red-zone
LDFLAGS+= \
--target x86_64-unknown-windows \
-nostdlib \
-Wl,-entry:efi_main \
-Wl,-subsystem:efi_application \
-fuse-ld=lld-link
The problem with that is that it
requires an LLVM toolchain. You might not find pre-built LLVM toolchains so easily
as GCC ones (if you need them) and the LLVM assembler is not fully compatible with the GCC one. If you're interested
only in writing UEFI applications, that might be the best solution for you. In my case, it wasn't. Note: you still need gnu-efi
or any other EFI library. Otherwise, you'll see to define by hand all the function signatures and types you'll ever need to use
in your app.
Vlad