linux_loader/lib.rs
1// Copyright (c) 2019 Intel Corporation. All rights reserved.
2// Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3//
4// Copyright 2017 The Chromium OS Authors. All rights reserved.
5// Use of this source code is governed by a BSD-style license that can be
6// found in the LICENSE-BSD-3-Clause file.
7//
8// SPDX-License-Identifier: Apache-2.0 AND BSD-3-Clause
9
10#![deny(missing_docs)]
11#![cfg_attr(docsrs, feature(doc_cfg))]
12
13//! A Linux kernel image loading crate.
14//!
15//! This crate offers support for loading raw ELF (vmlinux), compressed
16//! big zImage (bzImage) and PE (Image) kernel images.
17//! ELF support includes the Linux and PVH boot protocols.
18//! Support for any other kernel image format can be added by implementing
19//! the [`KernelLoader`] and [`BootConfigurator`].
20//!
21//! # Platform support
22//!
23//! - `x86_64`
24//! - `ARM64`
25//! - `RISC-V64`
26//!
27//! # Example - load an ELF kernel and configure boot params with the PVH protocol
28//!
29//! This example shows how to prepare a VM for booting with an ELF kernel, following the PVH
30//! boot protocol.
31//!
32//! ```rust
33//! # extern crate linux_loader;
34//! # extern crate vm_memory;
35//! # use std::{io::{Cursor, Read}, fs::File};
36//!
37//! # #[cfg(all(
38//! # any(target_arch = "x86", target_arch = "x86_64"),
39//! # any(feature = "elf", feature = "pe", feature = "bzimage")
40//! # ))]
41//! # mod imports {
42//! # pub use linux_loader::configurator::{BootConfigurator, BootParams};
43//! # pub use linux_loader::configurator::pvh::PvhBootConfigurator;
44//! # pub use linux_loader::loader::elf::start_info::{hvm_memmap_table_entry, hvm_start_info};
45//! # pub use linux_loader::loader::elf::Elf;
46//! # }
47//!
48//! # #[cfg(all(
49//! # any(target_arch = "x86", target_arch = "x86_64"),
50//! # any(feature = "elf", feature = "pe", feature = "bzimage")
51//! # ))]
52//! # pub use imports::*;
53//!
54//! # use linux_loader::loader::KernelLoader;
55//! # use vm_memory::{Address, GuestAddress, GuestMemoryMmap};
56//! # const E820_RAM: u32 = 1;
57//! # const MEM_SIZE: usize = 0x100_0000;
58//! # const XEN_HVM_START_MAGIC_VALUE: u32 = 0x336ec578;
59//!
60//! # #[cfg(all(
61//! # any(target_arch = "x86", target_arch = "x86_64"),
62//! # any(feature = "elf", feature = "pe", feature = "bzimage")
63//! # ))]
64//! fn build_boot_params() -> (hvm_start_info, Vec<hvm_memmap_table_entry>) {
65//! let mut start_info = hvm_start_info::default();
66//! let memmap_entry = hvm_memmap_table_entry {
67//! addr: 0x7000,
68//! size: 0,
69//! type_: E820_RAM,
70//! reserved: 0,
71//! };
72//! start_info.magic = XEN_HVM_START_MAGIC_VALUE;
73//! start_info.version = 1;
74//! start_info.nr_modules = 0;
75//! start_info.memmap_entries = 0;
76//! (start_info, vec![memmap_entry])
77//! }
78//!
79//! # #[cfg(all(
80//! # any(target_arch = "x86", target_arch = "x86_64"),
81//! # any(feature = "elf", feature = "pe", feature = "bzimage")
82//! # ))]
83//! fn main() {
84//! let guest_mem = GuestMemoryMmap::from_ranges(&[(GuestAddress(0x0), MEM_SIZE)]).unwrap();
85//!
86//! let mut elf_pvh_image = Vec::new();
87//! let path = concat!(
88//! env!("CARGO_MANIFEST_DIR"),
89//! "/src/loader/elf/test_elfnote.bin"
90//! );
91//! let mut file = File::open(path).unwrap();
92//! file.read_to_end(&mut elf_pvh_image).unwrap();
93//!
94//! // Load the kernel image.
95//! let loader_result =
96//! Elf::load(&guest_mem, None, &mut Cursor::new(&elf_pvh_image), None).unwrap();
97//!
98//! // Build boot parameters.
99//! let (mut start_info, memmap_entries) = build_boot_params();
100//! // Address in guest memory where the `start_info` struct will be written.
101//! let start_info_addr = GuestAddress(0x6000);
102//! // Address in guest memory where the memory map will be written.
103//! let memmap_addr = GuestAddress(0x7000);
104//! start_info.memmap_paddr = memmap_addr.raw_value();
105//!
106//! // Write boot parameters in guest memory.
107//! let mut boot_params = BootParams::new::<hvm_start_info>(&start_info, start_info_addr);
108//! boot_params.set_sections::<hvm_memmap_table_entry>(&memmap_entries, memmap_addr);
109//! PvhBootConfigurator::write_bootparams::<GuestMemoryMmap>(&boot_params, &guest_mem).unwrap();
110//! }
111//!
112//! # #[cfg(all(
113//! # any(target_arch = "aarch64", target_arch = "riscv64"),
114//! # any(feature = "elf", feature = "pe", feature = "bzimage")
115//! # ))]
116//! # fn main() {}
117//!
118//! # #[cfg(not(any(feature = "elf", feature = "pe", feature = "bzimage")))]
119//! # fn main() {}
120//! ```
121//!
122//! [`BootConfigurator`]: trait.BootConfigurator.html
123//! [`KernelLoader`]: trait.KernelLoader.html
124
125pub mod cmdline;
126pub mod configurator;
127pub mod loader;
128
129#[allow(clippy::undocumented_unsafe_blocks)]
130#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
131mod loader_gen;
132#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
133pub use loader_gen::*;
134
135extern crate vm_memory;