Skip to content

Commit da4de5e

Browse files
committed
Add a feature to extract image buffers to files in a provided output directory.
1 parent 52d933f commit da4de5e

File tree

1 file changed

+37
-2
lines changed

1 file changed

+37
-2
lines changed

src/main.rs

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@ extern crate memmap;
55
use memmap::MmapOptions;
66

77
use std::fs::File;
8+
use std::io::Write;
89
use std::mem::size_of;
10+
use std::path::PathBuf;
911
use std::ptr::read_unaligned;
1012
use std::slice;
1113

@@ -110,7 +112,32 @@ impl FdtDumper {
110112
Ok(())
111113
}
112114

115+
fn extract_images(&mut self, node: &DevTreeIndexNode) {
116+
let image_path = self.image_path.take().unwrap();
117+
118+
std::fs::create_dir_all(image_path.as_path()).expect("image path should be creatable");
119+
120+
for child in node.children() {
121+
match child.name() {
122+
Ok(image_name) => match child.props().find(|p| p.name() == Ok("data")) {
123+
Some(data) => {
124+
let mut path = image_path.clone();
125+
path.push(image_name);
126+
let mut file = File::create(path).expect("image file should be creatable");
127+
file.write_all(data.propbuf())
128+
.expect("image file should be writable");
129+
}
130+
None => eprintln!("no data found for image `{:?}`", image_name),
131+
},
132+
Err(err) => eprintln!("error parsing image: {:?}", err),
133+
}
134+
}
135+
}
136+
113137
fn dump_level(&mut self, node: &DevTreeIndexNode) -> DevTreeResult<()> {
138+
if self.image_path.is_some() && node.name() == Ok("images") {
139+
self.extract_images(node);
140+
}
114141
self.dump_node(node)?;
115142
self.indent += 1;
116143
for prop in node.props() {
@@ -152,12 +179,13 @@ impl FdtDumper {
152179
self.dump.push('\n');
153180
}
154181

155-
pub(crate) fn dump_tree(buf: &[u8]) -> DevTreeResult<()> {
182+
pub(crate) fn dump_tree(buf: &[u8], image_path: Option<PathBuf>) -> DevTreeResult<()> {
156183
let (_vec, index) = unsafe { allocate_index(buf)? };
157184

158185
let mut dumper = FdtDumper {
159186
dump: String::new(),
160187
indent: 0,
188+
image_path,
161189
};
162190

163191
dumper.dump_metadata(&index);
@@ -170,6 +198,7 @@ impl FdtDumper {
170198
struct FdtDumper {
171199
dump: String,
172200
indent: usize,
201+
image_path: Option<PathBuf>,
173202
}
174203

175204
fn main() {
@@ -181,9 +210,15 @@ fn main() {
181210
.required(true)
182211
.help("Path to dtb file"),
183212
)
213+
.arg(
214+
clap::Arg::new("extract-images")
215+
.short('e')
216+
.help("Output extracted images to the provided path"),
217+
)
184218
.get_matches();
185219

186220
let fname = args.get_one::<String>("dtb-file").unwrap();
221+
let image_path = args.get_one::<String>("extract-images").map(PathBuf::from);
187222

188223
let file = File::open(fname).unwrap_or_else(|_| panic!("Unable to open {}", fname));
189224

@@ -195,5 +230,5 @@ fn main() {
195230

196231
let slice = unsafe { slice::from_raw_parts(mmap.as_ptr(), mmap.len()) };
197232

198-
FdtDumper::dump_tree(slice).unwrap();
233+
FdtDumper::dump_tree(slice, image_path).unwrap();
199234
}

0 commit comments

Comments
 (0)