arch, vmm: Enable initramfs on AArch64

Ported Firecracker commit 144b6c.

Signed-off-by: Michael Zhao <michael.zhao@arm.com>
This commit is contained in:
Michael Zhao 2020-07-14 18:11:03 +08:00 committed by Rob Bradford
parent f449aec78e
commit 3e051e7b2c
3 changed files with 30 additions and 12 deletions

View File

@ -35,8 +35,8 @@ pub enum Error {
/// Failed to create a GIC.
SetupGIC(gic::Error),
/// Failed to compute the initrd address.
InitrdAddress,
/// Failed to compute the initramfs address.
InitramfsAddress,
/// Error configuring the general purpose registers
REGSConfiguration(regs::Error),
@ -165,6 +165,26 @@ pub fn configure_system<T: DeviceInfoForFDT + Clone + Debug>(
Ok(())
}
/// Returns the memory address where the initramfs could be loaded.
pub fn initramfs_load_addr(
guest_mem: &GuestMemoryMmap,
initramfs_size: usize,
) -> super::Result<u64> {
let round_to_pagesize = |size| (size + (super::PAGE_SIZE - 1)) & !(super::PAGE_SIZE - 1);
match GuestAddress(get_fdt_addr(&guest_mem))
.checked_sub(round_to_pagesize(initramfs_size) as u64)
{
Some(offset) => {
if guest_mem.address_in_range(offset) {
Ok(offset.raw_value())
} else {
Err(super::Error::AArch64Setup(Error::InitramfsAddress))
}
}
None => Err(super::Error::AArch64Setup(Error::InitramfsAddress)),
}
}
/// Returns the memory address where the kernel could be loaded.
pub fn get_kernel_start() -> u64 {
layout::RAM_64BIT_START

View File

@ -88,8 +88,8 @@ pub mod aarch64;
#[cfg(target_arch = "aarch64")]
pub use aarch64::{
arch_memory_regions, configure_system, configure_vcpu, fdt::DeviceInfoForFDT,
get_host_cpu_phys_bits, get_kernel_start, layout, layout::CMDLINE_MAX_SIZE, layout::IRQ_BASE,
layout::IRQ_MAX, EntryPoint,
get_host_cpu_phys_bits, get_kernel_start, initramfs_load_addr, layout,
layout::CMDLINE_MAX_SIZE, layout::IRQ_BASE, layout::IRQ_MAX, EntryPoint,
};
#[cfg(target_arch = "x86_64")]

View File

@ -47,12 +47,10 @@ use linux_loader::loader::elf::PvhBootCapability::PvhEntryPresent;
use linux_loader::loader::KernelLoader;
use signal_hook::{iterator::Signals, SIGINT, SIGTERM, SIGWINCH};
use std::collections::HashMap;
#[cfg(target_arch = "x86_64")]
use std::convert::TryInto;
use std::ffi::CString;
use std::fs::{File, OpenOptions};
use std::io::{self, Write};
#[cfg(target_arch = "x86_64")]
use std::io::{Seek, SeekFrom};
use std::num::Wrapping;
use std::ops::Deref;
@ -60,9 +58,7 @@ use std::path::PathBuf;
use std::sync::{Arc, Mutex, RwLock};
use std::{result, str, thread};
use url::Url;
use vm_memory::{Address, GuestAddress, GuestAddressSpace};
#[cfg(target_arch = "x86_64")]
use vm_memory::{Bytes, GuestMemoryMmap};
use vm_memory::{Address, Bytes, GuestAddress, GuestAddressSpace, GuestMemoryMmap};
use vm_migration::{
Migratable, MigratableError, Pausable, Snapshot, SnapshotDataSection, Snapshottable,
Transportable,
@ -245,7 +241,6 @@ impl VmState {
pub struct Vm {
kernel: File,
#[cfg_attr(target_arch = "aarch64", allow(dead_code))]
initramfs: Option<File>,
threads: Vec<thread::JoinHandle<()>>,
device_manager: Arc<Mutex<DeviceManager>>,
@ -434,7 +429,6 @@ impl Vm {
)
}
#[cfg(target_arch = "x86_64")]
fn load_initramfs(&mut self, guest_mem: &GuestMemoryMmap) -> Result<arch::InitramfsConfig> {
let mut initramfs = self.initramfs.as_ref().unwrap();
let size: usize = initramfs
@ -631,6 +625,10 @@ impl Vm {
let vcpu_mpidrs = self.cpu_manager.lock().unwrap().get_mpidrs();
let guest_memory = self.memory_manager.lock().as_ref().unwrap().guest_memory();
let mem = guest_memory.memory();
let initramfs_config = match self.initramfs {
Some(_) => Some(self.load_initramfs(mem.deref())?),
None => None,
};
let device_info = &self
.device_manager
@ -671,7 +669,7 @@ impl Vm {
self.cpu_manager.lock().unwrap().boot_vcpus() as u64,
vcpu_mpidrs,
device_info,
&None,
&initramfs_config,
&pci_space,
)
.map_err(Error::ConfigureSystem)?;