Skip to content

Commit 4b34235

Browse files
committed
loader: device tree loading support on ARM64
Signed-off-by: Qiu Wenbo <qiuwenbo@phytium.com.cn>
1 parent 0b78a30 commit 4b34235

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
@@ -59,6 +59,8 @@ pub enum Error {
5959
CommandLineCopy,
6060
/// Command line overflowed guest memory.
6161
CommandLineOverflow,
62+
/// Device tree binary too big.
63+
DtbTooBig,
6264
/// Invalid ELF magic number
6365
InvalidElfMagicNumber,
6466
/// Invalid program header size.
@@ -91,6 +93,8 @@ pub enum Error {
9193
ReadBzImageCompressedKernel,
9294
/// Unable to read Image header
9395
ReadImageHeader,
96+
/// Unable to read DTB image
97+
ReadDtbImage,
9498
/// Unable to seek to kernel start.
9599
SeekKernelStart,
96100
/// Unable to seek to ELF start.
@@ -107,6 +111,10 @@ pub enum Error {
107111
SeekImageEnd,
108112
/// Unable to seek to Image header.
109113
SeekImageHeader,
114+
/// Unable to seek to DTB start.
115+
SeekDtbStart,
116+
/// Unable to seek to DTB end.
117+
SeekDtbEnd,
110118
/// Unable to seek to note header.
111119
SeekNoteHeader,
112120
/// Unable to read note header.
@@ -126,6 +134,7 @@ impl error::Error for Error {
126134
}
127135
Error::CommandLineCopy => "Failed writing command line to guest memory",
128136
Error::CommandLineOverflow => "Command line overflowed guest memory",
137+
Error::DtbTooBig => "Device tree image too big",
129138
Error::InvalidElfMagicNumber => "Invalid Elf magic number",
130139
Error::InvalidProgramHeaderSize => "Invalid program header size",
131140
Error::InvalidProgramHeaderOffset => "Invalid program header offset",
@@ -141,6 +150,7 @@ impl error::Error for Error {
141150
Error::ReadProgramHeader => "Unable to read program header",
142151
Error::ReadBzImageHeader => "Unable to read bzImage header",
143152
Error::ReadImageHeader => "Unable to read Image header",
153+
Error::ReadDtbImage => "Unable to read DTB image",
144154
Error::ReadBzImageCompressedKernel => "Unable to read bzImage compressed kernel",
145155
Error::SeekKernelStart => "Unable to seek to kernel start",
146156
Error::SeekElfStart => "Unable to seek to elf start",
@@ -153,6 +163,8 @@ impl error::Error for Error {
153163
Error::InvalidPvhNote => "Invalid PVH note header",
154164
Error::SeekImageEnd => "Unable to seek Image end",
155165
Error::SeekImageHeader => "Unable to seek image header",
166+
Error::SeekDtbStart => "Unable to seek DTB start",
167+
Error::SeekDtbEnd => "Unable to seek DTB end",
156168
}
157169
}
158170
}
@@ -553,6 +565,36 @@ fn align_up(addr: u64, align: u64) -> usize {
553565
}
554566
}
555567

568+
/// Writes the device tree to the given memory slice.
569+
///
570+
/// # Arguments
571+
///
572+
/// * `guest_mem` - A u8 slice that will be partially overwritten by the device tree blob.
573+
/// * `guest_addr` - The address in `guest_mem` at which to load the device tree blob.
574+
/// * `dtb_image` - The device tree blob.
575+
#[cfg(target_arch = "aarch64")]
576+
pub fn load_dtb<F, M: GuestMemory>(
577+
guest_mem: &M,
578+
guest_addr: GuestAddress,
579+
dtb_image: &mut F,
580+
) -> Result<()>
581+
where
582+
F: Read + Seek,
583+
{
584+
let dtb_size = dtb_image
585+
.seek(SeekFrom::End(0))
586+
.map_err(|_| Error::SeekDtbEnd)? as usize;
587+
if dtb_size > 0x200000 {
588+
return Err(Error::DtbTooBig);
589+
}
590+
dtb_image
591+
.seek(SeekFrom::Start(0))
592+
.map_err(|_| Error::SeekDtbStart)?;
593+
guest_mem
594+
.read_exact_from(guest_addr, dtb_image, dtb_size)
595+
.map_err(|_| Error::ReadDtbImage)
596+
}
597+
556598
#[cfg(feature = "pe")]
557599
#[cfg(target_arch = "aarch64")]
558600
/// ARM64 Image (PE) format support

0 commit comments

Comments
 (0)