vm-fdt

The vm-fdt crate provides the ability to write Flattened Devicetree blobs as defined in the Devicetree specification.

In projects such as Crosvm and Firecracker the device tree is used to specify the virtual machine topology (memory, vcpu, caches, interrupts, and others) when booting the OS.

Design

In vm-fdt we define and work with the following primitives:

An FDT has one or multiple nodes, and each node can optionally have properties and child nodes, creating a tree structure.

The FdtWriter structure provides an interface suitable for dynamically generating a Devicetree blob at runtime. The supported operations are:

  1. Creating a node. This is done by calling begin_node on the FdtWriter. The call returns an object of type FdtWriterNode on which we can set properties (using the property_* functions as defined below), or add child nodes (via nested calls to begin_node). Properties for the node can only be added before creating child nodes (as defined in the specification). Each node must end with a call to the end_node function.
  2. Create properties. Properties are key-value pairs, where the key is a string, and the value is a raw bytes array. To make it easier to use, such that the caller of the FDT interface does not need to create a raw byte array, we define wrappers over common property types as follows:

Usage

The following code is creating an FDT blob with a root node that has 3 properties ("compatible", "#address-cells", and "#size-cells"), and contains 2 child nodes:

  1. "chosen", which has 2 properties ("linux,pci-probe-only" and "bootargs").
  2. "memory", which has one property ("device_type")

Below is a graphic representation of the FDT.

```rust use vm_fdt::{FdtWriter, Error};

fn create_fdt() -> Result, Error> { let mut fdt = FdtWriter::new()?;

let rootnode = fdt.beginnode("root")?; fdt.propertystring("compatible", "linux,dummy-virt")?; fdt.propertyu32("#address-cells", 0x2)?; fdt.property_u32("#size-cells", 0x2)?;

let chosennode = fdt.beginnode("chosen")?; fdt.propertyu32("linux,pci-probe-only", 1)?; fdt.propertystring("bootargs", "panic=-1 console=hvc0")?; fdt.endnode(chosennode)?;

let memorynode = fdt.beginnode("memory")?; fdt.propertystring("devicetype", "memory")?; fdt.endnode(memorynode)?;

fdt.endnode(rootnode)?;

fdt.finish() } ```

Features

This crate defines a development feature: long_running_test. This feature SHOULD NOT be used in production as it might enable functionality that is safe only for development use cases.

License

This project is licensed under either of