mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2025-02-22 19:32:20 +00:00
vmm:AArch64: load standalone firmware
A new firmware item has been added into payload config, we need extend ability to load standalone firmware on AArch64. "load_kernel" method will be the entry of image loading work including kernel and firmware. This change is back compatible. So, we can either load firmware through "-kernel" like before or "-firmware". Signed-off-by: Jianyong Wu <jianyong.wu@arm.com>
This commit is contained in:
parent
2054c8699a
commit
9b1452f258
@ -301,7 +301,6 @@ pub enum Error {
|
||||
#[error("Error joining kernel loading thread")]
|
||||
KernelLoadThreadJoin(std::boxed::Box<dyn std::any::Any + std::marker::Send>),
|
||||
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
#[error("Payload configuration is not bootable")]
|
||||
InvalidPayload,
|
||||
|
||||
@ -458,7 +457,7 @@ pub fn physical_bits(max_phys_bits: u8) -> u8 {
|
||||
}
|
||||
|
||||
pub struct Vm {
|
||||
#[cfg(any(target_arch = "aarch64", feature = "tdx"))]
|
||||
#[cfg(feature = "tdx")]
|
||||
kernel: Option<File>,
|
||||
initramfs: Option<File>,
|
||||
threads: Vec<thread::JoinHandle<()>>,
|
||||
@ -587,7 +586,7 @@ impl Vm {
|
||||
|
||||
let on_tty = unsafe { libc::isatty(libc::STDIN_FILENO as i32) } != 0;
|
||||
|
||||
#[cfg(any(target_arch = "aarch64", feature = "tdx"))]
|
||||
#[cfg(feature = "tdx")]
|
||||
let kernel = config
|
||||
.lock()
|
||||
.unwrap()
|
||||
@ -609,7 +608,7 @@ impl Vm {
|
||||
.map_err(Error::InitramfsFile)?;
|
||||
|
||||
Ok(Vm {
|
||||
#[cfg(any(target_arch = "aarch64", feature = "tdx"))]
|
||||
#[cfg(feature = "tdx")]
|
||||
kernel,
|
||||
initramfs,
|
||||
device_manager,
|
||||
@ -965,8 +964,18 @@ impl Vm {
|
||||
fn load_kernel(&mut self) -> Result<EntryPoint> {
|
||||
let guest_memory = self.memory_manager.lock().as_ref().unwrap().guest_memory();
|
||||
let mem = guest_memory.memory();
|
||||
let mut kernel = self.kernel.as_ref().unwrap();
|
||||
let entry_addr = match linux_loader::loader::pe::PE::load(
|
||||
let payload = self
|
||||
.config
|
||||
.lock()
|
||||
.unwrap()
|
||||
.payload
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.clone();
|
||||
let entry_addr = match (payload.firmware, payload.kernel) {
|
||||
(None, Some(kernel)) => {
|
||||
let mut kernel = File::open(kernel).map_err(Error::KernelFile)?;
|
||||
match linux_loader::loader::pe::PE::load(
|
||||
mem.deref(),
|
||||
Some(arch::layout::KERNEL_START),
|
||||
&mut kernel,
|
||||
@ -977,12 +986,20 @@ impl Vm {
|
||||
// If failed, retry to load it as UEFI binary.
|
||||
// As the UEFI binary is formatless, it must be the last option to try.
|
||||
Err(linux_loader::loader::Error::Pe(InvalidImageMagicNumber)) => {
|
||||
self.load_firmware(kernel)?;
|
||||
self.load_firmware(&kernel)?;
|
||||
arch::layout::UEFI_START
|
||||
}
|
||||
Err(e) => {
|
||||
return Err(Error::KernelLoad(e));
|
||||
}
|
||||
}
|
||||
}
|
||||
(Some(firmware), None) => {
|
||||
let firmware = File::open(firmware).map_err(Error::FirmwareFile)?;
|
||||
self.load_firmware(&firmware)?;
|
||||
arch::layout::UEFI_START
|
||||
}
|
||||
_ => return Err(Error::InvalidPayload),
|
||||
};
|
||||
|
||||
Ok(EntryPoint {
|
||||
@ -2121,11 +2138,21 @@ impl Vm {
|
||||
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
fn entry_point(&mut self) -> Result<Option<EntryPoint>> {
|
||||
Ok(if self.kernel.as_ref().is_some() {
|
||||
let payload = self
|
||||
.config
|
||||
.lock()
|
||||
.unwrap()
|
||||
.payload
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.clone();
|
||||
Ok(
|
||||
if payload.kernel.as_ref().is_some() || payload.firmware.as_ref().is_some() {
|
||||
Some(self.load_kernel()?)
|
||||
} else {
|
||||
None
|
||||
})
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
pub fn boot(&mut self) -> Result<()> {
|
||||
|
Loading…
x
Reference in New Issue
Block a user