!22 StratoVirt: Add fdt patches for musl compilation

From: @flyking001
Reviewed-by: @lijiajie128,@cellfaint
Signed-off-by: @cellfaint
This commit is contained in:
openeuler-ci-bot 2021-07-27 08:49:54 +00:00 committed by Gitee
commit cf198f22a8
6 changed files with 2736 additions and 2 deletions

View File

@ -0,0 +1,908 @@
From 792248c876ba6f3ef4fa1e6c05c7e9a157ec5528 Mon Sep 17 00:00:00 2001
From: Jiajie Li <lijiajie11@huawei.com>
Date: Wed, 23 Jun 2021 14:46:57 +0800
Subject: [PATCH 1/5] util/fdt: implement basic fdt API
This series of patches is for rust update to version >= 1.47.
Because the higher version of rust compile Stratovirt with
aarch64-unkonwn-linux-musl target, will get error like below:
```
note: /usr/lib/gcc/aarch64-linux-gnu/libfdt.a(fdt_sw.o): In function `fdt_property':
(.text+0x4d4): undefined reference to `__stack_chk_guard'
(.text+0x4e0): undefined reference to `__stack_chk_guard'
(.text+0x518): undefined reference to `__stack_chk_guard'
(.text+0x530): undefined reference to `__stack_chk_fail'
```
Rust community recommand to use vm-fdt(https://github.com/rust-vmm/vm-fdt)
to fix this problem. But this project is not released to crate.io for now.
So add basic implementation of fdt API.
Signed-off-by: Jiajie Li <lijiajie11@huawei.com>
---
Cargo.lock | 295 ++++++++++++++++++++++++-----------------------
util/Cargo.toml | 1 +
util/src/fdt.rs | 300 ++++++++++++++++++++++++++++++++++++++++++++++++
util/src/lib.rs | 26 +++++
4 files changed, 474 insertions(+), 148 deletions(-)
create mode 100644 util/src/fdt.rs
diff --git a/Cargo.lock b/Cargo.lock
index bf866cf..3bd4bdf 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -4,364 +4,363 @@
name = "StratoVirt"
version = "0.3.0"
dependencies = [
- "error-chain 0.12.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "kvm-ioctls 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.71 (registry+https://github.com/rust-lang/crates.io-index)",
- "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
- "machine_manager 0.3.0",
- "micro_vm 0.3.0",
- "util 0.3.0",
- "virtio 0.3.0",
- "vmm-sys-util 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "error-chain",
+ "kvm-ioctls",
+ "libc",
+ "log",
+ "machine_manager",
+ "micro_vm",
+ "util",
+ "virtio",
+ "vmm-sys-util",
]
[[package]]
name = "addr2line"
version = "0.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a49806b9dadc843c61e7c97e72490ad7f7220ae249012fbda9ad0609457c0543"
dependencies = [
- "gimli 0.21.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "gimli",
]
[[package]]
name = "address_space"
version = "0.3.0"
dependencies = [
- "error-chain 0.12.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "kvm-bindings 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "kvm-ioctls 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.71 (registry+https://github.com/rust-lang/crates.io-index)",
- "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
- "machine_manager 0.3.0",
- "util 0.3.0",
- "vmm-sys-util 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "error-chain",
+ "kvm-bindings",
+ "kvm-ioctls",
+ "libc",
+ "log",
+ "machine_manager",
+ "util",
+ "vmm-sys-util",
]
[[package]]
name = "adler32"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "567b077b825e468cc974f0020d4082ee6e03132512f207ef1a02fd5d00d1f32d"
[[package]]
name = "backtrace"
version = "0.3.49"
source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "05100821de9e028f12ae3d189176b41ee198341eb8f369956407fea2f5cc666c"
dependencies = [
- "addr2line 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.71 (registry+https://github.com/rust-lang/crates.io-index)",
- "miniz_oxide 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
- "object 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-demangle 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
+ "addr2line",
+ "cfg-if",
+ "libc",
+ "miniz_oxide",
+ "object",
+ "rustc-demangle",
]
[[package]]
name = "bitflags"
version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
[[package]]
name = "boot_loader"
version = "0.3.0"
dependencies = [
- "address_space 0.3.0",
- "error-chain 0.12.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "kvm-bindings 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "kvm-ioctls 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.71 (registry+https://github.com/rust-lang/crates.io-index)",
- "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
- "util 0.3.0",
- "vmm-sys-util 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "address_space",
+ "error-chain",
+ "kvm-bindings",
+ "kvm-ioctls",
+ "libc",
+ "log",
+ "util",
+ "vmm-sys-util",
]
[[package]]
name = "byteorder"
version = "1.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de"
[[package]]
name = "cfg-if"
version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
[[package]]
name = "cpu"
version = "0.3.0"
dependencies = [
- "error-chain 0.12.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "kvm-bindings 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "kvm-ioctls 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.71 (registry+https://github.com/rust-lang/crates.io-index)",
- "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
- "machine_manager 0.3.0",
- "util 0.3.0",
- "vmm-sys-util 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "error-chain",
+ "kvm-bindings",
+ "kvm-ioctls",
+ "libc",
+ "log",
+ "machine_manager",
+ "util",
+ "vmm-sys-util",
]
[[package]]
name = "devices"
version = "0.3.0"
dependencies = [
- "address_space 0.3.0",
- "boot_loader 0.3.0",
- "byteorder 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "error-chain 0.12.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "kvm-bindings 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "kvm-ioctls 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.71 (registry+https://github.com/rust-lang/crates.io-index)",
- "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
- "machine_manager 0.3.0",
- "serde 1.0.114 (registry+https://github.com/rust-lang/crates.io-index)",
- "sysbus 0.3.0",
- "util 0.3.0",
- "vmm-sys-util 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "address_space",
+ "boot_loader",
+ "byteorder",
+ "error-chain",
+ "kvm-bindings",
+ "kvm-ioctls",
+ "libc",
+ "log",
+ "machine_manager",
+ "serde",
+ "sysbus",
+ "util",
+ "vmm-sys-util",
]
[[package]]
name = "error-chain"
version = "0.12.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2d2f06b9cac1506ece98fe3231e3cc9c4410ec3d5b1f24ae1c8946f0742cdefc"
dependencies = [
- "backtrace 0.3.49 (registry+https://github.com/rust-lang/crates.io-index)",
- "version_check 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "backtrace",
+ "version_check",
]
[[package]]
name = "gimli"
version = "0.21.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bcc8e0c9bce37868955864dbecd2b1ab2bdf967e6f28066d65aaac620444b65c"
[[package]]
name = "itoa"
version = "0.4.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b8b7a7c0c47db5545ed3fef7468ee7bb5b74691498139e4b3f6a20685dc6dd8e"
[[package]]
name = "kvm-bindings"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8f1c07667561c3d12d77342baf28ca5d0f8c3ea2160778485640ec84a4571da2"
dependencies = [
- "vmm-sys-util 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "vmm-sys-util",
]
[[package]]
name = "kvm-ioctls"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "158d15da895bddca8223fa31dc9e8b9317bdc2fbc4635dea8dd575fc40dae37f"
dependencies = [
- "kvm-bindings 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.71 (registry+https://github.com/rust-lang/crates.io-index)",
- "vmm-sys-util 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "kvm-bindings",
+ "libc",
+ "vmm-sys-util",
]
[[package]]
name = "libc"
version = "0.2.71"
source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9457b06509d27052635f90d6466700c65095fdf75409b3fbdd903e988b886f49"
[[package]]
name = "log"
version = "0.4.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7"
dependencies = [
- "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cfg-if",
]
[[package]]
name = "machine_manager"
version = "0.3.0"
dependencies = [
- "error-chain 0.12.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.71 (registry+https://github.com/rust-lang/crates.io-index)",
- "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.114 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_json 1.0.55 (registry+https://github.com/rust-lang/crates.io-index)",
- "util 0.3.0",
- "vmm-sys-util 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "error-chain",
+ "libc",
+ "log",
+ "serde",
+ "serde_json",
+ "util",
+ "vmm-sys-util",
]
[[package]]
name = "micro_vm"
version = "0.3.0"
dependencies = [
- "address_space 0.3.0",
- "boot_loader 0.3.0",
- "cpu 0.3.0",
- "devices 0.3.0",
- "error-chain 0.12.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "kvm-bindings 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "kvm-ioctls 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.71 (registry+https://github.com/rust-lang/crates.io-index)",
- "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
- "machine_manager 0.3.0",
- "serde 1.0.114 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_json 1.0.55 (registry+https://github.com/rust-lang/crates.io-index)",
- "sysbus 0.3.0",
- "util 0.3.0",
- "virtio 0.3.0",
- "vmm-sys-util 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "address_space",
+ "boot_loader",
+ "cpu",
+ "devices",
+ "error-chain",
+ "kvm-bindings",
+ "kvm-ioctls",
+ "libc",
+ "log",
+ "machine_manager",
+ "serde",
+ "serde_json",
+ "sysbus",
+ "util",
+ "virtio",
+ "vmm-sys-util",
]
[[package]]
name = "miniz_oxide"
version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "791daaae1ed6889560f8c4359194f56648355540573244a5448a83ba1ecc7435"
dependencies = [
- "adler32 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "adler32",
]
[[package]]
name = "object"
version = "0.20.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1ab52be62400ca80aa00285d25253d7f7c437b7375c4de678f5405d3afe82ca5"
[[package]]
name = "proc-macro2"
version = "1.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "beae6331a816b1f65d04c45b078fd8e6c93e8071771f41b8163255bbd8d7c8fa"
dependencies = [
- "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "unicode-xid",
]
[[package]]
name = "quote"
version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "aa563d17ecb180e500da1cfd2b028310ac758de548efdd203e18f283af693f37"
dependencies = [
- "proc-macro2 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)",
+ "proc-macro2",
]
[[package]]
name = "rustc-demangle"
version = "0.1.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4c691c0e608126e00913e33f0ccf3727d5fc84573623b8d65b2df340b5201783"
[[package]]
name = "ryu"
version = "1.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e"
[[package]]
name = "serde"
version = "1.0.114"
source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5317f7588f0a5078ee60ef675ef96735a1442132dc645eb1d12c018620ed8cd3"
dependencies = [
- "serde_derive 1.0.114 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.114"
source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2a0be94b04690fbaed37cddffc5c134bf537c8e3329d53e982fe04c374978f8e"
dependencies = [
- "proc-macro2 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)",
- "quote 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
- "syn 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
+ "proc-macro2",
+ "quote",
+ "syn",
]
[[package]]
name = "serde_json"
version = "1.0.55"
source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ec2c5d7e739bc07a3e73381a39d61fdb5f671c60c1df26a130690665803d8226"
dependencies = [
- "itoa 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "ryu 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.114 (registry+https://github.com/rust-lang/crates.io-index)",
+ "itoa",
+ "ryu",
+ "serde",
]
[[package]]
name = "syn"
version = "1.0.37"
source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "239f255b9e3429350f188c27b807fc9920a15eb9145230ff1a7d054c08fec319"
dependencies = [
- "proc-macro2 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)",
- "quote 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
- "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "proc-macro2",
+ "quote",
+ "unicode-xid",
]
[[package]]
name = "sysbus"
version = "0.3.0"
dependencies = [
- "address_space 0.3.0",
- "error-chain 0.12.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "kvm-ioctls 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
- "vmm-sys-util 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "address_space",
+ "error-chain",
+ "kvm-ioctls",
+ "log",
+ "vmm-sys-util",
]
[[package]]
name = "unicode-xid"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c"
[[package]]
name = "util"
version = "0.3.0"
dependencies = [
- "error-chain 0.12.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "kvm-bindings 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "kvm-ioctls 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.71 (registry+https://github.com/rust-lang/crates.io-index)",
- "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
- "vmm-sys-util 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "byteorder",
+ "error-chain",
+ "kvm-bindings",
+ "kvm-ioctls",
+ "libc",
+ "log",
+ "vmm-sys-util",
]
[[package]]
name = "version_check"
version = "0.9.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b5a972e5669d67ba988ce3dc826706fb0a8b01471c088cb0b6110b805cc36aed"
[[package]]
name = "virtio"
version = "0.3.0"
dependencies = [
- "address_space 0.3.0",
- "byteorder 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "error-chain 0.12.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "kvm-ioctls 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.71 (registry+https://github.com/rust-lang/crates.io-index)",
- "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
- "machine_manager 0.3.0",
- "serde_json 1.0.55 (registry+https://github.com/rust-lang/crates.io-index)",
- "sysbus 0.3.0",
- "util 0.3.0",
- "vmm-sys-util 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "address_space",
+ "byteorder",
+ "error-chain",
+ "kvm-ioctls",
+ "libc",
+ "log",
+ "machine_manager",
+ "serde_json",
+ "sysbus",
+ "util",
+ "vmm-sys-util",
]
[[package]]
name = "vmm-sys-util"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d1cdd1d72e262bbfb014de65ada24c1ac50e10a2e3b1e8ec052df188c2ee5dfa"
dependencies = [
- "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.71 (registry+https://github.com/rust-lang/crates.io-index)",
+ "bitflags",
+ "libc",
]
-
-[metadata]
-"checksum addr2line 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a49806b9dadc843c61e7c97e72490ad7f7220ae249012fbda9ad0609457c0543"
-"checksum adler32 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "567b077b825e468cc974f0020d4082ee6e03132512f207ef1a02fd5d00d1f32d"
-"checksum backtrace 0.3.49 (registry+https://github.com/rust-lang/crates.io-index)" = "05100821de9e028f12ae3d189176b41ee198341eb8f369956407fea2f5cc666c"
-"checksum bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
-"checksum byteorder 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de"
-"checksum cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
-"checksum error-chain 0.12.4 (registry+https://github.com/rust-lang/crates.io-index)" = "2d2f06b9cac1506ece98fe3231e3cc9c4410ec3d5b1f24ae1c8946f0742cdefc"
-"checksum gimli 0.21.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bcc8e0c9bce37868955864dbecd2b1ab2bdf967e6f28066d65aaac620444b65c"
-"checksum itoa 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "b8b7a7c0c47db5545ed3fef7468ee7bb5b74691498139e4b3f6a20685dc6dd8e"
-"checksum kvm-bindings 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8f1c07667561c3d12d77342baf28ca5d0f8c3ea2160778485640ec84a4571da2"
-"checksum kvm-ioctls 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "158d15da895bddca8223fa31dc9e8b9317bdc2fbc4635dea8dd575fc40dae37f"
-"checksum libc 0.2.71 (registry+https://github.com/rust-lang/crates.io-index)" = "9457b06509d27052635f90d6466700c65095fdf75409b3fbdd903e988b886f49"
-"checksum log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7"
-"checksum miniz_oxide 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "791daaae1ed6889560f8c4359194f56648355540573244a5448a83ba1ecc7435"
-"checksum object 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1ab52be62400ca80aa00285d25253d7f7c437b7375c4de678f5405d3afe82ca5"
-"checksum proc-macro2 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)" = "beae6331a816b1f65d04c45b078fd8e6c93e8071771f41b8163255bbd8d7c8fa"
-"checksum quote 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)" = "aa563d17ecb180e500da1cfd2b028310ac758de548efdd203e18f283af693f37"
-"checksum rustc-demangle 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "4c691c0e608126e00913e33f0ccf3727d5fc84573623b8d65b2df340b5201783"
-"checksum ryu 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e"
-"checksum serde 1.0.114 (registry+https://github.com/rust-lang/crates.io-index)" = "5317f7588f0a5078ee60ef675ef96735a1442132dc645eb1d12c018620ed8cd3"
-"checksum serde_derive 1.0.114 (registry+https://github.com/rust-lang/crates.io-index)" = "2a0be94b04690fbaed37cddffc5c134bf537c8e3329d53e982fe04c374978f8e"
-"checksum serde_json 1.0.55 (registry+https://github.com/rust-lang/crates.io-index)" = "ec2c5d7e739bc07a3e73381a39d61fdb5f671c60c1df26a130690665803d8226"
-"checksum syn 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)" = "239f255b9e3429350f188c27b807fc9920a15eb9145230ff1a7d054c08fec319"
-"checksum unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c"
-"checksum version_check 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b5a972e5669d67ba988ce3dc826706fb0a8b01471c088cb0b6110b805cc36aed"
-"checksum vmm-sys-util 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d1cdd1d72e262bbfb014de65ada24c1ac50e10a2e3b1e8ec052df188c2ee5dfa"
diff --git a/util/Cargo.toml b/util/Cargo.toml
index 21d9764..a4a7f97 100644
--- a/util/Cargo.toml
+++ b/util/Cargo.toml
@@ -14,3 +14,4 @@ kvm-ioctls = "0.6.0"
libc = "0.2.71"
log = { version = "0.4.8", features = ["std"]}
vmm-sys-util = "0.7.0"
+byteorder = "1.3.4"
diff --git a/util/src/fdt.rs b/util/src/fdt.rs
new file mode 100644
index 0000000..2fdab44
--- /dev/null
+++ b/util/src/fdt.rs
@@ -0,0 +1,300 @@
+// Copyright (c) 2020 Huawei Technologies Co.,Ltd. All rights reserved.
+//
+// StratoVirt is licensed under Mulan PSL v2.
+// You can use this software according to the terms and conditions of the Mulan
+// PSL v2.
+// You may obtain a copy of Mulan PSL v2 at:
+// http://license.coscl.org.cn/MulanPSL2
+// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY
+// KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
+// NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
+// See the Mulan PSL v2 for more details.
+
+use std::mem::size_of;
+
+use crate::errors::{ErrorKind, Result, ResultExt};
+use byteorder::{BigEndian, ByteOrder};
+
+pub const CLK_PHANDLE: u32 = 1;
+pub const GIC_PHANDLE: u32 = 2;
+pub const GIC_ITS_PHANDLE: u32 = 3;
+pub const CPU_PHANDLE_START: u32 = 10;
+
+pub const GIC_FDT_IRQ_TYPE_SPI: u32 = 0;
+pub const GIC_FDT_IRQ_TYPE_PPI: u32 = 1;
+pub const IRQ_TYPE_EDGE_RISING: u32 = 1;
+pub const IRQ_TYPE_LEVEL_HIGH: u32 = 4;
+
+pub const FDT_MAX_SIZE: u32 = 0x1_0000;
+
+// Magic number in fdt header(big-endian).
+const FDT_MAGIC: u32 = 0xd00dfeed;
+// Fdt Header default information.
+const FDT_HEADER_SIZE: usize = 40;
+const FDT_VERSION: u32 = 17;
+const FDT_LAST_COMP_VERSION: u32 = 16;
+// Beginning token type of structure block.
+const FDT_BEGIN_NODE: u32 = 0x00000001;
+const FDT_END_NODE: u32 = 0x00000002;
+const FDT_PROP: u32 = 0x00000003;
+const FDT_END: u32 = 0x00000009;
+// Memory reservation block alignment.
+const MEM_RESERVE_ALIGNMENT: usize = 8;
+// Structure block alignment.
+const STRUCTURE_BLOCK_ALIGNMENT: usize = 4;
+
+/// FdtBuilder structure.
+pub struct FdtBuilder {
+ /// The header of flattened device tree.
+ fdt_header: Vec<u8>,
+ /// The memory reservation block of flattened device tree.
+ /// It provides the client program with a list of areas
+ /// in physical memory which are reserved.
+ mem_reserve: Vec<u8>,
+ /// The structure block of flattened device tree.
+ /// It describes the structure and contents of the tree.
+ structure_blk: Vec<u8>,
+ /// The strings block of flattened device tree.
+ /// It contains strings representing all the property names used in the tree.
+ strings_blk: Vec<u8>,
+ /// The physical ID of the systems boot CPU.
+ boot_cpuid_phys: u32,
+ /// The depth of nested node.
+ subnode_depth: u32,
+ /// Is there a open node or not.
+ begin_node: bool,
+}
+
+/// FdtReserveEntry structure.
+#[derive(Clone, Debug)]
+pub struct FdtReserveEntry {
+ /// The address of reserved memory.
+ /// On 32-bit CPUs the upper 32-bits of the value are ignored.
+ address: u64,
+ /// The size of reserved memory.
+ size: u64,
+}
+
+fn check_mem_reserve_overlap(mem_reservations: &[FdtReserveEntry]) -> bool {
+ if mem_reservations.len() <= 1 {
+ return true;
+ }
+
+ let mut mem_reser = mem_reservations.to_vec();
+ mem_reser.sort_by_key(|m| m.address);
+
+ for i in 0..(mem_reser.len() - 1) {
+ if mem_reser[i].address + mem_reser[i].size > mem_reser[i + 1].address {
+ return false;
+ }
+ }
+ true
+}
+
+// If there is null character in string, return false.
+fn check_string_legality(s: &str) -> bool {
+ !s.contains('\0')
+}
+
+impl Default for FdtBuilder {
+ fn default() -> Self {
+ Self {
+ fdt_header: vec![0_u8; FDT_HEADER_SIZE],
+ mem_reserve: Vec::new(),
+ structure_blk: Vec::new(),
+ strings_blk: Vec::new(),
+ boot_cpuid_phys: 0,
+ subnode_depth: 0,
+ begin_node: false,
+ }
+ }
+}
+
+impl FdtBuilder {
+ pub fn new() -> Self {
+ FdtBuilder::default()
+ }
+
+ pub fn finish(mut self) -> Result<Vec<u8>> {
+ if self.subnode_depth > 0 {
+ return Err(ErrorKind::NodeUnclosed(self.subnode_depth).into());
+ }
+ self.structure_blk
+ .extend_from_slice(&FDT_END.to_be_bytes()[..]);
+
+ // According to the spec, mem_reserve blocks shall be ended
+ // with an entry where both address and size are equal to 0.
+ self.mem_reserve.extend_from_slice(&0_u64.to_be_bytes());
+ self.mem_reserve.extend_from_slice(&0_u64.to_be_bytes());
+
+ // Fill fdt header.
+ let total_size = FDT_HEADER_SIZE
+ + self.mem_reserve.len()
+ + self.structure_blk.len()
+ + self.strings_blk.len();
+ let off_dt_struct = FDT_HEADER_SIZE + self.mem_reserve.len();
+ let off_dt_strings = FDT_HEADER_SIZE + self.mem_reserve.len() + self.structure_blk.len();
+ let off_mem_rsvmap = FDT_HEADER_SIZE;
+
+ BigEndian::write_u32(&mut self.fdt_header[0..4], FDT_MAGIC);
+ BigEndian::write_u32(&mut self.fdt_header[4..8], total_size as u32);
+ BigEndian::write_u32(&mut self.fdt_header[8..12], off_dt_struct as u32);
+ BigEndian::write_u32(&mut self.fdt_header[12..16], off_dt_strings as u32);
+ BigEndian::write_u32(&mut self.fdt_header[16..20], off_mem_rsvmap as u32);
+ BigEndian::write_u32(&mut self.fdt_header[20..24], FDT_VERSION);
+ BigEndian::write_u32(&mut self.fdt_header[24..28], FDT_LAST_COMP_VERSION);
+ BigEndian::write_u32(&mut self.fdt_header[28..32], self.boot_cpuid_phys);
+ BigEndian::write_u32(&mut self.fdt_header[32..36], self.strings_blk.len() as u32);
+ BigEndian::write_u32(
+ &mut self.fdt_header[36..40],
+ self.structure_blk.len() as u32,
+ );
+
+ self.fdt_header.extend_from_slice(&self.mem_reserve);
+ self.fdt_header.extend_from_slice(&self.structure_blk);
+ self.fdt_header.extend_from_slice(&self.strings_blk);
+ Ok(self.fdt_header)
+ }
+
+ pub fn add_mem_reserve(&mut self, mem_reservations: &[FdtReserveEntry]) -> Result<()> {
+ if !check_mem_reserve_overlap(mem_reservations) {
+ return Err(ErrorKind::MemReserveOverlap.into());
+ }
+
+ for mem_reser in mem_reservations {
+ self.mem_reserve
+ .extend_from_slice(&mem_reser.address.to_be_bytes());
+ self.mem_reserve
+ .extend_from_slice(&mem_reser.size.to_be_bytes());
+ }
+ self.align_structure_blk(MEM_RESERVE_ALIGNMENT);
+
+ Ok(())
+ }
+
+ pub fn begin_node(&mut self, node_name: &str) -> Result<u32> {
+ if !check_string_legality(node_name) {
+ return Err(ErrorKind::IllegalString(node_name.to_string()).into());
+ }
+
+ self.structure_blk
+ .extend_from_slice(&FDT_BEGIN_NODE.to_be_bytes()[..]);
+ if node_name.is_empty() {
+ self.structure_blk
+ .extend_from_slice(&0_u32.to_be_bytes()[..]);
+ } else {
+ let mut val_array = node_name.as_bytes().to_vec();
+ // The nodes name string should end with null('\0').
+ val_array.push(0x0_u8);
+ self.structure_blk.extend_from_slice(&val_array);
+ }
+ self.align_structure_blk(STRUCTURE_BLOCK_ALIGNMENT);
+ self.subnode_depth += 1;
+ self.begin_node = true;
+ Ok(self.subnode_depth)
+ }
+
+ pub fn end_node(&mut self, begin_node_depth: u32) -> Result<()> {
+ if begin_node_depth != self.subnode_depth {
+ return Err(ErrorKind::NodeDepthMismatch(begin_node_depth, self.subnode_depth).into());
+ }
+
+ self.structure_blk
+ .extend_from_slice(&FDT_END_NODE.to_be_bytes()[..]);
+ self.subnode_depth -= 1;
+ self.begin_node = false;
+ Ok(())
+ }
+
+ pub fn set_boot_cpuid_phys(&mut self, boot_cpuid: u32) {
+ self.boot_cpuid_phys = boot_cpuid;
+ }
+
+ pub fn set_property_string(&mut self, prop: &str, val: &str) -> Result<()> {
+ let mut val_array = val.as_bytes().to_vec();
+ // The string property should end with null('\0').
+ val_array.push(0x0_u8);
+ self.set_property(prop, &val_array)
+ .chain_err(|| ErrorKind::SetPropertyErr("string".to_string()))
+ }
+
+ pub fn set_property_u32(&mut self, prop: &str, val: u32) -> Result<()> {
+ self.set_property(prop, &val.to_be_bytes()[..])
+ .chain_err(|| ErrorKind::SetPropertyErr("u32".to_string()))
+ }
+
+ pub fn set_property_u64(&mut self, prop: &str, val: u64) -> Result<()> {
+ self.set_property(prop, &val.to_be_bytes()[..])
+ .chain_err(|| ErrorKind::SetPropertyErr("u64".to_string()))
+ }
+
+ pub fn set_property_array_u32(&mut self, prop: &str, array: &[u32]) -> Result<()> {
+ let mut prop_array = Vec::with_capacity(array.len() * size_of::<u32>());
+ for element in array {
+ prop_array.extend_from_slice(&element.to_be_bytes()[..]);
+ }
+ self.set_property(prop, &prop_array)
+ .chain_err(|| ErrorKind::SetPropertyErr("u32 array".to_string()))
+ }
+
+ pub fn set_property_array_u64(&mut self, prop: &str, array: &[u64]) -> Result<()> {
+ let mut prop_array = Vec::with_capacity(array.len() * size_of::<u64>());
+ for element in array {
+ prop_array.extend_from_slice(&element.to_be_bytes()[..]);
+ }
+ self.set_property(prop, &prop_array)
+ .chain_err(|| ErrorKind::SetPropertyErr("u64 array".to_string()))
+ }
+
+ pub fn set_property(&mut self, property_name: &str, property_val: &[u8]) -> Result<()> {
+ if !check_string_legality(property_name) {
+ return Err(ErrorKind::IllegalString(property_name.to_string()).into());
+ }
+
+ if !self.begin_node {
+ return Err(ErrorKind::IllegelPropertyPos.into());
+ }
+
+ let len = property_val.len() as u32;
+ let nameoff = self.strings_blk.len() as u32;
+ self.structure_blk
+ .extend_from_slice(&FDT_PROP.to_be_bytes()[..]);
+ self.structure_blk.extend_from_slice(&len.to_be_bytes()[..]);
+ self.structure_blk
+ .extend_from_slice(&nameoff.to_be_bytes()[..]);
+ self.structure_blk.extend_from_slice(property_val);
+ self.align_structure_blk(STRUCTURE_BLOCK_ALIGNMENT);
+
+ self.strings_blk.extend_from_slice(property_name.as_bytes());
+ // These strings in strings block should end with null('\0').
+ self.strings_blk.extend_from_slice("\0".as_bytes());
+
+ Ok(())
+ }
+
+ fn align_structure_blk(&mut self, alignment: usize) {
+ let remainder = self.structure_blk.len() % alignment;
+ if remainder != 0 {
+ self.structure_blk
+ .extend(vec![0_u8; (alignment - remainder) as usize]);
+ }
+ }
+}
+
+/// Trait for devices to be added to the Flattened Device Tree.
+#[allow(clippy::upper_case_acronyms)]
+pub trait CompileFDT {
+ /// function to generate fdt node
+ ///
+ /// # Arguments
+ ///
+ /// * `fdt` - the FdtBuilder to be filled.
+ fn generate_fdt_node(&self, fdt: &mut FdtBuilder) -> Result<()>;
+}
+
+pub fn dump_dtb(fdt: &[u8], file_path: &str) {
+ use std::fs::File;
+ use std::io::Write;
+ let mut f = File::create(file_path).unwrap();
+ f.write_all(fdt).expect("Unable to write data");
+}
diff --git a/util/src/lib.rs b/util/src/lib.rs
index a5feaef..d135c74 100644
--- a/util/src/lib.rs
+++ b/util/src/lib.rs
@@ -28,6 +28,8 @@ pub mod checksum;
pub mod daemonize;
#[cfg(target_arch = "aarch64")]
pub mod device_tree;
+#[cfg(target_arch = "aarch64")]
+pub mod fdt;
pub mod leak_bucket;
mod link_list;
pub mod loop_context;
@@ -131,6 +133,30 @@ pub mod errors {
description("Index out of bound of array")
display("Index :{} out of bound :{}", index, bound)
}
+ NodeDepthMismatch(target_dep: u32, real_dep: u32) {
+ description("Fdt structure nested node depth mismatch")
+ display("Desired node depth :{}, current node depth :{}", target_dep, real_dep)
+ }
+ NodeUnclosed(unclose: u32) {
+ description("Fdt structure block node unclose")
+ display("Still have {} node open when terminating the fdt", unclose)
+ }
+ IllegelPropertyPos {
+ description("Cann't add property outside the node")
+ display("Failed to add property because there is no open node")
+ }
+ IllegalString(s: String) {
+ description("The string for fdt should not contain null")
+ display("Failed to add string to fdt because of null character inside \"{}\"", s)
+ }
+ MemReserveOverlap {
+ description("The mem reserve entry should not overlap")
+ display("Failed to add overlapped mem reserve entries to fdt")
+ }
+ SetPropertyErr(s: String) {
+ description("Cann't set property for fdt node")
+ display("Failed to set {} property", s)
+ }
}
}
}
--
2.31.1

View File

@ -0,0 +1,132 @@
From bc7aa4bcc37cfd5244697e81af7555fa781249bb Mon Sep 17 00:00:00 2001
From: Jiajie Li <lijiajie11@huawei.com>
Date: Wed, 23 Jun 2021 15:06:21 +0800
Subject: [PATCH 2/5] devices/gicv3: use mod fdt instead of device_tree
Use fdt API provided by mod fdt, instead of mod device_tree
which is a wrapper around libfdt.
Signed-off-by: Jiajie Li <lijiajie11@huawei.com>
---
.../src/interrupt_controller/aarch64/gicv3.rs | 50 +++++++++----------
.../src/interrupt_controller/aarch64/mod.rs | 11 ++--
2 files changed, 31 insertions(+), 30 deletions(-)
diff --git a/devices/src/interrupt_controller/aarch64/gicv3.rs b/devices/src/interrupt_controller/aarch64/gicv3.rs
index 235bf37..a39a3d5 100644
--- a/devices/src/interrupt_controller/aarch64/gicv3.rs
+++ b/devices/src/interrupt_controller/aarch64/gicv3.rs
@@ -14,7 +14,7 @@ use std::sync::{Arc, Mutex};
use kvm_ioctls::{DeviceFd, VmFd};
use machine_manager::machine::{KvmVmState, MachineLifecycle};
-use util::device_tree;
+use util::fdt::{self, FdtBuilder};
use super::{GICConfig, GICDevice, UtilResult};
use crate::errors::{ErrorKind, Result, ResultExt};
@@ -379,7 +379,7 @@ impl GICDevice for GICv3 {
Ok(())
}
- fn generate_fdt(&self, fdt: &mut Vec<u8>) -> UtilResult<()> {
+ fn generate_fdt(&self, fdt: &mut FdtBuilder) -> UtilResult<()> {
let redist_count = self.redist_regions.len() as u32;
let mut gic_reg = vec![self.dist_base, self.dist_size];
@@ -388,34 +388,32 @@ impl GICDevice for GICv3 {
gic_reg.push(redist.size);
}
- let node = "/intc";
- device_tree::add_sub_node(fdt, node)?;
- device_tree::set_property_string(fdt, node, "compatible", "arm,gic-v3")?;
- device_tree::set_property(fdt, node, "interrupt-controller", None)?;
- device_tree::set_property_u32(fdt, node, "#interrupt-cells", 0x3)?;
- device_tree::set_property_u32(fdt, node, "phandle", device_tree::GIC_PHANDLE)?;
- device_tree::set_property_u32(fdt, node, "#address-cells", 0x2)?;
- device_tree::set_property_u32(fdt, node, "#size-cells", 0x2)?;
- device_tree::set_property_u32(fdt, node, "#redistributor-regions", redist_count)?;
- device_tree::set_property_array_u64(fdt, node, "reg", &gic_reg)?;
-
- let gic_intr = [
- device_tree::GIC_FDT_IRQ_TYPE_PPI,
- 0x9,
- device_tree::IRQ_TYPE_LEVEL_HIGH,
- ];
- device_tree::set_property_array_u32(fdt, node, "interrupts", &gic_intr)?;
+ let node = "intc";
+ let intc_node_dep = fdt.begin_node(node)?;
+ fdt.set_property_string("compatible", "arm,gic-v3")?;
+ fdt.set_property("interrupt-controller", &Vec::new())?;
+ fdt.set_property_u32("#interrupt-cells", 0x3)?;
+ fdt.set_property_u32("phandle", fdt::GIC_PHANDLE)?;
+ fdt.set_property_u32("#address-cells", 0x2)?;
+ fdt.set_property_u32("#size-cells", 0x2)?;
+ fdt.set_property_u32("#redistributor-regions", redist_count)?;
+ fdt.set_property_array_u64("reg", &gic_reg)?;
+
+ let gic_intr = [fdt::GIC_FDT_IRQ_TYPE_PPI, 0x9, fdt::IRQ_TYPE_LEVEL_HIGH];
+ fdt.set_property_array_u32("interrupts", &gic_intr)?;
if let Some(its) = &self.its_dev {
- device_tree::set_property(fdt, node, "ranges", None)?;
+ fdt.set_property("ranges", &Vec::new())?;
let its_reg = [its.msi_base, its.msi_size];
- let node = "/intc/its";
- device_tree::add_sub_node(fdt, node)?;
- device_tree::set_property_string(fdt, node, "compatible", "arm,gic-v3-its")?;
- device_tree::set_property(fdt, node, "msi-controller", None)?;
- device_tree::set_property_u32(fdt, node, "phandle", device_tree::GIC_ITS_PHANDLE)?;
- device_tree::set_property_array_u64(fdt, node, "reg", &its_reg)?;
+ let node = "its";
+ let its_node_dep = fdt.begin_node(node)?;
+ fdt.set_property_string("compatible", "arm,gic-v3-its")?;
+ fdt.set_property("msi-controller", &Vec::new())?;
+ fdt.set_property_u32("phandle", fdt::GIC_ITS_PHANDLE)?;
+ fdt.set_property_array_u64("reg", &its_reg)?;
+ fdt.end_node(its_node_dep)?;
}
+ fdt.end_node(intc_node_dep)?;
Ok(())
}
diff --git a/devices/src/interrupt_controller/aarch64/mod.rs b/devices/src/interrupt_controller/aarch64/mod.rs
index d2a1b50..f1b40cf 100644
--- a/devices/src/interrupt_controller/aarch64/mod.rs
+++ b/devices/src/interrupt_controller/aarch64/mod.rs
@@ -18,7 +18,10 @@ use std::sync::Arc;
use kvm_ioctls::VmFd;
use machine_manager::machine::{KvmVmState, MachineLifecycle};
-use util::{device_tree, errors::Result as UtilResult};
+use util::{
+ errors::Result as UtilResult,
+ fdt::{self, FdtBuilder},
+};
use crate::errors::{ErrorKind, Result, ResultExt};
@@ -88,7 +91,7 @@ pub trait GICDevice: MachineLifecycle {
/// # Arguments
///
/// * `fdt` - Device tree presented by bytes.
- fn generate_fdt(&self, fdt: &mut Vec<u8>) -> UtilResult<()>;
+ fn generate_fdt(&self, fdt: &mut FdtBuilder) -> UtilResult<()>;
}
/// A wrapper around creating and using a kvm-based interrupt controller.
@@ -121,8 +124,8 @@ impl InterruptController {
}
}
-impl device_tree::CompileFDT for InterruptController {
- fn generate_fdt_node(&self, fdt: &mut Vec<u8>) -> UtilResult<()> {
+impl fdt::CompileFDT for InterruptController {
+ fn generate_fdt_node(&self, fdt: &mut FdtBuilder) -> UtilResult<()> {
self.gic.generate_fdt(fdt)?;
Ok(())
}
--
2.31.1

View File

@ -0,0 +1,453 @@
From 999b6194eff54881f3ce4181f2355113fc72435b Mon Sep 17 00:00:00 2001
From: Jiajie Li <lijiajie11@huawei.com>
Date: Wed, 23 Jun 2021 15:20:54 +0800
Subject: [PATCH 3/5] machine/micro_vm: use fdt API of mod fdt instead of
device_tree
Use fdt API provided by mod fdt, instead of mod device_tree
which is a wrapper around libfdt.
Signed-off-by: Jiajie Li <lijiajie11@huawei.com>
---
micro_vm/src/lib.rs | 291 ++++++++++++++++++++++----------------------
1 file changed, 143 insertions(+), 148 deletions(-)
diff --git a/micro_vm/src/lib.rs b/micro_vm/src/lib.rs
index 7188f21..dd6cf97 100644
--- a/micro_vm/src/lib.rs
+++ b/micro_vm/src/lib.rs
@@ -111,7 +111,7 @@ use sysbus::{SysBusDevType, SysRes};
#[cfg(target_arch = "aarch64")]
use util::device_tree;
#[cfg(target_arch = "aarch64")]
-use util::device_tree::CompileFDT;
+use util::fdt::{self, CompileFDT, FdtBuilder};
use util::loop_context::{
EventLoopManager, EventNotifier, EventNotifierHelper, NotifierCallback, NotifierOperation,
};
@@ -628,12 +628,13 @@ impl LightMachine {
drop(boot_source);
#[cfg(target_arch = "aarch64")]
{
- let mut fdt = vec![0; device_tree::FDT_MAX_SIZE as usize];
- vm.generate_fdt_node(&mut fdt)?;
+ let mut fdt_helper = FdtBuilder::new();
+ vm.generate_fdt_node(&mut fdt_helper)?;
+ let fdt_vec = fdt_helper.finish()?;
vm.sys_mem.write(
- &mut fdt.as_slice(),
+ &mut fdt_vec.as_slice(),
GuestAddress(boot_config.fdt_addr as u64),
- fdt.len() as u64,
+ fdt_vec.len() as u64,
)?;
}
vm.register_power_event()?;
@@ -1477,23 +1478,23 @@ impl EventLoopManager for LightMachine {
// * `dev_info` - Device resource info of serial device.
// * `fdt` - Flatted device-tree blob where serial node will be filled into.
#[cfg(target_arch = "aarch64")]
-fn generate_serial_device_node(fdt: &mut Vec<u8>, res: &SysRes) -> util::errors::Result<()> {
- let node = format!("/uart@{:x}", res.region_base);
- device_tree::add_sub_node(fdt, &node)?;
- device_tree::set_property_string(fdt, &node, "compatible", "ns16550a")?;
- device_tree::set_property_string(fdt, &node, "clock-names", "apb_pclk")?;
- device_tree::set_property_u32(fdt, &node, "clocks", device_tree::CLK_PHANDLE)?;
- device_tree::set_property_array_u64(fdt, &node, "reg", &[res.region_base, res.region_size])?;
- device_tree::set_property_array_u32(
- fdt,
- &node,
+fn generate_serial_device_node(fdt: &mut FdtBuilder, res: &SysRes) -> util::errors::Result<()> {
+ let node = format!("uart@{:x}", res.region_base);
+ let serial_node_dep = fdt.begin_node(&node)?;
+ fdt.set_property_string("compatible", "ns16550a")?;
+ fdt.set_property_string("clock-names", "apb_pclk")?;
+ fdt.set_property_u32("clocks", fdt::CLK_PHANDLE)?;
+ fdt.set_property_array_u64("reg", &[res.region_base, res.region_size])?;
+ fdt.set_property_array_u32(
"interrupts",
&[
- device_tree::GIC_FDT_IRQ_TYPE_SPI,
+ fdt::GIC_FDT_IRQ_TYPE_SPI,
res.irq as u32,
- device_tree::IRQ_TYPE_EDGE_RISING,
+ fdt::IRQ_TYPE_EDGE_RISING,
],
)?;
+ fdt.end_node(serial_node_dep)?;
+
Ok(())
}
@@ -1504,23 +1505,23 @@ fn generate_serial_device_node(fdt: &mut Vec<u8>, res: &SysRes) -> util::errors:
// * `dev_info` - Device resource info of RTC device.
// * `fdt` - Flatted device-tree blob where RTC node will be filled into.
#[cfg(target_arch = "aarch64")]
-fn generate_rtc_device_node(fdt: &mut Vec<u8>, res: &SysRes) -> util::errors::Result<()> {
- let node = format!("/pl031@{:x}", res.region_base);
- device_tree::add_sub_node(fdt, &node)?;
- device_tree::set_property_string(fdt, &node, "compatible", "arm,pl031\0arm,primecell\0")?;
- device_tree::set_property_string(fdt, &node, "clock-names", "apb_pclk")?;
- device_tree::set_property_u32(fdt, &node, "clocks", device_tree::CLK_PHANDLE)?;
- device_tree::set_property_array_u64(fdt, &node, "reg", &[res.region_base, res.region_size])?;
- device_tree::set_property_array_u32(
- fdt,
- &node,
+fn generate_rtc_device_node(fdt: &mut FdtBuilder, res: &SysRes) -> util::errors::Result<()> {
+ let node = format!("pl031@{:x}", res.region_base);
+ let rtc_node_dep = fdt.begin_node(&node)?;
+ fdt.set_property_string("compatible", "arm,pl031\0arm,primecell\0")?;
+ fdt.set_property_string("clock-names", "apb_pclk")?;
+ fdt.set_property_u32("clocks", fdt::CLK_PHANDLE)?;
+ fdt.set_property_array_u64("reg", &[res.region_base, res.region_size])?;
+ fdt.set_property_array_u32(
"interrupts",
&[
- device_tree::GIC_FDT_IRQ_TYPE_SPI,
+ fdt::GIC_FDT_IRQ_TYPE_SPI,
res.irq as u32,
- device_tree::IRQ_TYPE_LEVEL_HIGH,
+ fdt::IRQ_TYPE_LEVEL_HIGH,
],
)?;
+ fdt.end_node(rtc_node_dep)?;
+
Ok(())
}
@@ -1531,22 +1532,21 @@ fn generate_rtc_device_node(fdt: &mut Vec<u8>, res: &SysRes) -> util::errors::Re
// * `dev_info` - Device resource info of Virtio-Mmio device.
// * `fdt` - Flatted device-tree blob where node will be filled into.
#[cfg(target_arch = "aarch64")]
-fn generate_virtio_devices_node(fdt: &mut Vec<u8>, res: &SysRes) -> util::errors::Result<()> {
- let node = format!("/virtio_mmio@{:x}", res.region_base);
- device_tree::add_sub_node(fdt, &node)?;
- device_tree::set_property_string(fdt, &node, "compatible", "virtio,mmio")?;
- device_tree::set_property_u32(fdt, &node, "interrupt-parent", device_tree::GIC_PHANDLE)?;
- device_tree::set_property_array_u64(fdt, &node, "reg", &[res.region_base, res.region_size])?;
- device_tree::set_property_array_u32(
- fdt,
- &node,
+fn generate_virtio_devices_node(fdt: &mut FdtBuilder, res: &SysRes) -> util::errors::Result<()> {
+ let node = format!("virtio_mmio@{:x}", res.region_base);
+ let virtio_node_dep = fdt.begin_node(&node)?;
+ fdt.set_property_string("compatible", "virtio,mmio")?;
+ fdt.set_property_u32("interrupt-parent", fdt::GIC_PHANDLE)?;
+ fdt.set_property_array_u64("reg", &[res.region_base, res.region_size])?;
+ fdt.set_property_array_u32(
"interrupts",
&[
- device_tree::GIC_FDT_IRQ_TYPE_SPI,
+ fdt::GIC_FDT_IRQ_TYPE_SPI,
res.irq as u32,
- device_tree::IRQ_TYPE_EDGE_RISING,
+ fdt::IRQ_TYPE_EDGE_RISING,
],
)?;
+ fdt.end_node(virtio_node_dep)?;
Ok(())
}
@@ -1555,73 +1555,72 @@ fn generate_virtio_devices_node(fdt: &mut Vec<u8>, res: &SysRes) -> util::errors
#[cfg(target_arch = "aarch64")]
trait CompileFDTHelper {
/// Function that helps to generate cpu nodes.
- fn generate_cpu_nodes(&self, fdt: &mut Vec<u8>) -> util::errors::Result<()>;
+ fn generate_cpu_nodes(&self, fdt: &mut FdtBuilder) -> util::errors::Result<()>;
/// Function that helps to generate memory nodes.
- fn generate_memory_node(&self, fdt: &mut Vec<u8>) -> util::errors::Result<()>;
+ fn generate_memory_node(&self, fdt: &mut FdtBuilder) -> util::errors::Result<()>;
/// Function that helps to generate Virtio-mmio devices' nodes.
- fn generate_devices_node(&self, fdt: &mut Vec<u8>) -> util::errors::Result<()>;
+ fn generate_devices_node(&self, fdt: &mut FdtBuilder) -> util::errors::Result<()>;
/// Function that helps to generate the chosen node.
- fn generate_chosen_node(&self, fdt: &mut Vec<u8>) -> util::errors::Result<()>;
+ fn generate_chosen_node(&self, fdt: &mut FdtBuilder) -> util::errors::Result<()>;
}
#[cfg(target_arch = "aarch64")]
impl CompileFDTHelper for LightMachine {
- fn generate_cpu_nodes(&self, fdt: &mut Vec<u8>) -> util::errors::Result<()> {
- let node = "/cpus";
+ fn generate_cpu_nodes(&self, fdt: &mut FdtBuilder) -> util::errors::Result<()> {
+ let node = "cpus";
- device_tree::add_sub_node(fdt, node)?;
- device_tree::set_property_u32(fdt, node, "#address-cells", 0x02)?;
- device_tree::set_property_u32(fdt, node, "#size-cells", 0x0)?;
+ let cpus_node_dep = fdt.begin_node(node)?;
+ fdt.set_property_u32("#address-cells", 0x02)?;
+ fdt.set_property_u32("#size-cells", 0x0)?;
// Generate CPU topology
if self.cpu_topo.max_cpus > 0 && self.cpu_topo.max_cpus % 8 == 0 {
- device_tree::add_sub_node(fdt, "/cpus/cpu-map")?;
+ let cpu_map_node_dep = fdt.begin_node("cpu-map")?;
let sockets = self.cpu_topo.max_cpus / 8;
for cluster in 0..u32::from(sockets) {
- let clster = format!("/cpus/cpu-map/cluster{}", cluster);
- device_tree::add_sub_node(fdt, &clster)?;
+ let clster = format!("cluster{}", cluster);
+ let cluster_node_dep = fdt.begin_node(&clster)?;
for i in 0..2_u32 {
- let sub_cluster = format!("{}/cluster{}", clster, i);
- device_tree::add_sub_node(fdt, &sub_cluster)?;
-
- let core0 = format!("{}/core0", sub_cluster);
- device_tree::add_sub_node(fdt, &core0)?;
- let thread0 = format!("{}/thread0", core0);
- device_tree::add_sub_node(fdt, &thread0)?;
- device_tree::set_property_u32(fdt, &thread0, "cpu", cluster * 8 + i * 4 + 10)?;
-
- let thread1 = format!("{}/thread1", core0);
- device_tree::add_sub_node(fdt, &thread1)?;
- device_tree::set_property_u32(
- fdt,
- &thread1,
- "cpu",
- cluster * 8 + i * 4 + 10 + 1,
- )?;
-
- let core1 = format!("{}/core1", sub_cluster);
- device_tree::add_sub_node(fdt, &core1)?;
- let thread0 = format!("{}/thread0", core1);
- device_tree::add_sub_node(fdt, &thread0)?;
- device_tree::set_property_u32(
- fdt,
- &thread0,
- "cpu",
- cluster * 8 + i * 4 + 10 + 2,
- )?;
-
- let thread1 = format!("{}/thread1", core1);
- device_tree::add_sub_node(fdt, &thread1)?;
- device_tree::set_property_u32(
- fdt,
- &thread1,
- "cpu",
- cluster * 8 + i * 4 + 10 + 3,
- )?;
+ let sub_cluster = format!("cluster{}", i);
+ let sub_cluster_node_dep = fdt.begin_node(&sub_cluster)?;
+
+ let core0 = "core0".to_string();
+ let core0_node_dep = fdt.begin_node(&core0)?;
+
+ let thread0 = "thread0".to_string();
+ let thread0_node_dep = fdt.begin_node(&thread0)?;
+ fdt.set_property_u32("cpu", cluster * 8 + i * 4 + 10)?;
+ fdt.end_node(thread0_node_dep)?;
+
+ let thread1 = "thread1".to_string();
+ let thread1_node_dep = fdt.begin_node(&thread1)?;
+ fdt.set_property_u32("cpu", cluster * 8 + i * 4 + 10 + 1)?;
+ fdt.end_node(thread1_node_dep)?;
+
+ fdt.end_node(core0_node_dep)?;
+
+ let core1 = "core1".to_string();
+ let core1_node_dep = fdt.begin_node(&core1)?;
+
+ let thread0 = "thread0".to_string();
+ let thread0_node_dep = fdt.begin_node(&thread0)?;
+ fdt.set_property_u32("cpu", cluster * 8 + i * 4 + 10 + 2)?;
+ fdt.end_node(thread0_node_dep)?;
+
+ let thread1 = "thread1".to_string();
+ let thread1_node_dep = fdt.begin_node(&thread1)?;
+ fdt.set_property_u32("cpu", cluster * 8 + i * 4 + 10 + 3)?;
+ fdt.end_node(thread1_node_dep)?;
+
+ fdt.end_node(core1_node_dep)?;
+
+ fdt.end_node(sub_cluster_node_dep)?;
}
+ fdt.end_node(cluster_node_dep)?;
}
+ fdt.end_node(cpu_map_node_dep)?;
}
let cpu_list = self.cpus.lock().unwrap();
@@ -1632,68 +1631,69 @@ impl CompileFDTHelper for LightMachine {
.unwrap()
.get_mpidr(cpu_list[cpu_index as usize].fd());
- let node = format!("/cpus/cpu@{:x}", mpidr);
- device_tree::add_sub_node(fdt, &node)?;
- device_tree::set_property_u32(
- fdt,
- &node,
- "phandle",
- u32::from(cpu_index) + device_tree::CPU_PHANDLE_START,
- )?;
- device_tree::set_property_string(fdt, &node, "device_type", "cpu")?;
- device_tree::set_property_string(fdt, &node, "compatible", "arm,arm-v8")?;
+ let node = format!("cpu@{:x}", mpidr);
+ let mpidr_node_dep = fdt.begin_node(&node)?;
+ fdt.set_property_u32("phandle", u32::from(cpu_index) + fdt::CPU_PHANDLE_START)?;
+ fdt.set_property_string("device_type", "cpu")?;
+ fdt.set_property_string("compatible", "arm,arm-v8")?;
if self.cpu_topo.max_cpus > 1 {
- device_tree::set_property_string(fdt, &node, "enable-method", "psci")?;
+ fdt.set_property_string("enable-method", "psci")?;
}
- device_tree::set_property_u64(fdt, &node, "reg", mpidr & 0x007F_FFFF)?;
+ fdt.set_property_u64("reg", mpidr & 0x007F_FFFF)?;
+ fdt.end_node(mpidr_node_dep)?;
}
+ fdt.end_node(cpus_node_dep)?;
+
Ok(())
}
- fn generate_memory_node(&self, fdt: &mut Vec<u8>) -> util::errors::Result<()> {
+ fn generate_memory_node(&self, fdt: &mut FdtBuilder) -> util::errors::Result<()> {
let mem_base = MEM_LAYOUT[LayoutEntryType::Mem as usize].0;
let mem_size = self.sys_mem.memory_end_address().raw_value()
- MEM_LAYOUT[LayoutEntryType::Mem as usize].0;
- let node = "/memory";
- device_tree::add_sub_node(fdt, node)?;
- device_tree::set_property_string(fdt, node, "device_type", "memory")?;
- device_tree::set_property_array_u64(fdt, node, "reg", &[mem_base, mem_size as u64])?;
+ let node = "memory";
+ let memory_node_dep = fdt.begin_node(node)?;
+ fdt.set_property_string("device_type", "memory")?;
+ fdt.set_property_array_u64("reg", &[mem_base, mem_size as u64])?;
+ fdt.end_node(memory_node_dep)?;
Ok(())
}
- fn generate_devices_node(&self, fdt: &mut Vec<u8>) -> util::errors::Result<()> {
+ fn generate_devices_node(&self, fdt: &mut FdtBuilder) -> util::errors::Result<()> {
// timer
let mut cells: Vec<u32> = Vec::new();
for &irq in [13, 14, 11, 10].iter() {
- cells.push(device_tree::GIC_FDT_IRQ_TYPE_PPI);
+ cells.push(fdt::GIC_FDT_IRQ_TYPE_PPI);
cells.push(irq);
- cells.push(device_tree::IRQ_TYPE_LEVEL_HIGH);
+ cells.push(fdt::IRQ_TYPE_LEVEL_HIGH);
}
- let node = "/timer";
- device_tree::add_sub_node(fdt, node)?;
- device_tree::set_property_string(fdt, node, "compatible", "arm,armv8-timer")?;
- device_tree::set_property(fdt, node, "always-on", None)?;
- device_tree::set_property_array_u32(fdt, node, "interrupts", &cells)?;
+ let node = "timer";
+ let timer_node_dep = fdt.begin_node(node)?;
+ fdt.set_property_string("compatible", "arm,armv8-timer")?;
+ fdt.set_property("always-on", &Vec::new())?;
+ fdt.set_property_array_u32("interrupts", &cells)?;
+ fdt.end_node(timer_node_dep)?;
// clock
- let node = "/apb-pclk";
- device_tree::add_sub_node(fdt, node)?;
- device_tree::set_property_string(fdt, node, "compatible", "fixed-clock")?;
- device_tree::set_property_string(fdt, node, "clock-output-names", "clk24mhz")?;
- device_tree::set_property_u32(fdt, node, "#clock-cells", 0x0)?;
- device_tree::set_property_u32(fdt, node, "clock-frequency", 24_000_000)?;
- device_tree::set_property_u32(fdt, node, "phandle", device_tree::CLK_PHANDLE)?;
+ let node = "apb-pclk";
+ let clock_node_dep = fdt.begin_node(node)?;
+ fdt.set_property_string("compatible", "fixed-clock")?;
+ fdt.set_property_string("clock-output-names", "clk24mhz")?;
+ fdt.set_property_u32("#clock-cells", 0x0)?;
+ fdt.set_property_u32("clock-frequency", 24_000_000)?;
+ fdt.set_property_u32("phandle", fdt::CLK_PHANDLE)?;
+ fdt.end_node(clock_node_dep)?;
// psci
- let node = "/psci";
- device_tree::add_sub_node(fdt, node)?;
- device_tree::set_property_string(fdt, node, "compatible", "arm,psci-0.2")?;
- device_tree::set_property_string(fdt, node, "method", "hvc")?;
+ let node = "psci";
+ let psci_node_dep = fdt.begin_node(node)?;
+ fdt.set_property_string("compatible", "arm,psci-0.2")?;
+ fdt.set_property_string("method", "hvc")?;
+ fdt.end_node(psci_node_dep)?;
- // Reversing vector is needed because FDT node is added in reverse.
- for dev in self.sysbus.devices.iter().rev() {
+ for dev in self.sysbus.devices.iter() {
let mut locked_dev = dev.lock().unwrap();
let dev_type = locked_dev.get_type();
let sys_res = locked_dev.get_sys_resource();
@@ -1707,46 +1707,39 @@ impl CompileFDTHelper for LightMachine {
Ok(())
}
- fn generate_chosen_node(&self, fdt: &mut Vec<u8>) -> util::errors::Result<()> {
- let node = "/chosen";
-
+ fn generate_chosen_node(&self, fdt: &mut FdtBuilder) -> util::errors::Result<()> {
+ let node = "chosen";
let boot_source = self.boot_source.lock().unwrap();
- device_tree::add_sub_node(fdt, node)?;
+ let chosen_node_dep = fdt.begin_node(node)?;
let cmdline = &boot_source.kernel_cmdline.to_string();
- device_tree::set_property_string(fdt, node, "bootargs", cmdline.as_str())?;
+ fdt.set_property_string("bootargs", cmdline.as_str())?;
match &boot_source.initrd {
Some(initrd) => {
- device_tree::set_property_u64(
- fdt,
- node,
- "linux,initrd-start",
- *initrd.initrd_addr.lock().unwrap(),
- )?;
- device_tree::set_property_u64(
- fdt,
- node,
+ fdt.set_property_u64("linux,initrd-start", *initrd.initrd_addr.lock().unwrap())?;
+ fdt.set_property_u64(
"linux,initrd-end",
*initrd.initrd_addr.lock().unwrap() + initrd.initrd_size,
)?;
}
None => {}
}
+ fdt.end_node(chosen_node_dep)?;
Ok(())
}
}
#[cfg(target_arch = "aarch64")]
-impl device_tree::CompileFDT for LightMachine {
- fn generate_fdt_node(&self, fdt: &mut Vec<u8>) -> util::errors::Result<()> {
- device_tree::create_device_tree(fdt)?;
+impl fdt::CompileFDT for LightMachine {
+ fn generate_fdt_node(&self, fdt: &mut FdtBuilder) -> util::errors::Result<()> {
+ let node_dep = fdt.begin_node("")?;
- device_tree::set_property_string(fdt, "/", "compatible", "linux,dummy-virt")?;
- device_tree::set_property_u32(fdt, "/", "#address-cells", 0x2)?;
- device_tree::set_property_u32(fdt, "/", "#size-cells", 0x2)?;
- device_tree::set_property_u32(fdt, "/", "interrupt-parent", device_tree::GIC_PHANDLE)?;
+ fdt.set_property_string("compatible", "linux,dummy-virt")?;
+ fdt.set_property_u32("#address-cells", 0x2)?;
+ fdt.set_property_u32("#size-cells", 0x2)?;
+ fdt.set_property_u32("interrupt-parent", fdt::GIC_PHANDLE)?;
self.generate_cpu_nodes(fdt)?;
self.generate_memory_node(fdt)?;
@@ -1754,6 +1747,8 @@ impl device_tree::CompileFDT for LightMachine {
self.generate_chosen_node(fdt)?;
self.irq_chip.as_ref().unwrap().generate_fdt_node(fdt)?;
+ fdt.end_node(node_dep)?;
+
Ok(())
}
}
--
2.31.1

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,220 @@
From 1081b4f57b1bc959fa5e26a1e6520f1cfbf999b0 Mon Sep 17 00:00:00 2001
From: Jiajie Li <lijiajie11@huawei.com>
Date: Thu, 24 Jun 2021 16:15:48 +0800
Subject: [PATCH 5/5] util/fdt: add some UT test cases
Test the basic function of mod fdt, like adding all kinds
of properties for fdt node, adding nested node, getting the
final result. What's more, add some boundary test cases.
Signed-off-by: Jiajie Li <lijiajie11@huawei.com>
---
util/src/device_tree.rs | 195 ++++++++++++++++++++++++++++++++++++++++
1 file changed, 195 insertions(+)
diff --git a/util/src/device_tree.rs b/util/src/device_tree.rs
index 2fdab44..d47b7f5 100644
--- a/util/src/device_tree.rs
+++ b/util/src/device_tree.rs
@@ -298,3 +298,198 @@ pub fn dump_dtb(fdt: &[u8], file_path: &str) {
let mut f = File::create(file_path).unwrap();
f.write_all(fdt).expect("Unable to write data");
}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ #[test]
+ fn test_add_all_properties() {
+ let mut fdt_builder = FdtBuilder::new();
+ let root_node = fdt_builder.begin_node("").unwrap();
+ fdt_builder.set_property("null", &[]).unwrap();
+ fdt_builder.set_property_u32("u32", 0x01234567).unwrap();
+ fdt_builder
+ .set_property_u64("u64", 0x0123456789abcdef)
+ .unwrap();
+ fdt_builder
+ .set_property_array_u32(
+ "u32_array",
+ &vec![0x11223344, 0x55667788, 0x99aabbcc, 0xddeeff00],
+ )
+ .unwrap();
+ fdt_builder
+ .set_property_array_u64("u64_array", &vec![0x0011223344556677, 0x8899aabbccddeeff])
+ .unwrap();
+ fdt_builder
+ .set_property_string("string", "hello fdt")
+ .unwrap();
+ fdt_builder.end_node(root_node).unwrap();
+ let right_fdt: Vec<u8> = vec![
+ 0xd0, 0x0d, 0xfe, 0xed, // 00: magic (0xd00dfeed)
+ 0x00, 0x00, 0x00, 0xf0, // 04: totalsize (0xf0)
+ 0x00, 0x00, 0x00, 0x38, // 08: off_dt_struct (0x38)
+ 0x00, 0x00, 0x00, 0xc8, // 0c: off_dt_strings (0xc8)
+ 0x00, 0x00, 0x00, 0x28, // 10: off_mem_rsvmap (0x28)
+ 0x00, 0x00, 0x00, 0x11, // 14: version (17)
+ 0x00, 0x00, 0x00, 0x10, // 18: last_comp_version (16)
+ 0x00, 0x00, 0x00, 0x00, // 1c: boot_cpuid_phys (0)
+ 0x00, 0x00, 0x00, 0x28, // 20: size_dt_strings (0x28)
+ 0x00, 0x00, 0x00, 0x90, // 24: size_dt_struct (0x90)
+ 0x00, 0x00, 0x00, 0x00, // 28: high address of memory reservation block terminator
+ 0x00, 0x00, 0x00, 0x00, // 2c: low address of memory reservation block terminator
+ 0x00, 0x00, 0x00, 0x00, // 30: high size of memory reservation block terminator
+ 0x00, 0x00, 0x00, 0x00, // 34: low size of memory reservation block terminator
+ 0x00, 0x00, 0x00, 0x01, // 38: FDT_BEGIN_NODE
+ 0x00, 0x00, 0x00, 0x00, // 3c: node name ("") with 4-byte alignment
+ 0x00, 0x00, 0x00, 0x03, // 40: FDT_PROP ("null")
+ 0x00, 0x00, 0x00, 0x00, // 44: property len (0)
+ 0x00, 0x00, 0x00, 0x00, // 48: property nameoff (0x00)
+ 0x00, 0x00, 0x00, 0x03, // 4c: FDT_PROP ("u32")
+ 0x00, 0x00, 0x00, 0x04, // 50: property len (4)
+ 0x00, 0x00, 0x00, 0x05, // 54: property nameoff (0x05)
+ 0x01, 0x23, 0x45, 0x67, // 58: propertys value (0x01234567)
+ 0x00, 0x00, 0x00, 0x03, // 5c: FDT_PROP ("u64")
+ 0x00, 0x00, 0x00, 0x08, // 60: property len (8)
+ 0x00, 0x00, 0x00, 0x09, // 64: property nameoff (0x09)
+ 0x01, 0x23, 0x45, 0x67, // 68: propertys value (0x01234567)
+ 0x89, 0xab, 0xcd, 0xef, // 6c: propertys value (0x89abcdef)
+ 0x00, 0x00, 0x00, 0x03, // 70: FDT_PROP ("u32_array")
+ 0x00, 0x00, 0x00, 0x10, // 74: property len (16)
+ 0x00, 0x00, 0x00, 0x0d, // 78: property nameoff (0x0d)
+ 0x11, 0x22, 0x33, 0x44, // 7c: propertys value (0x11223344)
+ 0x55, 0x66, 0x77, 0x88, // 80: propertys value (0x55667788)
+ 0x99, 0xaa, 0xbb, 0xcc, // 84: propertys value (0x99aabbcc)
+ 0xdd, 0xee, 0xff, 0x00, // 88: propertys value (0xddeeff00)
+ 0x00, 0x00, 0x00, 0x03, // 8c: FDT_PROP ("u64_array")
+ 0x00, 0x00, 0x00, 0x10, // 90: property len (16)
+ 0x00, 0x00, 0x00, 0x17, // 94: property nameoff (0x17)
+ 0x00, 0x11, 0x22, 0x33, // 98: propertys value (0x00112233)
+ 0x44, 0x55, 0x66, 0x77, // 9c: propertys value (0x44556677)
+ 0x88, 0x99, 0xaa, 0xbb, // a0: propertys value (0x8899aabb)
+ 0xcc, 0xdd, 0xee, 0xff, // a4: propertys value (0xccddeeff)
+ 0x00, 0x00, 0x00, 0x03, // a8: FDT_PROP ("string")
+ 0x00, 0x00, 0x00, 0x0a, // ac: property len (10)
+ 0x00, 0x00, 0x00, 0x21, // b0: property nameoff (0x21)
+ b'h', b'e', b'l', b'l', // b4: propertys value ("hell")
+ b'o', b' ', b'f', b'd', // b8: propertys value ("o fd")
+ b't', b'\0', 0x00, 0x00, // bc: propertys value ("t\0" with padding)
+ 0x00, 0x00, 0x00, 0x02, // c0: FDT_END_NODE
+ 0x00, 0x00, 0x00, 0x09, // c4: FDT_END
+ b'n', b'u', b'l', b'l', b'\0', // c8: "null" with offset 0x00
+ b'u', b'3', b'2', b'\0', // cd: "u32" with offset 0x05
+ b'u', b'6', b'4', b'\0', // d1: "u64" with offset 0x09
+ b'u', b'3', b'2', b'_', b'a', b'r', b'r', b'a', b'y',
+ b'\0', // d5: "u32_array" with offset 0x0d
+ b'u', b'6', b'4', b'_', b'a', b'r', b'r', b'a', b'y',
+ b'\0', // df: "u64_array" with offset 0x17
+ b's', b't', b'r', b'i', b'n', b'g', b'\0', // e9: "string" with offset 0x21
+ ];
+ let sample_fdt = fdt_builder.finish().unwrap();
+ assert_eq!(right_fdt, sample_fdt);
+ }
+
+ #[test]
+ fn test_nested_node() {
+ let mut fdt_builder = FdtBuilder::new();
+ let root_node = fdt_builder.begin_node("").unwrap();
+
+ let cpus_node = fdt_builder.begin_node("cpus").unwrap();
+ fdt_builder.set_property_u32("addrcells", 0x02).unwrap();
+ fdt_builder.set_property_u32("sizecells", 0x0).unwrap();
+
+ let cpu_map_node = fdt_builder.begin_node("cpu-map").unwrap();
+ fdt_builder.set_property_u32("cpu", 10).unwrap();
+
+ fdt_builder.end_node(cpu_map_node).unwrap();
+ fdt_builder.end_node(cpus_node).unwrap();
+ fdt_builder.end_node(root_node).unwrap();
+
+ fdt_builder.set_boot_cpuid_phys(1);
+
+ let right_fdt: Vec<u8> = vec![
+ 0xd0, 0x0d, 0xfe, 0xed, // 00: magic (0xd00dfeed)
+ 0x00, 0x00, 0x00, 0xb0, // 04: totalsize (0xb0)
+ 0x00, 0x00, 0x00, 0x38, // 08: off_dt_struct (0x38)
+ 0x00, 0x00, 0x00, 0x98, // 0c: off_dt_strings (0x98)
+ 0x00, 0x00, 0x00, 0x28, // 10: off_mem_rsvmap (0x28)
+ 0x00, 0x00, 0x00, 0x11, // 14: version (17)
+ 0x00, 0x00, 0x00, 0x10, // 18: last_comp_version (16)
+ 0x00, 0x00, 0x00, 0x01, // 1c: boot_cpuid_phys (1)
+ 0x00, 0x00, 0x00, 0x18, // 20: size_dt_strings (0x18)
+ 0x00, 0x00, 0x00, 0x60, // 24: size_dt_struct (0x60)
+ 0x00, 0x00, 0x00, 0x00, // 28: high address of memory reservation block terminator
+ 0x00, 0x00, 0x00, 0x00, // 2c: low address of memory reservation block terminator
+ 0x00, 0x00, 0x00, 0x00, // 30: high size of memory reservation block terminator
+ 0x00, 0x00, 0x00, 0x00, // 34: low size of memory reservation block terminator
+ 0x00, 0x00, 0x00, 0x01, // 38: FDT_BEGIN_NODE
+ 0x00, 0x00, 0x00, 0x00, // 3c: node name ("")
+ 0x00, 0x00, 0x00, 0x01, // 40: FDT_BEGIN_NODE
+ b'c', b'p', b'u', b's', // 44: node name ("cpus") with 4-byte alignment
+ b'\0', 0x00, 0x00, 0x00, // 48: padding
+ 0x00, 0x00, 0x00, 0x03, // 4c: FDT_PROP ("addrcells")
+ 0x00, 0x00, 0x00, 0x04, // 50: property len (4)
+ 0x00, 0x00, 0x00, 0x00, // 54: property nameoff (0x00)
+ 0x00, 0x00, 0x00, 0x02, // 58: propertys value (0x02)
+ 0x00, 0x00, 0x00, 0x03, // 5c: FDT_PROP ("sizecells")
+ 0x00, 0x00, 0x00, 0x04, // 60: property len (4)
+ 0x00, 0x00, 0x00, 0x0a, // 64: property nameoff (0xa)
+ 0x00, 0x00, 0x00, 0x00, // 68: propertys value (0x0)
+ 0x00, 0x00, 0x00, 0x01, // 6c: FDT_BEGIN_NODE
+ b'c', b'p', b'u', b'-', // 70: node name ("cpu-map")
+ b'm', b'a', b'p', b'\0', // 74: node name ("cpu-map")
+ 0x00, 0x00, 0x00, 0x03, // 78: FDT_PROP ("cpu")
+ 0x00, 0x00, 0x00, 0x04, // 7c: property len (4)
+ 0x00, 0x00, 0x00, 0x14, // 80: property nameoff (0x14)
+ 0x00, 0x00, 0x00, 0x0a, // 84: propertys value (10)
+ 0x00, 0x00, 0x00, 0x02, // 88: FDT_END_NODE
+ 0x00, 0x00, 0x00, 0x02, // 8c: FDT_END_NODE
+ 0x00, 0x00, 0x00, 0x02, // 90: FDT_END_NODE
+ 0x00, 0x00, 0x00, 0x09, // 94: FDT_END
+ b'a', b'd', b'd', b'r', b'c', b'e', b'l', b'l', b's',
+ b'\0', // 98: "addrcells" with offset 0x00
+ b's', b'i', b'z', b'e', b'c', b'e', b'l', b'l', b's',
+ b'\0', // a2: "sizecells" with offset 0x0a
+ b'c', b'p', b'u', b'\0', // ac: "cpu" with offset 0x14
+ ];
+ let sample_fdt = fdt_builder.finish().unwrap();
+ assert_eq!(right_fdt, sample_fdt);
+ }
+
+ #[test]
+ fn test_illegeal_string() {
+ let mut fdt_builder = FdtBuilder::new();
+ assert!(fdt_builder.begin_node("bad\0string").is_err());
+
+ fdt_builder.begin_node("good string").unwrap();
+ assert!(fdt_builder.set_property("bad property\0name", &[]).is_err());
+ assert!(fdt_builder
+ .set_property_string("good property name", "test\0val")
+ .is_ok());
+ }
+
+ #[test]
+ fn test_unclose_nested_node() {
+ let mut fdt_builder = FdtBuilder::new();
+ let root_node = fdt_builder.begin_node("").unwrap();
+ fdt_builder.begin_node("nested node").unwrap();
+ assert!(fdt_builder.end_node(root_node).is_err());
+ assert!(fdt_builder.finish().is_err());
+ }
+
+ #[test]
+ fn test_mem_reserve_overlap() {
+ let mut fdt_builder = FdtBuilder::new();
+ let mem_reservations = [
+ FdtReserveEntry {
+ address: 0x100,
+ size: 0x100,
+ },
+ FdtReserveEntry {
+ address: 0x150,
+ size: 0x100,
+ },
+ ];
+ assert!(fdt_builder.add_mem_reserve(&mem_reservations).is_err());
+ }
+}
--
2.31.1

View File

@ -6,7 +6,7 @@
Name: stratovirt
Version: 0.3.0
Release: 4
Release: 5
Summary: StratoVirt is an opensource VMM(Virtual Machine Manager) which aims to perform next generation virtualization.
License: Mulan PSL v2
@ -23,6 +23,12 @@ Patch0007: 0007-testcases-virtio_blk-decrease-hot-plugged-blk-number.patch
Patch0008: 0008-testscases-vmlife-decrease-test-blk-number.patch
Patch0009: 0009-README-update-readme.patch
Patch0010: 0010-docs-add-IMAGE_BUILD.md.patch
Patch0011: 0011-util-fdt-implement-basic-fdt-API.patch
Patch0012: 0012-devices-gicv3-use-mod-fdt-instead-of-device_tree.patch
Patch0013: 0013-machine-micro_vm-use-fdt-API-of-mod-fdt-instead-of-d.patch
Patch0014: 0014-Replace-mod-device_tree-with-mod-fdt.patch
Patch0015: 0015-util-fdt-add-some-UT-test-cases.patch
ExclusiveArch: x86_64 aarch64
@ -55,11 +61,19 @@ Summary: %{summary}
%build
%ifarch aarch64
sed -i '/\[build\]/a target="aarch64-unknown-linux-musl"' ./.cargo/config
%endif
%ifarch x86_64
sed -i '/\[build\]/a target="x86_64-unknown-linux-musl"' ./.cargo/config
%endif
sed -i '/\[source.crates-io\]/{n;d}' ./.cargo/config
sed -i '/\[source.local-registry\]/{n;d}' ./.cargo/config
sed -i '/\[source.local-registry\]/a directory = "vendor"' ./.cargo/config
%ifarch aarch64
sed -i 's/rustflags = \[/rustflags = \["-Clink-arg=-lgcc", "-Clink-arg=-lfdt", /g' ./.cargo/config
sed -i 's/rustflags = \[/rustflags = \["-Clink-arg=-lgcc", /g' ./.cargo/config
%endif
%cargo_build -a
@ -69,6 +83,12 @@ sed -i 's/rustflags = \[/rustflags = \["-Clink-arg=-lgcc", "-Clink-arg=-lfdt", /
chmod 550 ${RPM_BUILD_ROOT}/usr/bin/stratovirt
%changelog
* Tue Jul 27 2021 XuFei <xufei30@huawei.com> - 0.3.0-5
- Type:NA
- ID:NA
- SUG:NA
- DESC:add fdt patches for musl compilation
* Wed Jun 16 2021 XuFei <xufei30@huawei.com> - 0.3.0-4
- Type:NA
- ID:NA