-
Notifications
You must be signed in to change notification settings - Fork 1
/
BUILDING.txt
629 lines (522 loc) · 31.8 KB
/
BUILDING.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
NOTE
====
The rEFInd Makefiles are complex, in order to support building in three ways
(described shortly). As a consequence (and, likely, because I'm not exactly
a Makefile guru), tracking of header files is basically non-existent.
Therefore, if you use git to update to a later version of rEFInd, you should
do a "make clean" before building a new version of rEFInd, to be sure any
changed data structures are cleanly applied to all the object files that use
them.
Requirements
============
To compile rEFInd, you'll need the following:
* A Linux installation. Note that this installation does NOT need to be
EFI-based. It can use IA32 (aka x86, i386, or other things), X64 (aka
x86-64, AMD64, or EM64T), or AA64 (aka AARCH64 or ARM64), but unless you
use a cross-compiler, it must use the same CPU type and bit depth as your
EFI implementation. (Normally that means 64-bit X64.) If you don't
normally run Linux, you can run it in a VirtualBox or similar virtual
machine. (I describe some unsupported non-Linux build options later.)
* A standard set of Linux development tools, based on GCC. (I've tried
using Clang 3.4 under Ubuntu, with partial success. The main rEFInd
binary, gptsync, and some drivers compile successfully; but only gptsync
runs normally. The drivers I've tried and the main rEFInd binary crash.)
* One of the following:
* The TianoCore EDK2/UDK package (https://github.com/tianocore/edk2). This
toolkit is available in an unstable development version (EDK2) or in
"frozen" forms (UDK2014, UDK2017, UDK2018, and so on); however, the term
"EDK2" is often used in reference to the TianoCore toolkit generally. To
simplify matters, I officially support only one UDK version at any given
moment. Currently (rEFInd 0.12.1), this version is UDK2018; however, I
used UDK2017 for rEFInd 0.10.9 through 0.11.2, and UDK2014 may
unofficially work via a different build procedure (see below), which is
now deprecated. (This build process is broken with Ubuntu 20.04 and GCC
9.3.) The UDK2018 version I use is available from
https://github.com/tianocore/tianocore.github.io/wiki/UDK2018. I tried a
newer version in February of 2021 (edk2-edk2-stable202011), but it
failed to compile because of the removal of in-tree libraries and other
problems.
* The GNU-EFI package (http://sourceforge.net/projects/gnu-efi/). You can
install this from a package called "gnu-efi"; however, rEFInd relies on
features that were added sometime between version 3.0s and 3.0u, so I
recommend using 3.0u or later. The latest versions of GNU-EFI have
abandoned the trailing letter and switched to a more traditional
additional number, as in 3.0.4. You should check your GNU-EFI version
number; you may need to download the latest source code, compile it, and
install it locally. The Makefiles assume a GNU-EFI package installed via
a package manager. If you install from source code, you may need to
adjust those Makefiles' paths.
Of the two toolkits, I recommend using GNU-EFI if you're compiling for your
native architecture (e.g., X64 on an X64/x86-64/AMD64 system). GNU-EFI is
*MUCH* easier to install, particularly if you're using an unsupported
version of TianoCore -- the TianoCore developers keep making changes that
break its ability to compile; and even the procedures I document here can
break on distributions other than what I use -- Ubuntu 20.04, currently. (I
suspect the TianoCore developers are trying to support too many build
platforms.). In the past, TianoCore-based rEFInd binaries supported some
features didn't work when building with GNU-EFI; but these GNU-EFI
limitations have long been in the past. Because GNU-EFI is a standard part
of most Linux distributions but TianoCore's EDK2 is not, binaries built for
most distributions and in archives like my own Ubuntu PPA for rEFInd are
built with GNU-EFI. TianoCore still has some advantages, though. One of
these is that cross-compiling with it is easier (if you can get the
TianoCore package to build). For this reason, I use it to build my binary
.zip files, since I can build the X64, IA32, and AARCH64 binaries on one
computer. Also, I've had problems on a 32-bit Mac Mini with the drivers
produced by GNU-EFI hanging the system. (I haven't encountered this problem
on UEFI-based PCs.) The TianoCore EDK2 is also usable on a wide variety of
OSes, including macOS and Windows, so you might be able to get rEFInd to
compile on these OSes using TianoCore, although I do not provide support for
such attempts. (The upcoming section, "Compiling rEFInd Under MacOS," does
provide some pointers, though.)
Preparing Your Development Kit
==============================
If you're using Linux, GNU-EFI is the easiest way to compile rEFInd. I
don't describe GNU-EFI's setup here because it's likely to be fairly easy.
If your distribution provides a recent enough version, you should be able
to install a package called gnu-efi and be done with it. If not, you'll
need to download the source code tarball, build it, and install it. This
process is fairly typical of Linux packages. Read the GNU-EFI documentation
if you need help. If you're using GNU-EFI, you can skip the rest of this
section.
You might want to use the TianoCore toolkit if you have problems with
GNU-EFI or if you want to build rEFInd on a non-Linux platform.
Unfortunately, the TianoCore toolkit is weird by Linux programming
standards. It's also quite large -- it's intended as a means to develop a
complete EFI firmware implementation, so it contains much more code than is
needed to develop standalone EFI applications. I don't know of any Linux
distribution packages for it in RPM, Debian package file, or other formats;
you MUST install the kit from source code using its own unusual compilation
procedure. The installation documentation also omits at least one step and
is a bit unclear about others. Here's how to install the toolkit (note that
you'll need to be root to do this in the specified location):
1. Download UDK2018 from
https://github.com/tianocore/tianocore.github.io/wiki/UDK2018. (If you
must use it for some reason, you can download the older
UDK2014.SR1.UP1.P1 from
https://github.com/tianocore/tianocore.github.io/wiki/UDK2014-Releases
instead.) If you want to live on the "bleeding edge," you can use an EDK2
daily release version from https://github.com/tianocore/edk2. This
document describes three distinct compilation methods for TianoCore, each
of which has compatibility problems with some architectures.
Specifically, the "make tiano" target fails with EDK2 and UDK2018 for all
architectures; and the "make edk2" and "build" procedures work with EDK2
and UDK2018 for all architectures but require modifications of project
files to work with AARCH64.
2. Preparation procedures deviate depending on which development kit you're
using. For UDK2018 or an EDK2 daily build, follow these steps:
A. Type "cd /usr/local/".
B. Unzip the downloaded file (edk2-vUDK2018.zip) in the current directory
(/usr/local), or use git to pull down the latest source code. This
creates a subdirectory tree called edk2-vUDK2018.
C. Type "cd edk2-vUDK2018" to change into the extracted directory.
3. If you're using the older UDK2014, follow these steps:
A. Type "mkdir /usr/local/UDK2014". You can use another directory, but
the rEFInd Makefile assumes this location. You'll need to edit the
TIANOBASE variable in the top-level Makefile if you install somewhere
else.
B. Type "cd /usr/local/UDK2014".
C. Unzip the downloaded file
(UDK2014.SR1.UP1.P1.Complete.MyWorkSpace.zip) in the current directory
(/usr/local/UDK2014). This creates a handful of files, including a
tarball and a couple of .zip files.
D. Type "unzip UDK2014.SR1.UP1.MyWorkSpace.zip". This extracts the
platform-neutral portion of the development kit.
E. Type "cd MyWorkSpace".
F. Type "tar xvf ../BaseTools\(Unix\).tar". This extracts the
Linux/Unix-specific portions of the toolkit.
4. With any TianoCore version, type "source edksetup.sh BaseTools". This
sets up some environment variables, so subsequent steps (NOT including
compiling rEFInd or its drivers) must be typed in the shell you use for
this step.
5. Edit Conf/target.txt and change the following:
- ACTIVE_PLATFORM = MdePkg/MdePkg.dsc
- TARGET = RELEASE (DEBUG might work, but I've not tested it).
- TARGET_ARCH = X64 (on x86-64; leave this as IA32 on x86 or change it
to AARCH64 on ARM64). If you plan to build multiple architectures,
you can set this to "IA32 X64" or some other combination.
- TOOL_CHAIN_TAG = GCC5 (or other value depending on your GCC version;
type "gcc -v" to learn your GCC version number). Note that support
for the latest GCC version takes a while to make it into the
TianoCore toolkit, so if you're using a very recent GCC, you may need
to specify an earlier version and hope for the best or modify
Conf/tools_def.txt, as described shortly.
- MAX_CONCURRENT_THREAD_NUMBER = {#CPUs + 1}; set this to one more
than the number of CPUs in your computer to optimize build time
when using the "edk2" targets with UDK2018 or an EDK2 daily build.
This setting has no effect when using the "tiano" targets with
UDK2014.
The TianoCore Makefiles read some of these variables from this file
and use them when accessing directories, so be sure to type these
entries in the case specified.
6. The documentation refers to editing Conf/tools_def.txt in addition to
Conf/target.txt, but doesn't specify what to change in
Conf/tools_def.txt. Some of the changes I've needed to make in various
build environments include:
* When using GCC 4.7 on a Fedora 17 system with the original UDK2014,
GCC 4.7 was newer than the most recent GCC that TianoCore supported at
that time. With that setup, I found it necessary to change the
following line:
*_GCC46_X64_ASM_FLAGS = DEF(GCC46_ASM_FLAGS) -m64 -melf_x86_64
to:
*_GCC46_X64_ASM_FLAGS = DEF(GCC46_ASM_FLAGS) -m64
Although GCC 4.7 and Fedora 17 are both ancient, something similar may
be necessary if you're using a very recent GCC or some other compiler.
* When cross-compiling for ARM64 (AARCH64) on an x86-64 system,
I needed to edit various entries to point to the cross-compiler
rather than the usual compilers. For instance:
*_GCC49_AARCH64_CC_PATH = ENV(GCC49_AARCH64_PREFIX)gcc
to:
*_GCC49_AARCH64_CC_PATH = /usr/bin/aarch64-linux-gnu-gcc
Similar changes for other variables in the same block are necessary.
* When compiling for x86 (IA32) on an x86-64 system running Ubuntu
20.04, I needed to add "-fno-pie -fno-pic" to the GCC5_IA32_CC_FLAGS
definition. (At this time, TianoCore's UDK2018 and November 2020
snapshots' GCC definitions maxed out at GCC5, but Ubuntu 20.04 shipped
with GCC 9.3.)
* When compiling for ARM64 (AARCH64) on an x86-64 system running
Ubuntu 20.04, I needed to add "-fno-unwind-tables" to the
GCC5_AARCH64_CC_FLAGS definition.
7. You may need to remove "-Werror" from two locations in
BaseTools/Source/C/Makefiles/header.makefile. I found this to be
necessary under Ubuntu 20.04 (using GCC 9.3), but not under Ubuntu 18.04
(using GCC 7.5).
8. Type "make -C BaseTools/Source/C". (This step is not documented on the
EDK Web page.) Note that this requires the g++ compiler and UUID
development libraries.
9. Type "build" to build the main set of EDK2 files. This process is
likely to take a few minutes. This step requires Python 2; if you have
Python 3 installed, you may need to adjust the default python for this
build (for instance, by typing "eselect python set python2.7" in
Gentoo).
If you installed in a location other than the one I've specified, you must
edit the EDK2BASE (for "make edk2" builds) or TIANOBASE (for the deprecated
"make tiano" builds) variable in the top-level Makefile in the rEFInd source
package. Once the toolkit is installed, you can build the filesystem drivers
or rEFInd, as described below.
Preparing SBAT Support
======================
Starting with rEFInd 0.14.0, by default the build system adds an .sbat
section to the compiled binaries so as to support SBAT-enabled Shims.
Without the .sbat section, modern Shims won't launch an EFI binary, even if
it's otherwise properly signed. Including the .sbat section requires the
presence of a .csv file, as documented here:
https://github.com/rhboot/shim/blob/main/SBAT.md
The rEFInd source code includes two .csv files: refind-sbat.csv (which is
used by default) and refind-sbat-local.csv (which is intended for use if you
compile locally). If you make changes to the source code, PLEASE create and
use a suitable altered .csv file, as described in the link above. To select
which .csv file to use, set the REFIND_SBAT_CSV variable in Make.common or
override it on the command line, as in:
make REFIND_SBAT_CSV=foo.csv all
If you don't care about SBAT support and compiling rEFInd fails when adding
the SBAT section, you can set the OMIT_SBAT variable to 1, as in:
make OMIT_SBAT=1
See the upcoming sections for more information on options used to build
different programs or in different ways.
If you build rEFInd in the TianoCore way, as described later, in "Compiling
rEFInd the TianoCore Way," the SBAT section will not be added. It also will
not be added if you use the "make tiano" targets, which are deprecated. The
SBAT section will be added if you use the "make edk2" or "make gnuefi"
targets, though. The various make targets are described in more detail
shortly, in "Compiling rEFInd the Unix/Linux Way."
Compiling rEFInd the Unix/Linux Way
===================================
With your development system set up, you can compile rEFInd as follows:
1. Download and uncompress the rEFInd source code archive. (If you're
reading this file, you've probably already done this task.)
2. Open a Linux shell prompt
3. Change into the archive's main directory. You should see several files
including this BUILDING.txt file and several subdirectories such as
"refind", "libeg", "mok", "filesystems", and "include".
4. If you want to build with the TianoCore toolkit and you installed in a
location other than the one specified in "Preparing Your Development
Kit," you must edit Makefile in the main rEFInd directory: change the
EDK2BASE and/or TIANOBASE variables to point to your toolkit's location.
The EDK2BASE variable is used with the "edk2" target, which is useful
with all versions of TianoCore, with some caveats (described later), and
TIANOBASE is used with the "tiano" target (which can be used with
UDK2014, but not later versions).
5. Type "make" to build rEFInd and gptsync, or "make fs" to build the
filesystem drivers. The Makefile checks for the TianoCore toolkit and
tries to use it if it's present. Additional "make" targets enable you to
fine-tune how rEFInd is built and what components are built, as described
shortly. With any luck, rEFInd will compile without error, leaving the
"refind_ia32.efi", "refind_x64.efi", or "refind_aa64.efi" file, depending
on your platform, in the "refind" subdirectory. This same step builds the
"gptsync_ia32.efi", "gptsync_x64.efi", or "gptsync_aa64.efi" program
file, in the "gptsync" subdirectory. If you want to build IA32 binaries
on an x86-64 (X64) system and if you're using TianoCore, type "ARCH=ia32
make". Similarly, you can specify "ARCH=aarch64" to cross-compile for
ARM64, but this works only if you're using the TianoCore build kit, and
only if you set up TianoCore for cross-compiling. If you plan to build
multiple architectures, be sure to copy the .efi file for the first build
out of the refind subdirectory and type "make clean" before building the
second architecture.
The top-level rEFInd Makefile supports three toolchains, each of which
provides several options to compile a subset of rEFInd's programs. (Note
that I specify AMD64/x86-64/X64 filenames in the below for simplicity.) The
"make" targets are:
* gnuefi -- This target builds refind_x64.efi and gptsync_x64.efi with
the GNU-EFI toolkit.
* gptsync_gnuefi -- This target builds just the gptsync.efi program
with the GNU-EFI toolkit.
* fs_gnuefi -- This target builds all the filesystem drivers with the
GNU-EFI toolkit.
* all_gnuefi -- This target builds everything (refind_x64.efi,
gptsync_x64.efi, and the filesystem drivers) with the GNU-EFI toolkit.
* tiano -- This deprecated, and increasingly unreliable, target builds
refind_x64.efi and gptsync_x64.efi with the TianoCore toolkit by using
custom Makefile rules, bypassing the TianoCore toolkit's "build" command.
The result is slightly faster compilation in a more traditional Unix/Linux
way; but the compilation rules are fragile and work only with the UDK2014
toolkit. They worked with Ubuntu 18.04 and GCC 7.5, but now fail with
Ubuntu 20.04 and GCC 9.3. Also, the gptsync_x64.efi program is not built
on ARM64/AARCH64 because the build process fails. (As hybrid MBRs are
likely to be useless on this platform, the inability to build
gptsync_aa64.efi is no great loss.)
* gptsync_tiano -- This target works like the preceding one, but builds
only gptsync_x64.efi.
* fs_tiano -- This target works like the preceding two, but builds the
filesystem drivers.
* all_tiano -- This target builds refind_x64.efi, gptsync_x64.efi, and
the filesystem drivers using custom Makefile rules.
* edk2 -- Like the "tiano" target, this one builds with the TianoCore
toolkit; but it employs a build method more like that favored by
TianoCore. It relies on .dsc, .dec, and .inf files as well as the "build"
program that comes with TianoCore. This method works with UDK2014 and
UDK2018. It might work with more recent EDK2 snapshots, but as noted
earlier, my attempt to use a November 2020 snapshot failed because I
couldn't get it to compile. This method also works under macOS, if
TianoCore is properly prepared. One limitation is that building with
UDK2014 for ARM64/AARCH64 requires modifying the .inf files to remove the
reference to CompilerIntrinsicsLib. This build method is also a little bit
slower than the preceding ones, in part because EVERYTHING is built;
narrower targets simply copy fewer of the resulting files from within the
TianoCore directory tree. Note that this method, unlike the preceding
ones, requires WRITE access to the TianoCore build tree, or at least to
the Build and Conf subdirectories of that tree, as well as to the root of
the tree. (This method creates a symbolic link of the main rEFInd
directory into the root of the TianoCore tree, and the build process
creates a subdirectory called Build/Refind to hold temporary files and the
final .efi files. The "make" utility then copies these files to the same
locations used by the tiano and gnuefi targets.)
* gptsync_edk2 -- This target copies just the gptsync_x64.efi binary to its
final destination.
* fs_edk2 -- This target works like the "edk2" target, but copies only
the filesystem drivers to their destination.
* all_edk2 -- This target builds and copies everything using the
TianoCore-style build process.
* all -- This is the default target. It runs the "edk2" target if
the EDK2BASE variable points to a valid TianoCore toolkit. If not, it runs
the "tiano" target if the TIANOBASE variable points to a valid TianoCore
toolkit. If neither of these variables points to a valid TianoCore
toolkit, the "gnuefi" target is tried.
* gptsync -- This target builds the gptsync_x64.efi program using the
same precedence for toolkits as the "all" target.
* fs -- This target builds the filesystem drivers using the same precedence
for toolkits as the "all" target.
* clean -- This target deletes intermediate build files. Note that it
deletes intermediate files generated by ALL the build methods (gnuefi,
tiano, and edk2).
* install -- This target runs the refind-install script with no
arguments.
If rEFInd doesn't compile correctly, you'll need to track down the source
of the problem. Double-check that you've got all the necessary development
tools installed, including GCC, make, and either GNU-EFI or TianoCore EDK2.
You may also need to adjust the Makefile or Make.common file; or possibly
Make* files in code subdirectories. (The main Makefile controls the process
for both toolkits, while Make.common holds most common options.) The most
likely thing you'll need to change is the path to the various GNU-EFI
include files and libraries. Since rEFInd 0.6.2, the default Make.common
file includes the following GNU-EFI definitions:
EFIINC = /usr/include/efi
GNUEFILIB = /usr/lib
EFILIB = /usr/lib
EFICRT0 = /usr/lib
If you've installed GNU-EFI from source code, you may need to add "local" to
those paths, as in "/usr/local/include/efi". You might need to change
references to "lib" to "lib32" or "lib64" on some systems. Recall that you
need at least GNU-EFI version 3.0u to build rEFInd, and some older or
behind-the-times distributions might provide out-of-date versions of this
package.
If you're building for ARM64 using GNU-EFI, be aware that required
compilation options changed starting with GNU-EFI 3.0.17. As of rEFInd
0.14.2, rEFInd's own make options are set up for the older versions of
GNU-EFI. If you're using GNU-EFI 3.0.17 or later, you can EITHER:
* Edit Make.common: Change the line that reads "GNUEFI_ARM64_TARGET_SUPPORT
?= n" so that it reads "GNUEFI_ARM64_TARGET_SUPPORT ?= y" (change "n" to
"y"); or....
* Set the GNUEFI_ARM64_TARGET_SUPPORT variable to "y" on your "make" command
line, as in typing "GNUEFI_ARM64_TARGET_SUPPORT=y make" rather than simply
"make".
Note that the GNUEFI_ARM64_TARGET_SUPPORT variable has no effect when
building X64/AMD64/x86-64 or IA32/x86 targets. It also has no effect when
building with the TianoCore EDK2. Setting this variable is required ONLY
when building ARM64 binaries using GNU-EFI 3.0.17 or later.
If you're using TianoCore's EDK2, as noted earlier, you may need to adjust
the TIANOBASE or EDKBASE variable in Makefile.
A Note about NTFS
=================
Over the years, I've received far too many queries from people who've had
problems with rEFInd freezing because of the NTFS driver. Thus, beginning
with rEFInd 0.11.5, the NTFS driver is NOT compiled by default. (If using
Tianocore EDK2, the file is actually compiled, but it's not copied to the
output directory.) If you need it, you can still compile it manually by
changing into the filesystems directory and typing "make ntfs_gnuefi" if
you're using GNU-EFI; or by copying the file from
Build/Refind/RELEASE_GCC5/X64/ntfs.efi (or the equivalent for other
architectures) in the Tianocore EDK2 installation location if you're using
Tianocore EDK2. Alternatively, you can look at the NTFS driver in Pete
Batard's efifs project (http://efi.akeo.ie). I can't promise this driver
will be more reliable than rEFInd's, but it might be.
Compiling rEFInd the TianoCore Way
==================================
If you use TianoCore, you may know that the standard way to build
applications under that environment does not follow the typical Unix/Linux
development model described above. Instead, the application to be compiled
is dropped into the main TianoCore source tree and compiled there using the
"build" command. rEFInd can be compiled in this way. I am providing
instructions on compiling in this way because it may work better than
rEFInd's Makefiles in some cases, especially if you're using a non-Linux
platform for development. I've successfully compiled rEFInd 0.10.8 under
macOS in this way. (I present details and caveats shortly.) Note that the
"edk2" and related Makefile targets use this method behind the scenes. The
procedure is:
1. Download and prepare the TianoCore toolkit, as described earlier,
under "Preparing Your Development Kit." Note that you will have to adjust
this procedure if you're using a non-Linux OS.
2. Change to the directory that holds the BaseTools, MdePkg, ShellPkg, and
other directories and files. If you use the UDK2014.SR1.UP1.P1 package
noted earlier, this would be the MyWorkSpace directory.
3. Unpack the rEFInd source tarball in the current directory.
4. Rename the rEFInd directory (refind-{version}, where {version} is the
version number) to RefindPkg. Alternatively, create a symbolic link
called RefindPkg that points to the real directory.
5. Type "source edksetup.sh BaseTools". (You can skip this step if you're
using the same login session you used to build the TianoCore toolkit; you
need to type this command only if you've logged out and back in again,
are using a different window from the one you used to build TianoCore, or
have otherwise modified the environment variables set in edksetup.sh.)
6. If you're using UDK2014 AND you're compiling for AARCH64, you must
open refind.inf, gptsync.inf, and the .inf files for all the drivers in
the filesystems subdirectory and comment out the line that reads
"CompilerIntrinsicsLib". This library is needed for later versions of
EDK2 but is not present in (and not required for) UDK2014.
7. Type "build -p RefindPkg/RefindPkg.dsc" to build rEFInd. If you've
properly configured your TianoCore installation for cross-compiling, you
may add "-a {ARCH}", where {ARCH} is an architecture code, to compile for
that platform. For instance, "build -a IA32 -p RefindPkg/RefindPkg.dsc"
builds for IA32 (32-bit x86), even on another type of computer.
The rEFInd package should build, leaving binaries buried ridiculously deep
within the directory tree. For instance, on my test build, the rEFInd
binaries were at:
Build/Refind/RELEASE_GCC49/X64/btrfs.efi
Build/Refind/RELEASE_GCC49/X64/ext2.efi
Build/Refind/RELEASE_GCC49/X64/ext4.efi
Build/Refind/RELEASE_GCC49/X64/gptsync.efi
Build/Refind/RELEASE_GCC49/X64/hfs.efi
Build/Refind/RELEASE_GCC49/X64/iso9660.efi
Build/Refind/RELEASE_GCC49/X64/ntfs.efi
Build/Refind/RELEASE_GCC49/X64/refind.efi
Build/Refind/RELEASE_GCC49/X64/reiserfs.efi
I've tested this procedure under Ubuntu 16.04 with GCC 5.4.0 and under macOS
10.11 with both Clang 7.0.0/XCode 7.1.1 and Clang 8.0.0/XCode 8.1.1. (See
below for Mac caveats.) In theory, it might work under Windows, but if you
use anything but a GCC- or Clang-derived compiler, there's a good chance
you'll run into a compiler-specific code incompatibility.
Compiling rEFInd Under MacOS
============================
Building under macOS is *NOT SUPPORTED.* I've tested this procedure and it
seems to work in minimal testing. My build under macOS required several
changes for compilation to succeed:
* A relatively recent TianoCore EDK2 from the TianoCore git repository is
required; the stable UDK2014 and UDK2015 DO NOT work. I have yet to test
with the final release of UDK2017 or UDK2018, but I expect they might
work.
* Setting up the Mac development environment required following instructions
at https://github.com/tianocore/tianocore.github.io/wiki/Xcode, with the
caveat that the UnixPkg directory described there is essentially empty;
instead, I compiled the BaseTools/Source/C code, as described earlier. (I
don't know if this was strictly necessary, but the tools did compile,
despite several warnings.) I also skipped installing QEMU.
* Instead of "TOOL_CHAIN_TAG = GCC49", I set "TOOL_CHAIN_TAG = XCODE5" in
Conf/target.txt.
* I had to edit Conf/tools_def.txt and edit the RELEASE_XCODE5_X64_CC_FLAGS
line to remove the "-Werror" option. With this option set, the main rEFInd
binary and several drivers failed to build. **CAUTION:** The warnings that
prevented the rEFInd binary from compiling with "-Werror" intact related
to ((sysv_abi)) declarations in mok/mok.h. This makes me think that the
resulting binary may be incompatible with Shim, although I've not tested
this; my only testing of the binary built under macOS were on systems with
Secure Boot disabled or with the Secure Boot system under my complete
control and without Shim installed.
* I had to edit refind.inf and uncomment the line in the Packages section
that reads "StdLib/StdLib.dec".
* I've been unable to get the Btrfs driver to build. To adjust the package
to omit this driver, edit the RefindPkg.dsc file and remove the line near
the bottom that reads "RefindPkg/filesystems/btrfs.inf". (This limitation
may be resolved with rEFInd 0.12.1, but I haven't tested it.)
Note that if you want to use macOS or Windows to compile rEFInd, you might
be able to create a project or Makefile for your non-GCC compiler or use a
GCC port, such as MinGW (http://www.mingw.org), along with the procedure
described earlier, under "Compiling rEFInd the Unix/Linux Way." You'd
probably need to adjust the Makefiles in the latter case.
Installing rEFInd
=================
With rEFInd compiled, you can install it. The easiest way to do this is
with the refind-install script, which works on both Linux and macOS.
Alternatively, you can type "make install" to install using this script.
Note that this script copies files to the ESP and uses "efibootmgr" (on
Linux) or "bless" (on macOS) to add rEFInd to the firmware's boot loader
list. The docs/man/refind-install.8 file (and its HTML conversion,
docs/refind/refind-install.html) provides more details on this script and
its use.
If refind-install doesn't work for you or if you prefer to do the job
manually, you may. On a UEFI-based system, you'll want to copy files on the
ESP as follows:
* Create a directory for rEFInd, such as EFI/refind.
* Copy refind/refind_ia32.efi or refind_x64.efi to the ESP's EFI/refind
directory.
* Copy refind.conf-sample to the EFI/refind directory as refind.conf.
* Copy the icons subdirectory, including all its files, to EFI/refind.
You'll then need to activate rEFInd in your EFI. This can be done with
tools such as "efibootmgr" under Linux or "bless" under macOS. See the
docs/refind/installing.html file for details.
Note to Distribution Maintainers
================================
The refind-install script, and therefore the "install" target in the
Makefile, installs the program directly to the ESP and it modifies the
*CURRENT COMPUTER's* NVRAM. Thus, you should *NOT* use this target as part
of the build process for your binary packages (RPMs, Debian packages, etc.).
(Gentoo could use it in an ebuild, though....) You COULD, however, install
the files to a directory somewhere (/usr/share/refind or whatever) and then
call refind-install as part of the binary package installation process.
Placing the files directly in /boot/efi/EFI/{distname}/refind and then
having a post-install script call efibootmgr could also work, but this
assumes that the ESP is mounted at /boot/efi. Also, Debian packages try to
create symbolic links when updating packages, which won't work on an ESP,
which should use FAT. For packaging examples, see the refind.spec file and
debian subdirectory of the rEFInd source tarball.
Distribution packagers should create their own SBAT .csv filess, as
described earlier, in "Preparing SBAT Support" and adjust the
REFIND_SBAT_CSV variable in Make.common or override it on the make command
line, as in:
make REFIND_SBAT_CSV=foo.csv all
Adding Support for Network Boot
===============================
rEFInd provides EXPERIMENTAL support for booting over the network using
iPXE (http://ipxe.org) as a means to receive the payload. In order to
enable this feature you'll want to follow these instructions:
* cd net/
* make source
* make netboot
* copy bin/ipxe.efi and bin/ipxe_discover.efi to the EFI volume at EFI/tools/
Note that you may need to install additional development packages, such as
libiberty-dev and binutils-dev, in addition to those needed to build rEFInd
itself.
My own tests show this support to work under optimal conditions; however,
architecture (EFI vs. BIOS) detection may not work, and some computers will
hang or won't retrieve boot files from the network. For these reasons, this
support is disabled by default in rEFInd, and I do not provide iPXE
binaries.