@@ -52,6 +52,8 @@ pub enum Error {
5252 CommandLineCopy ,
5353 /// Command line overflowed guest memory.
5454 CommandLineOverflow ,
55+ /// Device tree bianry too big.
56+ DtbTooBig ,
5557 /// Invalid ELF magic number
5658 InvalidElfMagicNumber ,
5759 /// Invalid program header size.
@@ -84,6 +86,8 @@ pub enum Error {
8486 ReadBzImageCompressedKernel ,
8587 /// Unable to read Image header
8688 ReadImageHeader ,
89+ /// Unable to read DTB image
90+ ReadDtbImage ,
8791 /// Unable to seek to kernel start.
8892 SeekKernelStart ,
8993 /// Unable to seek to ELF start.
@@ -100,6 +104,10 @@ pub enum Error {
100104 SeekImageEnd ,
101105 /// Unable to seek to Image header.
102106 SeekImageHeader ,
107+ /// Unable to seek to DTB start.
108+ SeekDtbStart ,
109+ /// Unable to seek to DTB end.
110+ SeekDtbEnd ,
103111}
104112
105113/// A specialized `Result` type for the kernel loader.
@@ -113,6 +121,7 @@ impl error::Error for Error {
113121 }
114122 Error :: CommandLineCopy => "Failed writing command line to guest memory" ,
115123 Error :: CommandLineOverflow => "Command line overflowed guest memory" ,
124+ Error :: DtbTooBig => "Device tree image too big" ,
116125 Error :: InvalidElfMagicNumber => "Invalid Elf magic number" ,
117126 Error :: InvalidProgramHeaderSize => "Invalid program header size" ,
118127 Error :: InvalidProgramHeaderOffset => "Invalid program header offset" ,
@@ -128,6 +137,7 @@ impl error::Error for Error {
128137 Error :: ReadProgramHeader => "Unable to read program header" ,
129138 Error :: ReadBzImageHeader => "Unable to read bzImage header" ,
130139 Error :: ReadImageHeader => "Unable to read Image header" ,
140+ Error :: ReadDtbImage => "Unable to read DTB image" ,
131141 Error :: ReadBzImageCompressedKernel => "Unable to read bzImage compressed kernel" ,
132142 Error :: SeekKernelStart => "Unable to seek to kernel start" ,
133143 Error :: SeekElfStart => "Unable to seek to elf start" ,
@@ -137,6 +147,8 @@ impl error::Error for Error {
137147 Error :: SeekBzImageCompressedKernel => "Unable to seek bzImage compressed kernel" ,
138148 Error :: SeekImageEnd => "Unable to seek Image end" ,
139149 Error :: SeekImageHeader => "Unable to seek image header" ,
150+ Error :: SeekDtbStart => "Unable to seek DTB start" ,
151+ Error :: SeekDtbEnd => "Unable to seek DTB end" ,
140152 }
141153 }
142154}
@@ -422,6 +434,36 @@ pub fn load_cmdline<M: GuestMemory>(
422434 Ok ( ( ) )
423435}
424436
437+ /// Writes the device tree to the given memory slice.
438+ ///
439+ /// # Arguments
440+ ///
441+ /// * `guest_mem` - A u8 slice that will be partially overwritten by the device tree blob.
442+ /// * `guest_addr` - The address in `guest_mem` at which to load the device tree blob.
443+ /// * `dtb_image` - The device tree blob.
444+ #[ cfg( target_arch = "aarch64" ) ]
445+ pub fn load_dtb < F , M : GuestMemory > (
446+ guest_mem : & M ,
447+ guest_addr : GuestAddress ,
448+ dtb_image : & mut F ,
449+ ) -> Result < ( ) >
450+ where
451+ F : Read + Seek ,
452+ {
453+ let dtb_size = dtb_image
454+ . seek ( SeekFrom :: End ( 0 ) )
455+ . map_err ( |_| Error :: SeekDtbEnd ) ? as usize ;
456+ if dtb_size > 0x200000 {
457+ return Err ( Error :: DtbTooBig ) ;
458+ }
459+ dtb_image
460+ . seek ( SeekFrom :: Start ( 0 ) )
461+ . map_err ( |_| Error :: SeekDtbStart ) ?;
462+ guest_mem
463+ . read_exact_from ( guest_addr, dtb_image, dtb_size)
464+ . map_err ( |_| Error :: ReadDtbImage )
465+ }
466+
425467#[ cfg( feature = "image" ) ]
426468#[ cfg( target_arch = "aarch64" ) ]
427469/// ARM64 Image (PE) format support
0 commit comments