fn load<F, M: GuestMemory>(
        guest_mem: &M,
        kernel_start: Option<GuestAddress>,
        kernel_image: &mut F,
        highmem_start_address: Option<GuestAddress>,
    ) -> Result<KernelLoaderResult>
    where
        F: Read + Seek,
    {
        kernel_image
            .seek(SeekFrom::Start(0))
            .map_err(|_| Error::SeekElfStart)?;

        let mut ehdr = elf::Elf64_Ehdr::default();
        ehdr.as_bytes()
            .read_from(0, kernel_image, mem::size_of::<elf::Elf64_Ehdr>())
            .map_err(|_| Error::ReadElfHeader)?;

        // Sanity checks.
        Self::validate_header(&ehdr)?;
        if let Some(addr) = highmem_start_address {
            if (ehdr.e_entry as u64) < addr.raw_value() {
                return Err(Error::InvalidEntryAddress.into());
            }
        }

        let mut loader_result: KernelLoaderResult = Default::default();

        // Address where the kernel will be loaded.
        loader_result.kernel_load = match kernel_start {
            Some(start) => GuestAddress(start.raw_value() + (ehdr.e_entry as u64)),
            None => GuestAddress(ehdr.e_entry as u64),
        };

        kernel_image
            .seek(SeekFrom::Start(ehdr.e_phoff))
            .map_err(|_| Error::SeekProgramHeader)?;

        let phdr_sz = mem::size_of::<elf::Elf64_Phdr>();
        let mut phdrs: Vec<elf::Elf64_Phdr> = vec![];
        for _ in 0usize..ehdr.e_phnum as usize {
            let mut phdr = elf::Elf64_Phdr::default();
            phdr.as_bytes()
                .read_from(0, kernel_image, phdr_sz)
                .map_err(|_| Error::ReadProgramHeader)?;
            phdrs.push(phdr);
        }

        // Read in each section pointed to by the program headers.
        for phdr in phdrs {
            if phdr.p_type != elf::PT_LOAD || phdr.p_filesz == 0 {
                if phdr.p_type == elf::PT_NOTE {
                    // This segment describes a Note, check if PVH entry point is encoded.
                    loader_result.pvh_entry_addr = parse_elf_note(&phdr, kernel_image)?;
                }
                continue;
            }

            kernel_image
                .seek(SeekFrom::Start(phdr.p_offset))
                .map_err(|_| Error::SeekKernelStart)?;

            // if the vmm does not specify where the kernel should be loaded, just
            // load it to the physical address p_paddr for each segment.
            let mem_offset = match kernel_start {
                Some(start) => start
                    .checked_add(phdr.p_paddr as u64)
                    .ok_or(Error::InvalidProgramHeaderAddress)?,
                None => GuestAddress(phdr.p_paddr as u64),
            };

            guest_mem
                .read_exact_from(mem_offset, kernel_image, phdr.p_filesz as usize)
                .map_err(|_| Error::ReadKernelImage)?;

            let kernel_end = mem_offset
                .raw_value()
                .checked_add(phdr.p_memsz as GuestUsize)
                .ok_or(KernelLoaderError::MemoryOverflow)?;
            loader_result.kernel_end = std::cmp::max(loader_result.kernel_end, kernel_end);
        }

        // elf image has no setup_header which is defined for bzImage
        loader_result.setup_header = None;

        Ok(loader_result)
    }
/// Loads a kernel from a vmlinux elf image into guest memory.
///
/// The kernel is loaded into guest memory at offset `phdr.p_paddr` specified by the elf image.
///
/// # Arguments
///
/// * `guest_mem`: [`GuestMemory`] to load the kernel in.
/// * `kernel_start`: Address in guest memory where the kernel is loaded.
/// * `kernel_image` - Input vmlinux image.
/// * `highmem_start_address`: Address where high memory starts.
///
/// # Examples
///
/// ```rust
/// # extern crate vm_memory;
/// # use linux_loader::loader::*;
/// # use vm_memory::{Address, GuestAddress, GuestMemoryMmap};
/// # use std::io::Cursor;
/// let mem_size: usize = 0x1000000;
/// let himem_start = GuestAddress(0x0);
/// let kernel_addr = GuestAddress(0x200000);
/// let gm = GuestMemoryMmap::from_ranges(&[(GuestAddress(0x0), mem_size)]).unwrap();
/// let mut kernel_image = vec![];
/// kernel_image.extend_from_slice(include_bytes!("test_elf.bin"));
/// elf::Elf::load(
///     &gm,
///     Some(kernel_addr),
///     &mut Cursor::new(&kernel_image),
///     Some(himem_start),
/// ).unwrap();
/// ```
///
/// [`GuestMemory`]: https://docs.rs/vm-memory/latest/vm_memory/guest_memory/trait.GuestMemory.html
Loads a kernel from a vmlinux elf image into guest memory.
The kernel is loaded into guest memory at offset `phdr.p_paddr` specified by the elf image.
Loads a kernel from a vmlinux elf image into guest memory . The kernel is loaded into guest memory at offset ` phdr . p_paddr ` specified by the elf image .
fn load<F, M: GuestMemory>(
        guest_mem: &M,
        kernel_start: Option<GuestAddress>,
        kernel_image: &mut F,
        highmem_start_address: Option<GuestAddress>,
    ) -> Result<KernelLoaderResult>
    where
        F: Read + Seek,
    {
        kernel_image
            .seek(SeekFrom::Start(0))
            .map_err(|_| Error::SeekElfStart)?;
        let mut ehdr = elf::Elf64_Ehdr::default();
        ehdr.as_bytes()
            .read_from(0, kernel_image, mem::size_of::<elf::Elf64_Ehdr>())
            .map_err(|_| Error::ReadElfHeader)?;
        // Sanity checks.
        Self::validate_header(&ehdr)?;
        if let Some(addr) = highmem_start_address {
            if (ehdr.e_entry as u64) < addr.raw_value() {
                return Err(Error::InvalidEntryAddress.into());
            }
        }
        let mut loader_result: KernelLoaderResult = Default::default();
        // Address where the kernel will be loaded.
        loader_result.kernel_load = match kernel_start {
            Some(start) => GuestAddress(start.raw_value() + (ehdr.e_entry as u64)),
            None => GuestAddress(ehdr.e_entry as u64),
        };
        kernel_image
            .seek(SeekFrom::Start(ehdr.e_phoff))
            .map_err(|_| Error::SeekProgramHeader)?;
        let phdr_sz = mem::size_of::<elf::Elf64_Phdr>();
        let mut phdrs: Vec<elf::Elf64_Phdr> = vec![];
        for _ in 0usize..ehdr.e_phnum as usize {
            let mut phdr = elf::Elf64_Phdr::default();
            phdr.as_bytes()
                .read_from(0, kernel_image, phdr_sz)
                .map_err(|_| Error::ReadProgramHeader)?;
            phdrs.push(phdr);
        }
        // Read in each section pointed to by the program headers.
        for phdr in phdrs {
            if phdr.p_type != elf::PT_LOAD || phdr.p_filesz == 0 {
                if phdr.p_type == elf::PT_NOTE {
                    // This segment describes a Note, check if PVH entry point is encoded.
                    loader_result.pvh_entry_addr = parse_elf_note(&phdr, kernel_image)?;
                }
                continue;
            }
            kernel_image
                .seek(SeekFrom::Start(phdr.p_offset))
                .map_err(|_| Error::SeekKernelStart)?;
            // if the vmm does not specify where the kernel should be loaded, just
            // load it to the physical address p_paddr for each segment.
            let mem_offset = match kernel_start {
                Some(start) => start
                    .checked_add(phdr.p_paddr as u64)
                    .ok_or(Error::InvalidProgramHeaderAddress)?,
                None => GuestAddress(phdr.p_paddr as u64),
            };
            guest_mem
                .read_exact_from(mem_offset, kernel_image, phdr.p_filesz as usize)
                .map_err(|_| Error::ReadKernelImage)?;
            let kernel_end = mem_offset
                .raw_value()
                .checked_add(phdr.p_memsz as GuestUsize)
                .ok_or(KernelLoaderError::MemoryOverflow)?;
            loader_result.kernel_end = std::cmp::max(loader_result.kernel_end, kernel_end);
        }
        // elf image has no setup_header which is defined for bzImage
        loader_result.setup_header = None;
        Ok(loader_result)
    }
fn load < F , M : GuestMemory > ( guest_mem : & M , kernel_start : Option < GuestAddress > , kernel_image : & mut F , highmem_start_address : Option < GuestAddress > , ) -> Result < KernelLoaderResult > where F : Read + Seek , { kernel_image . seek ( SeekFrom :: Start ( 0 ) ) . map_err ( | _ | Error :: SeekElfStart ) ? ; let mut ehdr = elf :: Elf64_Ehdr :: default ( ) ; ehdr . as_bytes ( ) . read_from ( 0 , kernel_image , mem :: size_of :: < elf :: Elf64_Ehdr > ( ) ) . map_err ( | _ | Error :: ReadElfHeader ) ? ; // Sanity checks. Self :: validate_header ( & ehdr ) ? ; if let Some ( addr ) = highmem_start_address { if ( ehdr . e_entry as u64 ) < addr . raw_value ( ) { return Err ( Error :: InvalidEntryAddress . into ( ) ) ; } } let mut loader_result : KernelLoaderResult = Default :: default ( ) ; // Address where the kernel will be loaded. loader_result . kernel_load = match kernel_start { Some ( start ) => GuestAddress ( start . raw_value ( ) + ( ehdr . e_entry as u64 ) ) , None => GuestAddress ( ehdr . e_entry as u64 ) , } ; kernel_image . seek ( SeekFrom :: Start ( ehdr . e_phoff ) ) . map_err ( | _ | Error :: SeekProgramHeader ) ? ; let phdr_sz = mem :: size_of :: < elf :: Elf64_Phdr > ( ) ; let mut phdrs : Vec < elf :: Elf64_Phdr > = vec ! [ ] ; for _ in 0usize .. ehdr . e_phnum as usize { let mut phdr = elf :: Elf64_Phdr :: default ( ) ; phdr . as_bytes ( ) . read_from ( 0 , kernel_image , phdr_sz ) . map_err ( | _ | Error :: ReadProgramHeader ) ? ; phdrs . push ( phdr ) ; } // Read in each section pointed to by the program headers. for phdr in phdrs { if phdr . p_type != elf :: PT_LOAD || phdr . p_filesz == 0 { if phdr . p_type == elf :: PT_NOTE { // This segment describes a Note, check if PVH entry point is encoded. loader_result . pvh_entry_addr = parse_elf_note ( & phdr , kernel_image ) ? ; } continue ; } kernel_image . seek ( SeekFrom :: Start ( phdr . p_offset ) ) . map_err ( | _ | Error :: SeekKernelStart ) ? ; // if the vmm does not specify where the kernel should be loaded, just // load it to the physical address p_paddr for each segment. let mem_offset = match kernel_start { Some ( start ) => start . checked_add ( phdr . p_paddr as u64 ) . ok_or ( Error :: InvalidProgramHeaderAddress ) ? , None => GuestAddress ( phdr . p_paddr as u64 ) , } ; guest_mem . read_exact_from ( mem_offset , kernel_image , phdr . p_filesz as usize ) . map_err ( | _ | Error :: ReadKernelImage ) ? ; let kernel_end = mem_offset . raw_value ( ) . checked_add ( phdr . p_memsz as GuestUsize ) . ok_or ( KernelLoaderError :: MemoryOverflow ) ? ; loader_result . kernel_end = std :: cmp :: max ( loader_result . kernel_end , kernel_end ) ; } // elf image has no setup_header which is defined for bzImage loader_result . setup_header = None ; Ok ( loader_result ) }
Loads a kernel from a vmlinux elf image into guest memory.
Loads a kernel from a vmlinux elf image into guest memory .
guest_mem
&M
kernel_start
Option<GuestAddress>
kernel_image
&mut F
highmem_start_address
Option<GuestAddress>
guest_mem
&M
kernel_start
Option<GuestAddress>
kernel_image
&mut F
highmem_start_address
Option<GuestAddress>
examples
None
extern crate vm_memory;
None
use linux_loader::loader::*;
None
use vm_memory::{address, guestaddress, guestmemorymmap};
None
use std::io::cursor;
let mem_size: usize = 0x1000000;
let himem_start = GuestAddress(0x0);
let kernel_addr = GuestAddress(0x200000);
let gm = GuestMemoryMmap::from_ranges(&[(GuestAddress(0x0), mem_size)]).unwrap();
let mut kernel_image = vec![];
kernel_image.extend_from_slice(include_bytes!("test_elf.bin"));
elf::Elf::load(
&gm,
Some(kernel_addr),
&mut Cursor::new(&kernel_image),
Some(himem_start),
).unwrap();
```


let mem_size : usize = 0x1000000 ; let himem_start = GuestAddress ( 0x0 ) ; let kernel_addr = GuestAddress ( 0x200000 ) ; let gm = GuestMemoryMmap :: from_ranges ( & [ ( GuestAddress ( 0x0 ) mem_size ) ] ) . unwrap () ; let mut kernel_image = vec! [] ; kernel_image . extend_from_slice ( include_bytes! ( " test_elf . bin " )) ; elf :: Elf :: load ( &gm Some ( kernel_addr ) &mut Cursor :: new ( &kernel_image ) Some ( himem_start ) ) . unwrap () ; ` ` `