Xen EFI
Xen in EFI
Xen 4.3 and later can be built as EFI binaries. Xen 4.5 can be built as an EFI binary under ARM. Xen 4.9 can be built with Multiboot2 support which GRUB2 2.02 uses.
Linux 3.17 and later when built with CONFIG_XEN_EFI
can be booted under Xen in EFI platform.
Xen does support verifying of payloads, such as the initial kernel and its ramdisk via the Shim protocol (GUID: 0x605dab50, 0xe046, 0x4300, {0xab, 0xb6, 0x3d, 0xd8, 0x10, 0xdd, 0x8b, 0x23).
For shim repo, please see shim.
Compiling Xen as EFI
Compiling under x86
During the compilation process most of the Xen hypervisor code is compiled using the normal compiler (GCC). Only during the link-time do we employ the EFI linker to built an EFI binary.
As of Ubuntu 16.04 the binutils is compiled with PE (EFI) support. To verify run ld -V.
You are looking for i386pe in it, as so:
$ ld -V GNU ld version 2.26.1-1.2.fc25 Supported emulations: elf_x86_64 elf32_x86_64 elf_i386 elf_iamcu i386linux elf_l1om elf_k1om i386pep i386pe
Alternatively you can build you GCC crosstool chainOSDev UEFI link
Or recompile your binutils (Fedora 25):
- dnf download --source binutils
- rpm -hiv binutil*.srpm
- cd /usr/src/redhat/SPECS
- sudo dnf builddep --spec binutils.spec
- patch -p1 < pe_binutils.patch
The pe_binutils.patch looks as follow:
--- binutils.spec.orig 2017-01-31 09:24:18.988130013 -0500 +++ binutils.spec 2017-01-31 09:25:38.975347558 -0500 @@ -22,7 +22,7 @@ Summary: A GNU collection of binary utilities Name: %{?cross}binutils%{?_with_debug:-debug} Version: 2.26.1 -Release: 1%{?dist} +Release: 1.2%{?dist} License: GPLv3+ Group: Development/Tools URL: http://sources.redhat.com/binutils @@ -263,6 +263,11 @@ ;; esac +case %{binutils_target} in x86_64*|i?86*|arm*|aarch64*) + CARGS="$CARGS --enable-targets=x86_64-pep" + ;; +esac + %if 0%{?_with_debug:1} CFLAGS="$CFLAGS -O0 -ggdb2 -Wno-error -D_FORTIFY_SOURCE=0" %define enable_shared 0 @@ -519,6 +524,9 @@ %endif # %{isnative} %changelog +* Tue Jan 31 2017 Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> 2.26-1.1.2 +- Add PE support. + * Mon Aug 15 2016 Nick Clifton <nickc@redhat.com> 2.26.1-1 - Rebase on FSF binutils 2.26.1 release. - Retire: binutils-2.26-formatting.patch
- rpmbuild -ba binutils.spec
- cd ../RPMS/x86_64/
- rpm -U binut*.rpm
In either way, you will have an xen.efi file.
Compiling under ARM
From: efi.html:
For arm64, the PE/COFF header is open-coded in assembly, so no toolchain support for PE/COFF is required. Also, the PE/COFF header co-exists with the normal Image format, so a single binary may be booted as an Image file or as an EFI application.
Booting Xen under EFI platform
There are two ways of booting Xen:
- From the EFI platform - which shows up in BIOS boot menu.
- Using an bootloader (such as GRUB2)
Xen as EFI binary (loading)
Xen.efi as an EFI binary can be executed by the EFI firmware immediately. As the firmware does not provide an command line (nor would you want to have it), Xen expects an configuration file to tell it what initial domain (and ramdisk) to load afterwards. This configuration file must reside in the same directory as the xen.efi. Also the payloads (vmlinuz and ramdisk) MUST also reside in said directory.
The boot mechanism is simple:
EFI firmware => Xen.efi [loads vmlinuz and ramdisk and executes vmlinuz]
One can put the files in the /EFI/Boot and with efibootmgr configure the system to boot it:
efibootmgr -w -L Xen -l "\EFI\Xen\xen.efi" -c
which will produce a new boot target (for example):
[root@localhost EFI]# ls /boot/efi/EFI/Xen initramfs-3.17.1-302.fc21.x86_64.img vmlinuz-3.17.1-302.fc21.x86_64 xen.cfg xen.efi [root@localhost Xen]# efibootmgr -w -L Xen -l "\EFI\Xen\xen.efi" -c BootCurrent: 0000 Timeout: 0 seconds BootOrder: 0005,0001,0002,0003,0004,0000 Boot0000* Fedora Boot0001* UEFI: ASUS DRW-24B1ST Boot0002* CD/DVD Drive Boot0003* Hard Drive Boot0004* Network Card Boot0005* Xen
Xen as gz binary
GRUB2 loader when built as an EFI binary can load various OS-es. The most common one is Linux where it uses the linuxefi GRUB module. However GRUB2 also has support for multiboot protocol which is what Xen uses. Sadly v1 of multiboot API does not have enough data to provide information to Xen under the EFI platform.
As such a proposal had been discussed to add a multibootv2+EFI API which would provide enough data such that GRUB2's multiboot module could pass that to Xen compiled as ELF binary (.gz).
This would allow:
EFI firmware => GRUB2.EFI -> multiboot2 -> [xen.gz, vmlinuz, ramdisk]
And GRUB2 would be responsible for reading from the ESP the various files and loading them in the memory.
That work has been deferred to Xen 4.6.
As such the current workaround is to use the GRUB2 chainloader. Example:
menuentry "Xen EFI" { insmod part_gpt insmod search_fs_uuid insmod chain chainloader (hd0,gpt1)/EFI/XEN/xen.efi }