[RFC][UEFI][Driver] Support UEFI target

Abstract

To compile UEFI applications using Clang, we currently use Windows target triple (e.g. x86_64-pc-windows-msvc). We would like to introduce a first-class UEFI environment support to compile UEFI applications where only UEFI constraints are included and not the Windows ABI or API interoperability constraints. We intend to add support for this UEFI environment incrementally beginning with the introduction of UEFI specific target triple. The immediate focus and proposed implementation will cover Driver and Tool support for UEFI. Eventually, we would like to port runtime, compiler-rt builtins, libc and libc++ libraries.

Proposed Changes

This is an informal specification for a minimum viable implementation.

  • Introduce a new LLVM Triple OSType named UEFI.
  • Add UEFI toolchain support to the Clang driver.
  • For each of the target architectures, implement a UEFI TargetInfo e.g. UEFIX86_64TargetInfo.

We make some assumptions regarding certain aspects of the UEFI compilations that are not explicitly mentioned in the UEFI specification. This is to simplify the early implementation and we expect to expand the support as and when new projects are onboarded and require changes to these assumptions:

  1. Default subsystem - efi_application (EFI_IMAGE_SUSBSYTEM_EFI_APPLICATION)
  2. Default entry point - EfiMain

The following macro defines will be part of the implementation.

  • __UEFI__
  • __PECOFF__
    • If this macro can be set for all PE-COFF targets (i.e. UEFI and Windows PE-COFF targets), it can be useful.

This effort is carried out by the Fuchsia toolchain team at Google which I am part of. We plan to compile the UEFI early bring up code used by the Zircon kernel with the new target.

Discussion

We plan to provide a simple UEFI example that can be compiled and run on QEMU using the new target for demonstration and testing purposes. We fully welcome comments, questions and suggestions from the community on this effort.

2 Likes

Having an official target seems like an improvement over the existing hacks people are using. (I’ve seen hacks much uglier than using a Windows target.)

Do you have a plan to make recipes for building a complete toolchain available?

1 Like

As UEFI supports more architectures nowadays, it should also support at least also AArch64 and RISC-V. LoongArch uses UEFI too, AFAIK: GitHub - loongson/Firmware: Firmware Of LoongArch Machines

1 Like

RISC-V cannot be supported so long as there is no full PE/COFF spec for RISC-V; there are no architecture-specific relocations defined for it. Getting those likely depends on Microsoft wanting to do a Windows port, too, so don’t expect that to happen any time soon. The workaround is generally to build an ELF and convert it to PE/COFF, whether through some objcopy-like tool emitting a PE/COFF file itself or by constructing the PE/COFF header in assembly and using objcopy -O binary. This is the downside of UEFI using a spec owned by Microsoft for its object file format.

2 Likes

I think modelling UEFI as an OS makes sense to me, we should do it.

1 Like

Thank you.

We intend to provide documentation on how to build UEFI applications with the new target with examples. The Fuchsia toolchain CMake changes can also be useful as a reference.

1 Like