1 // Copyright 2020 Arm Limited (or its affiliates). All rights reserved. 2 // 3 // SPDX-License-Identifier: Apache-2.0 4 5 use std::io::{Read, Seek, SeekFrom}; 6 use std::os::fd::AsFd; 7 use std::result; 8 use vm_memory::{GuestAddress, GuestMemory}; 9 10 /// Errors thrown while loading UEFI binary 11 #[derive(Debug)] 12 pub enum Error { 13 /// Unable to seek to UEFI image start. 14 SeekUefiStart, 15 /// Unable to seek to UEFI image end. 16 SeekUefiEnd, 17 /// UEFI image too big. 18 UefiTooBig, 19 /// Unable to read UEFI image 20 ReadUefiImage, 21 } 22 type Result<T> = result::Result<T, Error>; 23 24 pub fn load_uefi<F, M: GuestMemory>( 25 guest_mem: &M, 26 guest_addr: GuestAddress, 27 uefi_image: &mut F, 28 ) -> Result<()> 29 where 30 F: Read + Seek + AsFd, 31 { 32 let uefi_size = uefi_image 33 .seek(SeekFrom::End(0)) 34 .map_err(|_| Error::SeekUefiEnd)? as usize; 35 36 // edk2 image on virtual platform is smaller than 3M 37 if uefi_size > 0x300000 { 38 return Err(Error::UefiTooBig); 39 } 40 uefi_image.rewind().map_err(|_| Error::SeekUefiStart)?; 41 guest_mem 42 .read_exact_volatile_from(guest_addr, &mut uefi_image.as_fd(), uefi_size) 43 .map_err(|_| Error::ReadUefiImage) 44 } 45