Skip to content

Commit 15a04eb

Browse files
committed
loader: support loading device tree on aarch64
Signed-off-by: Qiu Wenbo <qiuwenbo@phytium.com.cn>
1 parent 23338de commit 15a04eb

File tree

1 file changed

+42
-0
lines changed

1 file changed

+42
-0
lines changed

src/loader/mod.rs

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)