Device Tree Parser
A Rust library for parsing device tree files, supporting both binary Device Tree Blob (DTB) format and device tree source files. This library is designed for embedded systems and provides no_std compatibility with alloc support.
Features
- Binary DTB Parsing: Parse Device Tree Blob files with full structure validation
- Memory Reservation Support: Handle memory reservation blocks in DTB files
- Property Interpolation: Support for device tree property value parsing and interpolation
- Address Translation (v0.4.0+): Full support for device tree address translation between bus domains
- Ergonomic API (v0.3.0+): Modern Rust trait implementations for intuitive usage
Indextraits for property and child access:node["property"],node[0]IntoIteratorfor natural iteration:for child in &nodeTryFromfor type-safe value conversions:u32::try_from(&value)Displayfor pretty-printing nodes and properties
- Iterator Interface: Convenient tree traversal with
NodeIterator - No-std Compatible: Works in embedded environments with heap allocation
- Integration Tested: Validated against real QEMU-generated DTB files
Installation
Add this to your Cargo.toml:
[]
= "0.4.0"
Usage
Basic DTB Parsing
use ;
// Load your DTB data
let dtb_data = read?;
// Create a parser
let parser = new;
// Parse the header
let = parse?;
println!;
Tree Traversal
use ;
let dtb_data = read?;
let parser = new;
// Parse the device tree
let tree = parser.parse_tree?;
// Iterate through child nodes using ergonomic IntoIterator trait
for child in &tree
Ergonomic API Features (v0.3.0+)
use TryFrom;
use DeviceTreeParser;
let dtb_data = read?;
let parser = new;
let tree = parser.parse_tree?;
// Property access using Index trait
let model = &tree; // Instead of tree.find_property("model")
// Child access using Index trait
let first_child = &tree; // Access first child node
// Natural iteration over children
for child in &tree
// Type-safe conversions using TryFrom
if let Some = tree.find_property
Device Tree Address Translation (v0.4.0+)
Device trees often contain complex bus hierarchies where device addresses need to be translated to CPU-visible addresses. This library provides comprehensive address translation support:
use ;
let dtb_data = read?;
let parser = new;
let tree = parser.parse_tree?;
// Enhanced MMIO region discovery with address translation
let raw_regions = parser.discover_mmio_regions_translated?; // Device addresses
let cpu_regions = parser.discover_mmio_regions_translated?; // CPU addresses
for in raw_regions.iter.zip
// Find a specific device and translate its registers
let uart_nodes = tree.find_compatible_nodes;
for uart in uart_nodes
// Parse address/size cell specifications
for node in tree.iter_nodes
Address Translation Features
- Single-level translation:
translate_address()for direct parent-child translation - Multi-level translation:
translate_address_recursive()for complex bus hierarchies - Automatic cell parsing: Handles variable address/size cell configurations
- Range validation: Comprehensive bounds checking and overflow protection
- Error handling: Detailed error types for translation failures
- Helper methods: Convenient APIs for common translation scenarios
- Integration tested: Validated against real ARM SoC device trees
Documentation
📚 Complete Documentation Suite
-
Device Tree Introduction - New to device trees? Start here for a comprehensive introduction to concepts, terminology, and real-world examples.
-
Device Tree Specification Reference - Detailed mapping of our implementation to the official Device Tree Specification, including compliance notes and specification references.
-
Migration Guide - Upgrading from v0.1.x? Complete guide with before/after examples for the v0.2.0 zero-copy API changes.
-
Performance & Benchmarks - Comprehensive benchmark documentation and performance analysis of the zero-copy implementation.
🔗 External References
- Device Tree Specification v0.4 - Official specification
- Linux Kernel DT Documentation - Real-world usage examples
- Device Tree Compiler (dtc) - Reference tools
Building
Prerequisites
This project uses:
- Rust 2024 edition
- Nix flake for reproducible development environment (optional)
Build Commands
# Build the library
# Build with release optimizations
# Quick syntax checking
Development Environment (Nix)
If you have Nix installed, you can use the provided flake:
# Enter development shell
# Or run commands directly
Testing
Unit Tests
# Run all tests
# Run specific test
# Compile tests without running
Integration Tests
The project includes integration tests using real DTB files generated by QEMU:
# Run integration tests specifically
# Run tests with output
Test Data
Test data is located in test-data/ and includes:
virt.dtb: QEMU virtual machine device tree for testing
Benchmarks
The library includes comprehensive benchmarks to measure parsing performance:
# Run all benchmarks
# Quick benchmarks (faster, less accurate)
# Specific benchmark categories
# View HTML reports
See BENCHMARKS.md for detailed information on benchmark categories and interpretation.
Code Quality
Pre-commit Hook
A pre-commit hook is automatically set up to ensure code quality. It runs:
cargo fmt --checkto verify code formattingcargo clippyto catch common issues and enforce best practices
The hook automatically runs when you commit and will prevent commits if checks fail.
Manual Code Quality Checks
# Format code
# Run lints (if clippy is available)
# Check formatting without modifying files
Architecture
The library is structured as follows:
src/lib.rs- Main library interface and public APIsrc/dtb/- Device Tree Blob parsing implementationheader.rs- DTB header parsing and validationparser.rs- Core DTB parsing logictokens.rs- DTB token structure parsingtree.rs- Device tree node and property structuresmemory.rs- Memory reservation block handlingerror.rs- Error types and handling
src/parser.rs- General parsing utilitiessrc/integration_tests.rs- Real-world DTB parsing tests
API Reference
Main Types
DeviceTreeParser- Main parser interfaceDtbHeader- Device tree blob headerDeviceTreeNode- Individual device tree nodesProperty- Device tree propertiesPropertyValue- Typed property values with ergonomic trait implementationsMemoryReservation- Memory reservation entriesNodeIterator- Iterator for tree traversalAddressSpec- Address/size cell specifications for device tree addressingAddressRange- Address translation range mapping between bus domains
Ergonomic Traits (v0.3.0+)
Index<&str>forDeviceTreeNode- Property access:node["property_name"]Index<usize>forDeviceTreeNode- Child access:node[0]IntoIteratorfor&DeviceTreeNode- Natural iteration:for child in &nodeTryFrom<&PropertyValue>foru32,u64,Vec<u32>,&str,&[u8]- Type-safe conversionsDisplayforDeviceTreeNodeandProperty- Pretty-printingDefaultfor creating empty instances
Error Handling
The library uses DtbError for comprehensive error reporting during parsing operations.
No-std Support
This library is no_std compatible and only requires alloc for heap allocation. It's suitable for embedded systems and bare-metal environments.
Contributing
- Ensure all tests pass:
cargo test - Format code:
cargo fmt - Run lints:
cargo clippy - Follow the existing code style and patterns
- Add tests for new functionality
License
This project is licensed under the MIT License - see the LICENSE file for details.
Changelog
See CHANGELOG.md for detailed version history and release notes.