1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
//! 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`** — Enables [`xen_elfnote_phys32_entry!`].
//! - **`reader`** — Enables [`StartInfoReader`] and 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-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
//!
//! ```ignore (_start)
//! 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!(
//! # "2: jmp 2b",
//! // ...
//! );
//! }
//!
//! /// 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:#?}");
//!
//! # unimplemented!()
//! // ...
//! }
//! ```
//!
//! [x86/HVM direct boot ABI]: https://xenbits.xen.org/docs/unstable/misc/pvh.html
//! [QEMU]: https://www.qemu.org
//! [`linux-loader`]: https://github.com/rust-vmm/linux-loader
//! [Firecracker]: https://firecracker-microvm.github.io
//! [Cloud Hypervisor]: https://www.cloudhypervisor.org
//! [`StartInfo`]: self::start_info::StartInfo
//! [`StartInfoReader`]: self::start_info::reader::StartInfoReader
//! [`multiboot`]: https://docs.rs/multiboot
//! [Multiboot]: https://www.gnu.org/software/grub/manual/multiboot/multiboot.html
//! [`multiboot2`]: https://docs.rs/multiboot2
//! [Multiboot2]: https://www.gnu.org/software/grub/manual/multiboot2/multiboot.html
//! [`linux-boot-params`]: https://docs.rs/linux-boot-params
//! [Linux/x86 Boot Protocol]: https://www.kernel.org/doc/html/latest/arch/x86/boot.html