@@ -32,10 +32,18 @@ pub enum Error {
32
32
SeekImageEnd ,
33
33
/// Unable to seek to Image header.
34
34
SeekImageHeader ,
35
+ /// Unable to seek to DTB start.
36
+ SeekDtbStart ,
37
+ /// Unable to seek to DTB end.
38
+ SeekDtbEnd ,
39
+ /// Device tree binary too big.
40
+ DtbTooBig ,
35
41
/// Unable to read kernel image.
36
42
ReadKernelImage ,
37
43
/// Unable to read Image header
38
44
ReadImageHeader ,
45
+ /// Unable to read DTB image
46
+ ReadDtbImage ,
39
47
/// Invalid Image binary.
40
48
InvalidImage ,
41
49
/// Invalid Image magic number.
@@ -48,8 +56,12 @@ impl error::Error for Error {
48
56
Error :: SeekImageEnd => "Unable to seek Image end" ,
49
57
Error :: SeekImageHeader => "Unable to seek image header" ,
50
58
Error :: ReadImageHeader => "Unable to read Image header" ,
59
+ Error :: ReadDtbImage => "Unable to read DTB image" ,
60
+ Error :: SeekDtbStart => "Unable to seek DTB start" ,
61
+ Error :: SeekDtbEnd => "Unable to seek DTB end" ,
51
62
Error :: InvalidImage => "Invalid Image" ,
52
63
Error :: InvalidImageMagicNumber => "Invalid Image magic number" ,
64
+ Error :: DtbTooBig => "Device tree image too big" ,
53
65
Error :: ReadKernelImage => "Unable to read kernel image" ,
54
66
}
55
67
}
@@ -147,6 +159,36 @@ impl KernelLoader for PE {
147
159
}
148
160
}
149
161
162
+ /// Writes the device tree to the given memory slice.
163
+ ///
164
+ /// # Arguments
165
+ ///
166
+ /// * `guest_mem` - A u8 slice that will be partially overwritten by the device tree blob.
167
+ /// * `guest_addr` - The address in `guest_mem` at which to load the device tree blob.
168
+ /// * `dtb_image` - The device tree blob.
169
+ #[ cfg( target_arch = "aarch64" ) ]
170
+ pub fn load_dtb < F , M : GuestMemory > (
171
+ guest_mem : & M ,
172
+ guest_addr : GuestAddress ,
173
+ dtb_image : & mut F ,
174
+ ) -> Result < ( ) >
175
+ where
176
+ F : Read + Seek ,
177
+ {
178
+ let dtb_size = dtb_image
179
+ . seek ( SeekFrom :: End ( 0 ) )
180
+ . map_err ( |_| Error :: SeekDtbEnd ) ? as usize ;
181
+ if dtb_size > 0x200000 {
182
+ return Err ( Error :: DtbTooBig . into ( ) ) ;
183
+ }
184
+ dtb_image
185
+ . seek ( SeekFrom :: Start ( 0 ) )
186
+ . map_err ( |_| Error :: SeekDtbStart ) ?;
187
+ guest_mem
188
+ . read_exact_from ( guest_addr, dtb_image, dtb_size)
189
+ . map_err ( |_| Error :: ReadDtbImage . into ( ) )
190
+ }
191
+
150
192
#[ cfg( test) ]
151
193
mod tests {
152
194
use super :: * ;
0 commit comments