3个版本 (破坏性更新)

0.3.0 2023年11月15日
0.2.0 2021年11月1日
0.1.0 2021年8月5日

180Unix API 中排名

Download history 10139/week @ 2024-03-14 6698/week @ 2024-03-21 5453/week @ 2024-03-28 7931/week @ 2024-04-04 4823/week @ 2024-04-11 7239/week @ 2024-04-18 6041/week @ 2024-04-25 5673/week @ 2024-05-02 10247/week @ 2024-05-09 8280/week @ 2024-05-16 10715/week @ 2024-05-23 9819/week @ 2024-05-30 5112/week @ 2024-06-06 5841/week @ 2024-06-13 3930/week @ 2024-06-20 3227/week @ 2024-06-27

每月下载量19,553
用于dbs-boot

Apache-2.0 OR BSD-3-Clause

58KB
937

vm-fdt

vm-fdt包提供将Flattened Devicetree blob写入到Devicetree规范中定义的功能。

CrosvmFirecracker等项目中,设备树用于在启动操作系统时指定虚拟机拓扑(内存、vcpu、缓存、中断等)。

设计

在vm-fdt中,我们定义并使用以下原语:

  • FDT写入器(FdtWriter),
  • 节点(FdtWriterNode)和
  • 属性(定义为键值对)。

FDT有一个或多个节点,每个节点可以可选地包含属性和子节点,从而形成一个树状结构。

FdtWriter结构提供了一个适合在运行时动态生成Devicetree blob的接口。支持的运算包括:

  1. 创建节点。这是通过在FdtWriter上调用begin_node来完成的。该调用返回一个类型为FdtWriterNode的对象,我们可以设置属性(使用以下定义的property_*函数),或添加子节点(通过嵌套调用begin_node)。节点的属性只能添加在创建子节点之前(如规范中定义)。每个节点都必须通过调用end_node函数来结束。
  2. 创建属性。属性是键值对,其中键是一个字符串,值是一个原始字节数组。为了使用方便,使得调用FDT接口的用户不需要创建原始字节数组,我们定义了以下常见属性类型的包装器:
  • property_null(一个空属性)
  • property_string
  • 属性字符串列表
  • 属性_u32
  • 属性_u64
  • 属性数组_u32
  • 属性数组_u64
  • 属性(原始字节数组)

威胁模型

输入:调用 vm-fdt 公共接口的调用者是可信的。

输出:FDT blob 的内容位于内存中,且是可信的。此 crate 分配的内存与用户定义的节点和属性数量(通过 property*begin_node 函数)成正比。

#NR 威胁 缓解措施
1 由于编程错误,FDT 代码导致大内存分配。 vm-fdt 接口的操作者是可信的,内存分配与对公共 FDT 接口的调用次数成正比。在 vm-fdt 级别,blob 允许的最大大小为 4.3 GB。这是通过检查数据 blob 的长度是否适合 u32,以及 u32 的最大值为 4294967295(约 4.3 GB)来强制执行的。调用 vm-fdt 接口的调用者可以在调用 finish 函数时检查 FDT blob 的大小。
2 在初始化 FdtWriter 时传递大型内存预留数组会导致未定义行为。 检查内存预留的长度。所有基于输入的后续操作都检查溢出。
3 在初始化 FdtWriter 时传递重叠的内存预留会导致在客人内存中加载 blob 时出现未定义行为 FDT 规范明确定义,内存预留条目不得重叠。这是由 FdtWriter 强制执行的,并在单元测试中检查

用法

以下代码创建了一个具有根节点的 FDT blob,该根节点有 3 个属性(“compatible”、“#address-cells” 和 “#size-cells”),并包含 2 个子节点

  1. "chosen",它有 2 个属性(“linux,pci-probe-only” 和 “bootargs”)。
  2. "memory",它有一个属性(“device_type”)

以下是 FDT 的图形表示。

use vm_fdt::{FdtWriter, Error};

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

   let root_node = fdt.begin_node("root")?;
   fdt.property_string("compatible", "linux,dummy-virt")?;
   fdt.property_u32("#address-cells", 0x2)?;
   fdt.property_u32("#size-cells", 0x2)?;

   let chosen_node = fdt.begin_node("chosen")?;
   fdt.property_u32("linux,pci-probe-only", 1)?;
   fdt.property_string("bootargs", "panic=-1 console=hvc0")?;
   fdt.end_node(chosen_node)?;

   let memory_node = fdt.begin_node("memory")?;
   fdt.property_string("device_type", "memory")?;
   fdt.end_node(memory_node)?;

   fdt.end_node(root_node)?;

   fdt.finish()
}

特性

此 crate 定义了一个开发特性:long_running_test。此特性不应在生产中使用,因为它可能会启用仅在开发用例中安全的函数。

许可证

本项目许可采用以下之一

依赖项

~0–435KB