vm_fdt/lib.rs
1// Copyright 2021 The Chromium OS Authors. All rights reserved.
2// SPDX-License-Identifier: Apache-2.0 OR BSD-3-Clause
3
4#![cfg_attr(not(feature = "std"), no_std)]
5#![deny(missing_docs)]
6
7//! This crate provides the ability to manipulate Flattened Devicetree blobs.
8//!
9//! # Example
10//!
11//! In the following example we create an FDT blob with a root node, and 2
12//! children nodes. More details about this example are available in the readme.
13//!
14//! ```rust
15//! use vm_fdt::{Error, FdtWriter};
16//!
17//! fn create_fdt() -> Result<Vec<u8>, Error> {
18//! let mut fdt = FdtWriter::new()?;
19//!
20//! let root_node = fdt.begin_node("root")?;
21//! fdt.property_string("compatible", "linux,dummy-virt")?;
22//! fdt.property_u32("#address-cells", 0x2)?;
23//! fdt.property_u32("#size-cells", 0x2)?;
24//!
25//! let chosen_node = fdt.begin_node("chosen")?;
26//! fdt.property_u32("linux,pci-probe-only", 1)?;
27//! fdt.property_string("bootargs", "panic=-1 console=hvc0")?;
28//! fdt.end_node(chosen_node)?;
29//!
30//! let memory_node = fdt.begin_node("memory")?;
31//! fdt.property_string("device_type", "memory")?;
32//! fdt.end_node(memory_node)?;
33//!
34//! fdt.end_node(root_node)?;
35//!
36//! fdt.finish()
37//! }
38//!
39//! # let dtb = create_fdt().unwrap();
40//! ```
41//!
42//! By default the FDT does not have any memory reservations. If the user
43//! needs to add memory reservations as well, then a different constructor
44//! can be used as follows:
45//!
46//! ```rust
47//! use vm_fdt::{Error, FdtReserveEntry, FdtWriter};
48//!
49//! fn create_fdt() -> Result<Vec<u8>, Error> {
50//! let mut fdt = FdtWriter::new_with_mem_reserv(&[
51//! FdtReserveEntry::new(0x12345678AABBCCDD, 0x1234).unwrap(),
52//! FdtReserveEntry::new(0x1020304050607080, 0x5678).unwrap(),
53//! ])?;
54//! let root_node = fdt.begin_node("root")?;
55//! // ... add other nodes & properties
56//! fdt.end_node(root_node)?;
57//!
58//! fdt.finish()
59//! }
60//!
61//! # let dtb = create_fdt().unwrap();
62//! ```
63//!
64//! The [`phandle`](https://devicetree-specification.readthedocs.io/en/stable/devicetree-basics.html?#phandle)
65//! property should be set using [`FdtWriter::property_phandle`],
66//! so that the value is checked for uniqueness within the devicetree.
67//!
68//! ```rust
69//! use vm_fdt::{Error, FdtWriter};
70//!
71//! fn create_fdt() -> Result<Vec<u8>, Error> {
72//! let mut fdt = FdtWriter::new()?;
73//!
74//! let root_node = fdt.begin_node("root")?;
75//! fdt.property_phandle(1)?;
76//!
77//! fdt.end_node(root_node)?;
78//!
79//! fdt.finish()
80//! }
81//!
82//! # let dtb = create_fdt().unwrap();
83//! ```
84
85#[macro_use]
86extern crate alloc;
87
88mod writer;
89
90pub use writer::Result as FdtWriterResult;
91pub use writer::{Error, FdtReserveEntry, FdtWriter, FdtWriterNode};
92
93/// Magic number used in the FDT header.
94const FDT_MAGIC: u32 = 0xd00dfeed;
95
96const FDT_BEGIN_NODE: u32 = 0x00000001;
97const FDT_END_NODE: u32 = 0x00000002;
98const FDT_PROP: u32 = 0x00000003;
99const FDT_END: u32 = 0x00000009;
100
101const NODE_NAME_MAX_LEN: usize = 31;
102const PROPERTY_NAME_MAX_LEN: usize = 31;