How Xen Boots¶
This is an at-a-glance reference of Xen’s booting capabilities and expectations.
Build¶
A build of xen produces xen.gz
and optionally xen.efi
as final
artefacts.
For BIOS, Xen supports the Multiboot 1 and 2 protocols.
For EFI, Xen supports Multiboot 2 with EFI extensions, and native EFI64.
For virtualisation, Xen supports starting directly with the PVH boot protocol.
Objects¶
To begin with, most object files are compiled and linked. This includes the
Multiboot 1 and 2 headers and entrypoints, including the Multiboot 2 tags for
EFI extensions. When CONFIG_PVH_GUEST
is selected at build time, this
includes the PVH entrypoint and associated ELF notes.
Depending on whether the compiler supports __attribute__((__ms_abi__))
or
not, either an EFI stub is included which nops/fails applicable setup and
runtime calls, or full EFI support is included.
Protocols and entrypoints¶
All headers and tags are built in xen/arch/x86/boot/head.S
The Multiboot 1 headers request aligned modules and memory information. Entry
is via the start of the binary image, which is the start
symbol. This
entrypoint must be started in 32bit mode.
The Multiboot 2 headers are more flexible, and in addition request that the
image be loaded as high as possible below the 4G boundary, with 2M alignment.
Entry is still via the start
symbol as with MB1, and still in 32bit mode.
Headers for the EFI MB2 extensions are also present. These request that
ExitBootServices()
not be called, and register __efi_mb2_start
as an
alternative entrypoint, entered in 64bit mode.
If CONFIG_PVH_GUEST
was selected at build time, an Elf note is included
which indicates the ability to use the PVH boot protocol, and registers
__pvh_start
as the entrypoint, entered in 32bit mode.
xen.gz¶
The objects are linked together to form xen-syms
which is an ELF64
executable with full debugging symbols. xen.gz
is formed by stripping
xen-syms
, then repackaging the result as an ELF32 object with a single
load section at 2MB, and gzip
-ing the result. Despite the ELF32 having a
fixed load address, its contents are relocatable.
Any bootloader which unzips the binary and follows the ELF headers will place
it at the 2M boundary and jump to start
which is the identified entry
point. However, Xen depends on being entered with the MB1 or MB2 protocols,
and will terminate otherwise.
The MB2+EFI entrypoint depends on being entered with the MB2 protocol, and will terminate if the entry protocol is wrong, or if EFI details aren’t provided, or if EFI Boot Services are not available.
xen.efi¶
When a PEI-capable toolchain is found, the objects are linked together and a
PE32+ binary is created. It can be run directly from the EFI shell, and has
efi_start
as its entry symbol.
Note
xen.efi does contain all MB1/MB2/PVH tags included in the rest of the build. However, entry via anything other than the EFI64 protocol is unsupported, and won’t work.
Boot¶
Xen, once loaded into memory, identifies its position in order to relocate system structures. For 32bit entrypoints, this necessarily requires a call instruction, and therefore a stack, but none of the ABIs provide one.
In each supported 32bit entry protocol, %ebx
is a pointer to an info
structure, and it is highly likely that this structure does not overlap with
Xen. Therefore we use this as a temporary stack, preserving the prior value,
in order to calculate Xen’s position in memory.
If this heuristic happens to be wrong (most likely because we were booted by
some other protocol), the calculation stills works as long as %ebx
points
at RAM and does not alias the currently-executing instructions. This is
reasonably likely, and the best we can manage given no other information.