UDK2017 (UEFI Development Kit, 2017 release), released in June 2017, contains reasonably detailed instructions on how to build the UDK2017 release on a “Linux-like System” which in practical terms is actually Ubuntu 16.04 LTS Desktop and GCC 5. In this post, I show you how to install and build UDK2017 on Fedora 26 Desktop using GCC 7.
UDK2017 is simply a validated snapshot of the EDK 11 (EFI Development Kit, version 2) source code at a particular point in time. The previous validated snapshot of EDK 11 was UDK2015 which was released in September 2015. Why EDK2? It is because there was a major redesign and rewrite of the original version of the EDK and there was a need to differentiate between the two versions.
Henceforth, in this post I will use the term EDK2 instead of EDK 11.
This post assumes that you have a modicum of understanding about EDK2, Fedora, and the GCC toolchain. I also assume that gcc, git, and make are already installed. If not, you will need to install the appropriate RPMs. You also need the GNU C++ compiler installed because one of the build tools, i.e. vfrcompiler, requires building with a C++ compiler. Among other things, the vrfcompiler tool converts VFRs (Virtual Forms Representation) into IFRs (Internal Forms Representation) which form part of a UEFI HII (Human Interface Infrastructure) database.
First, you need to obtain the UDK2017 sources. You can use git to get a copy of the UDK2017 sources as shown here:
$ cd ~ $ git clone https://github.com/tianocore/edk2.git vUDK2017 $ mv vUDK2017 UDK2017
or, if you prefer, you can download a zipfile or a tarball of the source files from here.
In the rest of this post, I assume that UDK2017 is installed at ~/UDK2017. In my case, that is /home/fpm/UDK2017. For some unknown reason, the current online instructions for building UDK2017 on a “Linux-like System” specify the root as ~/src/MyWorkspace.
Next install all the necessary RPMs to build the UDK2017 build tools.
# dnf install gcc-c++ iasl nasm libuuid-devel
Now, you should be able to make all the necessary build tools which are needed to build applications in UDK2017.
$ cd ~/UDK2017/BaseTools $ make
For detailed information on all the EDK2 tools (and there are lots of them), refer to the EDK BaseTools User Guides. By the way, all EDK2 tools use INI style text based files to describe components, platforms and firmware volumes.
Assuming that the build tools have all been built successfully, the next step is to test and validate the build environment. Initialize the UDK2017 build environment using the edksetup.sh shell script.
$ cd ~/UDK2017 $ . ./edksetup.sh WORKSPACE: /home/fpm/UDK2017 EDK_TOOLS_PATH: /home/fpm/UDK2017/BaseTools CONF_PATH: /home/fpm/UDK2017/Conf $
Note difference when you initiate the build environment for the second time or subsequent times:
$ cd ~/UDK2017 $ . ./edksetup.sh Loading previous configuration from /home/fpm/UDK2017/Conf/BuildEnv.sh WORKSPACE: /home/fpm/UDK2017 EDK_TOOLS_PATH: /home/fpm/UDK2017/BaseTools CONF_PATH: /home/fpm/UDK2017/Conf
On Fedora 26, the default version of the GCC C compiler is 7.2.1. UDK2017 does not support GCC C compiler v7 out of the box. It only supports versions 4.4 through 5.0. However, it will still build modules (packages) and binaries using the default settings. Later on in this post, I will show you how to add GCC 7 support.
To test that your UDK2017 build environment is correct, enter following commands to build the supplied MdeModule package:
$ cd ~/UDK2017 $ . ./edksetup.sh $ build -p MdeModulePkg/MdeModulePkg.dsc -t GCC5 Build environment: Linux-4.12.9-300.fc26.x86_64-x86_64-with-fedora-26-Twenty_Six Build start time: 03:27:43, Oct.2 2017 WORKSPACE = /home/fpm/UDK2017 ECP_SOURCE = /home/fpm/UDK2017/EdkCompatibilityPkg EDK_SOURCE = /home/fpm/UDK2017/EdkCompatibilityPkg EFI_SOURCE = /home/fpm/UDK2017/EdkCompatibilityPkg EDK_TOOLS_PATH = /home/fpm/UDK2017/BaseTools CONF_PATH = /home/fpm/UDK2017/Conf Architecture(s) = X64 Build target = DEBUG Toolchain = GCC5 Active Platform = /home/fpm/UDK2017/MdeModulePkg/MdeModulePkg.dsc Processing meta-data .......
If the build is successful, there should be a UEFI executable named “HelloWorld.efi” in the ~/UDK2017/Build/MdeModule/DEBUG_GCC5/IA32 directory.
Now that you have proved that your basic build environment is working by building a specific package, it is time to build your own UEFI application. Typically, you will want your own source code area (sandbox?) within the UDK2017 directory framework for applications you develop. Let us call this area MyApps.
Create a new directory ~/UDK2017/MyApps and cd to that directory. Create a file named MyApps.dec containing the following text:
[Defines] DEC_SPECIFICATION = 0x00010005 PACKAGE_NAME = MyApps PACKAGE_GUID = B3E3D3D5-D62B-4497-A175-264F489D127E PACKAGE_VERSION = 0.01 [Guids] [PcdsFixedAtBuild]
The DEC (Declaration) file format was designed to support building packaging and distribution of EDK2 modules, as well as for building custom applications using the EDK2 build infrastructure. See the EDK II Package Declaration (DEC) File Format Specification for full details. It can be accessed from here.
Also, in the same subdirectory, create a file named MyApps.dsc containing the following text:
[Defines] PLATFORM_NAME = MyApps PLATFORM_GUID = 0458dade-8b6e-4e45-b773-1b27cbda3e06 PLATFORM_VERSION = 0.01 DSC_SPECIFICATION = 0x00010006 OUTPUT_DIRECTORY = Build/MyApps SUPPORTED_ARCHITECTURES = X64 BUILD_TARGETS = DEBUG|RELEASE|NOOPT SKUID_IDENTIFIER = DEFAULT # # Debug output control # DEFINE DEBUG_ENABLE_OUTPUT = FALSE # Set to TRUE to enable debug output DEFINE DEBUG_PRINT_ERROR_LEVEL = 0x80000040 # Flags to control amount of debug output DEFINE DEBUG_PROPERTY_MASK = 0 [PcdsFeatureFlag] [PcdsFixedAtBuild] gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|$(DEBUG_PROPERTY_MASK) gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|$(DEBUG_PRINT_ERROR_LEVEL) [PcdsFixedAtBuild.IPF] [LibraryClasses] # Entry Point Libraries UefiApplicationEntryPoint|MdePkg/Library/UefiApplicationEntryPoint/UefiApplicationEntryPoint.inf ShellCEntryLib|ShellPkg/Library/UefiShellCEntryLib/UefiShellCEntryLib.inf UefiDriverEntryPoint|MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntryPoint.inf # Common Libraries BaseLib|MdePkg/Library/BaseLib/BaseLib.inf BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf UefiLib|MdePkg/Library/UefiLib/UefiLib.inf PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf UefiBootServicesTableLib|MdePkg/Library/UefiBootServicesTableLib/UefiBootServicesTableLib.inf UefiRuntimeServicesTableLib|MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.inf !if $(DEBUG_ENABLE_OUTPUT) DebugLib|MdePkg/Library/UefiDebugLibConOut/UefiDebugLibConOut.inf DebugPrintErrorLevelLib|MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.inf !else ## DEBUG_ENABLE_OUTPUT DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf !endif ## DEBUG_ENABLE_OUTPUT DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf IoLib|MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf PciLib|MdePkg/Library/BasePciLibCf8/BasePciLibCf8.inf PciCf8Lib|MdePkg/Library/BasePciCf8Lib/BasePciCf8Lib.inf SynchronizationLib|MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf UefiRuntimeLib|MdePkg/Library/UefiRuntimeLib/UefiRuntimeLib.inf HiiLib|MdeModulePkg/Library/UefiHiiLib/UefiHiiLib.inf UefiHiiServicesLib|MdeModulePkg/Library/UefiHiiServicesLib/UefiHiiServicesLib.inf PerformanceLib|MdeModulePkg/Library/DxePerformanceLib/DxePerformanceLib.inf HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf FileHandleLib|MdePkg/Library/UefiFileHandleLib/UefiFileHandleLib.inf SortLib|MdeModulePkg/Library/UefiSortLib/UefiSortLib.inf ShellLib|ShellPkg/Library/UefiShellLib/UefiShellLib.inf ShellCommandLib|ShellPkg/Library/UefiShellCommandLib/UefiShellCommandLib.inf HandleParsingLib|ShellPkg/Library/UefiHandleParsingLib/UefiHandleParsingLib.inf CacheMaintenanceLib|MdePkg/Library/BaseCacheMaintenanceLib/BaseCacheMaintenanceLib.inf [Components] #### Applications #### MyApps/HelloWorld/HelloWorld.inf
A DSC file is an EDK2 platform description file that contains a list of:
- EDK2 Module INF Files
- EDK Components
- EDK libraries (used by EDK components)
- EDK2 Library class instance mappings (used by EDK2 modules)
- EDK2 PCD Entries
See the EDK II Platform Description (DSC) File Specification for full details. It can be accessed from here. The sample contents provided above contain most of the libraries that you should ever need. The only supported architecture in the above platform description file is X64; you can add additional architectures such as IA32 or AARCH64 if you want too.
Next, let us create a simple Hello World UEFI application. In our particular build environment, all the source files associated with our Hello World application are located in one directory and form a package. Go ahead an create a subdirectory under …/UDK2017/MyApps named HelloWorld.
In the HelloWorld subdirectory, create a file named HelloWorld.inf with the following contents:
Defines] INF_VERSION = 0x00010006 BASE_NAME = HelloWorld FILE_GUID = a912f198-7f0e-4803-b908-b757b806ec83 MODULE_TYPE = UEFI_APPLICATION VERSION_STRING = 1.0 ENTRY_POINT = ShellCEntryLib VALID_ARCHITECTURES = X64 [Sources] HelloWorld.c [Packages] MdePkg/MdePkg.dec ShellPkg/ShellPkg.dec [LibraryClasses] UefiLib ShellCEntryLib
An INF file is an EDK2 module information file. INF files are used by EDK2 build tools to generate AutoGen.c and AutoGen.h and Makefile/GNU makefile files for the EDK2 build infrastructure. The intent of a module’s INF file is to define the source files, libraries, and definitions relevant to building the module, creating one or more binary files that are either raw binary files or PE32 or PE32+ or COFF format files. See the EDK II Module Information (INF) File Specification for full details. It can be accessed from here.
Next, in the HelloWorld subdirectory, create a file named HelloWorld.c containing the folloowing:
#include <uefi.h> #include <Library/UefiLib.h> #include <Library/ShellCEntryLib.h> INTN EFIAPI ShellAppMain( UINTN Argc, CHAR16 **Argv) { Print(L"Hello World!\n"); return(0); }
This is the actual source file for our HelloWorld UEFI application. Everything else we have done up to this point was related to the EDK2 build environment.
Now, we finally get to build out HelloWorld application:
$ cd ~/UDK2017 $ . ./edksetup.sh Loading previous configuration from /home/fpm/UDK2017/Conf/BuildEnv.sh WORKSPACE: /home/fpm/UDK2017 EDK_TOOLS_PATH: /home/fpm/UDK2017/BaseTools CONF_PATH: /home/fpm/UDK2017/Conf $ build -p MyApps/MyApps.dsc -t GCC5 [UDK2017]$ build -p MyApps/MyApps.dsc -t GCC5 Build environment: Linux-4.12.9-300.fc26.x86_64-x86_64-with-fedora-26-Twenty_Six Build start time: 12:03:37, Sep.27 2017 WORKSPACE = /home/fpm/UDK2017 ECP_SOURCE = /home/fpm/UDK2017/EdkCompatibilityPkg EDK_SOURCE = /home/fpm/UDK2017/EdkCompatibilityPkg EFI_SOURCE = /home/fpm/UDK2017/EdkCompatibilityPkg EDK_TOOLS_PATH = /home/fpm/UDK2017/BaseTools CONF_PATH = /home/fpm/UDK2017/Conf Architecture(s) = X64 Build target = DEBUG Toolchain = GCC5 Active Platform = /home/fpm/UDK2017/MyApps/MyApps.dsc Processing meta-data . done! Building ... /home/fpm/UDK2017/MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf [X64] Building ... /home/fpm/UDK2017/MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf [X64] Building ... /home/fpm/UDK2017/MdePkg/Library/BaseLib/BaseLib.inf [X64] Building ... /home/fpm/UDK2017/MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf [X64] "gcc" -g -fshort-wchar -fno-builtin -fno-strict-aliasing -Wall -Werror -Wno-array-bounds -ffunction-sections -fdata-sections -include AutoGen.h -fno-common -DSTRING_ARRAY_NAME=BaseMemoryLibStrings -m64 -fno-stack-protector "-DEFIAPI=__attribute__((ms_abi))" -maccumulate-outgoing-args -mno-red-zone -Wno-address -mcmodel=small -fpie -fno-asynchronous-unwind-tables -Wno-address -flto -DUSING_LTO -Os -c -o /home/fpm/UDK2017/Build/MyApps/DEBUG_GCC5/X64/MdePkg/Library/BaseMemoryLib/BaseMemoryLib/OUTPUT/./SetMem.obj -I/home/fpm/UDK2017/MdePkg/Library/BaseMemoryLib -I/home/fpm/UDK2017/Build/MyApps/DEBUG_GCC5/X64/MdePkg/Library/BaseMemoryLib/BaseMemoryLib/DEBUG -I/home/fpm/UDK2017/MdePkg -I/home/fpm/UDK2017/MdePkg/Include -I/home/fpm/UDK2017/MdePkg/Include/X64 /home/fpm/UDK2017/MdePkg/Library/BaseMemoryLib/SetMem.c Building ... /home/fpm/UDK2017/MdePkg/Library/UefiBootServicesTableLib/UefiBootServicesTableLib.inf [X64] "gcc" -g -fshort-wchar -fno-builtin -fno-strict-aliasing -Wall -Werror -Wno-array-bounds -ffunction-sections -fdata-sections -include AutoGen.h -fno-common -DSTRING_ARRAY_NAME=BasePcdLibNullStrings -m64 -fno-stack-protector "-DEFIAPI=__attribute__((ms_abi))" -maccumulate-outgoing-args -mno-red-zone -Wno-address -mcmodel=small -fpie -fno-asynchronous-unwind-tables -Wno-address -flto -DUSING_LTO -Os -c -o /home/fpm/UDK2017/Build/MyApps/DEBUG_GCC5/X64/MdePkg/Library/BasePcdLibNull/BasePcdLibNull/OUTPUT/./PcdLib.obj -I/home/fpm/UDK2017/MdePkg/Library/BasePcdLibNull -I/home/fpm/UDK2017/Build/MyApps/DEBUG_GCC5/X64/MdePkg/Library/BasePcdLibNull/BasePcdLibNull/DEBUG -I/home/fpm/UDK2017/MdePkg -I/home/fpm/UDK2017/MdePkg/Include -I/home/fpm/UDK2017/MdePkg/Include/X64 /home/fpm/UDK2017/MdePkg/Library/BasePcdLibNull/PcdLib.c ... "gcc-ar" cr /home/fpm/UDK2017/Build/MyApps/DEBUG_GCC5/X64/MyApps/HelloWorld/HelloWorld/OUTPUT/HelloWorld.lib @/home/fpm/UDK2017/Build/MyApps/DEBUG_GCC5/X64/MyApps/HelloWorld/HelloWorld/OUTPUT/object_files.lst "gcc" -o /home/fpm/UDK2017/Build/MyApps/DEBUG_GCC5/X64/MyApps/HelloWorld/HelloWorld/DEBUG/HelloWorld.dll -nostdlib -Wl,-n,-q,--gc-sections -z common-page-size=0x40 -Wl,--entry,_ModuleEntryPoint -u _ModuleEntryPoint -Wl,-Map,/home/fpm/UDK2017/Build/MyApps/DEBUG_GCC5/X64/MyApps/HelloWorld/HelloWorld/DEBUG/HelloWorld.map,--whole-archive -Wl,-melf_x86_64,--oformat=elf64-x86-64,-pie -flto -Os -Wl,--start-group,@/home/fpm/UDK2017/Build/MyApps/DEBUG_GCC5/X64/MyApps/HelloWorld/HelloWorld/OUTPUT/static_library_files.lst,--end-group -g -fshort-wchar -fno-builtin -fno-strict-aliasing -Wall -Werror -Wno-array-bounds -ffunction-sections -fdata-sections -include AutoGen.h -fno-common -DSTRING_ARRAY_NAME=HelloWorldStrings -m64 -fno-stack-protector "-DEFIAPI=__attribute__((ms_abi))" -maccumulate-outgoing-args -mno-red-zone -Wno-address -mcmodel=small -fpie -fno-asynchronous-unwind-tables -Wno-address -flto -DUSING_LTO -Os -Wl,--defsym=PECOFF_HEADER_SIZE=0x228 -Wl,--script=/home/fpm/UDK2017/BaseTools/Scripts/GccBase.lds -Wno-error "objcopy" /home/fpm/UDK2017/Build/MyApps/DEBUG_GCC5/X64/MyApps/HelloWorld/HelloWorld/DEBUG/HelloWorld.dll cp -f /home/fpm/UDK2017/Build/MyApps/DEBUG_GCC5/X64/MyApps/HelloWorld/HelloWorld/DEBUG/HelloWorld.dll /home/fpm/UDK2017/Build/MyApps/DEBUG_GCC5/X64/MyApps/HelloWorld/HelloWorld/DEBUG/HelloWorld.debug objcopy --strip-unneeded -R .eh_frame /home/fpm/UDK2017/Build/MyApps/DEBUG_GCC5/X64/MyApps/HelloWorld/HelloWorld/DEBUG/HelloWorld.dll objcopy --add-gnu-debuglink=/home/fpm/UDK2017/Build/MyApps/DEBUG_GCC5/X64/MyApps/HelloWorld/HelloWorld/DEBUG/HelloWorld.debug /home/fpm/UDK2017/Build/MyApps/DEBUG_GCC5/X64/MyApps/HelloWorld/HelloWorld/DEBUG/HelloWorld.dll cp -f /home/fpm/UDK2017/Build/MyApps/DEBUG_GCC5/X64/MyApps/HelloWorld/HelloWorld/DEBUG/HelloWorld.debug /home/fpm/UDK2017/Build/MyApps/DEBUG_GCC5/X64/HelloWorld.debug "GenFw" -e UEFI_APPLICATION -o /home/fpm/UDK2017/Build/MyApps/DEBUG_GCC5/X64/MyApps/HelloWorld/HelloWorld/DEBUG/HelloWorld.efi /home/fpm/UDK2017/Build/MyApps/DEBUG_GCC5/X64/MyApps/HelloWorld/HelloWorld/DEBUG/HelloWorld.dll cp -f /home/fpm/UDK2017/Build/MyApps/DEBUG_GCC5/X64/MyApps/HelloWorld/HelloWorld/DEBUG/HelloWorld.efi /home/fpm/UDK2017/Build/MyApps/DEBUG_GCC5/X64/MyApps/HelloWorld/HelloWorld/OUTPUT cp -f /home/fpm/UDK2017/Build/MyApps/DEBUG_GCC5/X64/MyApps/HelloWorld/HelloWorld/DEBUG/HelloWorld.efi /home/fpm/UDK2017/Build/MyApps/DEBUG_GCC5/X64/HelloWorld.efi cp -f /home/fpm/UDK2017/Build/MyApps/DEBUG_GCC5/X64/MyApps/HelloWorld/HelloWorld/DEBUG/*.map /home/fpm/UDK2017/Build/MyApps/DEBUG_GCC5/X64/MyApps/HelloWorld/HelloWorld/OUTPUT - Done - Build end time: 12:03:45, Sep.27 2017 Build total time: 00:00:08 $
Note how a HelloWorld.dll was first built, and genfw was then used to convert that DLL into HelloWorld.efi which is actually a simple MSDOS executable.
Examining the list of files generated by our build revels more interesting information:
$ cd ~/UDK2017/Build/MyApps/DEBUG_GCC5/X64/MyApps/HelloWorld/HelloWorld/OUTPUT $ ls -al total 172 drwxrwxr-x. 2 fpm fpm 4096 Sep 27 12:03 . drwxrwxr-x. 4 fpm fpm 4096 Sep 27 12:03 .. -rw-rw-r--. 1 fpm fpm 44032 Sep 27 12:03 AutoGen.obj -rw-rw-r--. 1 fpm fpm 5888 Sep 27 12:03 HelloWorld.efi -rw-rw-r--. 1 fpm fpm 5098 Sep 27 12:03 HelloWorld.inf -rw-rw-r--. 1 fpm fpm 50640 Sep 27 12:03 HelloWorld.lib -rw-rw-r--. 1 fpm fpm 34503 Sep 27 12:03 HelloWorld.map -rw-rw-r--. 1 fpm fpm 4704 Sep 27 12:03 HelloWorld.obj -rw-rw-r--. 1 fpm fpm 190 Sep 27 12:03 object_files.lst -rw-rw-r--. 1 fpm fpm 1607 Sep 27 12:03 static_library_files.lst $ file HelloWorld.efi HelloWorld.efi: MS-DOS executable $ objdump -x HelloWorld.efi HelloWorld.efi: file format pei-x86-64 HelloWorld.efi architecture: i386:x86-64, flags 0x0000010b: HAS_RELOC, EXEC_P, HAS_DEBUG, D_PAGED start address 0x0000000000001070 Characteristics 0x2e executable line numbers stripped symbols stripped large address aware Time/Date Wed Dec 31 19:00:00 1969 Magic 020b (PE32+) MajorLinkerVersion 0 MinorLinkerVersion 0 SizeOfCode 00001200 SizeOfInitializedData 00000240 SizeOfUninitializedData 00000000 AddressOfEntryPoint 0000000000001070 BaseOfCode 0000000000000240 ImageBase 0000000000000000 SectionAlignment 0000000000000040 FileAlignment 0000000000000040 MajorOSystemVersion 0 MinorOSystemVersion 0 MajorImageVersion 0 MinorImageVersion 0 MajorSubsystemVersion 0 MinorSubsystemVersion 0 Win32Version 00000000 SizeOfImage 00001700 SizeOfHeaders 00000240 CheckSum 00000000 Subsystem 0000000a (EFI application) DllCharacteristics 00000000 SizeOfStackReserve 0000000000000000 SizeOfStackCommit 0000000000000000 SizeOfHeapReserve 0000000000000000 SizeOfHeapCommit 0000000000000000 LoaderFlags 00000000 NumberOfRvaAndSizes 00000010 The Data Directory Entry 0 0000000000000000 00000000 Export Directory [.edata (or where ever we found it)] Entry 1 0000000000000000 00000000 Import Directory [parts of .idata] Entry 2 0000000000000000 00000000 Resource Directory [.rsrc] Entry 3 0000000000000000 00000000 Exception Directory [.pdata] Entry 4 0000000000000000 00000000 Security Directory Entry 5 0000000000001680 00000080 Base Relocation Directory [.reloc] Entry 6 00000000000015b8 0000001c Debug Directory Entry 7 0000000000000000 00000000 Description Directory Entry 8 0000000000000000 00000000 Special Directory Entry 9 0000000000000000 00000000 Thread Storage Directory [.tls] Entry a 0000000000000000 00000000 Load Configuration Directory Entry b 0000000000000000 00000000 Bound Import Directory Entry c 0000000000000000 00000000 Import Address Table Directory Entry d 0000000000000000 00000000 Delay Import Directory Entry e 0000000000000000 00000000 CLR Runtime Header Entry f 0000000000000000 00000000 Reserved PE File Base Relocations (interpreted .reloc section contents) Virtual Address: 00001000 Chunk size 128 (0x80) Number of fixups 60 reloc 0 offset 460 [1460] DIR64 reloc 1 offset 468 [1468] DIR64 reloc 2 offset 470 [1470] DIR64 reloc 3 offset 478 [1478] DIR64 reloc 4 offset 480 [1480] DIR64 reloc 5 offset 488 [1488] DIR64 reloc 6 offset 490 [1490] DIR64 reloc 7 offset 498 [1498] DIR64 reloc 8 offset 4a0 [14a0] DIR64 reloc 9 offset 4a8 [14a8] DIR64 reloc 10 offset 4b0 [14b0] DIR64 reloc 11 offset 4b8 [14b8] DIR64 reloc 12 offset 4c0 [14c0] DIR64 reloc 13 offset 4c8 [14c8] DIR64 reloc 14 offset 4d0 [14d0] DIR64 reloc 15 offset 4d8 [14d8] DIR64 reloc 16 offset 4e0 [14e0] DIR64 reloc 17 offset 4e8 [14e8] DIR64 reloc 18 offset 4f0 [14f0] DIR64 reloc 19 offset 4f8 [14f8] DIR64 reloc 20 offset 500 [1500] DIR64 reloc 21 offset 508 [1508] DIR64 reloc 22 offset 510 [1510] DIR64 reloc 23 offset 518 [1518] DIR64 reloc 24 offset 520 [1520] DIR64 reloc 25 offset 528 [1528] DIR64 reloc 26 offset 530 [1530] DIR64 reloc 27 offset 538 [1538] DIR64 reloc 28 offset 540 [1540] DIR64 reloc 29 offset 548 [1548] DIR64 reloc 30 offset 550 [1550] DIR64 reloc 31 offset 558 [1558] DIR64 reloc 32 offset 560 [1560] DIR64 reloc 33 offset 568 [1568] DIR64 reloc 34 offset 570 [1570] DIR64 reloc 35 offset 578 [1578] DIR64 reloc 36 offset 580 [1580] DIR64 reloc 37 offset 588 [1588] DIR64 reloc 38 offset 590 [1590] DIR64 reloc 39 offset 0 [1000] ABSOLUTE reloc 40 offset 0 [1000] ABSOLUTE reloc 41 offset 0 [1000] ABSOLUTE reloc 42 offset 0 [1000] ABSOLUTE reloc 43 offset 0 [1000] ABSOLUTE reloc 44 offset 0 [1000] ABSOLUTE reloc 45 offset 0 [1000] ABSOLUTE reloc 46 offset 0 [1000] ABSOLUTE reloc 47 offset 0 [1000] ABSOLUTE reloc 48 offset 0 [1000] ABSOLUTE reloc 49 offset 0 [1000] ABSOLUTE reloc 50 offset 0 [1000] ABSOLUTE reloc 51 offset 0 [1000] ABSOLUTE reloc 52 offset 0 [1000] ABSOLUTE reloc 53 offset 0 [1000] ABSOLUTE reloc 54 offset 0 [1000] ABSOLUTE reloc 55 offset 0 [1000] ABSOLUTE reloc 56 offset 0 [1000] ABSOLUTE reloc 57 offset 0 [1000] ABSOLUTE reloc 58 offset 0 [1000] ABSOLUTE reloc 59 offset 0 [1000] ABSOLUTE There is a debug directory in .data at 0x15b8 Type Size Rva Offset 2 CodeView 00000070 000015d4 000015d4 (format NB10 signature 00000000 age 0) Sections: Idx Name Size VMA LMA File off Algn 0 .text 00001200 0000000000000240 0000000000000240 00000240 2**4 CONTENTS, ALLOC, LOAD, READONLY, CODE 1 .data 00000240 0000000000001440 0000000000001440 00001440 2**4 CONTENTS, ALLOC, LOAD, DATA 2 .reloc 00000080 0000000000001680 0000000000001680 00001680 2**2 CONTENTS, ALLOC, LOAD, READONLY, DATA SYMBOL TABLE: no symbols $
Turning now to how to add GCC version 7 support to the UDK2017 build environment. Fortunately, only one file needs to be augmented, i.e. …/UDK2017/Conf/tools_def.txt. Here are the diffs:
210a211,213 > DEFINE GCC7_IA32_PREFIX = ENV(GCC7_BIN) > DEFINE GCC7_X64_PREFIX = ENV(GCC7_BIN) > 4630a4634,4645 > > DEFINE GCC7_IA32_CC_FLAGS = DEF(GCC5_IA32_CC_FLAGS) > DEFINE GCC7_X64_CC_FLAGS = DEF(GCC5_X64_CC_FLAGS) > DEFINE GCC7_IA32_X64_DLINK_COMMON = DEF(GCC5_IA32_X64_DLINK_COMMON) > DEFINE GCC7_IA32_X64_ASLDLINK_FLAGS = DEF(GCC5_IA32_X64_ASLDLINK_FLAGS) > DEFINE GCC7_IA32_X64_DLINK_FLAGS = DEF(GCC5_IA32_X64_DLINK_FLAGS) > DEFINE GCC7_IA32_DLINK2_FLAGS = DEF(GCC5_IA32_DLINK2_FLAGS) -Wno-error > DEFINE GCC7_X64_DLINK_FLAGS = DEF(GCC5_X64_DLINK_FLAGS) > DEFINE GCC7_X64_DLINK2_FLAGS = DEF(GCC5_X64_DLINK2_FLAGS) -Wno-error > DEFINE GCC7_ASM_FLAGS = DEF(GCC5_ASM_FLAGS) > > 5563a5579,5666 > > > #################################################################################### > # > # GCC 7 - This configuration is used to compile under Linux to produce > # PE/COFF binaries using GCC 7 > # > #################################################################################### > *_GCC7_*_*_FAMILY = GCC > > *_GCC7_*_MAKE_PATH = DEF(GCC7_IA32_PREFIX)make > *_GCC7_*_*_DLL = ENV(GCC7_DLL) > *_GCC7_*_ASL_PATH = DEF(UNIX_IASL_BIN) > *_GCC7_*_DTC_PATH = DEF(DTC_BIN) > > *_GCC7_*_PP_FLAGS = DEF(GCC_PP_FLAGS) > *_GCC7_*_ASLPP_FLAGS = DEF(GCC_ASLPP_FLAGS) > *_GCC7_*_ASLCC_FLAGS = DEF(GCC_ASLCC_FLAGS) > *_GCC7_*_VFRPP_FLAGS = DEF(GCC_VFRPP_FLAGS) > *_GCC7_*_APP_FLAGS = > *_GCC7_*_ASL_FLAGS = DEF(IASL_FLAGS) > *_GCC7_*_ASL_OUTFLAGS = DEF(IASL_OUTFLAGS) > > ################## > # GCC7 IA32 definitions > ################## > *_GCC7_IA32_OBJCOPY_PATH = DEF(GCC7_IA32_PREFIX)objcopy > *_GCC7_IA32_CC_PATH = DEF(GCC7_IA32_PREFIX)gcc > *_GCC7_IA32_SLINK_PATH = DEF(GCC7_IA32_PREFIX)gcc-ar > *_GCC7_IA32_DLINK_PATH = DEF(GCC7_IA32_PREFIX)gcc > *_GCC7_IA32_ASLDLINK_PATH = DEF(GCC7_IA32_PREFIX)gcc > *_GCC7_IA32_ASM_PATH = DEF(GCC7_IA32_PREFIX)gcc > *_GCC7_IA32_PP_PATH = DEF(GCC7_IA32_PREFIX)gcc > *_GCC7_IA32_VFRPP_PATH = DEF(GCC7_IA32_PREFIX)gcc > *_GCC7_IA32_ASLCC_PATH = DEF(GCC7_IA32_PREFIX)gcc > *_GCC7_IA32_ASLPP_PATH = DEF(GCC7_IA32_PREFIX)gcc > *_GCC7_IA32_RC_PATH = DEF(GCC7_IA32_PREFIX)objcopy > > *_GCC7_IA32_ASLCC_FLAGS = DEF(GCC_ASLCC_FLAGS) -m32 -fno-lto > *_GCC7_IA32_ASLDLINK_FLAGS = DEF(GCC7_IA32_X64_ASLDLINK_FLAGS) -Wl,-m,elf_i386 > *_GCC7_IA32_ASM_FLAGS = DEF(GCC7_ASM_FLAGS) -m32 -march=i386 > *_GCC7_IA32_DLINK2_FLAGS = DEF(GCC7_IA32_DLINK2_FLAGS) > *_GCC7_IA32_RC_FLAGS = DEF(GCC_IA32_RC_FLAGS) > *_GCC7_IA32_OBJCOPY_FLAGS = > *_GCC7_IA32_NASM_FLAGS = -f elf32 > > DEBUG_GCC7_IA32_CC_FLAGS = DEF(GCC7_IA32_CC_FLAGS) -flto -Os > DEBUG_GCC7_IA32_DLINK_FLAGS = DEF(GCC7_IA32_X64_DLINK_FLAGS) -flto -Os -Wl,-m,elf_i386,--oformat=elf32-i386 > > RELEASE_GCC7_IA32_CC_FLAGS = DEF(GCC7_IA32_CC_FLAGS) -flto -Os -Wno-unused-but-set-variable -Wno-unused-const-variable > RELEASE_GCC7_IA32_DLINK_FLAGS = DEF(GCC7_IA32_X64_DLINK_FLAGS) -flto -Os -Wl,-m,elf_i386,--oformat=elf32-i386 > > NOOPT_GCC7_IA32_CC_FLAGS = DEF(GCC7_IA32_CC_FLAGS) -O0 > NOOPT_GCC7_IA32_DLINK_FLAGS = DEF(GCC7_IA32_X64_DLINK_FLAGS) -Wl,-m,elf_i386,--oformat=elf32-i386 -O0 > > ################## > # GCC7 X64 definitions > ################## > *_GCC7_X64_OBJCOPY_PATH = DEF(GCC7_X64_PREFIX)objcopy > *_GCC7_X64_CC_PATH = DEF(GCC7_X64_PREFIX)gcc > *_GCC7_X64_SLINK_PATH = DEF(GCC7_X64_PREFIX)gcc-ar > *_GCC7_X64_DLINK_PATH = DEF(GCC7_X64_PREFIX)gcc > *_GCC7_X64_ASLDLINK_PATH = DEF(GCC7_X64_PREFIX)gcc > *_GCC7_X64_ASM_PATH = DEF(GCC7_X64_PREFIX)gcc > *_GCC7_X64_PP_PATH = DEF(GCC7_X64_PREFIX)gcc > *_GCC7_X64_VFRPP_PATH = DEF(GCC7_X64_PREFIX)gcc > *_GCC7_X64_ASLCC_PATH = DEF(GCC7_X64_PREFIX)gcc > *_GCC7_X64_ASLPP_PATH = DEF(GCC7_X64_PREFIX)gcc > *_GCC7_X64_RC_PATH = DEF(GCC7_X64_PREFIX)objcopy > > *_GCC7_X64_ASLCC_FLAGS = DEF(GCC_ASLCC_FLAGS) -m64 -fno-lto > *_GCC7_X64_ASLDLINK_FLAGS = DEF(GCC7_IA32_X64_ASLDLINK_FLAGS) -Wl,-m,elf_x86_64 > *_GCC7_X64_ASM_FLAGS = DEF(GCC7_ASM_FLAGS) -m64 > *_GCC7_X64_DLINK2_FLAGS = DEF(GCC7_X64_DLINK2_FLAGS) > *_GCC7_X64_RC_FLAGS = DEF(GCC_X64_RC_FLAGS) > *_GCC7_X64_OBJCOPY_FLAGS = > *_GCC7_X64_NASM_FLAGS = -f elf64 > > DEBUG_GCC7_X64_CC_FLAGS = DEF(GCC7_X64_CC_FLAGS) -flto -DUSING_LTO -Os > DEBUG_GCC7_X64_DLINK_FLAGS = DEF(GCC7_X64_DLINK_FLAGS) -flto -Os > > RELEASE_GCC7_X64_CC_FLAGS = DEF(GCC7_X64_CC_FLAGS) -flto -DUSING_LTO -Os -Wno-unused-but-set-variable -Wno-unused-const-variable > RELEASE_GCC7_X64_DLINK_FLAGS = DEF(GCC7_X64_DLINK_FLAGS) -flto -Os > > NOOPT_GCC7_X64_CC_FLAGS = DEF(GCC7_X64_CC_FLAGS) -O0 > NOOPT_GCC7_X64_DLINK_FLAGS = DEF(GCC7_X64_DLINK_FLAGS) -O0
You can download the full updated tools_def.txt from here. The file is named UDK2017_GCC7_tools_def.txt.
You can also set defaults for a number of the build options such the package to build, the target architecture, toolchain to use, and more. To do this, you need to modify …/UDK2017/Conf/target.txt. Here are the diffs of the modifications I made to my version of this file:
26c26,27 < ACTIVE_PLATFORM = Nt32Pkg/Nt32Pkg.dsc --- > # ACTIVE_PLATFORM = Nt32Pkg/Nt32Pkg.dsc > ACTIVE_PLATFORM = MyApps/MyApps.dsc 50c51 < TARGET_ARCH = IA32 --- > TARGET_ARCH = X64 60c61,62 < TOOL_CHAIN_TAG = MYTOOLS --- > # TOOL_CHAIN_TAG = MYTOOLS > TOOL_CHAIN_TAG = GCC7 65c67,68 < MAX_CONCURRENT_THREAD_NUMBER = 1 --- > # MAX_CONCURRENT_THREAD_NUMBER = 1 > MAX_CONCURRENT_THREAD_NUMBER = 5
Now when you type build by itself, it looks in …/UDK2017/Conf/target.txt as usual, sees that it should use …/UDK2017/MyApps/MyApps.dsc to determine what package to build, and uses the GCC7 toolchain to build a 64-bit version of the application.
OK, this post is getting quite long and it is time to stop. Hopefully, you now have sufficient information to start developing UEFI applications on Fedora 26. Whilst I have not tested it, all that I have described here should also work on RHEL and CentOS distributions.
UPDATE: December 2017. I upgraded to Fedora 27 and everything still works.