xref: /openbmc/u-boot/doc/README.u-boot_on_efi (revision 378b29cbc6607ad8246b1381bc74ec62bdb19105)
1f3b5056cSHeinrich Schuchardt# SPDX-License-Identifier: GPL-2.0+
2f3b5056cSHeinrich Schuchardt#
383d290c5STom Rini# Copyright (C) 2015 Google, Inc
4f3b5056cSHeinrich Schuchardt
5f3b5056cSHeinrich SchuchardtU-Boot on EFI
6f3b5056cSHeinrich Schuchardt=============
7f3b5056cSHeinrich SchuchardtThis document provides information about U-Boot running on top of EFI, either
8f3b5056cSHeinrich Schuchardtas an application or just as a means of getting U-Boot onto a new platform.
9f3b5056cSHeinrich Schuchardt
10f3b5056cSHeinrich Schuchardt
11f3b5056cSHeinrich Schuchardt=========== Table of Contents ===========
12f3b5056cSHeinrich Schuchardt
13f3b5056cSHeinrich SchuchardtMotivation
14f3b5056cSHeinrich SchuchardtStatus
15f3b5056cSHeinrich SchuchardtBuild Instructions
16f3b5056cSHeinrich SchuchardtTrying it out
17f3b5056cSHeinrich SchuchardtInner workings
18f3b5056cSHeinrich SchuchardtEFI Application
19f3b5056cSHeinrich SchuchardtEFI Payload
20f3b5056cSHeinrich SchuchardtTables
21f3b5056cSHeinrich SchuchardtInterrupts
22f3b5056cSHeinrich Schuchardt32/64-bit
23f3b5056cSHeinrich SchuchardtFuture work
24f3b5056cSHeinrich SchuchardtWhere is the code?
25f3b5056cSHeinrich Schuchardt
26f3b5056cSHeinrich Schuchardt
27f3b5056cSHeinrich SchuchardtMotivation
28f3b5056cSHeinrich Schuchardt----------
29f3b5056cSHeinrich SchuchardtRunning U-Boot on EFI is useful in several situations:
30f3b5056cSHeinrich Schuchardt
31f3b5056cSHeinrich Schuchardt- You have EFI running on a board but U-Boot does not natively support it
32f3b5056cSHeinrich Schuchardtfully yet. You can boot into U-Boot from EFI and use that until U-Boot is
33f3b5056cSHeinrich Schuchardtfully ported
34f3b5056cSHeinrich Schuchardt
35f3b5056cSHeinrich Schuchardt- You need to use an EFI implementation (e.g. UEFI) because your vendor
36f3b5056cSHeinrich Schuchardtrequires it in order to provide support
37f3b5056cSHeinrich Schuchardt
38f3b5056cSHeinrich Schuchardt- You plan to use coreboot to boot into U-Boot but coreboot support does
39f3b5056cSHeinrich Schuchardtnot currently exist for your platform. In the meantime you can use U-Boot
40f3b5056cSHeinrich Schuchardton EFI and then move to U-Boot on coreboot when ready
41f3b5056cSHeinrich Schuchardt
42f3b5056cSHeinrich Schuchardt- You use EFI but want to experiment with a simpler alternative like U-Boot
43f3b5056cSHeinrich Schuchardt
44f3b5056cSHeinrich Schuchardt
45f3b5056cSHeinrich SchuchardtStatus
46f3b5056cSHeinrich Schuchardt------
47f3b5056cSHeinrich SchuchardtOnly x86 is supported at present. If you are using EFI on another architecture
48f3b5056cSHeinrich Schuchardtyou may want to reconsider. However, much of the code is generic so could be
49f3b5056cSHeinrich Schuchardtported.
50f3b5056cSHeinrich Schuchardt
51f3b5056cSHeinrich SchuchardtU-Boot supports running as an EFI application for 32-bit EFI only. This is
52f3b5056cSHeinrich Schuchardtnot very useful since only a serial port is provided. You can look around at
53f3b5056cSHeinrich Schuchardtmemory and type 'help' but that is about it.
54f3b5056cSHeinrich Schuchardt
55f3b5056cSHeinrich SchuchardtMore usefully, U-Boot supports building itself as a payload for either 32-bit
56f3b5056cSHeinrich Schuchardtor 64-bit EFI. U-Boot is packaged up and loaded in its entirety by EFI. Once
57f3b5056cSHeinrich Schuchardtstarted, U-Boot changes to 32-bit mode (currently) and takes over the
58f3b5056cSHeinrich Schuchardtmachine. You can use devices, boot a kernel, etc.
59f3b5056cSHeinrich Schuchardt
60f3b5056cSHeinrich Schuchardt
61f3b5056cSHeinrich SchuchardtBuild Instructions
62f3b5056cSHeinrich Schuchardt------------------
63f3b5056cSHeinrich SchuchardtFirst choose a board that has EFI support and obtain an EFI implementation
64f3b5056cSHeinrich Schuchardtfor that board. It will be either 32-bit or 64-bit. Alternatively, you can
65f3b5056cSHeinrich Schuchardtopt for using QEMU [1] and the OVMF [2], as detailed below.
66f3b5056cSHeinrich Schuchardt
67f3b5056cSHeinrich SchuchardtTo build U-Boot as an EFI application (32-bit EFI required), enable CONFIG_EFI
68*3ebd892fSBin Mengand CONFIG_EFI_APP. The efi-x86_app config (efi-x86_app_defconfig) is set up
69*3ebd892fSBin Mengfor this. Just build U-Boot as normal, e.g.
70f3b5056cSHeinrich Schuchardt
71*3ebd892fSBin Meng   make efi-x86_app_defconfig
72f3b5056cSHeinrich Schuchardt   make
73f3b5056cSHeinrich Schuchardt
7432151d40SBin MengTo build U-Boot as an EFI payload (32-bit or 64-bit EFI can be used), enable
7532151d40SBin MengCONFIG_EFI, CONFIG_EFI_STUB, and select either CONFIG_EFI_STUB_32BIT or
7632151d40SBin MengCONFIG_EFI_STUB_64BIT. The efi-x86_payload configs (efi-x86_payload32_defconfig
7732151d40SBin Mengand efi-x86_payload32_defconfig) are set up for this. Then build U-Boot as
7832151d40SBin Mengnormal, e.g.
79f3b5056cSHeinrich Schuchardt
8032151d40SBin Meng   make efi-x86_payload32_defconfig (or efi-x86_payload64_defconfig)
81f3b5056cSHeinrich Schuchardt   make
82f3b5056cSHeinrich Schuchardt
83f3b5056cSHeinrich SchuchardtYou will end up with one of these files depending on what you build for:
84f3b5056cSHeinrich Schuchardt
85f3b5056cSHeinrich Schuchardt   u-boot-app.efi      - U-Boot EFI application
86f3b5056cSHeinrich Schuchardt   u-boot-payload.efi  - U-Boot EFI payload application
87f3b5056cSHeinrich Schuchardt
88f3b5056cSHeinrich Schuchardt
89f3b5056cSHeinrich SchuchardtTrying it out
90f3b5056cSHeinrich Schuchardt-------------
91f3b5056cSHeinrich SchuchardtQEMU is an emulator and it can emulate an x86 machine. Please make sure your
92f3b5056cSHeinrich SchuchardtQEMU version is 2.3.0 or above to test this. You can run the payload with
93f3b5056cSHeinrich Schuchardtsomething like this:
94f3b5056cSHeinrich Schuchardt
95f3b5056cSHeinrich Schuchardt   mkdir /tmp/efi
96f3b5056cSHeinrich Schuchardt   cp /path/to/u-boot*.efi /tmp/efi
97f3b5056cSHeinrich Schuchardt   qemu-system-x86_64 -bios bios.bin -hda fat:/tmp/efi/
98f3b5056cSHeinrich Schuchardt
99f3b5056cSHeinrich SchuchardtAdd -nographic if you want to use the terminal for output. Once it starts
100f3b5056cSHeinrich Schuchardttype 'fs0:u-boot-payload.efi' to run the payload or 'fs0:u-boot-app.efi' to
101f3b5056cSHeinrich Schuchardtrun the application. 'bios.bin' is the EFI 'BIOS'. Check [2] to obtain a
102f3b5056cSHeinrich Schuchardtprebuilt EFI BIOS for QEMU or you can build one from source as well.
103f3b5056cSHeinrich Schuchardt
104f3b5056cSHeinrich SchuchardtTo try it on real hardware, put u-boot-app.efi on a suitable boot medium,
105f3b5056cSHeinrich Schuchardtsuch as a USB stick. Then you can type something like this to start it:
106f3b5056cSHeinrich Schuchardt
107f3b5056cSHeinrich Schuchardt   fs0:u-boot-payload.efi
108f3b5056cSHeinrich Schuchardt
109f3b5056cSHeinrich Schuchardt(or fs0:u-boot-app.efi for the application)
110f3b5056cSHeinrich Schuchardt
111f3b5056cSHeinrich SchuchardtThis will start the payload, copy U-Boot into RAM and start U-Boot. Note
112f3b5056cSHeinrich Schuchardtthat EFI does not support booting a 64-bit application from a 32-bit
113f3b5056cSHeinrich SchuchardtEFI (or vice versa). Also it will often fail to print an error message if
114f3b5056cSHeinrich Schuchardtyou get this wrong.
115f3b5056cSHeinrich Schuchardt
116f3b5056cSHeinrich Schuchardt
117f3b5056cSHeinrich SchuchardtInner workings
118f3b5056cSHeinrich Schuchardt==============
119f3b5056cSHeinrich SchuchardtHere follow a few implementation notes for those who want to fiddle with
120f3b5056cSHeinrich Schuchardtthis and perhaps contribute patches.
121f3b5056cSHeinrich Schuchardt
122f3b5056cSHeinrich SchuchardtThe application and payload approaches sound similar but are in fact
123f3b5056cSHeinrich Schuchardtimplemented completely differently.
124f3b5056cSHeinrich Schuchardt
125f3b5056cSHeinrich SchuchardtEFI Application
126f3b5056cSHeinrich Schuchardt---------------
127f3b5056cSHeinrich SchuchardtFor the application the whole of U-Boot is built as a shared library. The
128f3b5056cSHeinrich Schuchardtefi_main() function is in lib/efi/efi_app.c. It sets up some basic EFI
129f3b5056cSHeinrich Schuchardtfunctions with efi_init(), sets up U-Boot global_data, allocates memory for
130f3b5056cSHeinrich SchuchardtU-Boot's malloc(), etc. and enters the normal init sequence (board_init_f()
131f3b5056cSHeinrich Schuchardtand board_init_r()).
132f3b5056cSHeinrich Schuchardt
133f3b5056cSHeinrich SchuchardtSince U-Boot limits its memory access to the allocated regions very little
134f3b5056cSHeinrich Schuchardtspecial code is needed. The CONFIG_EFI_APP option controls a few things
135f3b5056cSHeinrich Schuchardtthat need to change so 'git grep CONFIG_EFI_APP' may be instructive.
136f3b5056cSHeinrich SchuchardtThe CONFIG_EFI option controls more general EFI adjustments.
137f3b5056cSHeinrich Schuchardt
138f3b5056cSHeinrich SchuchardtThe only available driver is the serial driver. This calls back into EFI
139f3b5056cSHeinrich Schuchardt'boot services' to send and receive characters. Although it is implemented
140f3b5056cSHeinrich Schuchardtas a serial driver the console device is not necessarilly serial. If you
141f3b5056cSHeinrich Schuchardtboot EFI with video output then the 'serial' device will operate on your
142f3b5056cSHeinrich Schuchardttarget devices's display instead and the device's USB keyboard will also
143f3b5056cSHeinrich Schuchardtwork if connected. If you have both serial and video output, then both
144f3b5056cSHeinrich Schuchardtconsoles will be active. Even though U-Boot does the same thing normally,
145f3b5056cSHeinrich SchuchardtThese are features of EFI, not U-Boot.
146f3b5056cSHeinrich Schuchardt
147f3b5056cSHeinrich SchuchardtVery little code is involved in implementing the EFI application feature.
148f3b5056cSHeinrich SchuchardtU-Boot is highly portable. Most of the difficulty is in modifying the
149f3b5056cSHeinrich SchuchardtMakefile settings to pass the right build flags. In particular there is very
150f3b5056cSHeinrich Schuchardtlittle x86-specific code involved - you can find most of it in
151f3b5056cSHeinrich Schuchardtarch/x86/cpu. Porting to ARM (which can also use EFI if you are brave
152f3b5056cSHeinrich Schuchardtenough) should be straightforward.
153f3b5056cSHeinrich Schuchardt
154f3b5056cSHeinrich SchuchardtUse the 'reset' command to get back to EFI.
155f3b5056cSHeinrich Schuchardt
156f3b5056cSHeinrich SchuchardtEFI Payload
157f3b5056cSHeinrich Schuchardt-----------
158f3b5056cSHeinrich SchuchardtThe payload approach is a different kettle of fish. It works by building
159f3b5056cSHeinrich SchuchardtU-Boot exactly as normal for your target board, then adding the entire
160f3b5056cSHeinrich Schuchardtimage (including device tree) into a small EFI stub application responsible
161f3b5056cSHeinrich Schuchardtfor booting it. The stub application is built as a normal EFI application
162f3b5056cSHeinrich Schuchardtexcept that it has a lot of data attached to it.
163f3b5056cSHeinrich Schuchardt
164f3b5056cSHeinrich SchuchardtThe stub application is implemented in lib/efi/efi_stub.c. The efi_main()
165f3b5056cSHeinrich Schuchardtfunction is called by EFI. It is responsible for copying U-Boot from its
166f3b5056cSHeinrich Schuchardtoriginal location into memory, disabling EFI boot services and starting
167f3b5056cSHeinrich SchuchardtU-Boot. U-Boot then starts as normal, relocates, starts all drivers, etc.
168f3b5056cSHeinrich Schuchardt
169f3b5056cSHeinrich SchuchardtThe stub application is architecture-dependent. At present it has some
170f3b5056cSHeinrich Schuchardtx86-specific code and a comment at the top of efi_stub.c describes this.
171f3b5056cSHeinrich Schuchardt
172f3b5056cSHeinrich SchuchardtWhile the stub application does allocate some memory from EFI this is not
173f3b5056cSHeinrich Schuchardtused by U-Boot (the payload). In fact when U-Boot starts it has all of the
174f3b5056cSHeinrich Schuchardtmemory available to it and can operate as it pleases (but see the next
175f3b5056cSHeinrich Schuchardtsection).
176f3b5056cSHeinrich Schuchardt
177f3b5056cSHeinrich SchuchardtTables
178f3b5056cSHeinrich Schuchardt------
179f3b5056cSHeinrich SchuchardtThe payload can pass information to U-Boot in the form of EFI tables. At
180f3b5056cSHeinrich Schuchardtpresent this feature is used to pass the EFI memory map, an inordinately
181f3b5056cSHeinrich Schuchardtlarge list of memory regions. You can use the 'efi mem all' command to
182f3b5056cSHeinrich Schuchardtdisplay this list. U-Boot uses the list to work out where to relocate
183f3b5056cSHeinrich Schuchardtitself.
184f3b5056cSHeinrich Schuchardt
185f3b5056cSHeinrich SchuchardtAlthough U-Boot can use any memory it likes, EFI marks some memory as used
186f3b5056cSHeinrich Schuchardtby 'run-time services', code that hangs around while U-Boot is running and
187f3b5056cSHeinrich Schuchardtis even present when Linux is running. This is common on x86 and provides
188f3b5056cSHeinrich Schuchardta way for Linux to call back into the firmware to control things like CPU
189f3b5056cSHeinrich Schuchardtfan speed. U-Boot uses only 'conventional' memory, in EFI terminology. It
190f3b5056cSHeinrich Schuchardtwill relocate itself to the top of the largest block of memory it can find
191f3b5056cSHeinrich Schuchardtbelow 4GB.
192f3b5056cSHeinrich Schuchardt
193f3b5056cSHeinrich SchuchardtInterrupts
194f3b5056cSHeinrich Schuchardt----------
195f3b5056cSHeinrich SchuchardtU-Boot drivers typically don't use interrupts. Since EFI enables interrupts
196f3b5056cSHeinrich Schuchardtit is possible that an interrupt will fire that U-Boot cannot handle. This
197f3b5056cSHeinrich Schuchardtseems to cause problems. For this reason the U-Boot payload runs with
198f3b5056cSHeinrich Schuchardtinterrupts disabled at present.
199f3b5056cSHeinrich Schuchardt
200f3b5056cSHeinrich Schuchardt32/64-bit
201f3b5056cSHeinrich Schuchardt---------
202f3b5056cSHeinrich SchuchardtWhile the EFI application can in principle be built as either 32- or 64-bit,
203f3b5056cSHeinrich Schuchardtonly 32-bit is currently supported. This means that the application can only
204f3b5056cSHeinrich Schuchardtbe used with 32-bit EFI.
205f3b5056cSHeinrich Schuchardt
206f3b5056cSHeinrich SchuchardtThe payload stub can be build as either 32- or 64-bits. Only a small amount
207f3b5056cSHeinrich Schuchardtof code is built this way (see the extra- line in lib/efi/Makefile).
208f3b5056cSHeinrich SchuchardtEverything else is built as a normal U-Boot, so is always 32-bit on x86 at
209f3b5056cSHeinrich Schuchardtpresent.
210f3b5056cSHeinrich Schuchardt
211f3b5056cSHeinrich SchuchardtFuture work
212f3b5056cSHeinrich Schuchardt-----------
213f3b5056cSHeinrich SchuchardtThis work could be extended in a number of ways:
214f3b5056cSHeinrich Schuchardt
215f3b5056cSHeinrich Schuchardt- Add ARM support
216f3b5056cSHeinrich Schuchardt
217f3b5056cSHeinrich Schuchardt- Add 64-bit application support
218f3b5056cSHeinrich Schuchardt
219f3b5056cSHeinrich Schuchardt- Figure out how to solve the interrupt problem
220f3b5056cSHeinrich Schuchardt
221f3b5056cSHeinrich Schuchardt- Add more drivers to the application side (e.g. video, block devices, USB,
222f3b5056cSHeinrich Schuchardtenvironment access). This would mostly be an academic exercise as a strong
223f3b5056cSHeinrich Schuchardtuse case is not readily apparent, but it might be fun.
224f3b5056cSHeinrich Schuchardt
225f3b5056cSHeinrich Schuchardt- Avoid turning off boot services in the stub. Instead allow U-Boot to make
226f3b5056cSHeinrich Schuchardtuse of boot services in case it wants to. It is unclear what it might want
227f3b5056cSHeinrich Schuchardtthough.
228f3b5056cSHeinrich Schuchardt
229f3b5056cSHeinrich SchuchardtWhere is the code?
230f3b5056cSHeinrich Schuchardt------------------
231f3b5056cSHeinrich Schuchardtlib/efi
232f3b5056cSHeinrich Schuchardt	payload stub, application, support code. Mostly arch-neutral
233f3b5056cSHeinrich Schuchardt
234f3b5056cSHeinrich Schuchardtarch/x86/cpu/efi
2354f1dacd4SBin Meng	x86 support code for running as an EFI application and payload
236f3b5056cSHeinrich Schuchardt
237*3ebd892fSBin Mengboard/efi/efi-x86_app/efi.c
238f3b5056cSHeinrich Schuchardt	x86 board code for running as an EFI application
239f3b5056cSHeinrich Schuchardt
24032151d40SBin Mengboard/efi/efi-x86_payload
24132151d40SBin Meng	generic x86 EFI payload board support code
24232151d40SBin Meng
243f3b5056cSHeinrich Schuchardtcommon/cmd_efi.c
244f3b5056cSHeinrich Schuchardt	the 'efi' command
245f3b5056cSHeinrich Schuchardt
246f3b5056cSHeinrich Schuchardt--
247f3b5056cSHeinrich SchuchardtBen Stoltz, Simon Glass
248f3b5056cSHeinrich SchuchardtGoogle, Inc
249f3b5056cSHeinrich SchuchardtJuly 2015
250f3b5056cSHeinrich Schuchardt
251f3b5056cSHeinrich Schuchardt[1] http://www.qemu.org
252f3b5056cSHeinrich Schuchardt[2] http://www.tianocore.org/ovmf/
253