From 792248c876ba6f3ef4fa1e6c05c7e9a157ec5528 Mon Sep 17 00:00:00 2001 From: Jiajie Li 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 --- 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, + /// 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, + /// The structure block of flattened device tree. + /// It describes the structure and contents of the tree. + structure_blk: Vec, + /// The strings block of flattened device tree. + /// It contains strings representing all the property names used in the tree. + strings_blk: Vec, + /// The physical ID of the system’s 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> { + 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 { + 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 node’s 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::()); + 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::()); + 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