fdt_raw/
fdt.rs

1use core::fmt;
2
3use crate::{
4    Chosen, FdtError, Memory, MemoryReservation, Node, data::Bytes, header::Header, iter::FdtIter,
5};
6
7/// Memory reservation block iterator
8pub struct MemoryReservationIter<'a> {
9    data: &'a [u8],
10    offset: usize,
11}
12
13impl<'a> Iterator for MemoryReservationIter<'a> {
14    type Item = MemoryReservation;
15
16    fn next(&mut self) -> Option<Self::Item> {
17        // 确保我们有足够的数据来读取地址和大小(各8字节)
18        if self.offset + 16 > self.data.len() {
19            return None;
20        }
21
22        // 读取地址(8字节,大端序)
23        let address_bytes = &self.data[self.offset..self.offset + 8];
24        let address = u64::from_be_bytes(address_bytes.try_into().unwrap());
25        self.offset += 8;
26
27        // 读取大小(8字节,大端序)
28        let size_bytes = &self.data[self.offset..self.offset + 8];
29        let size = u64::from_be_bytes(size_bytes.try_into().unwrap());
30        self.offset += 8;
31
32        // 检查是否到达终止符(地址和大小都为0)
33        if address == 0 && size == 0 {
34            return None;
35        }
36
37        Some(MemoryReservation { address, size })
38    }
39}
40
41/// 写入缩进(使用空格)
42fn write_indent(f: &mut fmt::Formatter<'_>, count: usize, ch: &str) -> fmt::Result {
43    for _ in 0..count {
44        write!(f, "{}", ch)?;
45    }
46    Ok(())
47}
48
49#[derive(Clone)]
50pub struct Fdt<'a> {
51    header: Header,
52    pub(crate) data: Bytes<'a>,
53}
54
55impl<'a> Fdt<'a> {
56    /// Create a new `Fdt` from byte slice.
57    pub fn from_bytes(data: &'a [u8]) -> Result<Fdt<'a>, FdtError> {
58        let header = Header::from_bytes(data)?;
59        if data.len() < header.totalsize as usize {
60            return Err(FdtError::BufferTooSmall {
61                pos: header.totalsize as usize,
62            });
63        }
64        let buffer = Bytes::new(data);
65
66        Ok(Fdt {
67            header,
68            data: buffer,
69        })
70    }
71
72    /// Create a new `Fdt` from a raw pointer and size in bytes.
73    ///
74    /// # Safety
75    ///
76    /// The caller must ensure that the pointer is valid and points to a
77    /// memory region of at least `size` bytes that contains a valid device tree
78    /// blob.
79    pub unsafe fn from_ptr(ptr: *mut u8) -> Result<Fdt<'a>, FdtError> {
80        let header = unsafe { Header::from_ptr(ptr)? };
81
82        let data_slice = unsafe { core::slice::from_raw_parts(ptr, header.totalsize as _) };
83        let data = Bytes::new(data_slice);
84
85        Ok(Fdt { header, data })
86    }
87
88    pub fn header(&self) -> &Header {
89        &self.header
90    }
91
92    pub fn as_slice(&self) -> &'a [u8] {
93        self.data.as_slice()
94    }
95
96    pub fn all_nodes(&self) -> FdtIter<'a> {
97        FdtIter::new(self.clone())
98    }
99
100    /// Get an iterator over memory reservation entries
101    pub fn memory_reservations(&self) -> MemoryReservationIter<'a> {
102        MemoryReservationIter {
103            data: self.data.as_slice(),
104            offset: self.header.off_mem_rsvmap as usize,
105        }
106    }
107
108    pub fn chosen(&self) -> Option<Chosen<'a>> {
109        for node in self.all_nodes() {
110            if let Node::Chosen(c) = node {
111                return Some(c);
112            }
113        }
114        None
115    }
116
117    pub fn memory(&self) -> Option<Memory<'a>> {
118        for node in self.all_nodes() {
119            if let Node::Memory(m) = node {
120                return Some(m);
121            }
122        }
123        None
124    }
125}
126
127impl fmt::Display for Fdt<'_> {
128    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
129        writeln!(f, "/dts-v1/;")?;
130        writeln!(f)?;
131
132        let mut prev_level = 0;
133
134        for node in self.all_nodes() {
135            let level = node.level();
136
137            // 关闭前一层级的节点
138            while prev_level > level {
139                prev_level -= 1;
140                write_indent(f, prev_level, "    ")?;
141                writeln!(f, "}};\n")?;
142            }
143
144            write_indent(f, level, "    ")?;
145            let name = if node.name().is_empty() {
146                "/"
147            } else {
148                node.name()
149            };
150
151            // 打印节点头部
152            writeln!(f, "{} {{", name)?;
153
154            // 打印属性
155            for prop in node.properties() {
156                write_indent(f, level + 1, "    ")?;
157                writeln!(f, "{};", prop)?;
158            }
159
160            prev_level = level + 1;
161        }
162
163        // 关闭剩余的节点
164        while prev_level > 0 {
165            prev_level -= 1;
166            write_indent(f, prev_level, "    ")?;
167            writeln!(f, "}};\n")?;
168        }
169
170        Ok(())
171    }
172}
173
174impl fmt::Debug for Fdt<'_> {
175    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
176        writeln!(f, "Fdt {{")?;
177        writeln!(f, "\theader: {:?}", self.header)?;
178        writeln!(f, "\tnodes:")?;
179
180        for node in self.all_nodes() {
181            let level = node.level();
182            // 基础缩进 2 个 tab,每层再加 1 个 tab
183            write_indent(f, level + 2, "\t")?;
184
185            let name = if node.name().is_empty() {
186                "/"
187            } else {
188                node.name()
189            };
190
191            // 打印节点名称和基本信息
192            writeln!(
193                f,
194                "[{}] address_cells={}, size_cells={}",
195                name, node.address_cells, node.size_cells
196            )?;
197
198            // 打印属性
199            for prop in node.properties() {
200                write_indent(f, level + 3, "\t")?;
201                if let Some(v) = prop.as_address_cells() {
202                    writeln!(f, "#address-cells: {}", v)?;
203                } else if let Some(v) = prop.as_size_cells() {
204                    writeln!(f, "#size-cells: {}", v)?;
205                } else if let Some(v) = prop.as_interrupt_cells() {
206                    writeln!(f, "#interrupt-cells: {}", v)?;
207                } else if let Some(s) = prop.as_status() {
208                    writeln!(f, "status: {:?}", s)?;
209                } else if let Some(p) = prop.as_phandle() {
210                    writeln!(f, "phandle: {}", p)?;
211                } else {
212                    // 默认处理未知属性
213                    if prop.is_empty() {
214                        writeln!(f, "{}", prop.name())?;
215                    } else if let Some(s) = prop.as_str() {
216                        writeln!(f, "{}: \"{}\"", prop.name(), s)?;
217                    } else if prop.len() == 4 {
218                        let v = u32::from_be_bytes(prop.data().as_slice().try_into().unwrap());
219                        writeln!(f, "{}: {:#x}", prop.name(), v)?;
220                    } else {
221                        writeln!(f, "{}: <{} bytes>", prop.name(), prop.len())?;
222                    }
223                }
224            }
225        }
226
227        writeln!(f, "}}")
228    }
229}
230
231#[cfg(test)]
232mod tests {
233    use super::*;
234    use heapless::Vec;
235
236    #[test]
237    fn test_memory_reservation_iterator() {
238        // 创建一个简单的测试数据:一个内存保留条目 + 终止符
239        let mut test_data = [0u8; 32];
240
241        // 地址: 0x80000000, 大小: 0x10000000 (256MB)
242        test_data[0..8].copy_from_slice(&0x80000000u64.to_be_bytes());
243        test_data[8..16].copy_from_slice(&0x10000000u64.to_be_bytes());
244        // 终止符: address=0, size=0
245        test_data[16..24].copy_from_slice(&0u64.to_be_bytes());
246        test_data[24..32].copy_from_slice(&0u64.to_be_bytes());
247
248        let iter = MemoryReservationIter {
249            data: &test_data,
250            offset: 0,
251        };
252
253        let reservations: Vec<MemoryReservation, 4> = iter.collect();
254        assert_eq!(reservations.len(), 1);
255        assert_eq!(reservations[0].address, 0x80000000);
256        assert_eq!(reservations[0].size, 0x10000000);
257    }
258
259    #[test]
260    fn test_empty_memory_reservation_iterator() {
261        // 只有终止符
262        let mut test_data = [0u8; 16];
263        test_data[0..8].copy_from_slice(&0u64.to_be_bytes());
264        test_data[8..16].copy_from_slice(&0u64.to_be_bytes());
265
266        let iter = MemoryReservationIter {
267            data: &test_data,
268            offset: 0,
269        };
270
271        let reservations: Vec<MemoryReservation, 4> = iter.collect();
272        assert_eq!(reservations.len(), 0);
273    }
274}