Skip to content

Commit ab5cf74

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

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
@@ -61,6 +61,8 @@ pub enum Error {
6161
CommandLineCopy,
6262
/// Command line overflowed guest memory.
6363
CommandLineOverflow,
64+
/// Device tree binary too big.
65+
DtbTooBig,
6466
/// Invalid ELF magic number
6567
InvalidElfMagicNumber,
6668
/// Invalid program header size.
@@ -93,6 +95,8 @@ pub enum Error {
9395
ReadBzImageCompressedKernel,
9496
/// Unable to read Image header
9597
ReadImageHeader,
98+
/// Unable to read DTB image
99+
ReadDtbImage,
96100
/// Unable to seek to kernel start.
97101
SeekKernelStart,
98102
/// Unable to seek to ELF start.
@@ -109,6 +113,10 @@ pub enum Error {
109113
SeekImageEnd,
110114
/// Unable to seek to Image header.
111115
SeekImageHeader,
116+
/// Unable to seek to DTB start.
117+
SeekDtbStart,
118+
/// Unable to seek to DTB end.
119+
SeekDtbEnd,
112120
/// Unable to seek to note header.
113121
SeekNoteHeader,
114122
/// Unable to read note header.
@@ -128,6 +136,7 @@ impl error::Error for Error {
128136
}
129137
Error::CommandLineCopy => "Failed writing command line to guest memory",
130138
Error::CommandLineOverflow => "Command line overflowed guest memory",
139+
Error::DtbTooBig => "Device tree image too big",
131140
Error::InvalidElfMagicNumber => "Invalid Elf magic number",
132141
Error::InvalidProgramHeaderSize => "Invalid program header size",
133142
Error::InvalidProgramHeaderOffset => "Invalid program header offset",
@@ -143,6 +152,7 @@ impl error::Error for Error {
143152
Error::ReadProgramHeader => "Unable to read program header",
144153
Error::ReadBzImageHeader => "Unable to read bzImage header",
145154
Error::ReadImageHeader => "Unable to read Image header",
155+
Error::ReadDtbImage => "Unable to read DTB image",
146156
Error::ReadBzImageCompressedKernel => "Unable to read bzImage compressed kernel",
147157
Error::SeekKernelStart => "Unable to seek to kernel start",
148158
Error::SeekElfStart => "Unable to seek to elf start",
@@ -155,6 +165,8 @@ impl error::Error for Error {
155165
Error::InvalidPvhNote => "Invalid PVH note header",
156166
Error::SeekImageEnd => "Unable to seek Image end",
157167
Error::SeekImageHeader => "Unable to seek image header",
168+
Error::SeekDtbStart => "Unable to seek DTB start",
169+
Error::SeekDtbEnd => "Unable to seek DTB end",
158170
}
159171
}
160172
}
@@ -538,6 +550,36 @@ fn align_up(addr: u64, align: u64) -> usize {
538550
}
539551
}
540552

553+
/// Writes the device tree to the given memory slice.
554+
///
555+
/// # Arguments
556+
///
557+
/// * `guest_mem` - A u8 slice that will be partially overwritten by the device tree blob.
558+
/// * `guest_addr` - The address in `guest_mem` at which to load the device tree blob.
559+
/// * `dtb_image` - The device tree blob.
560+
#[cfg(target_arch = "aarch64")]
561+
pub fn load_dtb<F, M: GuestMemory>(
562+
guest_mem: &M,
563+
guest_addr: GuestAddress,
564+
dtb_image: &mut F,
565+
) -> Result<()>
566+
where
567+
F: Read + Seek,
568+
{
569+
let dtb_size = dtb_image
570+
.seek(SeekFrom::End(0))
571+
.map_err(|_| Error::SeekDtbEnd)? as usize;
572+
if dtb_size > 0x200000 {
573+
return Err(Error::DtbTooBig);
574+
}
575+
dtb_image
576+
.seek(SeekFrom::Start(0))
577+
.map_err(|_| Error::SeekDtbStart)?;
578+
guest_mem
579+
.read_exact_from(guest_addr, dtb_image, dtb_size)
580+
.map_err(|_| Error::ReadDtbImage)
581+
}
582+
541583
#[cfg(feature = "image")]
542584
#[cfg(target_arch = "aarch64")]
543585
/// ARM64 Image (PE) format support

0 commit comments

Comments
 (0)