UEFI: Difference between revisions

1,859 bytes added ,  2 years ago
m
Reverted edits by Leapofazzam (talk) to last revision by Bumbread
[unchecked revision][unchecked revision]
m (why)
m (Reverted edits by Leapofazzam (talk) to last revision by Bumbread)
Line 58:
 
====Development environment====
Legacy bootloaders can be developed in any environment that can generate flat binary images: NASM, GCC, etc. UEFI applications can be developed in any language that can be compiled and linked into a [[PE]] executable file and supports the calling convention used to access functions established in memory by the UEFI firmware. In practice this means one of twothree development environments: EDK2 and, GNU-EFI or POSIX-UEFI.
 
[[EDK2]] is a large and complex, yet feature filled environment with its own build system. It can be configured to use GCC, LLVM, MinGW, Microsoft Visual C++, etc. as a cross-compiler. Not only can it be used to compile UEFI applications, but it can also be used to compile UEFI firmware to be flashed to a BIOS ROM.
 
[[GNU-EFI]] is a set of libraries and headers for compiling UEFI applications with a system's native GCC (does not work with LLVM CLang). It can't be used to compile UEFI firmware. Since it's just a couple of libraries against which a UEFI application can be linked, it is much easier to use than TianoCore.
 
[[POSIX-UEFI]] is very similar to GNU-EFI, but it is distributed mainly as a source, not as a binary library, has ANSI C like names and works with GCC as well as LLVM CLang. It's shipped with a Makefile that sets up the compiler flags for you.
 
====Emulation====
Line 121 ⟶ 123:
 
A good starting point is writing a UEFI application that uses the System Table to fetch a memory map, and uses the "File" protocol to read files from FAT-formatted disks. The next step might be to use the System Table to locate ACPI tables.
 
==Developing with POSIX-UEFI==
:''Main article: [[POSIX-UEFI]]
 
One option to compile UEFI applications on POSIX like systems is POSIX-UEFI. It provies a [[libc]]-like API for your EFI application, and ships with a Makefile that can detect and set up the toolchain for you. It can use GCC or LLVM, and defaults to using the host compiler, but a cross compiler is still recommended.
 
It uses POSIX style typedefs (like ''uintn_t'' instead of ''UINTN''), and it does not ship with the standard EFI headers. You can still get interfaces not covered by POSIX-UEFI (such as GOP) by installing the EFI headers from GNU-EFI or EDK2. Also, it compiles with the MS ABI, meaning that UEFI services can be called natively (i.e., without uefi_call_wrapper) so long as your apps are compiled with it as well.
The traditional "Hello, world" UEFI program goes like this.
<source lang="c">
#include <uefi.h>
int main (int argc, char **argv)
{
printf("Hello, world!\n");
return 0;
}
</source>
Makefile looks like this:
<source lang="make">
TARGET = main.efi
include uefi/Makefile
</source>
Run make to build it. The result of this process is a PE executable file ''main.efi''.
 
==Developing with GNU-EFI==
Line 534 ⟶ 559:
Note that functions strictly internal to the application can use whatever calling convention the developer chooses.
 
==== POSIX-UEFI, GNU-EFI and GCC ====
{{Main|GNU-EFI}}
cdecl is the standard calling convention used by GCC, so no special attributes or modifiers are needed for writing the main entry point or calling UEFI functions in an x86 UEFI application developed with GNU-EFI. For x86-64, however, the entry point function must be declared with the "___attribute___((ms_abi))" modifier and all calls to UEFI-provided functions must be made through the "uefi_call_wrapper" thunk. This thunk is called with cdecl, but then translates to the Microsoft x86-64 calling convention before calling the requested UEFI function. This is necessary because older releases of GCC do not support specifying calling conventions for function pointers.
 
For [[POSIX-UEFI]], which also uses GCC, your entry point looks like the standard main(), and no special ABI is required. Also the build environment takes care of the compiler flags for you, so you can simply call UEFI functions without "uefi_call_wrapper", no matter if you're using the host gcc or a cross-compiler.
For developer convenience, GNU-EFI provides the "EFIAPI" macro, which expands to "cdecl" when targeting x86 and "__attribute__(ms_abi))" when targeting x86-64. Additionally, the "uefi_call_wrapper" thunk will simply pass the call through on x86. This allows the same source code to target x86 and x86-64. For example, the following main function will compile with the correct calling convention on both x86 and x86-64 and the call through the "uefi_call_wrapper" thunk will select the correct calling convention to use when calling the UEFI function (in this case, printing a string).
 
For developer convenience, both POSIX-UEFI and GNU-EFI provides the "EFIAPI" macro, which expands to "cdecl" when targeting x86 and "__attribute__(ms_abi))" when targeting x86-64. Additionally, the "uefi_call_wrapper" thunk will simply pass the call through on x86. This allows the same source code to target x86 and x86-64. For example, the following main function will compile with the correct calling convention on both x86 and x86-64 and the call through the "uefi_call_wrapper" thunk will select the correct calling convention to use when calling the UEFI function (in this case, printing a string).
<source lang="c">
EFI_STATUS EFIAPI efi_main(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
Line 599 ⟶ 626:
* [[PE]] file format
* [[TianoCore]]
* [[EDK2POSIX-UEFI]]
* [[GNU-EFI]]
* [https://github.com/nebulaeonline/nebulae/tree/UefiBarebones Uefi Barebones MSVC/Clang/Visual Studio]
Line 613 ⟶ 640:
* [https://web.archive.org/web/20160316192235/http://internshipatdell.wikispaces.com/file/view/How+to+build+an+UEFI+application.pptx Presentation guiding through simple UEFI application setup]
* [https://uefi.org/sites/default/files/resources/UEFI-Plugfest-WindowsBootEnvironment.pdf Presentation giving an overview of windows uefi booting]
* [https://gitlab.com/bztsrc/posix-uefi POSIX-UEFI] documentation and source
* [[Wikipedia:Extensible_Firmware_Interface|Wikipedia Article on EFI]]