This is an at-a-glance reference of Xen's booting capabilities and expectations.
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.
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.
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.
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.
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.
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.