Sign in Join
Wiki copytemporary

UEFI: what changed

Revision 1 to 2. Removed lines have a minus sign; added lines have a plus sign.

OldNewLine
11## Motivations behind this target
22
33The Unified Extensible Firmware Interface (UEFI) now replaces BIOS in most current PCs.
44
55Currently, there are two main options to develop UEFI applications:
66
77- [Tianocore](http://www.tianocore.org/)
88- [gnu-efi](http://sourceforge.net/projects/gnu-efi/)
99
1010Both solutions require a tedious setup process.
1111
1212Thank to its internal linker, Free Pascal can become the easiest option to develop UEFI applications, as no external tools would be required to start hacking.
1313
1414## Technical requirements
1515
1616UEFI applications are PE binaries like the Windows target, which Free Pascal already supports. The only difference is the subsystem in the PE header.
1717
1818Calling conventions under UEFI are identical to the ones under Windows on the same architecture, which Free Pascal already supports, too.
1919
2020## Current state
2121
2222*My current patch against trunk is here : <http://nan.tf/download/uefi_all_03_01_2016.diff>.*
2323
2424*It is not yet a clean patch : lots of debug output inside.*
2525
2626**I have resume my work on this target. Here is my updated patch against trunk : <http://nan.tf/download/fpc_uefi_28_04_2017.diff>**
2727
2828Currently, I am focusing on UEFI32 because i have a few cheap atom machines with that version (see <https://software.intel.com/en-us/blogs/2015/07/22/why-cheap-systems-run-32-bit-uefi-on-x64-systems>) and because i use Haiku as my main development platform, without a 64 bits freepascal yet.
2929
3030But UEFI64 support should be easy to had with careful API declarations.
3131
3232A branch is now available with the current development state at <https://svn.freepascal.org/cgi-bin/viewvc.cgi/branches/olivier/uefi/>
3333
3434## Build instructions
3535
3636For UEFI 32 target, the build command line is :
3737
38-`make all OS_TARGET=uefi CPU_TARGET=i386`
38+```text
39+make all OS_TARGET=uefi CPU_TARGET=i386
40+```
3941
4042For UEFI 64 target, the build command line is :
4143
42-`make all OS_TARGET=uefi CPU_TARGET=x86_64`
44+```text
45+make all OS_TARGET=uefi CPU_TARGET=x86_64
46+```
4347
4448If you want to cross compile from a different architecture, it might be necessary to specify OS_SOURCE and CPU_SOURCE. Here is for example the command line for Haiku 32 bits.
4549
46-`make all OS_TARGET=uefi CPU_TARGET=x86_64 OS_SOURCE=haiku CPU_SOURCE=i386`
50+```text
51+make all OS_TARGET=uefi CPU_TARGET=x86_64 OS_SOURCE=haiku CPU_SOURCE=i386
52+```
4753
4854## Known problems
4955
5056*Affectation of string constant to string variable does not work. It is currently necessary to create strings through an array of WideChar.*
5157
5258``` pascal
5359var
5460 s : string;
5561begin
5662 s := 'Hello world !';
5763end;
5864```
5965
6066*Maybe it is related to Position Independent Code generation in the case of PE executables ?*
6167
6268*Any hints in this area are welcome ;-)*
6369
6470**With current trunk (3.1.1), this bug has been fixed. It helps a lot to be able to use WriteLn('Something to write') instead of constructing an array of WideChar and call UEFI functions as before ;-).**
6571
6672Other known problem :
6773
6874``` pascal
6975 list := TStringList.Create;
7076```
7177
7278While constructing other kind of object works as expected, this one currently crash the program... I will have to investigate.
7379
7480Update : it seems related to uses : without any uses in my program, it just works... With only one, it crash.
7581
7682Update 2 : I have finally found the problem : SysUtils initialize some static constructions BEFORE unit initialization. That is why it was always crashing when adding a uses to SysUtils in a simple program, but before the **initialization** section. That explain why my debugging messages in SysUtils where never displayed...
7783
7884## Testing UEFI applications with qemu
7985
8086See [OSDev UEFI Emulation with QEMU and OVMF](http://wiki.osdev.org/UEFI#Emulation_with_QEMU_and_OVMF)
8187
8288To avoid creating an image, i use FAT emulation to a local directory where my UEFI application is located :
8389
8490``` bash
8591qemu-system-i386-x86 -pflash /path/to/OVMF.fd -hda fat:local_directory -net none
8692```
8793
8894"-net none" avoid net booting to save a few seconds in the boot process.
8995
9096From UEFI shell, then write :
9197
92-`fs0:`
98+```text
99+fs0:
100+```
93101
94102to switch to the directory where are located your application then you can launch it :
95103
96-`app.efi`
104+```text
105+app.efi
106+```
97107
98108## History
99109
100110Everything has started after reading this article while i was lurking about UEFI development : <http://blog.theincredibleholk.org/blog/2013/11/18/booting-to-rust/>
101111
102112What about doing that in Freepascal as well ?
103113
104114It appears that Freepascal is even a better target for such a project because of its internal linker for PE targets : no need to install and configure an external one.
105115
106116**August 2014**
107117
108118Proof of concept : Freepascal is able to output a PE binary that can run in an UEFI environment. It can output a static text and the version of the firmware to the screen using an UEFI method.
109119
110120**April 2017**
111121
112122After observing that an annoying bug about string constant was fixed, i have resumed my work on this target.
113123
114124Currently, here are the features that are implemented :
115125
116-`- WriteLn support (no more awkward array of WideChar allocation required)`\
117-`- Memory allocation`
126+```text
127+- WriteLn support (no more awkward array of WideChar allocation required)
128+- Memory allocation
129+```
118130
119131**May 2017**
120132
121133Start of x86_64 support (not functional yet). The idea is to check if the 'uses' problem is related to the use of PE32 binary format. UEFI is supposed to use PE32+ (with 64 bits relocations). UEFI specifications are not clear whether this variant is also used for UEFI32. With a x86_64 CPU and the win64 linker, this uncertainty should disappear...
122134
123135Update : after a binary comparison between two different binaries compiled with the official UEFI tools, UEFI32 binaries are plain PE32 ones, with an IMAGE_OPTIONAL_HEADER with a size of 224 bytes while an UEFI64 binary contains an IMAGE_OPTIONAL_HEADER with a size of 240 bytes (some fields are 64 bits instead of 32 bits). This is confirmed in <https://msdn.microsoft.com/en-us/library/windows/desktop/ms680339(v=vs.85>).aspx. Afterthought, it make sense : i suspect Intel has chosen PE binary format and Application Binary Interface (ABI) like the corresponding ones in Windows to minimize the work at Microsoft and make sure they will adopt the UEFI specifications...
124136
125137**August 2017**
126138
127139## External resources
128140
129141Some interesting development resources around UEFI :
130142
131143- [UEFI specifications](http://www.uefi.org/)
132144- [OS development under UEFI](http://wiki.osdev.org/UEFI)
133145- [Managing EFI Boot Loaders for Linux: Basic Principles](http://www.rodsbooks.com/efi-bootloaders/principles.html)
134146
135147---
136148*From the Free Pascal wiki, page "UEFI", as it stood on 2020-03-01 after a change by Trev, out of the wiki's dump of 2024-05-26. Copyright stays with the author who wrote it, according to the old wiki's [[Licensing]] page. If you have concerns about this material, [message the admin](/wiki-contact).*
137149Category: Operating Systems and Platforms

Back to history