Page 1 of 1

Mingw64?

Posted: Sun Jan 10, 2021 1:24 pm
by PeterX
I want to try mingw 64bit for programming an UEFI application.
Can someone tell me which Ubuntu-APT-package and which shell command I have to use?

I only find *mingw32*. I can't find any *mingw64* package/command. Maybe expecting mingw64 is wrong?

(There was this thread but I didn't want to hijack it:
viewtopic.php?f=1&t=39343 )

Greetings
Peter

Re: Mingw64?

Posted: Sun Jan 10, 2021 1:47 pm
by kzinti
On my Linux Mint, it is called "gcc-mingw-w64" or "gcc-mingw-w64-x86-64".

Do a search for "mingw-w64"...

Re: Mingw64?

Posted: Sun Jan 10, 2021 3:47 pm
by PeterX
kzinti wrote:On my Linux Mint, it is called "gcc-mingw-w64" or "gcc-mingw-w64-x86-64".

Do a search for "mingw-w64"...
Thanks! I managed to install the package "gcc-mingw-w64-x86-64".

But the only shell command I have now is "mingw-genlib". No "mingw-w64*", no "gcc-mingw*" etc. Maybe my APT is broken?

But I found this:
https://wiki.osdev.org/UEFI_App_Bare_Bones
I will follow that and come back if I still have questions after that.

EDIT: I think I solved it. The mentioned wiki page says it is "x86_64-w64-mingw32-gcc". The "32" was irritating me because I don't want to produce 32bit code. But it seems to be the way to go.

Greetings
Peter

Re: Mingw64?

Posted: Mon Jan 11, 2021 7:39 am
by bzt
PeterX wrote:EDIT: I think I solved it. The mentioned wiki page says it is "x86_64-w64-mingw32-gcc". The "32" was irritating me because I don't want to produce 32bit code. But it seems to be the way to go.
Have no worries, "w32" in mingw32 refers to the Win32 API, it has nothing to do with the actual output format. You're going to compile in freestanding mode with nostdlib, so OS API doesn't matter.

Cheers,
bzt

Re: Mingw64?

Posted: Mon Jan 11, 2021 2:17 pm
by vvaltchev
I'm sorry for (probably) the stupid question: why using mingw, in particular on Linux, at all?
I mean, if you're developing on Linux it makes more sense to me to use directly GCC's toolchain, doesn't it?
If you need a pre-built cross toolchain, you can download one from: https://toolchains.bootlin.com/
Or, if you're developing a kernel on Windows and you'd like to take advantage of the GCC toolchain,
why not using WSL (aka Bash for Windows) ?

Re: Mingw64?

Posted: Mon Jan 11, 2021 2:35 pm
by PeterX
vvaltchev wrote:I'm sorry for (probably) the stupid question: why using mingw, in particular on Linux, at all?
I mean, if you're developing on Linux it makes more sense to me to use directly GCC's toolchain, doesn't it?
I want to develop on Linux for UEFI. Since the UEFI API is nearly 100% identical to Windows API/ABI, the target Windows is correct (but only file format, calling conventions and such basic stuff).

So far mingw has turned out to be less hassle than GNU-EFI, Tianocore's EDK2, CLang/LLVM and cross-gcc. I guess CLang would also work well after minor work.

Greetings
Peter

Re: Mingw64?

Posted: Mon Jan 11, 2021 7:01 pm
by vvaltchev
PeterX wrote: I want to develop on Linux for UEFI. Since the UEFI API is nearly 100% identical to Windows API/ABI, the target Windows is correct (but only file format, calling conventions and such basic stuff).
So far mingw has turned out to be less hassle than GNU-EFI, Tianocore's EDK2, CLang/LLVM and cross-gcc. I guess CLang would also work well after minor work.
I'm really surprised: my experience with GCC + GNU-EFI is pretty good, instead.
I mean, it's true that it requires some extra flags during compile-time plus one trick,
the invocation of objcopy at the end, as described here in GNU-EFI but, most of the flags
are needed because we're building and linking with an additional library and we're creating
a shared library. Overall, nothing too tricky.

In my case, I can build everything with system's compiler as well (if gcc-multilib is installed): a cross compiler is not
actually required. If I had to build for ARCH=x86_64, I wouldn't even need gcc-multilib, just the default gcc toolchain
on my Linux distro. I can also debug my UEFI bootloader with GDB as well, with some minor tricks.

Therefore, at this point I'd be curious to ask you:
  • 1. OK, you use a windows-ABI compiler, but you still need a library for the UEFI definitions. Which library do you use for that?
    2. Excluding the objcopy trick, what else is much better/easier in your MINGW workflow?
    3. Which build system do you use? (e.g. gnu make, CMake, other etc.)
Vlad

Re: Mingw64?

Posted: Mon Jan 11, 2021 7:50 pm
by PeterX
vvaltchev wrote:
  • 1. OK, you use a windows-ABI compiler, but you still need a library for the UEFI definitions. Which library do you use for that?
    2. Excluding the objcopy trick, what else is much better/easier in your MINGW workflow?
    3. Which build system do you use? (e.g. gnu make, CMake, other etc.)
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?
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.
3. I use GNU make (without using special GNUish aspects of make).

Re: Mingw64?

Posted: Tue Jan 12, 2021 9:40 am
by vvaltchev
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

Re: Mingw64?

Posted: Tue Jan 12, 2021 11:03 am
by PeterX
Thanks, Vlad, but I will probably stick to my way.

BTW Your kernel is a really cool idea.

Greetings
Peter