| Crates.io | fdt-edit |
| lib.rs | fdt-edit |
| version | 0.1.5 |
| created_at | 2025-12-07 09:58:51.806405+00 |
| updated_at | 2025-12-19 04:53:44.368903+00 |
| description | A high-level library for creating, editing, and encoding Flattened Device Tree (FDT) structures |
| homepage | https://github.com/drivercraft/fdt-parser |
| repository | https://github.com/drivercraft/fdt-parser |
| max_upload_size | |
| id | 1971372 |
| size | 130,442 |
A high-level Rust library for creating, editing, and encoding Flattened Device Tree (FDT) structures.
fdt-edit is a feature-rich device tree manipulation library built on top of fdt-raw. It provides comprehensive functionality for creating new device trees from scratch, modifying existing device trees, and encoding the edited device trees into standard DTB format.
no_std compatible: Suitable for embedded environmentsAn editable device tree container that:
Supports multiple specialized node types:
use fdt_edit::Fdt;
// Parse existing DTB from bytes
let raw_data = include_bytes!("path/to/device-tree.dtb");
let fdt = Fdt::from_bytes(&raw_data)?;
// Access nodes by path
let node = fdt.get_by_path("/chosen");
if let Some(chosen) = node {
println!("Found chosen node: {}", chosen.name());
}
// Encode back to DTB format
let dtb_data = fdt.encode();
std::fs::write("output.dtb", dtb_data.as_bytes())?;
use fdt_edit::{Fdt, NodeKind};
let fdt = Fdt::from_bytes(&dtb_data)?;
// Iterate through all nodes
for node in fdt.all_nodes() {
println!("Node: {} at path {}", node.name(), node.path());
// Match specialized node types
match node.as_ref() {
NodeKind::Memory(mem) => {
println!(" Memory node with regions:");
for region in mem.regions() {
println!(" address=0x{:x}, size=0x{:x}", region.address, region.size);
}
}
NodeKind::Clock(clock) => {
println!(" Clock node: {} (#clock-cells={})", clock.name(), clock.clock_cells);
}
NodeKind::Pci(pci) => {
if let Some(range) = pci.bus_range() {
println!(" PCI bus range: {:?}", range);
}
}
_ => {
println!(" Generic node");
}
}
}
// Find nodes by path pattern
let virtio_nodes: Vec<_> = fdt.find_by_path("/virtio_mmio").collect();
println!("Found {} virtio_mmio nodes", virtio_nodes.len());
use fdt_edit::{Fdt, Node};
let mut fdt = Fdt::from_bytes(&dtb_data)?;
// Create new node manually
let mut new_node = Node::new("test-device@12340000");
// Add properties (API in development)
// new_node.add_property("compatible", &["vendor,test-device"]);
// new_node.add_property("reg", &[0x12340000u64, 0x1000u64]);
// Add to root node
fdt.root.add_child(new_node);
// Remove existing node
if fdt.get_by_path("/psci").is_some() {
let removed = fdt.remove_node("/psci")?;
println!("Removed psci node: {}", removed.unwrap().name());
}
// Save the modified device tree
let modified_dtb = fdt.encode();
std::fs::write("modified.dtb", modified_dtb.as_bytes())?;
use fdt_edit::{Fdt, NodeKind};
let fdt = Fdt::from_bytes(&dtb_data)?;
// Find and work with memory nodes
for node in fdt.all_nodes() {
if let NodeKind::Memory(mem) = node.as_ref() {
let regions = mem.regions();
if !regions.is_empty() {
println!("Memory node '{}' has {} regions:", mem.name(), regions.len());
for (i, region) in regions.iter().enumerate() {
println!(" Region {}: 0x{:x}-0x{:x}", i, region.address, region.address + region.size);
}
}
}
}
// Find clock nodes
let mut clock_count = 0;
for node in fdt.all_nodes() {
if let NodeKind::Clock(clock) = node.as_ref() {
clock_count += 1;
println!("Clock {}: cells={}, output-names={:?}",
clock.name(),
clock.clock_cells,
clock.clock_output_names);
}
}
use fdt_edit::Fdt;
let fdt = Fdt::from_bytes(&dtb_data)?;
// Display as DTS format (including memory reservations)
println!("{}", fdt);
// Output will show:
// /dts-v1/;
// /memreserve/ 0x80000000 0x100000;
// / {
// #address-cells = <0x2>;
// #size-cells = <0x2>;
// compatible = "qemu,arm64";
// ...
// };
This library is under active development. Currently supported features:
fdt-raw - Low-level FDT parsing librarylog = "0.4" - Logging supportenum_dispatch = "0.3.13" - Enum dispatch optimizationdtb-file - Test dataenv_logger = "0.11" - Logger implementationThe library includes comprehensive tests that verify round-trip compatibility:
cargo test
The main test (test_parse_and_rebuild) ensures that:
dtcThis project is licensed under open source licenses. Please see the LICENSE file in the project root for specific license types.
Issues and Pull Requests are welcome. Please ensure:
cargo fmt)cargo test)cargo clippy)More usage examples can be found in the source code test files, particularly in tests/edit.rs.