xref: /openbmc/u-boot/doc/README.u-boot_on_efi (revision 4f1dacd43fcb5d4e97407df51b48dfde5e920078)
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
68f3b5056cSHeinrich Schuchardtand CONFIG_EFI_APP. The efi-x86 config (efi-x86_defconfig) is set up for this.
69f3b5056cSHeinrich SchuchardtJust build U-Boot as normal, e.g.
70f3b5056cSHeinrich Schuchardt
71f3b5056cSHeinrich Schuchardt   make efi-x86_defconfig
72f3b5056cSHeinrich Schuchardt   make
73f3b5056cSHeinrich Schuchardt
74f3b5056cSHeinrich SchuchardtTo build U-Boot as an EFI payload (32-bit or 64-bit EFI can be used), adjust an
75f3b5056cSHeinrich Schuchardtexisting config (like qemu-x86_defconfig) to enable CONFIG_EFI, CONFIG_EFI_STUB
76f3b5056cSHeinrich Schuchardtand either CONFIG_EFI_STUB_32BIT or CONFIG_EFI_STUB_64BIT. All of these are
77f3b5056cSHeinrich Schuchardtboolean Kconfig options. Then build U-Boot as normal, e.g.
78f3b5056cSHeinrich Schuchardt
79f3b5056cSHeinrich Schuchardt   make qemu-x86_defconfig
80f3b5056cSHeinrich Schuchardt   make
81f3b5056cSHeinrich Schuchardt
82f3b5056cSHeinrich SchuchardtYou will end up with one of these files depending on what you build for:
83f3b5056cSHeinrich Schuchardt
84f3b5056cSHeinrich Schuchardt   u-boot-app.efi      - U-Boot EFI application
85f3b5056cSHeinrich Schuchardt   u-boot-payload.efi  - U-Boot EFI payload application
86f3b5056cSHeinrich Schuchardt
87f3b5056cSHeinrich Schuchardt
88f3b5056cSHeinrich SchuchardtTrying it out
89f3b5056cSHeinrich Schuchardt-------------
90f3b5056cSHeinrich SchuchardtQEMU is an emulator and it can emulate an x86 machine. Please make sure your
91f3b5056cSHeinrich SchuchardtQEMU version is 2.3.0 or above to test this. You can run the payload with
92f3b5056cSHeinrich Schuchardtsomething like this:
93f3b5056cSHeinrich Schuchardt
94f3b5056cSHeinrich Schuchardt   mkdir /tmp/efi
95f3b5056cSHeinrich Schuchardt   cp /path/to/u-boot*.efi /tmp/efi
96f3b5056cSHeinrich Schuchardt   qemu-system-x86_64 -bios bios.bin -hda fat:/tmp/efi/
97f3b5056cSHeinrich Schuchardt
98f3b5056cSHeinrich SchuchardtAdd -nographic if you want to use the terminal for output. Once it starts
99f3b5056cSHeinrich Schuchardttype 'fs0:u-boot-payload.efi' to run the payload or 'fs0:u-boot-app.efi' to
100f3b5056cSHeinrich Schuchardtrun the application. 'bios.bin' is the EFI 'BIOS'. Check [2] to obtain a
101f3b5056cSHeinrich Schuchardtprebuilt EFI BIOS for QEMU or you can build one from source as well.
102f3b5056cSHeinrich Schuchardt
103f3b5056cSHeinrich SchuchardtTo try it on real hardware, put u-boot-app.efi on a suitable boot medium,
104f3b5056cSHeinrich Schuchardtsuch as a USB stick. Then you can type something like this to start it:
105f3b5056cSHeinrich Schuchardt
106f3b5056cSHeinrich Schuchardt   fs0:u-boot-payload.efi
107f3b5056cSHeinrich Schuchardt
108f3b5056cSHeinrich Schuchardt(or fs0:u-boot-app.efi for the application)
109f3b5056cSHeinrich Schuchardt
110f3b5056cSHeinrich SchuchardtThis will start the payload, copy U-Boot into RAM and start U-Boot. Note
111f3b5056cSHeinrich Schuchardtthat EFI does not support booting a 64-bit application from a 32-bit
112f3b5056cSHeinrich SchuchardtEFI (or vice versa). Also it will often fail to print an error message if
113f3b5056cSHeinrich Schuchardtyou get this wrong.
114f3b5056cSHeinrich Schuchardt
115f3b5056cSHeinrich Schuchardt
116f3b5056cSHeinrich SchuchardtInner workings
117f3b5056cSHeinrich Schuchardt==============
118f3b5056cSHeinrich SchuchardtHere follow a few implementation notes for those who want to fiddle with
119f3b5056cSHeinrich Schuchardtthis and perhaps contribute patches.
120f3b5056cSHeinrich Schuchardt
121f3b5056cSHeinrich SchuchardtThe application and payload approaches sound similar but are in fact
122f3b5056cSHeinrich Schuchardtimplemented completely differently.
123f3b5056cSHeinrich Schuchardt
124f3b5056cSHeinrich SchuchardtEFI Application
125f3b5056cSHeinrich Schuchardt---------------
126f3b5056cSHeinrich SchuchardtFor the application the whole of U-Boot is built as a shared library. The
127f3b5056cSHeinrich Schuchardtefi_main() function is in lib/efi/efi_app.c. It sets up some basic EFI
128f3b5056cSHeinrich Schuchardtfunctions with efi_init(), sets up U-Boot global_data, allocates memory for
129f3b5056cSHeinrich SchuchardtU-Boot's malloc(), etc. and enters the normal init sequence (board_init_f()
130f3b5056cSHeinrich Schuchardtand board_init_r()).
131f3b5056cSHeinrich Schuchardt
132f3b5056cSHeinrich SchuchardtSince U-Boot limits its memory access to the allocated regions very little
133f3b5056cSHeinrich Schuchardtspecial code is needed. The CONFIG_EFI_APP option controls a few things
134f3b5056cSHeinrich Schuchardtthat need to change so 'git grep CONFIG_EFI_APP' may be instructive.
135f3b5056cSHeinrich SchuchardtThe CONFIG_EFI option controls more general EFI adjustments.
136f3b5056cSHeinrich Schuchardt
137f3b5056cSHeinrich SchuchardtThe only available driver is the serial driver. This calls back into EFI
138f3b5056cSHeinrich Schuchardt'boot services' to send and receive characters. Although it is implemented
139f3b5056cSHeinrich Schuchardtas a serial driver the console device is not necessarilly serial. If you
140f3b5056cSHeinrich Schuchardtboot EFI with video output then the 'serial' device will operate on your
141f3b5056cSHeinrich Schuchardttarget devices's display instead and the device's USB keyboard will also
142f3b5056cSHeinrich Schuchardtwork if connected. If you have both serial and video output, then both
143f3b5056cSHeinrich Schuchardtconsoles will be active. Even though U-Boot does the same thing normally,
144f3b5056cSHeinrich SchuchardtThese are features of EFI, not U-Boot.
145f3b5056cSHeinrich Schuchardt
146f3b5056cSHeinrich SchuchardtVery little code is involved in implementing the EFI application feature.
147f3b5056cSHeinrich SchuchardtU-Boot is highly portable. Most of the difficulty is in modifying the
148f3b5056cSHeinrich SchuchardtMakefile settings to pass the right build flags. In particular there is very
149f3b5056cSHeinrich Schuchardtlittle x86-specific code involved - you can find most of it in
150f3b5056cSHeinrich Schuchardtarch/x86/cpu. Porting to ARM (which can also use EFI if you are brave
151f3b5056cSHeinrich Schuchardtenough) should be straightforward.
152f3b5056cSHeinrich Schuchardt
153f3b5056cSHeinrich SchuchardtUse the 'reset' command to get back to EFI.
154f3b5056cSHeinrich Schuchardt
155f3b5056cSHeinrich SchuchardtEFI Payload
156f3b5056cSHeinrich Schuchardt-----------
157f3b5056cSHeinrich SchuchardtThe payload approach is a different kettle of fish. It works by building
158f3b5056cSHeinrich SchuchardtU-Boot exactly as normal for your target board, then adding the entire
159f3b5056cSHeinrich Schuchardtimage (including device tree) into a small EFI stub application responsible
160f3b5056cSHeinrich Schuchardtfor booting it. The stub application is built as a normal EFI application
161f3b5056cSHeinrich Schuchardtexcept that it has a lot of data attached to it.
162f3b5056cSHeinrich Schuchardt
163f3b5056cSHeinrich SchuchardtThe stub application is implemented in lib/efi/efi_stub.c. The efi_main()
164f3b5056cSHeinrich Schuchardtfunction is called by EFI. It is responsible for copying U-Boot from its
165f3b5056cSHeinrich Schuchardtoriginal location into memory, disabling EFI boot services and starting
166f3b5056cSHeinrich SchuchardtU-Boot. U-Boot then starts as normal, relocates, starts all drivers, etc.
167f3b5056cSHeinrich Schuchardt
168f3b5056cSHeinrich SchuchardtThe stub application is architecture-dependent. At present it has some
169f3b5056cSHeinrich Schuchardtx86-specific code and a comment at the top of efi_stub.c describes this.
170f3b5056cSHeinrich Schuchardt
171f3b5056cSHeinrich SchuchardtWhile the stub application does allocate some memory from EFI this is not
172f3b5056cSHeinrich Schuchardtused by U-Boot (the payload). In fact when U-Boot starts it has all of the
173f3b5056cSHeinrich Schuchardtmemory available to it and can operate as it pleases (but see the next
174f3b5056cSHeinrich Schuchardtsection).
175f3b5056cSHeinrich Schuchardt
176f3b5056cSHeinrich SchuchardtTables
177f3b5056cSHeinrich Schuchardt------
178f3b5056cSHeinrich SchuchardtThe payload can pass information to U-Boot in the form of EFI tables. At
179f3b5056cSHeinrich Schuchardtpresent this feature is used to pass the EFI memory map, an inordinately
180f3b5056cSHeinrich Schuchardtlarge list of memory regions. You can use the 'efi mem all' command to
181f3b5056cSHeinrich Schuchardtdisplay this list. U-Boot uses the list to work out where to relocate
182f3b5056cSHeinrich Schuchardtitself.
183f3b5056cSHeinrich Schuchardt
184f3b5056cSHeinrich SchuchardtAlthough U-Boot can use any memory it likes, EFI marks some memory as used
185f3b5056cSHeinrich Schuchardtby 'run-time services', code that hangs around while U-Boot is running and
186f3b5056cSHeinrich Schuchardtis even present when Linux is running. This is common on x86 and provides
187f3b5056cSHeinrich Schuchardta way for Linux to call back into the firmware to control things like CPU
188f3b5056cSHeinrich Schuchardtfan speed. U-Boot uses only 'conventional' memory, in EFI terminology. It
189f3b5056cSHeinrich Schuchardtwill relocate itself to the top of the largest block of memory it can find
190f3b5056cSHeinrich Schuchardtbelow 4GB.
191f3b5056cSHeinrich Schuchardt
192f3b5056cSHeinrich SchuchardtInterrupts
193f3b5056cSHeinrich Schuchardt----------
194f3b5056cSHeinrich SchuchardtU-Boot drivers typically don't use interrupts. Since EFI enables interrupts
195f3b5056cSHeinrich Schuchardtit is possible that an interrupt will fire that U-Boot cannot handle. This
196f3b5056cSHeinrich Schuchardtseems to cause problems. For this reason the U-Boot payload runs with
197f3b5056cSHeinrich Schuchardtinterrupts disabled at present.
198f3b5056cSHeinrich Schuchardt
199f3b5056cSHeinrich Schuchardt32/64-bit
200f3b5056cSHeinrich Schuchardt---------
201f3b5056cSHeinrich SchuchardtWhile the EFI application can in principle be built as either 32- or 64-bit,
202f3b5056cSHeinrich Schuchardtonly 32-bit is currently supported. This means that the application can only
203f3b5056cSHeinrich Schuchardtbe used with 32-bit EFI.
204f3b5056cSHeinrich Schuchardt
205f3b5056cSHeinrich SchuchardtThe payload stub can be build as either 32- or 64-bits. Only a small amount
206f3b5056cSHeinrich Schuchardtof code is built this way (see the extra- line in lib/efi/Makefile).
207f3b5056cSHeinrich SchuchardtEverything else is built as a normal U-Boot, so is always 32-bit on x86 at
208f3b5056cSHeinrich Schuchardtpresent.
209f3b5056cSHeinrich Schuchardt
210f3b5056cSHeinrich SchuchardtFuture work
211f3b5056cSHeinrich Schuchardt-----------
212f3b5056cSHeinrich SchuchardtThis work could be extended in a number of ways:
213f3b5056cSHeinrich Schuchardt
214f3b5056cSHeinrich Schuchardt- Add a generic x86 EFI payload configuration. At present you need to modify
215f3b5056cSHeinrich Schuchardtan existing one, but mostly the low-level x86 code is disabled when booting
216f3b5056cSHeinrich Schuchardton EFI anyway, so a generic 'EFI' board could be created with a suitable set
217f3b5056cSHeinrich Schuchardtof drivers enabled.
218f3b5056cSHeinrich Schuchardt
219f3b5056cSHeinrich Schuchardt- Add ARM support
220f3b5056cSHeinrich Schuchardt
221f3b5056cSHeinrich Schuchardt- Add 64-bit application support
222f3b5056cSHeinrich Schuchardt
223f3b5056cSHeinrich Schuchardt- Figure out how to solve the interrupt problem
224f3b5056cSHeinrich Schuchardt
225f3b5056cSHeinrich Schuchardt- Add more drivers to the application side (e.g. video, block devices, USB,
226f3b5056cSHeinrich Schuchardtenvironment access). This would mostly be an academic exercise as a strong
227f3b5056cSHeinrich Schuchardtuse case is not readily apparent, but it might be fun.
228f3b5056cSHeinrich Schuchardt
229f3b5056cSHeinrich Schuchardt- Avoid turning off boot services in the stub. Instead allow U-Boot to make
230f3b5056cSHeinrich Schuchardtuse of boot services in case it wants to. It is unclear what it might want
231f3b5056cSHeinrich Schuchardtthough.
232f3b5056cSHeinrich Schuchardt
233f3b5056cSHeinrich SchuchardtWhere is the code?
234f3b5056cSHeinrich Schuchardt------------------
235f3b5056cSHeinrich Schuchardtlib/efi
236f3b5056cSHeinrich Schuchardt	payload stub, application, support code. Mostly arch-neutral
237f3b5056cSHeinrich Schuchardt
238f3b5056cSHeinrich Schuchardtarch/x86/cpu/efi
239*4f1dacd4SBin Meng	x86 support code for running as an EFI application and payload
240f3b5056cSHeinrich Schuchardt
241f3b5056cSHeinrich Schuchardtboard/efi/efi-x86/efi.c
242f3b5056cSHeinrich Schuchardt	x86 board code for running as an EFI application
243f3b5056cSHeinrich Schuchardt
244f3b5056cSHeinrich Schuchardtcommon/cmd_efi.c
245f3b5056cSHeinrich Schuchardt	the 'efi' command
246f3b5056cSHeinrich Schuchardt
247f3b5056cSHeinrich Schuchardt--
248f3b5056cSHeinrich SchuchardtBen Stoltz, Simon Glass
249f3b5056cSHeinrich SchuchardtGoogle, Inc
250f3b5056cSHeinrich SchuchardtJuly 2015
251f3b5056cSHeinrich Schuchardt
252f3b5056cSHeinrich Schuchardt[1] http://www.qemu.org
253f3b5056cSHeinrich Schuchardt[2] http://www.tianocore.org/ovmf/
254