|
@@ -2,6 +2,53 @@
|
|
// v. 2.0. If a copy of the MPL was not distributed with this file, You can
|
|
// v. 2.0. If a copy of the MPL was not distributed with this file, You can
|
|
// obtain one at https://mozilla.org/MPL/2.0/.
|
|
// obtain one at https://mozilla.org/MPL/2.0/.
|
|
|
|
|
|
|
|
+//! # `fdt`
|
|
|
|
+//!
|
|
|
|
+//! A pure-Rust `#![no_std]` crate for parsing Flattened Devicetrees, with the goal of having a
|
|
|
|
+//! very ergonomic and idiomatic API.
|
|
|
|
+//!
|
|
|
|
+//! [](https://crates.io/crates/fdt) [](https://docs.rs/fdt) 
|
|
|
|
+//!
|
|
|
|
+//! ## License
|
|
|
|
+//!
|
|
|
|
+//! This crate is licensed under the Mozilla Public License 2.0 (see the LICENSE file).
|
|
|
|
+//!
|
|
|
|
+//! ## Example
|
|
|
|
+//!
|
|
|
|
+//! ```rust,no_run
|
|
|
|
+//! static MY_FDT: &[u8] = include_bytes!("../test.dtb");
|
|
|
|
+//!
|
|
|
|
+//! fn main() {
|
|
|
|
+//! let fdt = fdt::Fdt::new(MY_FDT).unwrap();
|
|
|
|
+//!
|
|
|
|
+//! println!("This is a devicetree representation of a {}", fdt.root().model());
|
|
|
|
+//! println!("...which is compatible with at least: {}", fdt.root().compatible().first());
|
|
|
|
+//! println!("...and has {} CPU(s)", fdt.cpus().count());
|
|
|
|
+//! println!(
|
|
|
|
+//! "...and has at least one memory location at: {:#X}\n",
|
|
|
|
+//! fdt.memory().regions().next().unwrap().starting_address as usize
|
|
|
|
+//! );
|
|
|
|
+//!
|
|
|
|
+//! let chosen = fdt.chosen();
|
|
|
|
+//! if let Some(bootargs) = chosen.bootargs() {
|
|
|
|
+//! println!("The bootargs are: {:?}", bootargs);
|
|
|
|
+//! }
|
|
|
|
+//!
|
|
|
|
+//! if let Some(stdout) = chosen.stdout() {
|
|
|
|
+//! println!("It would write stdout to: {}", stdout.name);
|
|
|
|
+//! }
|
|
|
|
+//!
|
|
|
|
+//! let soc = fdt.find_node("/soc");
|
|
|
|
+//! println!("Does it have a `/soc` node? {}", if soc.is_some() { "yes" } else { "no" });
|
|
|
|
+//! if let Some(soc) = soc {
|
|
|
|
+//! println!("...and it has the following children:");
|
|
|
|
+//! for child in soc.children() {
|
|
|
|
+//! println!(" {}", child.name);
|
|
|
|
+//! }
|
|
|
|
+//! }
|
|
|
|
+//! }
|
|
|
|
+//! ```
|
|
|
|
+
|
|
#![no_std]
|
|
#![no_std]
|
|
|
|
|
|
#[cfg(test)]
|
|
#[cfg(test)]
|
|
@@ -109,6 +156,9 @@ impl FdtHeader {
|
|
|
|
|
|
impl<'a> Fdt<'a> {
|
|
impl<'a> Fdt<'a> {
|
|
/// Construct a new `Fdt` from a byte buffer
|
|
/// Construct a new `Fdt` from a byte buffer
|
|
|
|
+ ///
|
|
|
|
+ /// Note: this function does ***not*** require that the data be 4-byte
|
|
|
|
+ /// aligned
|
|
pub fn new(data: &'a [u8]) -> Result<Self, FdtError> {
|
|
pub fn new(data: &'a [u8]) -> Result<Self, FdtError> {
|
|
let mut stream = FdtData::new(data);
|
|
let mut stream = FdtData::new(data);
|
|
let header = FdtHeader::from_bytes(&mut stream).ok_or(FdtError::BufferTooSmall)?;
|
|
let header = FdtHeader::from_bytes(&mut stream).ok_or(FdtError::BufferTooSmall)?;
|
|
@@ -125,6 +175,9 @@ impl<'a> Fdt<'a> {
|
|
/// # Safety
|
|
/// # Safety
|
|
/// This function performs a read to verify the magic value. If the pointer
|
|
/// This function performs a read to verify the magic value. If the pointer
|
|
/// is invalid this can result in undefined behavior.
|
|
/// is invalid this can result in undefined behavior.
|
|
|
|
+ ///
|
|
|
|
+ /// Note: this function does ***not*** require that the data be 4-byte
|
|
|
|
+ /// aligned
|
|
pub unsafe fn from_ptr(ptr: *const u8) -> Result<Self, FdtError> {
|
|
pub unsafe fn from_ptr(ptr: *const u8) -> Result<Self, FdtError> {
|
|
if ptr.is_null() {
|
|
if ptr.is_null() {
|
|
return Err(FdtError::BadPtr);
|
|
return Err(FdtError::BadPtr);
|