mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2026-08-05 02:19:16 +00:00
arch: load initramfs and populate zero page
* load the initramfs File into the guest memory, aligned to page size * finally setup the initramfs address and its size into the boot params (in configure_64bit_boot) Signed-off-by: Damjan Georgievski <gdamjan@gmail.com>
This commit is contained in:
committed by
Sebastien Boeuf
parent
1f9bc68c54
commit
6cce7b9560
@@ -38,9 +38,10 @@ use kvm_ioctls::*;
|
||||
use linux_loader::cmdline::Cmdline;
|
||||
use linux_loader::loader::KernelLoader;
|
||||
use signal_hook::{iterator::Signals, SIGINT, SIGTERM, SIGWINCH};
|
||||
use std::convert::TryInto;
|
||||
use std::ffi::CString;
|
||||
use std::fs::File;
|
||||
use std::io;
|
||||
use std::io::{self, Seek, SeekFrom};
|
||||
use std::ops::Deref;
|
||||
use std::path::PathBuf;
|
||||
use std::sync::{Arc, Mutex, RwLock};
|
||||
@@ -78,9 +79,15 @@ pub enum Error {
|
||||
/// Cannot open the kernel image
|
||||
KernelFile(io::Error),
|
||||
|
||||
/// Cannot open the initramfs image
|
||||
InitramfsFile(io::Error),
|
||||
|
||||
/// Cannot load the kernel in memory
|
||||
KernelLoad(linux_loader::loader::Error),
|
||||
|
||||
/// Cannot load the initramfs in memory
|
||||
InitramfsLoad,
|
||||
|
||||
/// Cannot load the command line in memory
|
||||
LoadCmdLine(linux_loader::loader::Error),
|
||||
|
||||
@@ -219,6 +226,7 @@ impl VmState {
|
||||
|
||||
pub struct Vm {
|
||||
kernel: File,
|
||||
initramfs: Option<File>,
|
||||
threads: Vec<thread::JoinHandle<()>>,
|
||||
device_manager: Arc<Mutex<DeviceManager>>,
|
||||
config: Arc<Mutex<VmConfig>>,
|
||||
@@ -254,6 +262,11 @@ impl Vm {
|
||||
let kernel = File::open(&config.lock().unwrap().kernel.as_ref().unwrap().path)
|
||||
.map_err(Error::KernelFile)?;
|
||||
|
||||
let initramfs = match &config.lock().unwrap().initramfs {
|
||||
Some(initramfs) => Some(File::open(&initramfs.path).map_err(Error::InitramfsFile)?),
|
||||
None => None,
|
||||
};
|
||||
|
||||
let fd: VmFd;
|
||||
loop {
|
||||
match kvm.create_vm() {
|
||||
@@ -377,6 +390,7 @@ impl Vm {
|
||||
|
||||
Ok(Vm {
|
||||
kernel,
|
||||
initramfs,
|
||||
device_manager,
|
||||
config,
|
||||
on_tty,
|
||||
@@ -388,6 +402,28 @@ impl Vm {
|
||||
})
|
||||
}
|
||||
|
||||
fn load_initramfs(&mut self, guest_mem: &GuestMemoryMmap) -> Result<arch::InitramfsConfig> {
|
||||
let mut initramfs = self.initramfs.as_ref().unwrap();
|
||||
let size: usize = initramfs
|
||||
.seek(SeekFrom::End(0))
|
||||
.map_err(|_| Error::InitramfsLoad)?
|
||||
.try_into()
|
||||
.unwrap();
|
||||
initramfs
|
||||
.seek(SeekFrom::Start(0))
|
||||
.map_err(|_| Error::InitramfsLoad)?;
|
||||
|
||||
let address =
|
||||
arch::initramfs_load_addr(guest_mem, size).map_err(|_| Error::InitramfsLoad)?;
|
||||
let address = GuestAddress(address);
|
||||
|
||||
guest_mem
|
||||
.read_from(address, &mut initramfs, size)
|
||||
.map_err(|_| Error::InitramfsLoad)?;
|
||||
|
||||
Ok(arch::InitramfsConfig { address, size })
|
||||
}
|
||||
|
||||
fn load_kernel(&mut self) -> Result<EntryPoint> {
|
||||
let mut cmdline = Cmdline::new(arch::CMDLINE_MAX_SIZE);
|
||||
cmdline
|
||||
@@ -425,6 +461,12 @@ impl Vm {
|
||||
&cmdline_cstring,
|
||||
)
|
||||
.map_err(Error::LoadCmdLine)?;
|
||||
|
||||
let initramfs_config = match self.initramfs {
|
||||
Some(_) => Some(self.load_initramfs(mem.deref())?),
|
||||
None => None,
|
||||
};
|
||||
|
||||
let boot_vcpus = self.cpu_manager.lock().unwrap().boot_vcpus();
|
||||
let _max_vcpus = self.cpu_manager.lock().unwrap().max_vcpus();
|
||||
|
||||
@@ -447,6 +489,7 @@ impl Vm {
|
||||
&mem,
|
||||
arch::layout::CMDLINE_START,
|
||||
cmdline_cstring.to_bytes().len() + 1,
|
||||
&initramfs_config,
|
||||
boot_vcpus,
|
||||
Some(hdr),
|
||||
rsdp_addr,
|
||||
@@ -481,6 +524,7 @@ impl Vm {
|
||||
&mem,
|
||||
arch::layout::CMDLINE_START,
|
||||
cmdline_cstring.to_bytes().len() + 1,
|
||||
&initramfs_config,
|
||||
boot_vcpus,
|
||||
None,
|
||||
rsdp_addr,
|
||||
|
||||
Reference in New Issue
Block a user