Skip to main content

Crate pvh

Crate pvh 

Source
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

§Tested VMMs

VMMTested
QEMU
Firecracker
Cloud Hypervisor
  • multiboot — Makes kernels bootable via Multiboot. QEMU supports direct kernel boot of Multiboot kernels. linux-loader does not support Multiboot, though.
  • multiboot2 — Makes kernels bootable via Multiboot2. Neither QEMU nor linux-loader support direct kernel boot of Multiboot2 kernels, though.
  • linux-boot-params — Makes kernels bootable via the Linux/x86 Boot Protocol. This is supported by QEMU and linux-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_ENTRY note.