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
Index
traits for property and child access:node["property"]
,node[0]
IntoIterator
for natural iteration:for child in &node
TryFrom
for type-safe value conversions:u32::try_from(&value)
Display
for 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 --check
to verify code formattingcargo clippy
to 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]
IntoIterator
for&DeviceTreeNode
- Natural iteration:for child in &node
TryFrom<&PropertyValue>
foru32
,u64
,Vec<u32>
,&str
,&[u8]
- Type-safe conversionsDisplay
forDeviceTreeNode
andProperty
- Pretty-printingDefault
for 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.