Expand description
Xen’s x86/HVM direct boot ABI (PVH).
This crate contains definitions for Xen’s x86/HVM direct boot ABI (PVH).
PVH is commonly used for direct kernel boot in virtual machine managers
(VMMs), such as QEMU and VMMs using the linux-loader crate, such as
Firecracker and Cloud Hypervisor.
This crate allows kernels to be booted via PVH and helps with reading the
data that is provided via physical addresses. The structures of this crate
can also be used in VMMs or bootloaders for creating appropriate
StartInfo structures when loading a kernel.
§Kernels
xen_elfnote_phys32_entry! creates a XEN_ELFNOTE_PHYS32_ENTRY note to
advertize the PVH entry point to the loader. On entry, ebx contains the
physical memory address of StartInfo. For details, see start_info.
§Features
elfnote— Enablesxen_elfnote_phys32_entry!.reader— EnablesStartInfoReaderand related readers.
§Tested VMMs
| VMM | Tested |
|---|---|
| QEMU | ✅ |
| Firecracker | ✅ |
| Cloud Hypervisor | ✅ |
§Related crates
multiboot— Makes kernels bootable via Multiboot. QEMU supports direct kernel boot of Multiboot kernels.linux-loaderdoes not support Multiboot, though.multiboot2— Makes kernels bootable via Multiboot2. Neither QEMU norlinux-loadersupport direct kernel boot of Multiboot2 kernels, though.linux-boot-params— Makes kernels bootable via the Linux/x86 Boot Protocol. This is supported by QEMU andlinux-loader, but is more complex than PVH. This might also not be straightforward to use on Xen.
§Examples
ⓘ
use pvh::start_info::reader::StartInfoReader;
pvh::xen_elfnote_phys32_entry!(pvh_start32);
/// The PVH entry point.
#[unsafe(naked)]
unsafe extern "C" fn pvh_start32() -> ! {
core::arch::naked_asm!(
".code32", // `start_info_paddr` is now in ebx.
// ...
".code64",
);
}
/// The native ELF entry point.
#[unsafe(no_mangle)]
#[unsafe(naked)]
unsafe extern "C" fn _start() -> ! {
core::arch::naked_asm!(
// ...
);
}
/// The Rust entry point.
unsafe extern "C" fn rust_start(start_info_paddr: u32) -> ! {
// SAFETY: The caller upholds that `start_info_paddr` is valid.
// We have configured the machine to use identity-mapping.
let start_info = unsafe { StartInfoReader::from_paddr_identity(start_info_paddr).unwrap() };
println!("Start info:");
println!("{start_info:#?}");
// ...
}Modules§
- start_
info - PVH start info.
Macros§
- xen_
elfnote_ phys32_ entry - Creates a
XEN_ELFNOTE_PHYS32_ENTRYnote.