Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 29 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,39 @@ jobs:
- name: Check code format
run: cargo fmt --all -- --check
- name: Clippy
run: cargo clippy --manifest-path ./fdt-parser/Cargo.toml --target ${{ matrix.targets }} --all-features -- -A clippy::new_without_default
run: cargo clippy --manifest-path ./fdt-parser/Cargo.toml --target ${{ matrix.targets }} --all-features -- -A clippy::new_without_default
- name: Build
run: cargo build -p fdt-parser --target ${{ matrix.targets }} --all-features
- name: Install dtc
if: ${{ matrix.targets == 'x86_64-unknown-linux-gnu' }}
run: sudo apt-get install device-tree-compiler
- name: Unit test
if: ${{ matrix.targets == 'x86_64-unknown-linux-gnu' }}
run: cargo test --target ${{ matrix.targets }} -- --nocapture
run: cargo test --target ${{ matrix.targets }} -- --nocapture

doc:
runs-on: ubuntu-latest
strategy:
fail-fast: false
permissions:
contents: write
env:
default-branch: ${{ format('refs/heads/{0}', github.event.repository.default_branch) }}
RUSTDOCFLAGS: -D rustdoc::broken_intra_doc_links -D missing-docs
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@nightly
with:
toolchain: nightly-2025-12-12
- name: Build docs
continue-on-error: ${{ github.ref != env.default-branch && github.event_name != 'pull_request' }}
run: |
cargo doc --no-deps --all-features
printf '<meta http-equiv="refresh" content="0;url=%s/index.html">' $(cargo tree | head -1 | cut -d' ' -f1) > target/doc/index.html
- name: Deploy to Github Pages
if: ${{ github.ref == env.default-branch }}
uses: JamesIves/github-pages-deploy-action@v4
with:
single-commit: true
branch: gh-pages
folder: target/doc
2 changes: 1 addition & 1 deletion dtb-file/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "dtb-file"
version = "0.1.0"
version = "0.1.1"
edition = "2024"
publish = false

Expand Down
20 changes: 20 additions & 0 deletions dtb-file/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
//! Test data and sample Device Tree Blob (DTB) files for the FDT parser.
//!
//! This crate provides embedded DTB files from various hardware platforms
//! for testing purposes, along with a helper struct to ensure 4-byte alignment
//! required by the FDT specification.

use core::ops::Deref;

const TEST_RPI_4_FDT: &[u8] = include_bytes!("dtb/bcm2711-rpi-4-b.dtb");
Expand All @@ -6,32 +12,43 @@ const TEST_QEMU_FDT: &[u8] = include_bytes!("dtb/qemu_pci.dtb");
const TEST_3568_FDT: &[u8] = include_bytes!("dtb/rk3568-firefly-roc-pc-se.dtb");
const TEST_RESERVE_FDT: &[u8] = include_bytes!("dtb/test_reserve.dtb");

/// Returns the FDT data for Raspberry Pi 4 Model B.
pub fn fdt_rpi_4b() -> Align4Vec {
Align4Vec::new(TEST_RPI_4_FDT)
}

/// Returns the FDT data for Phytium platform.
pub fn fdt_phytium() -> Align4Vec {
Align4Vec::new(TEST_PHYTIUM_FDT)
}

/// Returns the FDT data for QEMU with PCI support.
pub fn fdt_qemu() -> Align4Vec {
Align4Vec::new(TEST_QEMU_FDT)
}

/// Returns the FDT data for RK3568 Firefly ROC PC SE.
pub fn fdt_3568() -> Align4Vec {
Align4Vec::new(TEST_3568_FDT)
}

/// Returns the FDT data with reserved memory entries for testing.
pub fn fdt_reserve() -> Align4Vec {
Align4Vec::new(TEST_RESERVE_FDT)
}

/// A 4-byte aligned buffer for FDT data.
///
/// The Device Tree Blob specification requires that the FDT structure
/// be 4-byte aligned in memory. This wrapper allocates aligned memory
/// and provides raw pointer access for FDT parsing.
pub struct Align4Vec {
ptr: *mut u8,
size: usize,
}

impl Align4Vec {
/// Creates a new 4-byte aligned buffer from the provided data.
pub fn new(data: &[u8]) -> Self {
let size = data.len();
let layout = core::alloc::Layout::from_size_align(size, 4).unwrap();
Expand All @@ -40,19 +57,22 @@ impl Align4Vec {
Align4Vec { ptr, size }
}

/// Returns a raw pointer to the aligned buffer.
pub fn ptr(&self) -> *mut u8 {
self.ptr
}
}

impl Drop for Align4Vec {
/// Deallocates the aligned buffer when the `Align4Vec` is dropped.
fn drop(&mut self) {
let layout = core::alloc::Layout::from_size_align(self.size, 4).unwrap();
unsafe { std::alloc::dealloc(self.ptr, layout) };
}
}

impl Deref for Align4Vec {
/// Allows treating `Align4Vec` as a byte slice for convenient data access.
type Target = [u8];

fn deref(&self) -> &Self::Target {
Expand Down
4 changes: 2 additions & 2 deletions dtb-tool/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
[package]
name = "dtb-tool"
version = "0.1.0"
version = "0.1.1"
authors = ["Zhourui <zrufo747@outlook.com>"]
edition = "2021"
repository = "https://github.com/qclic/fdt-parser"
repository = "https://github.com/drivercraft/fdt-parser"
documentation = "https://docs.rs/fdt-parser"
license = "MPL-2.0"
description = "A pure-Rust `#![no_std]` crate for parsing FDT"
Expand Down
12 changes: 9 additions & 3 deletions dtb-tool/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,22 @@
//! Command-line tool for inspecting and converting Device Tree Blob (DTB) files.
//!
//! This tool reads a DTB file, parses it using the `fdt_parser` library,
//! and outputs a human-readable text representation showing the device tree
//! structure including nodes, compatible strings, and memory reservations.

use clap::Parser;
use fdt_parser::Fdt;
use std::io::Write;

/// Simple DTB parser
/// Command-line arguments for the DTB parser tool.
#[derive(Parser, Debug)]
#[command(version, about, long_about = None)]
struct Args {
/// dtb file path
/// Path to the input DTB file
#[arg(short, long)]
input: String,

/// output file path
/// Path to the output text file
#[arg(short, long)]
output: String,
}
Expand Down
24 changes: 12 additions & 12 deletions example_all_nodes.rs
Original file line number Diff line number Diff line change
@@ -1,59 +1,59 @@
// 示例:使用 all_nodes 函数
// Example: Using the all_nodes function
extern crate alloc;
use alloc::{string::String, vec::Vec};

use fdt_edit::{Fdt, Node, NodeRef};

fn main() {
// 创建一个示例 FDT
// Create an example FDT
let mut fdt = Fdt::new();

// 添加一些示例节点
// Add some example nodes
{
let root = &mut fdt.root;
let mut soc = Node::new_raw("soc");
let mut uart = Node::new_raw("uart@4000");
let mut gpio = Node::new_raw("gpio@5000");
let mut led = Node::new_raw("led");

// 设置属性
// Set properties
uart.add_property(fdt_edit::Property::new_str("compatible", "vendor,uart"));
gpio.add_property(fdt_edit::Property::new_str("compatible", "vendor,gpio"));
led.add_property(fdt_edit::Property::new_str("compatible", "vendor,led"));

// 构建树结构
// Build the tree structure
gpio.add_child(led);
soc.add_child(uart);
soc.add_child(gpio);
root.add_child(soc);
}

// 使用 all_nodes 获取所有节点
// Use all_nodes to get all nodes
let all_nodes: Vec<NodeRef> = fdt.all_nodes().collect();

println!("FDT 中所有节点 (深度优先遍历):");
println!("All nodes in FDT (depth-first traversal):");
for (i, node_ref) in all_nodes.iter().enumerate() {
println!(
"{}: 节点 '{}', 路径: '{}', 深度: {}",
"{}: Node '{}', Path: '{}', Depth: {}",
i + 1,
node_ref.node.name(),
node_ref.context.current_path,
node_ref.context.depth
);

// 显示节点的 compatible 属性
// Display the node's compatible property
let compatibles: Vec<&str> = node_ref.compatibles();
if !compatibles.is_empty() {
println!(" Compatible: {:?}", compatibles);
}
}

// 使用 find_compatible 查找特定节点
// Use find_compatible to find specific nodes
let uart_nodes = fdt.find_compatible(&["vendor,uart"]);
println!("\n找到 UART 节点:");
println!("\nFound UART nodes:");
for node_ref in uart_nodes {
println!(
" 节点: {}, 完整路径: '{}'",
" Node: {}, Full path: '{}'",
node_ref.node.name(),
node_ref.context.current_path
);
Expand Down
2 changes: 1 addition & 1 deletion fdt-edit/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ license = "MIT OR Apache-2.0"
name = "fdt-edit"
readme = "README.md"
repository = "https://github.com/drivercraft/fdt-parser"
version = "0.1.6"
version = "0.1.7"

[dependencies]
enum_dispatch = "0.3.13"
Expand Down
15 changes: 8 additions & 7 deletions fdt-edit/examples/fdt_debug_demo.rs
Original file line number Diff line number Diff line change
@@ -1,24 +1,25 @@
//! FDT 深度调试演示
//! FDT deep debug demonstration
//!
//! 演示如何使用新的深度调试功能来遍历和打印设备树的所有节点
//! Demonstrates how to use the new deep debug functionality to traverse
//! and print all nodes in the device tree.

use dtb_file::fdt_rpi_4b;
use fdt_edit::Fdt;

fn main() -> Result<(), Box<dyn std::error::Error>> {
env_logger::init();

// RPI 4B DTB 数据创建 FDT
// Create FDT from RPI 4B DTB data
let raw_data = fdt_rpi_4b();
let fdt = Fdt::from_bytes(&raw_data)?;

println!("=== FDT 基本调试信息 ===");
// 基本调试格式(紧凑)
println!("=== FDT Basic Debug Information ===");
// Basic debug format (compact)
println!("{:?}", fdt);
println!();

println!("=== FDT 深度调试信息 ===");
// 深度调试格式(遍历所有节点)
println!("=== FDT Deep Debug Information ===");
// Deep debug format (traverses all nodes)
println!("{:#?}", fdt);

Ok(())
Expand Down
Loading