mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 10:11:27 +01:00
This patch adds support for bundling the xen.efi hypervisor, the xen.cfg configuration file, the Linux kernel and initrd, as well as the XSM, and architectural specific files into a single "unified" EFI executable. This allows an administrator to update the components independently without requiring rebuilding xen, as well as to replace the components in an existing image. The resulting EFI executable can be invoked directly from the UEFI Boot Manager, removing the need to use a separate loader like grub as well as removing dependencies on local filesystem access. And since it is a single file, it can be signed and validated by UEFI Secure Boot without requring the shim protocol. It is inspired by systemd-boot's unified kernel technique and borrows the function to locate PE sections from systemd's LGPL'ed code. During EFI boot, Xen looks at its own loaded image to locate the PE sections for the Xen configuration (`.config`), dom0 kernel (`.kernel`), dom0 initrd (`.ramdisk`), and XSM config (`.xsm`), which are included after building xen.efi using objcopy to add named sections for each input file. For x86, the CPU ucode can be included in a section named `.ucode`, which is loaded in the efi_arch_cfg_file_late() stage of the boot process. On ARM systems the Device Tree can be included in a section named `.dtb`, which is loaded during the efi_arch_cfg_file_early() stage of the boot process. Note that the system will fall back to loading files from disk if the named sections do not exist. This allows distributions to continue with the status quo if they want a signed kernel + config, while still allowing a user provided initrd (which is how the shim protocol currently works as well). This patch also adds constness to the section parameter of efi_arch_cfg_file_early() and efi_arch_cfg_file_late(), changes pe_find_section() to use a const CHAR16 section name, and adds pe_name_compare() to match section names. Signed-off-by: Trammell Hudson <hudson@trmm.net> Reviewed-by: Jan Beulich <jbeulich@suse.com> [Fix ARM build by including pe.init.o] Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
168 lines
6.7 KiB
Plaintext
168 lines
6.7 KiB
Plaintext
For x86, building xen.efi requires gcc 4.5.x or above (4.6.x or newer
|
|
recommended, as 4.5.x was probably never really tested for this purpose) and
|
|
binutils 2.22 or newer. Additionally, the binutils build must be configured to
|
|
include support for the x86_64-pep emulation (i.e.
|
|
`--enable-targets=x86_64-pep` or an option of equivalent effect should be
|
|
passed to the configure script).
|
|
|
|
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. When booted as an EFI application, Xen requires a
|
|
configuration file as described below unless a bootloader, such as GRUB, has
|
|
loaded the modules and describes them in the device tree provided to Xen. If a
|
|
bootloader provides a device tree containing modules then any configuration
|
|
files are ignored, and the bootloader is responsible for populating all
|
|
relevant device tree nodes.
|
|
|
|
Once built, `make install-xen` will place the resulting binary directly into
|
|
the EFI boot partition, provided `EFI_VENDOR` is set in the environment (and
|
|
`EFI_MOUNTPOINT` is overridden as needed, should the default of `/boot/efi` not
|
|
match your system). The xen.efi binary will also be installed in
|
|
`/usr/lib64/efi/`, unless `EFI_DIR` is set in the environment to override this
|
|
default.
|
|
|
|
The binary itself will require a configuration file (names with the `.efi`
|
|
extension of the binary's name replaced by `.cfg`, and - until an existing
|
|
file is found - trailing name components dropped at `.`, `-`, and `_`
|
|
separators will be tried) to be present in the same directory as the binary.
|
|
(To illustrate the name handling, a binary named `xen-4.2-unstable.efi` would
|
|
try `xen-4.2-unstable.cfg`, `xen-4.2.cfg`, `xen-4.cfg`, and `xen.cfg` in
|
|
order.) One can override this with a command line option (`-cfg=<filename>`).
|
|
This configuration file and EFI commandline are only used for booting directly
|
|
from EFI firmware, or when using an EFI loader that does not support
|
|
the multiboot2 protocol. When booting using GRUB or another multiboot aware
|
|
loader the EFI commandline is ignored and all information is passed from
|
|
the loader to Xen using the multiboot protocol.
|
|
|
|
The configuration file consists of one or more sections headed by a section
|
|
name enclosed in square brackets, with individual values specified in each
|
|
section. A section named `[global]` is treated specially to allow certain
|
|
settings to apply to all other sections (or to provide defaults for certain
|
|
settings in case individual sections don't specify them). This file (for now)
|
|
needs to be of ASCII type and not e.g. UTF-8 or UTF-16. A typical file would
|
|
thus look like this (`#` serving as comment character):
|
|
|
|
**************************example begin******************************
|
|
|
|
[global]
|
|
default=sle11sp2
|
|
|
|
[sle11sp2]
|
|
options=console=vga,com1 com1=57600 loglvl=all noreboot
|
|
kernel=vmlinuz-3.0.31-0.4-xen [domain 0 command line options]
|
|
ramdisk=initrd-3.0.31-0.4-xen
|
|
|
|
**************************example end********************************
|
|
|
|
The individual values used here are:
|
|
|
|
###`default=<name>`
|
|
|
|
Specifies the section to use for booting, if none was specified on the command
|
|
line; only meaningful in the `[global]` section. This isn't required; if
|
|
absent, section headers will be ignored and for each value looked for the
|
|
first instance within the file will be used.
|
|
|
|
###`options=<text>`
|
|
|
|
Specifies the options passed to the hypervisor, see [Xen Hypervisor Command
|
|
Line Options](xen-command-line.html).
|
|
|
|
###`kernel=<filename>[ <options>]`
|
|
|
|
Specifies the Dom0 kernel binary and the options to pass to it.
|
|
|
|
The options should in general be the same as is used when booting
|
|
natively, e.g. including `root=...` etc.
|
|
|
|
Check your bootloader (e.g. grub) configuration or `/proc/cmdline` for
|
|
the native configuration.
|
|
|
|
###`ramdisk=<filename>`
|
|
|
|
Specifies a Linux-style initial RAM disk image to load.
|
|
|
|
Other values to specify are:
|
|
|
|
###`video=gfx-<xres>[x<yres>[x<depth>]]`
|
|
|
|
Specifies a video mode to select if available. In case of problems, the
|
|
`-basevideo` command line option can be used to skip altering video modes.
|
|
|
|
###`xsm=<filename>`
|
|
|
|
Specifies an XSM module to load.
|
|
|
|
###`ucode=<filename>`
|
|
|
|
Specifies a CPU microcode blob to load. (x86 only)
|
|
|
|
###`dtb=<filename>`
|
|
|
|
Specifies a device tree file to load. The platform firmware may provide a
|
|
DTB in an EFI configuration table, so this field is optional in that
|
|
case. A dtb specified in the configuration file will override a device tree
|
|
provided in the EFI configuration table. (ARM only)
|
|
|
|
###`chain=<filename>`
|
|
|
|
Specifies an alternate configuration file to use in case the specified section
|
|
(and in particular its `kernel=` setting) can't be found in the default (or
|
|
specified) configuration file. This is only meaningful in the [global] section
|
|
and really not meant to be used together with the `-cfg=` command line option.
|
|
|
|
Filenames must be specified relative to the location of the EFI binary.
|
|
|
|
Extra options to be passed to Xen can also be specified on the command line,
|
|
following a `--` separator option.
|
|
|
|
## Unified Xen kernel image
|
|
|
|
The "Unified" kernel image can be generated by adding additional
|
|
sections to the Xen EFI executable with objcopy, similar to how
|
|
[systemd-boot uses the stub to add them to the Linux kernel](https://wiki.archlinux.org/index.php/systemd-boot#Preparing_a_unified_kernel_image)
|
|
|
|
The sections for the xen configuration file, the dom0 kernel, dom0 initrd,
|
|
XSM and CPU microcode should be added after the Xen `.pad` section, the
|
|
ending address of which can be located with:
|
|
|
|
```
|
|
objdump -h xen.efi \
|
|
| perl -ane '/\.pad/ && printf "0x%016x\n", hex($F[2]) + hex($F[3])'
|
|
```
|
|
|
|
For all the examples the `.pad` section ended at 0xffff82d041000000.
|
|
All the sections are optional (`.config`, `.kernel`, `.ramdisk`, `.xsm`,
|
|
`.ucode` (x86) and `.dtb` (ARM)) and the order does not matter.
|
|
The virtual addresses do not need to be contiguous, although they should not
|
|
be overlapping and should all be greater than the last virtual address of the
|
|
hypervisor components.
|
|
|
|
```
|
|
objcopy \
|
|
--add-section .config=xen.cfg \
|
|
--change-section-vma .config=0xffff82d041000000
|
|
--add-section .ucode=ucode.bin \
|
|
--change-section-vma .ucode=0xffff82d041010000 \
|
|
--add-section .xsm=xsm.cfg \
|
|
--change-section-vma .xsm=0xffff82d041080000 \
|
|
--add-section .kernel=vmlinux \
|
|
--change-section-vma .kernel=0xffff82d041100000 \
|
|
--add-section .ramdisk=initrd.img \
|
|
--change-section-vma .ramdisk=0xffff82d042000000 \
|
|
xen.efi \
|
|
xen.unified.efi
|
|
```
|
|
|
|
The unified executable can be signed with sbsigntool to make
|
|
it usable with UEFI secure boot:
|
|
|
|
```
|
|
sbsign \
|
|
--key signing.key \
|
|
--cert cert.pem \
|
|
--output xen.signed.efi \
|
|
xen.unified.efi
|
|
```
|