Skip to content

Commit 1d889dc

Browse files
committed
feat(fdt): change memory method to return iterator for multiple nodes
The memory() method now returns an iterator that can yield multiple memory nodes instead of returning just the first one found. This allows handling device trees with multiple memory regions. BREAKING CHANGE: The memory() method return type changed from Option<Memory<'a>> to impl Iterator<Item = Memory<'a>> + 'a. Callers must now use .next() or other iterator methods to access memory nodes.
1 parent a4b42e8 commit 1d889dc

File tree

3 files changed

+88
-1
lines changed

3 files changed

+88
-1
lines changed

fdt-edit/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ license = "MIT OR Apache-2.0"
1111
name = "fdt-edit"
1212
readme = "README.md"
1313
repository = "https://github.com/drivercraft/fdt-parser"
14-
version = "0.1.5"
14+
version = "0.1.6"
1515

1616
[dependencies]
1717
enum_dispatch = "0.3.13"

fdt-raw/src/fdt.rs

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,45 @@ impl<'a> Fdt<'a> {
252252
}
253253
})
254254
}
255+
256+
pub fn reserved_memory(&self) -> impl Iterator<Item = Node<'a>> + 'a {
257+
ReservedMemoryIter {
258+
node_iter: self.all_nodes(),
259+
in_reserved_memory: false,
260+
reserved_level: 0,
261+
}
262+
}
263+
}
264+
265+
struct ReservedMemoryIter<'a> {
266+
node_iter: FdtIter<'a>,
267+
in_reserved_memory: bool,
268+
reserved_level: usize,
269+
}
270+
271+
impl<'a> Iterator for ReservedMemoryIter<'a> {
272+
type Item = Node<'a>;
273+
274+
fn next(&mut self) -> Option<Self::Item> {
275+
while let Some(node) = self.node_iter.next() {
276+
if node.name() == "reserved-memory" {
277+
self.in_reserved_memory = true;
278+
self.reserved_level = node.level();
279+
continue;
280+
}
281+
282+
if self.in_reserved_memory {
283+
if node.level() <= self.reserved_level {
284+
// 已经离开 reserved-memory 节点
285+
self.in_reserved_memory = false;
286+
return None;
287+
} else {
288+
return Some(node);
289+
}
290+
}
291+
}
292+
None
293+
}
255294
}
256295

257296
impl fmt::Display for Fdt<'_> {

fdt-raw/tests/rsv.rs

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
use std::sync::Once;
2+
3+
use dtb_file::{fdt_qemu, fdt_rpi_4b};
4+
use fdt_raw::Fdt;
5+
6+
fn init_logging() {
7+
static INIT: Once = Once::new();
8+
INIT.call_once(|| {
9+
let _ = env_logger::builder()
10+
.is_test(true)
11+
.filter_level(log::LevelFilter::Trace)
12+
.try_init();
13+
});
14+
}
15+
16+
#[test]
17+
fn test_rsv1() {
18+
init_logging();
19+
20+
let raw = fdt_qemu();
21+
let fdt = Fdt::from_bytes(&raw).unwrap();
22+
23+
for node in fdt.reserved_memory() {
24+
println!("reserved memory node: {}", node.name());
25+
let ranges = node.ranges().unwrap();
26+
for range in ranges.iter() {
27+
println!(" range: {range:#x?}");
28+
}
29+
}
30+
}
31+
32+
#[test]
33+
fn test_rsv2() {
34+
init_logging();
35+
36+
let raw = fdt_rpi_4b();
37+
let fdt = Fdt::from_bytes(&raw).unwrap();
38+
39+
for node in fdt.reserved_memory() {
40+
println!("reserved memory node: {}", node.name());
41+
}
42+
43+
let want_names = ["linux,cma", "nvram@0", "nvram@1"];
44+
45+
for (i, node) in fdt.reserved_memory().enumerate() {
46+
assert_eq!(node.name(), want_names[i]);
47+
}
48+
}

0 commit comments

Comments
 (0)