build: Finish migration to monorepo
This commit is contained in:
@@ -0,0 +1,2 @@
|
||||
[alias]
|
||||
xtask = "run --manifest-path ./xtask/Cargo.toml --"
|
||||
@@ -1 +1,2 @@
|
||||
/target
|
||||
/toolchain
|
||||
|
||||
Generated
+2008
File diff suppressed because it is too large
Load Diff
+17
@@ -0,0 +1,17 @@
|
||||
[workspace]
|
||||
resolver = "2"
|
||||
exclude = [
|
||||
"boot/yboot",
|
||||
"boot/yboot-proto",
|
||||
"tool/abi-generator",
|
||||
"toolchain",
|
||||
]
|
||||
members = [
|
||||
"xtask",
|
||||
"kernel/tools/gentables",
|
||||
"kernel",
|
||||
"lib/abi",
|
||||
"lib/abi-def",
|
||||
"lib/libyalloc",
|
||||
"lib/runtime",
|
||||
]
|
||||
@@ -11,7 +11,4 @@ bytemuck = { version = "1.13.1", features = ["derive"] }
|
||||
log = "0.4.19"
|
||||
uefi = "0.24.0"
|
||||
uefi-services = "0.21.0"
|
||||
yboot-proto = { git = "https://git.alnyan.me/yggdrasil/yboot-proto.git" }
|
||||
|
||||
[patch.'https://git.alnyan.me/yggdrasil/yboot-proto.git']
|
||||
yboot-proto = { path = "../yboot-proto" }
|
||||
|
||||
+5
-5
@@ -10,9 +10,9 @@ authors = ["Mark Poliakov <mark@alnyan.me>"]
|
||||
opt-level = 3
|
||||
|
||||
[dependencies]
|
||||
abi-lib = { git = "https://git.alnyan.me/yggdrasil/abi-generator.git" }
|
||||
abi-lib = { path = "../lib/abi-lib" }
|
||||
yggdrasil-abi = { path = "../lib/abi" }
|
||||
|
||||
yggdrasil-abi = { git = "https://git.alnyan.me/yggdrasil/yggdrasil-abi.git" }
|
||||
vfs = { path = "lib/vfs" }
|
||||
device-api = { path = "lib/device-api", features = ["derive"] }
|
||||
libk = { path = "libk" }
|
||||
@@ -65,7 +65,7 @@ device-tree = { path = "lib/device-tree" }
|
||||
kernel-arch-aarch64 = { path = "arch/aarch64" }
|
||||
|
||||
[target.'cfg(target_arch = "x86_64")'.dependencies]
|
||||
yboot-proto = { git = "https://git.alnyan.me/yggdrasil/yboot-proto.git" }
|
||||
yboot-proto = { path = "../boot/yboot-proto" }
|
||||
aml = { git = "https://github.com/alnyan/acpi.git", branch = "acpi-system" }
|
||||
acpi_lib = { git = "https://github.com/alnyan/acpi.git", package = "acpi", branch = "acpi-system" }
|
||||
acpi-system = { git = "https://github.com/alnyan/acpi-system.git" }
|
||||
@@ -74,8 +74,8 @@ kernel-arch-x86_64 = { path = "arch/x86_64" }
|
||||
|
||||
[build-dependencies]
|
||||
prettyplease = "0.2.15"
|
||||
yggdrasil-abi-def = { git = "https://git.alnyan.me/yggdrasil/yggdrasil-abi-def.git" }
|
||||
abi-generator = { git = "https://git.alnyan.me/yggdrasil/abi-generator.git" }
|
||||
yggdrasil-abi-def = { path = "../lib/abi-def" }
|
||||
abi-generator = { path = "../tool/abi-generator" }
|
||||
|
||||
[features]
|
||||
default = ["fb_console"]
|
||||
|
||||
@@ -3,10 +3,8 @@ name = "kernel-arch-aarch64"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
yggdrasil-abi = { git = "https://git.alnyan.me/yggdrasil/yggdrasil-abi.git" }
|
||||
yggdrasil-abi = { path = "../../../lib/abi" }
|
||||
kernel-arch-interface = { path = "../interface" }
|
||||
libk-mm-interface = { path = "../../libk/libk-mm/interface" }
|
||||
memtables = { path = "../../lib/memtables" }
|
||||
|
||||
@@ -5,5 +5,5 @@ edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
kernel-arch-interface = { path = "../interface" }
|
||||
yggdrasil-abi = { git = "https://git.alnyan.me/yggdrasil/yggdrasil-abi.git" }
|
||||
yggdrasil-abi = { path = "../../../lib/abi" }
|
||||
libk-mm-interface = { path = "../../libk/libk-mm/interface" }
|
||||
|
||||
@@ -3,8 +3,6 @@ name = "kernel-arch-interface"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
yggdrasil-abi = { git = "https://git.alnyan.me/yggdrasil/yggdrasil-abi.git" }
|
||||
yggdrasil-abi = { path = "../../../lib/abi" }
|
||||
device-api = { path = "../../lib/device-api", features = ["derive"] }
|
||||
|
||||
@@ -3,10 +3,8 @@ name = "kernel-arch-x86_64"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
yggdrasil-abi = { git = "https://git.alnyan.me/yggdrasil/yggdrasil-abi.git" }
|
||||
yggdrasil-abi = { path = "../../../lib/abi" }
|
||||
kernel-arch-interface = { path = "../interface" }
|
||||
libk-mm-interface = { path = "../../libk/libk-mm/interface" }
|
||||
memtables = { path = "../../lib/memtables" }
|
||||
|
||||
@@ -4,10 +4,8 @@ version = "0.1.0"
|
||||
edition = "2021"
|
||||
authors = ["Mark Poliakov <mark@alnyan.me>"]
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
yggdrasil-abi = { git = "https://git.alnyan.me/yggdrasil/yggdrasil-abi.git" }
|
||||
yggdrasil-abi = { path = "../../../../lib/abi" }
|
||||
libk-mm = { path = "../../../libk/libk-mm" }
|
||||
libk-thread = { path = "../../../libk/libk-thread" }
|
||||
libk-util = { path = "../../../libk/libk-util" }
|
||||
|
||||
@@ -4,10 +4,8 @@ version = "0.1.0"
|
||||
edition = "2021"
|
||||
authors = ["Mark Poliakov <mark@alnyan.me>"]
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
yggdrasil-abi = { git = "https://git.alnyan.me/yggdrasil/yggdrasil-abi.git" }
|
||||
yggdrasil-abi = { path = "../../../../lib/abi" }
|
||||
libk-util = { path = "../../../libk/libk-util" }
|
||||
libk-mm = { path = "../../../libk/libk-mm" }
|
||||
|
||||
|
||||
@@ -4,10 +4,8 @@ version = "0.1.0"
|
||||
edition = "2021"
|
||||
authors = ["Mark Poliakov <mark@alnyan.me>"]
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
yggdrasil-abi = { git = "https://git.alnyan.me/yggdrasil/yggdrasil-abi.git" }
|
||||
yggdrasil-abi = { path = "../../../../lib/abi" }
|
||||
libk-util = { path = "../../../libk/libk-util" }
|
||||
libk-thread = { path = "../../../libk/libk-thread" }
|
||||
libk-mm = { path = "../../../libk/libk-mm" }
|
||||
|
||||
@@ -4,10 +4,8 @@ version = "0.1.0"
|
||||
edition = "2021"
|
||||
authors = ["Mark Poliakov <mark@alnyan.me>"]
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
yggdrasil-abi = { git = "https://git.alnyan.me/yggdrasil/yggdrasil-abi.git" }
|
||||
yggdrasil-abi = { path = "../../../../lib/abi" }
|
||||
device-api = { path = "../../../lib/device-api", features = ["derive"] }
|
||||
libk-mm = { path = "../../../libk/libk-mm" }
|
||||
libk-device = { path = "../../../libk/libk-device" }
|
||||
|
||||
@@ -5,7 +5,7 @@ edition = "2021"
|
||||
authors = ["Mark Poliakov <mark@alnyan.me>"]
|
||||
|
||||
[dependencies]
|
||||
yggdrasil-abi = { git = "https://git.alnyan.me/yggdrasil/yggdrasil-abi.git" }
|
||||
yggdrasil-abi = { path = "../../../../lib/abi" }
|
||||
device-api = { path = "../../../lib/device-api", features = ["derive"] }
|
||||
ygg_driver_input = { path = "../../input" }
|
||||
|
||||
|
||||
@@ -4,10 +4,8 @@ version = "0.1.0"
|
||||
edition = "2021"
|
||||
authors = ["Mark Poliakov <mark@alnyan.me>"]
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
yggdrasil-abi = { git = "https://git.alnyan.me/yggdrasil/yggdrasil-abi.git" }
|
||||
yggdrasil-abi = { path = "../../../../lib/abi" }
|
||||
vfs = { path = "../../../lib/vfs" }
|
||||
libk-util = { path = "../../../libk/libk-util" }
|
||||
|
||||
|
||||
@@ -4,10 +4,8 @@ version = "0.1.0"
|
||||
edition = "2021"
|
||||
authors = ["Mark Poliakov <mark@alnyan.me>"]
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
yggdrasil-abi = { git = "https://git.alnyan.me/yggdrasil/yggdrasil-abi.git" }
|
||||
yggdrasil-abi = { path = "../../../../lib/abi" }
|
||||
libk-util = { path = "../../../libk/libk-util" }
|
||||
vfs = { path = "../../../lib/vfs" }
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
yggdrasil-abi = { git = "https://git.alnyan.me/yggdrasil/yggdrasil-abi.git" }
|
||||
yggdrasil-abi = { path = "../../../lib/abi" }
|
||||
libk-util = { path = "../../libk/libk-util" }
|
||||
libk-thread = { path = "../../libk/libk-thread" }
|
||||
libk-mm = { path = "../../libk/libk-mm" }
|
||||
|
||||
@@ -3,10 +3,8 @@ name = "ygg_driver_net_core"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
yggdrasil-abi = { git = "https://git.alnyan.me/yggdrasil/yggdrasil-abi.git", features = ["serde_kernel", "bytemuck"] }
|
||||
yggdrasil-abi = { path = "../../../../lib/abi", features = ["serde_kernel", "bytemuck"] }
|
||||
libk-mm = { path = "../../../libk/libk-mm" }
|
||||
libk-util = { path = "../../../libk/libk-util" }
|
||||
libk-thread = { path = "../../../libk/libk-thread" }
|
||||
|
||||
@@ -3,10 +3,8 @@ name = "ygg_driver_net_loopback"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
yggdrasil-abi = { git = "https://git.alnyan.me/yggdrasil/yggdrasil-abi.git" }
|
||||
yggdrasil-abi = { path = "../../../../lib/abi" }
|
||||
libk-util = { path = "../../../libk/libk-util" }
|
||||
libk-mm = { path = "../../../libk/libk-mm" }
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ edition = "2021"
|
||||
authors = ["Mark Poliakov <mark@alnyan.me>"]
|
||||
|
||||
[dependencies]
|
||||
yggdrasil-abi = { git = "https://git.alnyan.me/yggdrasil/yggdrasil-abi.git" }
|
||||
yggdrasil-abi = { path = "../../../../lib/abi" }
|
||||
device-api = { path = "../../../lib/device-api", features = ["derive"] }
|
||||
ygg_driver_pci = { path = "../../bus/pci" }
|
||||
ygg_driver_usb = { path = "../../bus/usb" }
|
||||
|
||||
@@ -3,10 +3,8 @@ name = "ygg_driver_virtio_core"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
yggdrasil-abi = { git = "https://git.alnyan.me/yggdrasil/yggdrasil-abi.git" }
|
||||
yggdrasil-abi = { path = "../../../../lib/abi" }
|
||||
libk-mm = { path = "../../../libk/libk-mm" }
|
||||
device-api = { path = "../../../lib/device-api", features = ["derive"] }
|
||||
|
||||
|
||||
@@ -3,10 +3,8 @@ name = "ygg_driver_virtio_net"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
yggdrasil-abi = { git = "https://git.alnyan.me/yggdrasil/yggdrasil-abi.git" }
|
||||
yggdrasil-abi = { path = "../../../../lib/abi" }
|
||||
libk-util = { path = "../../../libk/libk-util" }
|
||||
libk-mm = { path = "../../../libk/libk-mm" }
|
||||
device-api = { path = "../../../lib/device-api", features = ["derive"] }
|
||||
|
||||
@@ -7,7 +7,7 @@ authors = ["Mark Poliakov <mark@alnyan.me>"]
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
yggdrasil-abi = { git = "https://git.alnyan.me/yggdrasil/yggdrasil-abi.git" }
|
||||
yggdrasil-abi = { path = "../../../lib/abi" }
|
||||
device-api-macros = { path = "macros", optional = true }
|
||||
|
||||
[features]
|
||||
|
||||
@@ -6,7 +6,7 @@ edition = "2021"
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
yggdrasil-abi = { git = "https://git.alnyan.me/yggdrasil/yggdrasil-abi.git" }
|
||||
yggdrasil-abi = { path = "../../../lib/abi" }
|
||||
device-api = { path = "../device-api", features = ["derive"] }
|
||||
libk-mm = { path = "../../libk/libk-mm" }
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ authors = ["Mark Poliakov <mark@alnyan.me>"]
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
yggdrasil-abi = { git = "https://git.alnyan.me/yggdrasil/yggdrasil-abi.git", features = ["alloc"] }
|
||||
yggdrasil-abi = { path = "../../../lib/abi", features = ["alloc"] }
|
||||
libk-mm = { path = "../../libk/libk-mm" }
|
||||
libk-util = { path = "../../libk/libk-util" }
|
||||
libk-thread = { path = "../../libk/libk-thread" }
|
||||
|
||||
@@ -7,7 +7,7 @@ authors = ["Mark Poliakov <mark@alnyan.me>"]
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
yggdrasil-abi = { git = "https://git.alnyan.me/yggdrasil/yggdrasil-abi.git" }
|
||||
yggdrasil-abi = { path = "../../../lib/abi" }
|
||||
|
||||
discrete_range_map = { git = "https://git.alnyan.me/yggdrasil/discrete_range_map.git" }
|
||||
|
||||
|
||||
@@ -4,8 +4,6 @@ version = "0.1.0"
|
||||
edition = "2021"
|
||||
authors = ["Mark Poliakov <mark@alnyan.me>"]
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
libk-mm = { path = "libk-mm" }
|
||||
libk-util = { path = "libk-util" }
|
||||
@@ -13,7 +11,7 @@ libk-thread = { path = "libk-thread" }
|
||||
libk-device = { path = "libk-device" }
|
||||
kernel-arch = { path = "../arch" }
|
||||
|
||||
yggdrasil-abi = { git = "https://git.alnyan.me/yggdrasil/yggdrasil-abi.git" }
|
||||
yggdrasil-abi = { path = "../../lib/abi" }
|
||||
device-api = { path = "../lib/device-api", features = ["derive"] }
|
||||
|
||||
log = "0.4.20"
|
||||
|
||||
@@ -3,11 +3,9 @@ name = "libk-device"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
libk-util = { path = "../libk-util" }
|
||||
kernel-arch = { path = "../../arch" }
|
||||
|
||||
yggdrasil-abi = { git = "https://git.alnyan.me/yggdrasil/yggdrasil-abi.git" }
|
||||
yggdrasil-abi = { path = "../../../lib/abi" }
|
||||
device-api = { path = "../../lib/device-api", features = ["derive"] }
|
||||
|
||||
@@ -6,7 +6,7 @@ edition = "2021"
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
yggdrasil-abi = { git = "https://git.alnyan.me/yggdrasil/yggdrasil-abi.git" }
|
||||
yggdrasil-abi = { path = "../../../lib/abi" }
|
||||
kernel-arch = { path = "../../arch" }
|
||||
libk-util = { path = "../libk-util" }
|
||||
libk-mm-interface = { path = "interface" }
|
||||
|
||||
@@ -6,7 +6,7 @@ edition = "2021"
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
yggdrasil-abi = { git = "https://git.alnyan.me/yggdrasil/yggdrasil-abi.git" }
|
||||
yggdrasil-abi = { path = "../../../../lib/abi" }
|
||||
|
||||
kernel-arch-interface = { path = "../../../arch/interface" }
|
||||
|
||||
|
||||
@@ -10,9 +10,9 @@ libk-util = { path = "../libk-util" }
|
||||
libk-mm = { path = "../libk-mm" }
|
||||
libk-device = { path = "../libk-device" }
|
||||
kernel-arch = { path = "../../arch" }
|
||||
abi-lib = { git = "https://git.alnyan.me/yggdrasil/abi-generator.git" }
|
||||
|
||||
yggdrasil-abi = { git = "https://git.alnyan.me/yggdrasil/yggdrasil-abi.git" }
|
||||
abi-lib = { path = "../../../lib/abi-lib" }
|
||||
yggdrasil-abi = { path = "../../../lib/abi" }
|
||||
|
||||
log = "0.4.20"
|
||||
atomic_enum = "0.2.0"
|
||||
|
||||
@@ -6,7 +6,7 @@ edition = "2021"
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
yggdrasil-abi = { git = "https://git.alnyan.me/yggdrasil/yggdrasil-abi.git" }
|
||||
yggdrasil-abi = { path = "../../../lib/abi" }
|
||||
kernel-arch = { path = "../../arch" }
|
||||
|
||||
log = "0.4.20"
|
||||
|
||||
+3
-3
@@ -14,11 +14,11 @@ compiler_builtins = { version = "0.1", optional = true }
|
||||
serde = { version = "1.0.193", features = ["derive"], default-features = false, optional = true }
|
||||
bytemuck = { version = "1.14.0", features = ["derive"], optional = true }
|
||||
|
||||
abi-lib = { git = "https://git.alnyan.me/yggdrasil/abi-generator.git" }
|
||||
abi-lib = { path = "../../lib/abi-lib" }
|
||||
|
||||
[build-dependencies]
|
||||
yggdrasil-abi-def = { git = "https://git.alnyan.me/yggdrasil/yggdrasil-abi-def.git" }
|
||||
abi-generator = { git = "https://git.alnyan.me/yggdrasil/abi-generator.git" }
|
||||
yggdrasil-abi-def = { path = "../abi-def" }
|
||||
abi-generator = { path = "../../tool/abi-generator" }
|
||||
prettyplease = "0.2.15"
|
||||
|
||||
[features]
|
||||
|
||||
@@ -14,7 +14,7 @@ compiler_builtins = { version = "0.1", optional = true }
|
||||
[target.'cfg(unix)'.dependencies]
|
||||
libc = { version = "0.2.140", default-features = false }
|
||||
[target.'cfg(not(unix))'.dependencies]
|
||||
yggdrasil-rt = { git = "https://git.alnyan.me/yggdrasil/yggdrasil-rt.git", default-features = false }
|
||||
yggdrasil-rt = { path = "../runtime", default-features = false }
|
||||
|
||||
[features]
|
||||
default = []
|
||||
|
||||
@@ -6,17 +6,17 @@ authors = ["Mark Poliakov <mark@alnyan.me>"]
|
||||
build = "build.rs"
|
||||
|
||||
[dependencies]
|
||||
yggdrasil-abi = { git = "https://git.alnyan.me/yggdrasil/yggdrasil-abi.git" }
|
||||
yggdrasil-abi = { path = "../abi" }
|
||||
|
||||
core = { version = "1.0.0", optional = true, package = "rustc-std-workspace-core" }
|
||||
alloc = { version = "1.0.0", optional = true, package = "rustc-std-workspace-alloc" }
|
||||
compiler_builtins = { version = "0.1", optional = true }
|
||||
|
||||
abi-lib = { git = "https://git.alnyan.me/yggdrasil/abi-generator.git" }
|
||||
abi-lib = { path = "../abi-lib" }
|
||||
|
||||
[build-dependencies]
|
||||
abi-generator = { git = "https://git.alnyan.me/yggdrasil/abi-generator.git" }
|
||||
yggdrasil-abi-def = { git = "https://git.alnyan.me/yggdrasil/yggdrasil-abi-def.git" }
|
||||
abi-generator = { path = "../../tool/abi-generator" }
|
||||
yggdrasil-abi-def = { path = "../abi-def" }
|
||||
prettyplease = "0.2.15"
|
||||
cc = "*"
|
||||
|
||||
|
||||
Executable
+14
@@ -0,0 +1,14 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Setup interface
|
||||
ip tuntap add dev qemu-tap0 mode tap
|
||||
ip link set dev qemu-tap0 up
|
||||
ip addr add dev qemu-tap0 11.0.0.1/24
|
||||
|
||||
# Start DHCP server
|
||||
systemctl start dnsmasq.service
|
||||
|
||||
# Setup forwarding to the outer network
|
||||
iptables -t nat -A POSTROUTING --src 11.0.0.0/24 -j MASQUERADE
|
||||
iptables -A FORWARD --src 11.0.0.0/24 -j ACCEPT
|
||||
iptables -A FORWARD --dst 11.0.0.0/24 -j ACCEPT
|
||||
@@ -8,6 +8,3 @@ proc-macro2 = "^1.0.63"
|
||||
quote = "^1.0"
|
||||
syn = { version = "2.0.32", features = ["full"] }
|
||||
thiserror = "1.0.47"
|
||||
|
||||
[workspace]
|
||||
members = ["abi-lib", "example-abi"]
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
[package]
|
||||
name = "example-abi"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
abi-lib = { path = "../abi-lib" }
|
||||
|
||||
[build-dependencies]
|
||||
abi-generator = { path = ".." }
|
||||
prettyplease = "0.2.15"
|
||||
@@ -1,34 +0,0 @@
|
||||
use std::{env, path::Path};
|
||||
|
||||
use abi_generator::{
|
||||
abi::{ty::TypeWidth, AbiBuilder},
|
||||
syntax::UnwrapFancy,
|
||||
TargetEnv,
|
||||
};
|
||||
|
||||
fn main() {
|
||||
println!("cargo:rerun-if-changed={}", "syscall.abi");
|
||||
let output_dir = env::var("OUT_DIR").unwrap();
|
||||
let output = Path::new(&output_dir);
|
||||
|
||||
let abi = AbiBuilder::from_file(
|
||||
"syscall.abi",
|
||||
TargetEnv {
|
||||
thin_pointer_width: TypeWidth::U64,
|
||||
fat_pointer_width: TypeWidth::U128,
|
||||
},
|
||||
)
|
||||
.unwrap_fancy("syscall.abi");
|
||||
|
||||
let types_file = prettyplease::unparse(
|
||||
&abi.emit_file(true, false)
|
||||
.unwrap_fancy("Could not emit generated types"),
|
||||
);
|
||||
let syscalls_file = prettyplease::unparse(
|
||||
&abi.emit_file(false, true)
|
||||
.unwrap_fancy("Could not emit generated syscalls"),
|
||||
);
|
||||
|
||||
std::fs::write(output.join("generated_types.rs"), types_file).unwrap();
|
||||
std::fs::write(output.join("generated_syscalls.rs"), syscalls_file).unwrap();
|
||||
}
|
||||
@@ -1,152 +0,0 @@
|
||||
#![feature(exposed_provenance)]
|
||||
|
||||
use std::sync::Mutex;
|
||||
|
||||
mod types {
|
||||
use std::marker::PhantomData;
|
||||
|
||||
use abi_lib::{SyscallFatRegister, SyscallRegister};
|
||||
|
||||
pub enum MappingSource {}
|
||||
pub struct MountOptions;
|
||||
pub struct UnmountOptions;
|
||||
pub struct DirectoryEntry;
|
||||
pub struct FileAttr;
|
||||
pub struct SpawnOptions<'a> {
|
||||
_a: PhantomData<&'a ()>,
|
||||
}
|
||||
pub struct ThreadSpawnOptions;
|
||||
pub enum MutexOperation {}
|
||||
pub struct SignalEntryData;
|
||||
pub struct DeviceRequest;
|
||||
pub enum SentMessage {}
|
||||
pub enum ReceivedMessageMetadata {}
|
||||
pub struct TerminalOptions;
|
||||
pub struct TerminalSize;
|
||||
pub struct ExecveOptions;
|
||||
pub struct FileMetadataUpdate;
|
||||
pub enum ProcessInfoElement {}
|
||||
pub enum SocketOption {}
|
||||
pub enum SystemInfo {}
|
||||
|
||||
pub enum ExitCode {
|
||||
Exited(u32),
|
||||
Killed(u32),
|
||||
}
|
||||
|
||||
pub enum SeekFrom {
|
||||
Start(u64),
|
||||
Current(i64),
|
||||
End(i64),
|
||||
}
|
||||
|
||||
impl SyscallRegister for ExitCode {
|
||||
fn into_syscall_register(self) -> usize {
|
||||
match self {
|
||||
Self::Killed(value) => (value as usize) | (1 << u32::BITS),
|
||||
Self::Exited(value) => value as usize,
|
||||
}
|
||||
}
|
||||
|
||||
fn from_syscall_register(value: usize) -> Self {
|
||||
if value & (1 << u32::BITS) != 0 {
|
||||
Self::Killed(value as _)
|
||||
} else {
|
||||
Self::Exited(value as _)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl SyscallFatRegister for SeekFrom {
|
||||
fn as_syscall_meta(&self) -> usize {
|
||||
match self {
|
||||
Self::Start(_) => 0,
|
||||
Self::Current(_) => 1,
|
||||
Self::End(_) => 2,
|
||||
}
|
||||
}
|
||||
|
||||
fn as_syscall_data(&self) -> usize {
|
||||
match self {
|
||||
&Self::Start(value) => value as _,
|
||||
&Self::Current(value) | &Self::End(value) => value as _,
|
||||
}
|
||||
}
|
||||
|
||||
fn from_syscall_registers(_meta: usize, _data: usize) -> Self {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
include!(concat!(env!("OUT_DIR"), "/generated_types.rs"));
|
||||
}
|
||||
|
||||
mod calls {
|
||||
use super::types::*;
|
||||
|
||||
macro_rules! syscall {
|
||||
($f:expr $(,)?) => {
|
||||
$crate::syscall0($f)
|
||||
};
|
||||
($f:expr, $a0:expr $(,)?) => {
|
||||
$crate::syscall1($f, $a0)
|
||||
};
|
||||
($f:expr, $a0:expr, $a1:expr $(,)?) => {
|
||||
$crate::syscall2($f, $a0, $a1)
|
||||
};
|
||||
($f:expr, $a0:expr, $a1:expr, $a2:expr $(,)?) => {
|
||||
$crate::syscall3($f, $a0, $a1, $a2)
|
||||
};
|
||||
($f:expr, $a0:expr, $a1:expr, $a2:expr, $a3:expr $(,)?) => {
|
||||
$crate::syscall4($f, $a0, $a1, $a2, $a3)
|
||||
};
|
||||
($f:expr, $a0:expr, $a1:expr, $a2:expr, $a3:expr, $a4:expr $(,)?) => {
|
||||
$crate::syscall5($f, $a0, $a1, $a2, $a3, $a4)
|
||||
};
|
||||
}
|
||||
|
||||
include!(concat!(env!("OUT_DIR"), "/generated_syscalls.rs"));
|
||||
}
|
||||
|
||||
pub use calls::*;
|
||||
pub use types::*;
|
||||
|
||||
static SYSCALL_TRACE: Mutex<Vec<(SyscallFunction, Vec<usize>)>> = Mutex::new(Vec::new());
|
||||
|
||||
fn syscall0(f: SyscallFunction) -> usize {
|
||||
SYSCALL_TRACE.lock().unwrap().push((f, vec![]));
|
||||
0
|
||||
}
|
||||
|
||||
fn syscall1(f: SyscallFunction, a0: usize) -> usize {
|
||||
SYSCALL_TRACE.lock().unwrap().push((f, vec![a0]));
|
||||
0
|
||||
}
|
||||
|
||||
fn syscall2(f: SyscallFunction, a0: usize, a1: usize) -> usize {
|
||||
SYSCALL_TRACE.lock().unwrap().push((f, vec![a0, a1]));
|
||||
0
|
||||
}
|
||||
|
||||
fn syscall3(f: SyscallFunction, a0: usize, a1: usize, a2: usize) -> usize {
|
||||
SYSCALL_TRACE.lock().unwrap().push((f, vec![a0, a1, a2]));
|
||||
0
|
||||
}
|
||||
|
||||
fn syscall4(f: SyscallFunction, a0: usize, a1: usize, a2: usize, a3: usize) -> usize {
|
||||
SYSCALL_TRACE
|
||||
.lock()
|
||||
.unwrap()
|
||||
.push((f, vec![a0, a1, a2, a3]));
|
||||
0
|
||||
}
|
||||
|
||||
fn syscall5(f: SyscallFunction, a0: usize, a1: usize, a2: usize, a3: usize, a4: usize) -> usize {
|
||||
SYSCALL_TRACE
|
||||
.lock()
|
||||
.unwrap()
|
||||
.push((f, vec![a0, a1, a2, a3, a4]));
|
||||
0
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
@@ -1,201 +0,0 @@
|
||||
// vi:syntax=yggdrasil_abi:
|
||||
|
||||
extern {
|
||||
type Duration = core::time::Duration;
|
||||
type Mutex = core::sync::atomic::AtomicU32;
|
||||
type SocketAddr = core::net::SocketAddr;
|
||||
|
||||
type SystemInfo;
|
||||
type MappingSource;
|
||||
type SpawnOptions;
|
||||
type ThreadSpawnOptions;
|
||||
type MutexOperation;
|
||||
type SignalEntryData;
|
||||
type ProcessInfoElement;
|
||||
type ExecveOptions;
|
||||
type MountOptions;
|
||||
type UnmountOptions;
|
||||
type DirectoryEntry;
|
||||
type FileAttr;
|
||||
type DeviceRequest;
|
||||
type SentMessage;
|
||||
type ReceivedMessageMetadata;
|
||||
type TerminalOptions;
|
||||
type TerminalSize;
|
||||
type FileMetadataUpdate;
|
||||
type SocketOption;
|
||||
|
||||
#[thin]
|
||||
type ExitCode;
|
||||
#[fat]
|
||||
type SeekFrom;
|
||||
}
|
||||
|
||||
newtype Fd(u32);
|
||||
newtype ProcessId(u32);
|
||||
newtype ThreadId(u32);
|
||||
newtype ProcessGroupId(u32);
|
||||
|
||||
// TODO define these as enums
|
||||
newtype MessageDestination(u32);
|
||||
|
||||
bitfield OpenOptions(u32) {
|
||||
/// Open the file with read capability
|
||||
READ: 0,
|
||||
/// Open the file with write capability
|
||||
WRITE: 1,
|
||||
|
||||
/// Position at the end of the opened file
|
||||
APPEND: 2,
|
||||
/// Truncate the file to zero bytes when opening
|
||||
TRUNCATE: 3,
|
||||
|
||||
/// Create a new file if it does not exist
|
||||
CREATE: 4,
|
||||
}
|
||||
|
||||
bitfield FileMode(u32) {
|
||||
/// Other user execute access
|
||||
OTHER_EXEC: 0,
|
||||
/// Other user write access
|
||||
OTHER_WRITE: 1,
|
||||
/// Other user read access
|
||||
OTHER_READ: 2,
|
||||
|
||||
/// Group execute access
|
||||
GROUP_EXEC: 0,
|
||||
/// Group write access
|
||||
GROUP_WRITE: 1,
|
||||
/// Group read access
|
||||
GROUP_READ: 2,
|
||||
|
||||
/// Owner execute access
|
||||
USER_EXEC: 0,
|
||||
/// Owner write access
|
||||
USER_WRITE: 1,
|
||||
/// Owner read access
|
||||
USER_READ: 2,
|
||||
}
|
||||
|
||||
enum Signal(u32) {
|
||||
MemoryAccessViolation = 1,
|
||||
Aborted = 2,
|
||||
Killed = 3,
|
||||
Interrupted = 4
|
||||
}
|
||||
|
||||
enum PollControl(u32) {
|
||||
AddFd = 1
|
||||
}
|
||||
|
||||
enum SocketType(u32) {
|
||||
RawPacket = 1,
|
||||
TcpStream = 2,
|
||||
UdpPacket = 3
|
||||
}
|
||||
|
||||
enum Error(u32) {
|
||||
Dummy = 1,
|
||||
UndefinedSyscall = 2,
|
||||
InvalidArgument = 3,
|
||||
}
|
||||
|
||||
syscall test_syscall(a: &(u32, u64));
|
||||
//
|
||||
// // Misc
|
||||
//
|
||||
// syscall debug_trace(msg: &str);
|
||||
// syscall get_random(buffer: &mut [u8]);
|
||||
// syscall get_system_info(info: &mut SystemInfo) -> Result<Fd>;
|
||||
//
|
||||
// // Memory management
|
||||
//
|
||||
// syscall map_memory(hint: Option<NonZeroUsize>, len: usize, source: &MappingSource) -> Result<usize>;
|
||||
// syscall unmap_memory(virt: usize, len: usize) -> Result<()>;
|
||||
//
|
||||
// // Process/thread management
|
||||
//
|
||||
// syscall spawn_process(options: &SpawnOptions<'_>) -> Result<ProcessId>;
|
||||
// syscall spawn_thread(options: &ThreadSpawnOptions) -> Result<ThreadId>;
|
||||
//
|
||||
// syscall exit_thread(code: ExitCode) -> !;
|
||||
// syscall exit_process(code: ExitCode) -> !;
|
||||
// syscall wait_process(pid: ProcessId, status: &mut ExitCode) -> Result<()>;
|
||||
// syscall send_signal(pid: ProcessId, signal: Signal) -> Result<()>;
|
||||
// syscall nanosleep(duration: &Duration);
|
||||
//
|
||||
// syscall mutex(mutex: &Mutex, op: &MutexOperation) -> Result<()>;
|
||||
//
|
||||
// syscall set_signal_entry(entry: usize, stack: usize);
|
||||
// syscall exit_signal(frame: &SignalEntryData) -> !;
|
||||
//
|
||||
// syscall get_pid() -> ProcessId;
|
||||
//
|
||||
// syscall start_session() -> Result<()>;
|
||||
// syscall set_process_group_id(pid: ProcessId, pgid: Option<ProcessGroupId>) -> Result<ProcessGroupId>;
|
||||
//
|
||||
// syscall get_process_info(what: &mut ProcessInfoElement) -> Result<()>;
|
||||
// syscall set_process_info(what: &ProcessInfoElement) -> Result<()>;
|
||||
//
|
||||
// // C compat
|
||||
//
|
||||
// syscall fork() -> Result<ProcessId>;
|
||||
// syscall execve(opts: &ExecveOptions) -> Result<()>;
|
||||
//
|
||||
// // I/O
|
||||
//
|
||||
// syscall write(fd: Fd, data: &[u8]) -> Result<usize>;
|
||||
// syscall read(fd: Fd, data: &mut [u8]) -> Result<usize>;
|
||||
// syscall open(at: Option<Fd>, path: &str, opts: OpenOptions, mode: FileMode) -> Result<Fd>;
|
||||
// syscall close(fd: Fd) -> Result<()>;
|
||||
// syscall mount(options: &MountOptions) -> Result<()>;
|
||||
// syscall unmount(options: &UnmountOptions) -> Result<()>;
|
||||
// syscall open_directory(at: Option<Fd>, path: &str) -> Result<Fd>;
|
||||
// syscall read_directory_entries(fd: Fd, buffer: &mut [MaybeUninit<DirectoryEntry>]) -> Result<usize>;
|
||||
// syscall create_directory(at: Option<Fd>, path: &str, mode: FileMode) -> Result<()>;
|
||||
// syscall remove(at: Option<Fd>, path: &str) -> Result<()>;
|
||||
// syscall remove_directory(at: Option<Fd>, path: &str) -> Result<()>;
|
||||
// syscall get_metadata(at: Option<Fd>, path: &str, metadata: &mut FileAttr, follow: bool) -> Result<()>;
|
||||
// // TODO this one is broken
|
||||
// syscall seek(fd: Fd, pos: SeekFrom) -> Result<usize>;
|
||||
//
|
||||
// syscall device_request(fd: Fd, req: &mut DeviceRequest) -> Result<()>;
|
||||
//
|
||||
// syscall create_pipe(ends: &mut [MaybeUninit<Fd>; 2]) -> Result<()>;
|
||||
//
|
||||
// syscall create_poll_channel() -> Result<Fd>;
|
||||
// syscall poll_channel_control(poll_fd: Fd, ctl: PollControl, fd: Fd) -> Result<()>;
|
||||
// syscall poll_channel_wait(poll_fd: Fd, timeout: &Option<Duration>, out: &mut Option<Fd>) -> Result<()>;
|
||||
//
|
||||
// syscall open_channel(name: &str, subscribe: bool) -> Result<Fd>;
|
||||
// syscall send_message(fd: Fd, message: &SentMessage, destination: MessageDestination) -> Result<()>;
|
||||
// syscall receive_message(
|
||||
// fd: Fd,
|
||||
// metadata: &mut MaybeUninit<ReceivedMessageMetadata>,
|
||||
// buffer: &mut [u8],
|
||||
// from: &mut MaybeUninit<u32>
|
||||
// ) -> Result<usize>;
|
||||
//
|
||||
// syscall create_shared_memory(size: usize) -> Result<Fd>;
|
||||
// syscall create_pty(options: &TerminalOptions, size: &TerminalSize, fds: &mut [MaybeUninit<Fd>; 2]) -> Result<()>;
|
||||
//
|
||||
// syscall clone_fd(source: Fd, target: Option<Fd>) -> Result<Fd>;
|
||||
//
|
||||
// syscall update_metadata(at: Option<Fd>, path: &str, update: &FileMetadataUpdate) -> Result<()>;
|
||||
//
|
||||
// syscall create_timer(repeat: bool) -> Result<Fd>;
|
||||
//
|
||||
// // Network
|
||||
//
|
||||
// syscall bind_socket(listen_address: &SocketAddr, ty: SocketType) -> Result<Fd>;
|
||||
// syscall connect_socket(
|
||||
// socket_fd: Option<Fd>,
|
||||
// remote_address: &SocketAddr,
|
||||
// ty: SocketType,
|
||||
// local_address: &mut MaybeUninit<SocketAddr>
|
||||
// ) -> Result<Fd>;
|
||||
// syscall send_to(socket_fd: Fd, data: &[u8], recepient: &Option<SocketAddr>) -> Result<usize>;
|
||||
// syscall receive_from(socket_fd: Fd, buffer: &mut [u8], sender: &mut MaybeUninit<SocketAddr>) -> Result<usize>;
|
||||
// syscall get_socket_option(socket_fd: Fd, option: &mut SocketOption) -> Result<()>;
|
||||
// syscall set_socket_option(socket_fd: Fd, option: &SocketOption) -> Result<()>;
|
||||
// syscall accept(listener: Fd, address: &mut MaybeUninit<SocketAddr>) -> Result<Fd>;
|
||||
Generated
-2
@@ -5,7 +5,6 @@ version = 3
|
||||
[[package]]
|
||||
name = "abi-generator"
|
||||
version = "0.1.0"
|
||||
source = "git+https://git.alnyan.me/yggdrasil/abi-generator.git#635bf51bb1cde626d477df477604d58d107bc037"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@@ -16,7 +15,6 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "abi-lib"
|
||||
version = "0.1.0"
|
||||
source = "git+https://git.alnyan.me/yggdrasil/abi-generator.git#635bf51bb1cde626d477df477604d58d107bc037"
|
||||
|
||||
[[package]]
|
||||
name = "anstyle"
|
||||
|
||||
@@ -12,10 +12,3 @@ members = [
|
||||
"lib/libterm",
|
||||
"netutils"
|
||||
]
|
||||
|
||||
[patch.'https://git.alnyan.me/yggdrasil/yggdrasil-rt.git']
|
||||
yggdrasil-rt = { path = "../yggdrasil-rt" }
|
||||
[patch.'https://git.alnyan.me/yggdrasil/yggdrasil-abi.git']
|
||||
yggdrasil-abi = { path = "../abi" }
|
||||
[patch.'https://git.alnyan.me/yggdrasil/yggdrasil-abi-def.git']
|
||||
yggdrasil-abi-def = { path = "../abi-def" }
|
||||
|
||||
@@ -5,7 +5,7 @@ edition = "2021"
|
||||
authors = ["Mark Poliakov <mark@alnyan.me>"]
|
||||
|
||||
[dependencies]
|
||||
yggdrasil-abi = { git = "https://git.alnyan.me/yggdrasil/yggdrasil-abi.git", features = ["serde"] }
|
||||
yggdrasil-abi = { path = "../../lib/abi", features = ["serde"] }
|
||||
serde-ipc = { path = "../lib/serde-ipc" }
|
||||
libcolors = { path = "../lib/libcolors", default_features = false }
|
||||
|
||||
|
||||
@@ -17,4 +17,4 @@ path = "src/rc.rs"
|
||||
[dependencies]
|
||||
serde = { version = "1.0.193", features = ["derive"] }
|
||||
serde_json = "1.0.108"
|
||||
yggdrasil-rt = { git = "https://git.alnyan.me/yggdrasil/yggdrasil-rt.git" }
|
||||
yggdrasil-rt = { path = "../../lib/runtime" }
|
||||
|
||||
@@ -6,7 +6,7 @@ authors = ["Mark Poliakov <mark@alnyan.me>"]
|
||||
|
||||
[dependencies]
|
||||
serde-ipc = { path = "../serde-ipc" }
|
||||
yggdrasil-abi = { git = "https://git.alnyan.me/yggdrasil/yggdrasil-abi.git", features = ["serde"] }
|
||||
yggdrasil-abi = { path = "../../../lib/abi", features = ["serde"] }
|
||||
|
||||
serde = { version = "1.0.193", features = ["derive"] }
|
||||
thiserror = "1.0.56"
|
||||
|
||||
@@ -6,7 +6,7 @@ edition = "2021"
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
yggdrasil-abi = { git = "https://git.alnyan.me/yggdrasil/yggdrasil-abi.git", features = ["serde", "alloc", "bytemuck"] }
|
||||
yggdrasil-abi = { path = "../../lib/abi", features = ["serde", "alloc", "bytemuck"] }
|
||||
|
||||
clap = { version = "4.3.19", features = ["std", "derive", "help", "usage"], default-features = false }
|
||||
thiserror = "1.0.50"
|
||||
|
||||
@@ -12,8 +12,8 @@ thiserror = "1.0.50"
|
||||
nom = "7.1.3"
|
||||
|
||||
[target.'cfg(target_os = "yggdrasil")'.dependencies]
|
||||
yggdrasil-rt = { git = "https://git.alnyan.me/yggdrasil/yggdrasil-rt.git" }
|
||||
yggdrasil-abi = { git = "https://git.alnyan.me/yggdrasil/yggdrasil-abi.git" }
|
||||
yggdrasil-rt = { path = "../../lib/runtime" }
|
||||
yggdrasil-abi = { path = "../../lib/abi" }
|
||||
|
||||
[target.'cfg(unix)'.dependencies]
|
||||
libc = "*"
|
||||
|
||||
@@ -8,7 +8,7 @@ authors = ["Mark Poliakov <mark@alnyan.me>"]
|
||||
|
||||
[dependencies]
|
||||
libterm = { path = "../lib/libterm" }
|
||||
yggdrasil-abi = { git = "https://git.alnyan.me/yggdrasil/yggdrasil-abi.git", features = ["serde", "alloc", "bytemuck"] }
|
||||
yggdrasil-abi = { path = "../../lib/abi", features = ["serde", "alloc", "bytemuck"] }
|
||||
|
||||
thiserror = "1.0.50"
|
||||
clap = { version = "4.3.19", features = ["std", "derive", "help", "usage"], default-features = false }
|
||||
|
||||
Generated
+771
@@ -0,0 +1,771 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "aho-corasick"
|
||||
version = "1.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anstream"
|
||||
version = "0.6.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d96bd03f33fe50a863e394ee9718a706f988b9079b20c3784fb726e7678b62fb"
|
||||
dependencies = [
|
||||
"anstyle",
|
||||
"anstyle-parse",
|
||||
"anstyle-query",
|
||||
"anstyle-wincon",
|
||||
"colorchoice",
|
||||
"utf8parse",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anstyle"
|
||||
version = "1.0.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8901269c6307e8d93993578286ac0edf7f195079ffff5ebdeea6a59ffb7e36bc"
|
||||
|
||||
[[package]]
|
||||
name = "anstyle-parse"
|
||||
version = "0.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c75ac65da39e5fe5ab759307499ddad880d724eed2f6ce5b5e8a26f4f387928c"
|
||||
dependencies = [
|
||||
"utf8parse",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anstyle-query"
|
||||
version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e28923312444cdd728e4738b3f9c9cac739500909bb3d3c94b43551b16517648"
|
||||
dependencies = [
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anstyle-wincon"
|
||||
version = "3.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1cd54b81ec8d6180e24654d0b371ad22fc3dd083b6ff8ba325b72e00c87660a7"
|
||||
dependencies = [
|
||||
"anstyle",
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "1.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "2.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf"
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.0.88"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "02f341c093d19155a6e41631ce5971aac4e9a868262212153124c15fa22d1cdc"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "clap"
|
||||
version = "4.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c918d541ef2913577a0f9566e9ce27cb35b6df072075769e0b26cb5a554520da"
|
||||
dependencies = [
|
||||
"clap_builder",
|
||||
"clap_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap_builder"
|
||||
version = "4.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9f3e7391dad68afb0c2ede1bf619f579a3dc9c2ec67f089baa397123a2f3d1eb"
|
||||
dependencies = [
|
||||
"anstream",
|
||||
"anstyle",
|
||||
"clap_lex",
|
||||
"strsim",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap_derive"
|
||||
version = "4.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "307bc0538d5f0f83b8248db3087aa92fe504e4691294d0c96c0eabc33f47ba47"
|
||||
dependencies = [
|
||||
"heck",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap_lex"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce"
|
||||
|
||||
[[package]]
|
||||
name = "colorchoice"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7"
|
||||
|
||||
[[package]]
|
||||
name = "either"
|
||||
version = "1.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "11157ac094ffbdde99aa67b23417ebdd801842852b500e395a45a9c0aac03e4a"
|
||||
|
||||
[[package]]
|
||||
name = "env_filter"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a009aa4810eb158359dda09d0c87378e4bbb89b5a801f016885a4707ba24f7ea"
|
||||
dependencies = [
|
||||
"log",
|
||||
"regex",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "env_logger"
|
||||
version = "0.11.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6c012a26a7f605efc424dd53697843a72be7dc86ad2d01f7814337794a12231d"
|
||||
dependencies = [
|
||||
"anstream",
|
||||
"anstyle",
|
||||
"env_filter",
|
||||
"humantime",
|
||||
"log",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "equivalent"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
|
||||
|
||||
[[package]]
|
||||
name = "errno"
|
||||
version = "0.3.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "filetime"
|
||||
version = "0.2.23"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1ee447700ac8aa0b2f2bd7bc4462ad686ba06baa6727ac149a2d6277f0d240fd"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"redox_syscall",
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "form_urlencoded"
|
||||
version = "1.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456"
|
||||
dependencies = [
|
||||
"percent-encoding",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "git2"
|
||||
version = "0.18.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1b3ba52851e73b46a4c3df1d89343741112003f0f6f13beb0dfac9e457c3fdcd"
|
||||
dependencies = [
|
||||
"bitflags 2.4.2",
|
||||
"libc",
|
||||
"libgit2-sys",
|
||||
"log",
|
||||
"openssl-probe",
|
||||
"openssl-sys",
|
||||
"url",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.14.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604"
|
||||
|
||||
[[package]]
|
||||
name = "heck"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
|
||||
|
||||
[[package]]
|
||||
name = "home"
|
||||
version = "0.5.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5"
|
||||
dependencies = [
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "humantime"
|
||||
version = "2.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4"
|
||||
|
||||
[[package]]
|
||||
name = "idna"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6"
|
||||
dependencies = [
|
||||
"unicode-bidi",
|
||||
"unicode-normalization",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
version = "2.2.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7b0b929d511467233429c45a44ac1dcaa21ba0f5ba11e4879e6ed28ddb4f9df4"
|
||||
dependencies = [
|
||||
"equivalent",
|
||||
"hashbrown",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.153"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd"
|
||||
|
||||
[[package]]
|
||||
name = "libgit2-sys"
|
||||
version = "0.16.2+1.7.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ee4126d8b4ee5c9d9ea891dd875cfdc1e9d0950437179104b183d7d8a74d24e8"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"libc",
|
||||
"libssh2-sys",
|
||||
"libz-sys",
|
||||
"openssl-sys",
|
||||
"pkg-config",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libssh2-sys"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2dc8a030b787e2119a731f1951d6a773e2280c660f8ec4b0f5e1505a386e71ee"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"libc",
|
||||
"libz-sys",
|
||||
"openssl-sys",
|
||||
"pkg-config",
|
||||
"vcpkg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libz-sys"
|
||||
version = "1.1.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "037731f5d3aaa87a5675e895b63ddff1a87624bc29f77004ea829809654e48f6"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"libc",
|
||||
"pkg-config",
|
||||
"vcpkg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "linux-raw-sys"
|
||||
version = "0.4.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c"
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c"
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.7.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149"
|
||||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
version = "1.19.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
|
||||
|
||||
[[package]]
|
||||
name = "openssl-probe"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf"
|
||||
|
||||
[[package]]
|
||||
name = "openssl-sys"
|
||||
version = "0.9.101"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dda2b0f344e78efc2facf7d195d098df0dd72151b26ab98da807afc26c198dff"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"libc",
|
||||
"pkg-config",
|
||||
"vcpkg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "percent-encoding"
|
||||
version = "2.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e"
|
||||
|
||||
[[package]]
|
||||
name = "pkg-config"
|
||||
version = "0.3.30"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.78"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "qemu"
|
||||
version = "0.1.0"
|
||||
source = "git+https://git.alnyan.me/yggdrasil/qemu.git#d20b34f9533684edeab295b0a76f3e12620d4e09"
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.35"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa"
|
||||
dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "1.10.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b62dbe01f0b06f9d8dc7d49e05a0785f153b00b2c227856282f671e0318c9b15"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
"regex-automata",
|
||||
"regex-syntax",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex-automata"
|
||||
version = "0.4.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
"regex-syntax",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex-syntax"
|
||||
version = "0.8.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f"
|
||||
|
||||
[[package]]
|
||||
name = "rustix"
|
||||
version = "0.38.31"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6ea3e1a662af26cd7a3ba09c0297a31af215563ecf42817c98df621387f4e949"
|
||||
dependencies = [
|
||||
"bitflags 2.4.2",
|
||||
"errno",
|
||||
"libc",
|
||||
"linux-raw-sys",
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "same-file"
|
||||
version = "1.0.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502"
|
||||
dependencies = [
|
||||
"winapi-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.197"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.197"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_spanned"
|
||||
version = "0.6.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "eb3622f419d1296904700073ea6cc23ad690adbd66f13ea683df73298736f0c1"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "strsim"
|
||||
version = "0.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5ee073c9e4cd00e28217186dbe12796d692868f432bf2e97ee73bed0c56dfa01"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.52"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b699d15b36d1f02c3e7c69f8ffef53de37aefae075d8488d4ba1a7788d574a07"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tar"
|
||||
version = "0.4.40"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b16afcea1f22891c49a00c751c7b63b2233284064f11a200fc624137c51e2ddb"
|
||||
dependencies = [
|
||||
"filetime",
|
||||
"libc",
|
||||
"xattr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.57"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1e45bcbe8ed29775f228095caf2cd67af7a4ccf756ebff23a306bf3e8b47b24b"
|
||||
dependencies = [
|
||||
"thiserror-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror-impl"
|
||||
version = "1.0.57"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a953cb265bef375dae3de6663da4d3804eee9682ea80d8e2542529b73c531c81"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tinyvec"
|
||||
version = "1.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50"
|
||||
dependencies = [
|
||||
"tinyvec_macros",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tinyvec_macros"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
|
||||
|
||||
[[package]]
|
||||
name = "toml"
|
||||
version = "0.8.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9a9aad4a3066010876e8dcf5a8a06e70a558751117a145c6ce2b82c2e2054290"
|
||||
dependencies = [
|
||||
"serde",
|
||||
"serde_spanned",
|
||||
"toml_datetime",
|
||||
"toml_edit",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml_datetime"
|
||||
version = "0.6.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml_edit"
|
||||
version = "0.22.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2c1b5fd4128cc8d3e0cb74d4ed9a9cc7c7284becd4df68f5f940e1ad123606f6"
|
||||
dependencies = [
|
||||
"indexmap",
|
||||
"serde",
|
||||
"serde_spanned",
|
||||
"toml_datetime",
|
||||
"winnow",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-bidi"
|
||||
version = "0.3.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-normalization"
|
||||
version = "0.1.23"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5"
|
||||
dependencies = [
|
||||
"tinyvec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "url"
|
||||
version = "2.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633"
|
||||
dependencies = [
|
||||
"form_urlencoded",
|
||||
"idna",
|
||||
"percent-encoding",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "utf8parse"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a"
|
||||
|
||||
[[package]]
|
||||
name = "vcpkg"
|
||||
version = "0.2.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
|
||||
|
||||
[[package]]
|
||||
name = "walkdir"
|
||||
version = "2.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b"
|
||||
dependencies = [
|
||||
"same-file",
|
||||
"winapi-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "which"
|
||||
version = "6.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7fa5e0c10bf77f44aac573e498d1a82d5fbd5e91f6fc0a99e7be4b38e85e101c"
|
||||
dependencies = [
|
||||
"either",
|
||||
"home",
|
||||
"once_cell",
|
||||
"rustix",
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.3.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
|
||||
dependencies = [
|
||||
"winapi-i686-pc-windows-gnu",
|
||||
"winapi-x86_64-pc-windows-gnu",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-i686-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||
|
||||
[[package]]
|
||||
name = "winapi-util"
|
||||
version = "0.1.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596"
|
||||
dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-x86_64-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.52.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
|
||||
dependencies = [
|
||||
"windows-targets",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-targets"
|
||||
version = "0.52.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7dd37b7e5ab9018759f893a1952c9420d060016fc19a472b4bb20d1bdd694d1b"
|
||||
dependencies = [
|
||||
"windows_aarch64_gnullvm",
|
||||
"windows_aarch64_msvc",
|
||||
"windows_i686_gnu",
|
||||
"windows_i686_msvc",
|
||||
"windows_x86_64_gnu",
|
||||
"windows_x86_64_gnullvm",
|
||||
"windows_x86_64_msvc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_gnullvm"
|
||||
version = "0.52.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bcf46cf4c365c6f2d1cc93ce535f2c8b244591df96ceee75d8e83deb70a9cac9"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.52.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "da9f259dd3bcf6990b55bffd094c4f7235817ba4ceebde8e6d11cd0c5633b675"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.52.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b474d8268f99e0995f25b9f095bc7434632601028cf86590aea5c8a5cb7801d3"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.52.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1515e9a29e5bed743cb4415a9ecf5dfca648ce85ee42e15873c3cd8610ff8e02"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.52.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5eee091590e89cc02ad514ffe3ead9eb6b660aedca2183455434b93546371a03"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnullvm"
|
||||
version = "0.52.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "77ca79f2451b49fa9e2af39f0747fe999fcda4f5e241b2898624dca97a1f2177"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.52.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "32b752e52a2da0ddfbdbcc6fceadfeede4c939ed16d13e648833a61dfb611ed8"
|
||||
|
||||
[[package]]
|
||||
name = "winnow"
|
||||
version = "0.6.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dffa400e67ed5a4dd237983829e66475f0a4a26938c4b04c21baede6262215b8"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "xattr"
|
||||
version = "1.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8da84f1a25939b27f6820d92aed108f83ff920fdf11a7b19366c27c4cda81d4f"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"linux-raw-sys",
|
||||
"rustix",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "xtask"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"env_logger",
|
||||
"git2",
|
||||
"log",
|
||||
"qemu",
|
||||
"serde",
|
||||
"tar",
|
||||
"thiserror",
|
||||
"toml",
|
||||
"walkdir",
|
||||
"which",
|
||||
]
|
||||
@@ -0,0 +1,19 @@
|
||||
[package]
|
||||
name = "xtask"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
build = "build.rs"
|
||||
|
||||
[dependencies]
|
||||
clap = { version = "4.5.1", features = ["env", "derive"] }
|
||||
git2 = "0.18.2"
|
||||
thiserror = "1.0.57"
|
||||
|
||||
qemu = { git = "https://git.alnyan.me/yggdrasil/qemu.git" }
|
||||
toml = "0.8.10"
|
||||
serde = { version = "1.0.197", features = ["derive"] }
|
||||
which = "6.0.0"
|
||||
walkdir = "2.5.0"
|
||||
tar = "0.4.40"
|
||||
env_logger = "0.11.2"
|
||||
log = "0.4.21"
|
||||
@@ -0,0 +1,6 @@
|
||||
fn main() {
|
||||
println!(
|
||||
"cargo:rustc-env=TARGET={}",
|
||||
std::env::var("TARGET").unwrap()
|
||||
);
|
||||
}
|
||||
Executable
+1
@@ -0,0 +1 @@
|
||||
#!/bin/sh
|
||||
@@ -0,0 +1,81 @@
|
||||
use std::{ffi::OsStr, path::Path, process::Command};
|
||||
|
||||
use crate::{
|
||||
env::{BuildEnv, Profile},
|
||||
error::Error,
|
||||
};
|
||||
|
||||
pub enum CargoBuilder<'e> {
|
||||
Host,
|
||||
Userspace(&'e BuildEnv),
|
||||
Kernel(&'e BuildEnv),
|
||||
}
|
||||
|
||||
impl<'e> CargoBuilder<'e> {
|
||||
pub fn run<P: AsRef<Path>, S: AsRef<OsStr>>(self, dir: P, arg: S) -> Result<(), Error> {
|
||||
let mut command = Command::new("cargo");
|
||||
|
||||
command.current_dir(dir);
|
||||
|
||||
match self {
|
||||
Self::Userspace(env) => {
|
||||
// Add clippy dependency libraries to LD_LIBRARY_PATH
|
||||
let toolchain_libs_path = env
|
||||
.workspace_root
|
||||
.join("toolchain/build")
|
||||
.join(&env.host_triple)
|
||||
.join("stage1/lib/rustlib")
|
||||
.join(&env.host_triple)
|
||||
.join("lib");
|
||||
let ld_library_path = std::env::var("LD_LIBRARY_PATH");
|
||||
let ld_library_path = match ld_library_path {
|
||||
Ok(path) => format!("{}:{}", toolchain_libs_path.display(), path),
|
||||
Err(_) => toolchain_libs_path.display().to_string(),
|
||||
};
|
||||
|
||||
command.env("LD_LIBRARY_PATH", ld_library_path);
|
||||
|
||||
command
|
||||
.arg("+ygg-stage1")
|
||||
.arg(arg)
|
||||
.arg(&format!("--target={}", env.arch.user_triple()));
|
||||
|
||||
if env.profile == Profile::Release {
|
||||
command.arg("--release");
|
||||
}
|
||||
}
|
||||
Self::Host => {
|
||||
command.arg("+nightly").arg(arg);
|
||||
}
|
||||
Self::Kernel(env) => {
|
||||
command.arg("+nightly").arg(arg);
|
||||
|
||||
let target_spec_arg = format!(
|
||||
"--target={}/etc/{}.json",
|
||||
env.workspace_root.display(),
|
||||
env.arch.kernel_triple()
|
||||
);
|
||||
|
||||
command.arg(target_spec_arg);
|
||||
command.args(["-Z", "build-std=core,alloc,compiler_builtins"]);
|
||||
|
||||
if env.profile == Profile::Release {
|
||||
command.arg("--release");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
log::trace!("Run cargo: {:?}", command);
|
||||
|
||||
let status = command.status()?;
|
||||
if status.success() {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(Error::CargoFailed)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn build<P: AsRef<Path>>(self, dir: P) -> Result<(), Error> {
|
||||
self.run(dir, "build")
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,134 @@
|
||||
use std::{path::PathBuf, process::Command};
|
||||
|
||||
use crate::{
|
||||
build::cargo::CargoBuilder,
|
||||
check::{self, AllOk},
|
||||
env::{Arch, BuildEnv},
|
||||
error::Error,
|
||||
};
|
||||
|
||||
pub mod x86_64;
|
||||
|
||||
mod cargo;
|
||||
pub mod toolchain;
|
||||
mod userspace;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum CheckAction {
|
||||
Check,
|
||||
Clippy,
|
||||
}
|
||||
|
||||
impl CheckAction {
|
||||
pub fn command(&self) -> &str {
|
||||
match self {
|
||||
Self::Clippy => "clippy",
|
||||
Self::Check => "check",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ToolsBuilt(pub PathBuf);
|
||||
pub struct KernelBuilt(pub PathBuf);
|
||||
pub struct KernelProcessed(pub KernelBuilt);
|
||||
pub struct InitrdGenerated(pub PathBuf);
|
||||
pub struct ImageBuilt(pub PathBuf);
|
||||
pub enum AllBuilt {
|
||||
X86_64(ImageBuilt),
|
||||
AArch64(KernelProcessed, InitrdGenerated),
|
||||
}
|
||||
|
||||
pub fn build_kernel_tools(env: &BuildEnv, _: AllOk) -> Result<ToolsBuilt, Error> {
|
||||
log::info!("Building kernel tools");
|
||||
CargoBuilder::Host.build("kernel/tools/gentables")?;
|
||||
Ok(ToolsBuilt(
|
||||
env.workspace_root.join("target/debug/gentables"),
|
||||
))
|
||||
}
|
||||
|
||||
pub fn build_kernel(env: &BuildEnv, _: AllOk) -> Result<KernelBuilt, Error> {
|
||||
log::info!("Building kernel");
|
||||
CargoBuilder::Kernel(env).build("kernel")?;
|
||||
Ok(KernelBuilt(env.kernel_output_dir.join("yggdrasil-kernel")))
|
||||
}
|
||||
|
||||
pub fn generate_kernel_tables(
|
||||
kernel: KernelBuilt,
|
||||
tools: ToolsBuilt,
|
||||
) -> Result<KernelProcessed, Error> {
|
||||
log::info!("Generating kernel MMU translation tables");
|
||||
let status = Command::new(tools.0).arg(kernel.0.clone()).status()?;
|
||||
if status.success() {
|
||||
Ok(KernelProcessed(kernel))
|
||||
} else {
|
||||
Err(Error::GentablesError)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn build_all(env: BuildEnv) -> Result<AllBuilt, Error> {
|
||||
log::debug!("Environment: {:#?}", env);
|
||||
|
||||
let check = check::check_build_env(env.arch)?;
|
||||
|
||||
// Kernel stuff
|
||||
let tools = build_kernel_tools(&env, check)?;
|
||||
let kernel = build_kernel(&env, check)?;
|
||||
let kernel = generate_kernel_tables(kernel, tools)?;
|
||||
|
||||
// Userspace stuff
|
||||
let initrd = userspace::build_initrd(&env, check)?;
|
||||
|
||||
// Build target-specific image
|
||||
let image = match env.arch {
|
||||
Arch::aarch64 => AllBuilt::AArch64(kernel, initrd),
|
||||
Arch::x86_64 => AllBuilt::X86_64(x86_64::build_image(&env, kernel, initrd)?),
|
||||
};
|
||||
|
||||
Ok(image)
|
||||
}
|
||||
|
||||
pub fn check_all(env: BuildEnv, action: CheckAction) -> Result<(), Error> {
|
||||
let action = action.command();
|
||||
|
||||
if env.arch == Arch::x86_64 {
|
||||
CargoBuilder::Host.run(env.workspace_root.join("boot/yboot-proto"), action)?;
|
||||
CargoBuilder::Host.run(env.workspace_root.join("boot/yboot"), action)?;
|
||||
}
|
||||
|
||||
CargoBuilder::Userspace(&env).run(env.workspace_root.join("userspace"), action)?;
|
||||
CargoBuilder::Kernel(&env).run(env.workspace_root.join("kernel"), action)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn test_all(env: BuildEnv) -> Result<(), Error> {
|
||||
for path in ["kernel/lib/vfs", "kernel/driver/fs/memfs", "lib/abi"] {
|
||||
CargoBuilder::Host.run(env.workspace_root.join(path), "test")?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn clean_userspace(env: &BuildEnv) -> Result<(), Error> {
|
||||
CargoBuilder::Host.run(env.workspace_root.join("userspace"), "clean")
|
||||
}
|
||||
|
||||
pub fn clean_all(env: &BuildEnv, clean_toolchain: bool) -> Result<(), Error> {
|
||||
log::info!("Cleaning");
|
||||
|
||||
CargoBuilder::Host.run(&env.workspace_root, "clean")?;
|
||||
clean_userspace(env)?;
|
||||
|
||||
if clean_toolchain {
|
||||
Command::new("./x")
|
||||
.current_dir(env.workspace_root.join("toolchain"))
|
||||
.arg("clean")
|
||||
.status()?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn build_toolchain(env: BuildEnv, branch: &str) -> Result<(), Error> {
|
||||
toolchain::fetch(&env, branch)?;
|
||||
toolchain::build(&env)
|
||||
}
|
||||
@@ -0,0 +1,149 @@
|
||||
// use std::{collections::HashMap, path::Path};
|
||||
|
||||
use std::{collections::HashMap, path::Path, process::Command};
|
||||
|
||||
use crate::{env::BuildEnv, error::Error, util};
|
||||
|
||||
const TOOLCHAIN_URL: &str = "https://git.alnyan.me/yggdrasil/yggdrasil-rust";
|
||||
|
||||
#[derive(Debug, serde::Serialize)]
|
||||
struct RustBuildConfig {
|
||||
host: Vec<String>,
|
||||
target: Vec<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, serde::Serialize)]
|
||||
struct RustTargetConfig {
|
||||
cc: Option<String>,
|
||||
cxx: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, serde::Serialize)]
|
||||
struct RustRustConfig {
|
||||
incremental: bool,
|
||||
}
|
||||
|
||||
#[derive(Debug, serde::Serialize)]
|
||||
#[serde(rename_all = "kebab-case")]
|
||||
struct RustToolchainConfig {
|
||||
profile: String,
|
||||
changelog_seen: u32,
|
||||
change_id: u32,
|
||||
|
||||
build: RustBuildConfig,
|
||||
target: HashMap<String, RustTargetConfig>,
|
||||
rust: RustRustConfig,
|
||||
}
|
||||
|
||||
fn configure<P: AsRef<Path>>(env: &BuildEnv, config_toml_path: P) -> Result<(), Error> {
|
||||
let config = RustToolchainConfig {
|
||||
profile: "user".into(),
|
||||
changelog_seen: 2,
|
||||
change_id: 102579,
|
||||
|
||||
build: RustBuildConfig {
|
||||
host: vec![env.host_triple.clone()],
|
||||
target: vec![
|
||||
env.host_triple.clone(),
|
||||
"x86_64-unknown-yggdrasil".into(),
|
||||
"aarch64-unknown-yggdrasil".into(),
|
||||
],
|
||||
},
|
||||
target: HashMap::from_iter([(
|
||||
"aarch64-unknown-yggdrasil".into(),
|
||||
RustTargetConfig {
|
||||
cc: Some("aarch64-linux-gnu-gcc".into()),
|
||||
cxx: Some("aarch64-linux-gnu-g++".into()),
|
||||
},
|
||||
)]),
|
||||
rust: RustRustConfig { incremental: true },
|
||||
};
|
||||
|
||||
let toml = toml::to_string_pretty(&config)?;
|
||||
std::fs::write(config_toml_path, toml.as_bytes())?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn is_toolchain_linked() -> bool {
|
||||
util::run_external_command("cargo", ["+ygg-stage1", "--version"], true).is_ok()
|
||||
}
|
||||
|
||||
fn link_rustup_toolchain<P: AsRef<Path>>(env: &BuildEnv, toolchain_root: P) -> Result<(), Error> {
|
||||
util::run_external_command(
|
||||
"rustup",
|
||||
[
|
||||
"toolchain",
|
||||
"link",
|
||||
"ygg-stage1",
|
||||
&format!(
|
||||
"{}",
|
||||
toolchain_root
|
||||
.as_ref()
|
||||
.join("build")
|
||||
.join(&env.host_triple)
|
||||
.join("stage1")
|
||||
.display()
|
||||
),
|
||||
],
|
||||
false,
|
||||
)
|
||||
}
|
||||
|
||||
fn do_build<P: AsRef<Path>>(toolchain_root: P) -> Result<(), Error> {
|
||||
let status = Command::new("./x")
|
||||
.current_dir(toolchain_root)
|
||||
.args(["build", "--stage=1"])
|
||||
.status()?;
|
||||
if status.success() {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(Error::ToolchainBuildFailed)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn fetch(env: &BuildEnv, branch: &str) -> Result<(), Error> {
|
||||
let path = env.workspace_root.join("toolchain");
|
||||
|
||||
match git2::Repository::open(&path) {
|
||||
Ok(_) => {}
|
||||
Err(err) if err.code() == git2::ErrorCode::NotFound => {
|
||||
log::info!(
|
||||
"Fetching toolchain: src={}, branch={}",
|
||||
TOOLCHAIN_URL,
|
||||
branch
|
||||
);
|
||||
|
||||
git2::build::RepoBuilder::new()
|
||||
.branch(branch)
|
||||
.clone(TOOLCHAIN_URL, &path)?;
|
||||
}
|
||||
Err(err) => return Err(err.into()),
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn build(env: &BuildEnv) -> Result<(), Error> {
|
||||
let toolchain_path = env.workspace_root.join("toolchain");
|
||||
let config_toml_path = toolchain_path.join("config.toml");
|
||||
|
||||
assert!(toolchain_path.exists());
|
||||
|
||||
// Write config.toml
|
||||
if !config_toml_path.exists() {
|
||||
configure(env, config_toml_path)?;
|
||||
}
|
||||
|
||||
log::info!("Building toolchain");
|
||||
do_build(&toolchain_path)?;
|
||||
|
||||
if !is_toolchain_linked() {
|
||||
log::info!("Linking the newly built toolchain to +ygg-stage1");
|
||||
link_rustup_toolchain(env, &toolchain_path)?;
|
||||
} else {
|
||||
log::debug!("Toolchain already linked");
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -0,0 +1,145 @@
|
||||
use std::{
|
||||
fs::{self, File},
|
||||
io::BufWriter,
|
||||
path::Path,
|
||||
};
|
||||
|
||||
use walkdir::WalkDir;
|
||||
|
||||
use crate::{build::cargo::CargoBuilder, check::AllOk, env::BuildEnv, error::Error, util};
|
||||
|
||||
use super::InitrdGenerated;
|
||||
|
||||
const PROGRAMS: &[(&str, &str)] = &[
|
||||
// init
|
||||
("init", "init"),
|
||||
("rc", "sbin/rc"),
|
||||
("service", "sbin/service"),
|
||||
("logd", "sbin/logd"),
|
||||
// shell
|
||||
("shell", "bin/sh"),
|
||||
// sysutils
|
||||
("mount", "sbin/mount"),
|
||||
("login", "sbin/login"),
|
||||
("ls", "bin/ls"),
|
||||
("mkdir", "bin/mkdir"),
|
||||
("touch", "bin/touch"),
|
||||
("rm", "bin/rm"),
|
||||
("cat", "bin/cat"),
|
||||
("hexd", "bin/hexd"),
|
||||
("dd", "bin/dd"),
|
||||
("random", "bin/random"),
|
||||
("view", "bin/view"),
|
||||
("chmod", "bin/chmod"),
|
||||
("sha256sum", "bin/sha256sum"),
|
||||
("sysmon", "bin/sysmon"),
|
||||
// netutils
|
||||
("netconf", "sbin/netconf"),
|
||||
("dhcp-client", "sbin/dhcp-client"),
|
||||
("nc", "bin/nc"),
|
||||
("http", "bin/http"),
|
||||
("dnsq", "bin/dnsq"),
|
||||
("ping", "bin/ping"),
|
||||
// colors
|
||||
("colors", "bin/colors"),
|
||||
("term", "bin/term"),
|
||||
// red
|
||||
("red", "bin/red"),
|
||||
];
|
||||
|
||||
fn build_userspace(env: &BuildEnv, _: AllOk) -> Result<(), Error> {
|
||||
log::info!("Building userspace");
|
||||
CargoBuilder::Userspace(env).build(env.workspace_root.join("userspace"))?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn build_rootfs<S: AsRef<Path>, D: AsRef<Path>>(
|
||||
env: &BuildEnv,
|
||||
build_dir: S,
|
||||
rootfs_dir: D,
|
||||
_: AllOk,
|
||||
) -> Result<(), Error> {
|
||||
let user_dir = env.workspace_root.join("userspace");
|
||||
let build_dir = build_dir.as_ref();
|
||||
let rootfs_dir = rootfs_dir.as_ref();
|
||||
|
||||
log::info!("Building rootfs: {}", rootfs_dir.display());
|
||||
|
||||
for dir in ["sbin", "bin", "dev", "sys", "tmp"] {
|
||||
fs::create_dir_all(rootfs_dir.join(dir))?;
|
||||
File::create(rootfs_dir.join(dir).join(".do_not_remove"))?;
|
||||
}
|
||||
|
||||
// TODO grab this from cargo somehow?
|
||||
for &(src, dst) in PROGRAMS {
|
||||
let src_path = build_dir.join(src);
|
||||
let dst_path = rootfs_dir.join(dst);
|
||||
|
||||
if let Some(dst_parent) = dst_path.parent() {
|
||||
fs::create_dir_all(dst_parent)?;
|
||||
}
|
||||
|
||||
log::trace!(
|
||||
"Install binary: {} -> {}",
|
||||
src_path.display(),
|
||||
dst_path.display()
|
||||
);
|
||||
fs::copy(src_path, dst_path)?;
|
||||
}
|
||||
|
||||
// Copy /etc
|
||||
util::copy_dir_recursive(user_dir.join("etc"), rootfs_dir.join("etc"))?;
|
||||
|
||||
// Copy architecture-specific directories
|
||||
let arch_dir = user_dir.join("arch").join(env.arch.name());
|
||||
let arch_rc_d = arch_dir.join("rc.d");
|
||||
let arch_inittab = arch_dir.join("inittab");
|
||||
|
||||
if arch_rc_d.exists() {
|
||||
util::copy_dir_recursive(arch_rc_d, rootfs_dir.join("etc/rc.d"))?;
|
||||
}
|
||||
if arch_inittab.exists() {
|
||||
fs::copy(arch_inittab, rootfs_dir.join("etc/inittab"))?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn pack_initrd<P: AsRef<Path>>(env: &BuildEnv, rootfs_dir: P) -> Result<InitrdGenerated, Error> {
|
||||
let initrd_tar = env.userspace_output_dir.join("initrd.tar");
|
||||
|
||||
log::info!("Building initrd");
|
||||
|
||||
let tar = File::create(&initrd_tar)?;
|
||||
let tar = BufWriter::new(tar);
|
||||
let mut tar = tar::Builder::new(tar);
|
||||
|
||||
for entry in WalkDir::new(&rootfs_dir)
|
||||
.follow_links(false)
|
||||
.into_iter()
|
||||
.filter(|e| e.as_ref().map(|e| !e.file_type().is_dir()).unwrap_or(false))
|
||||
{
|
||||
let entry = entry?;
|
||||
let src_path = entry.path();
|
||||
let rel_path = src_path
|
||||
.strip_prefix(&rootfs_dir)
|
||||
.map_err(|_| Error::InvalidPath(src_path.into()))?;
|
||||
|
||||
if entry.file_type().is_file() {
|
||||
let mut file = File::open(entry.path())?;
|
||||
tar.append_file(rel_path, &mut file)?;
|
||||
} else {
|
||||
todo!();
|
||||
}
|
||||
}
|
||||
|
||||
Ok(InitrdGenerated(initrd_tar))
|
||||
}
|
||||
|
||||
pub fn build_initrd(env: &BuildEnv, check: AllOk) -> Result<InitrdGenerated, Error> {
|
||||
let rootfs_dir = env.userspace_output_dir.join("rootfs");
|
||||
|
||||
build_userspace(env, check)?;
|
||||
build_rootfs(env, &env.userspace_output_dir, &rootfs_dir, check)?;
|
||||
pack_initrd(env, rootfs_dir)
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
use std::path::PathBuf;
|
||||
|
||||
use crate::{build::cargo::CargoBuilder, env::BuildEnv, error::Error, util};
|
||||
|
||||
use super::{ImageBuilt, InitrdGenerated, KernelProcessed};
|
||||
|
||||
pub struct YbootBuilt(PathBuf);
|
||||
|
||||
fn build_yboot(env: &BuildEnv) -> Result<YbootBuilt, Error> {
|
||||
log::info!("Building yboot");
|
||||
CargoBuilder::Host.build("boot/yboot")?;
|
||||
let binary = env.workspace_root.join(format!(
|
||||
"boot/yboot/target/x86_64-unknown-uefi/debug/yboot.efi"
|
||||
));
|
||||
Ok(YbootBuilt(binary))
|
||||
}
|
||||
|
||||
fn build_uefi_image(
|
||||
env: &BuildEnv,
|
||||
yboot: YbootBuilt,
|
||||
kernel: KernelProcessed,
|
||||
initrd: InitrdGenerated,
|
||||
) -> Result<ImageBuilt, Error> {
|
||||
log::info!("Building x86-64 UEFI image");
|
||||
let image_path = env.kernel_output_dir.join("image.fat32");
|
||||
|
||||
util::run_external_command(
|
||||
"dd",
|
||||
[
|
||||
"if=/dev/zero",
|
||||
&format!("of={}", image_path.display()),
|
||||
"bs=1M",
|
||||
"count=256",
|
||||
],
|
||||
false,
|
||||
)?;
|
||||
util::run_external_command(
|
||||
"mkfs.vfat",
|
||||
["-F32".as_ref(), image_path.as_os_str()],
|
||||
false,
|
||||
)?;
|
||||
util::run_external_command(
|
||||
"mmd",
|
||||
["-i".as_ref(), image_path.as_os_str(), "::EFI".as_ref()],
|
||||
false,
|
||||
)?;
|
||||
util::run_external_command(
|
||||
"mmd",
|
||||
["-i".as_ref(), image_path.as_os_str(), "::EFI/Boot".as_ref()],
|
||||
false,
|
||||
)?;
|
||||
util::run_external_command(
|
||||
"mcopy",
|
||||
[
|
||||
"-i".as_ref(),
|
||||
image_path.as_os_str(),
|
||||
yboot.0.as_os_str(),
|
||||
"::EFI/Boot/BootX64.efi".as_ref(),
|
||||
],
|
||||
false,
|
||||
)?;
|
||||
util::run_external_command(
|
||||
"mcopy",
|
||||
[
|
||||
"-i".as_ref(),
|
||||
image_path.as_os_str(),
|
||||
kernel.0 .0.as_os_str(),
|
||||
"::kernel.elf".as_ref(),
|
||||
],
|
||||
false,
|
||||
)?;
|
||||
util::run_external_command(
|
||||
"mcopy",
|
||||
[
|
||||
"-i".as_ref(),
|
||||
image_path.as_os_str(),
|
||||
initrd.0.as_os_str(),
|
||||
"::initrd.img".as_ref(),
|
||||
],
|
||||
false,
|
||||
)?;
|
||||
|
||||
Ok(ImageBuilt(image_path))
|
||||
}
|
||||
|
||||
pub fn build_image(
|
||||
env: &BuildEnv,
|
||||
kernel: KernelProcessed,
|
||||
initrd: InitrdGenerated,
|
||||
) -> Result<ImageBuilt, Error> {
|
||||
let yboot = build_yboot(env)?;
|
||||
let image = build_uefi_image(env, yboot, kernel, initrd)?;
|
||||
Ok(image)
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
use crate::{build::toolchain, env::Arch, error::Error};
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct CommandsOk;
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct UserToolchainOk;
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct SourcesOk;
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct AllOk(CommandsOk, UserToolchainOk);
|
||||
|
||||
fn check_user_toolchain() -> Result<UserToolchainOk, Error> {
|
||||
if !toolchain::is_toolchain_linked() {
|
||||
return Err(Error::MissingTools(vec![(
|
||||
"toolchain",
|
||||
"Use `cargo xtask toolchain` command to build and install the toolchain",
|
||||
)]));
|
||||
}
|
||||
Ok(UserToolchainOk)
|
||||
}
|
||||
|
||||
fn check_command_list<I: IntoIterator<Item = (&'static str, &'static str)>>(
|
||||
list: I,
|
||||
) -> Result<CommandsOk, Error> {
|
||||
let mut missing = vec![];
|
||||
for (command, guide) in list {
|
||||
if which::which(command).is_err() {
|
||||
missing.push((command, guide));
|
||||
}
|
||||
}
|
||||
if missing.is_empty() {
|
||||
Ok(CommandsOk)
|
||||
} else {
|
||||
Err(Error::MissingTools(missing))
|
||||
}
|
||||
}
|
||||
|
||||
fn check_commands_x86_64() -> Result<CommandsOk, Error> {
|
||||
check_command_list([
|
||||
("mtools", "Install the `mtools` package"),
|
||||
("mkfs.vfat", "Install the `dosfstools` package"),
|
||||
("ld64.lld", "Install LLVM"),
|
||||
])
|
||||
}
|
||||
|
||||
fn check_commands_aarch64() -> Result<CommandsOk, Error> {
|
||||
check_command_list([
|
||||
("llvm-objcopy", "Install LLVM"),
|
||||
("ld64.lld", "Install LLVM"),
|
||||
])
|
||||
}
|
||||
|
||||
pub fn check_build_env(arch: Arch) -> Result<AllOk, Error> {
|
||||
let user_toolchain = check_user_toolchain()?;
|
||||
let commands = match arch {
|
||||
Arch::x86_64 => check_commands_x86_64()?,
|
||||
Arch::aarch64 => check_commands_aarch64()?,
|
||||
};
|
||||
Ok(AllOk(commands, user_toolchain))
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
use std::path::PathBuf;
|
||||
|
||||
use clap::ValueEnum;
|
||||
|
||||
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, ValueEnum)]
|
||||
pub enum Profile {
|
||||
#[default]
|
||||
Debug,
|
||||
Release,
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, ValueEnum)]
|
||||
#[allow(non_camel_case_types)]
|
||||
#[clap(rename_all = "verbatim")]
|
||||
pub enum Arch {
|
||||
#[default]
|
||||
aarch64,
|
||||
x86_64,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct BuildEnv {
|
||||
pub profile: Profile,
|
||||
pub arch: Arch,
|
||||
pub host_triple: String,
|
||||
|
||||
pub workspace_root: PathBuf,
|
||||
|
||||
pub kernel_output_dir: PathBuf,
|
||||
pub userspace_output_dir: PathBuf,
|
||||
}
|
||||
|
||||
impl BuildEnv {
|
||||
pub fn new(profile: Profile, arch: Arch, workspace_root: PathBuf) -> Self {
|
||||
let kernel_output_dir =
|
||||
workspace_root.join(format!("target/{}/{}", arch.kernel_triple(), profile.dir()));
|
||||
let userspace_output_dir = workspace_root.join(format!(
|
||||
"userspace/target/{}-unknown-yggdrasil/{}",
|
||||
arch.name(),
|
||||
profile.dir()
|
||||
));
|
||||
let host = env!("TARGET");
|
||||
|
||||
Self {
|
||||
profile,
|
||||
arch,
|
||||
host_triple: host.into(),
|
||||
|
||||
workspace_root,
|
||||
|
||||
kernel_output_dir,
|
||||
userspace_output_dir,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Profile {
|
||||
pub fn dir(&self) -> &str {
|
||||
match self {
|
||||
Self::Debug => "debug",
|
||||
Self::Release => "release",
|
||||
}
|
||||
}
|
||||
|
||||
pub fn name(&self) -> &str {
|
||||
self.dir()
|
||||
}
|
||||
}
|
||||
|
||||
impl Arch {
|
||||
pub fn kernel_triple(&self) -> &str {
|
||||
match self {
|
||||
Self::aarch64 => "aarch64-unknown-qemu",
|
||||
Self::x86_64 => "x86_64-unknown-none",
|
||||
}
|
||||
}
|
||||
|
||||
pub fn user_triple(&self) -> &str {
|
||||
match self {
|
||||
Self::aarch64 => "aarch64-unknown-yggdrasil",
|
||||
Self::x86_64 => "x86_64-unknown-yggdrasil",
|
||||
}
|
||||
}
|
||||
|
||||
pub fn name(&self) -> &str {
|
||||
match self {
|
||||
Self::aarch64 => "aarch64",
|
||||
Self::x86_64 => "x86_64",
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
use std::{io, path::PathBuf};
|
||||
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
pub enum Error {
|
||||
#[error("{0}")]
|
||||
SystemError(#[from] io::Error),
|
||||
#[error("Cargo command failed")]
|
||||
CargoFailed,
|
||||
#[error("Could not generate a processed kernel image")]
|
||||
GentablesError,
|
||||
#[error("Could not build userspace programs")]
|
||||
UserspaceBuildFailed,
|
||||
#[error("External command failed")]
|
||||
ExternalCommandFailed,
|
||||
#[error("Missing tools: {0:?}")]
|
||||
MissingTools(Vec<(&'static str, &'static str)>),
|
||||
#[error("git error: {0}")]
|
||||
GitError(#[from] git2::Error),
|
||||
#[error("Could not build toolchain")]
|
||||
ToolchainBuildFailed,
|
||||
#[error("Could not configure toolchain: {0}")]
|
||||
ToolchainConfigError(#[from] toml::ser::Error),
|
||||
#[error("Could not load qemu.toml: {0}")]
|
||||
InvalidQemuConfig(#[from] toml::de::Error),
|
||||
#[error("Could not copy directory")]
|
||||
CopyDirectoryError(#[from] walkdir::Error),
|
||||
#[error("Invalid path: {0:?}")]
|
||||
InvalidPath(PathBuf),
|
||||
}
|
||||
@@ -0,0 +1,144 @@
|
||||
// #![deny(warnings)]
|
||||
|
||||
use std::{
|
||||
fs,
|
||||
path::{Path, PathBuf},
|
||||
process::ExitCode,
|
||||
};
|
||||
|
||||
use build::CheckAction;
|
||||
use clap::{Parser, Subcommand};
|
||||
use env::{Arch, Profile};
|
||||
use error::Error;
|
||||
|
||||
#[macro_use]
|
||||
pub mod util;
|
||||
|
||||
pub mod build;
|
||||
pub mod check;
|
||||
pub mod env;
|
||||
pub mod error;
|
||||
pub mod qemu;
|
||||
|
||||
#[derive(Parser)]
|
||||
struct Args {
|
||||
#[clap(long, env, help = "Use --release profile for built components")]
|
||||
release: bool,
|
||||
#[clap(
|
||||
short,
|
||||
long,
|
||||
env,
|
||||
default_value_t,
|
||||
value_enum,
|
||||
help = "Target architecture"
|
||||
)]
|
||||
arch: Arch,
|
||||
#[clap(
|
||||
short,
|
||||
long,
|
||||
help = "Do a clean userspace rebuild (e.g. toolchain has changed)"
|
||||
)]
|
||||
clean_userspace: bool,
|
||||
|
||||
#[clap(subcommand)]
|
||||
action: Option<SubArgs>,
|
||||
}
|
||||
|
||||
#[derive(Default, Subcommand)]
|
||||
enum SubArgs {
|
||||
#[default]
|
||||
#[clap(about = "Build the OS")]
|
||||
Build,
|
||||
#[clap(about = "Run `cargo check` on components")]
|
||||
Check,
|
||||
#[clap(about = "Run `cargo clippy` on components")]
|
||||
Clippy,
|
||||
#[clap(about = "Run `cargo test` on components")]
|
||||
Test,
|
||||
#[clap(about = "Clean all build artifacts")]
|
||||
Clean {
|
||||
#[clap(short, long, help = "Clean toolchain as well")]
|
||||
toolchain: bool,
|
||||
},
|
||||
|
||||
// #[clap(about = "Print `git status` for the components", alias = "gst")]
|
||||
// GitStatus,
|
||||
#[clap(about = "Run the OS image in QEMU")]
|
||||
Qemu {
|
||||
#[clap(
|
||||
short,
|
||||
long,
|
||||
env,
|
||||
help = "Override the default QEMU binary for the target"
|
||||
)]
|
||||
qemu: Option<PathBuf>,
|
||||
#[clap(help = "Extra arguments for QEMU")]
|
||||
extra_args: Vec<String>,
|
||||
},
|
||||
|
||||
#[clap(about = "Build the Yggdrasil OS Rust toolchain")]
|
||||
Toolchain {
|
||||
#[clap(
|
||||
default_value = "alnyan/yggdrasil-master",
|
||||
help = "Use a specific toolchain repo branch"
|
||||
)]
|
||||
branch: String,
|
||||
},
|
||||
#[clap(about = "Print the host triple")]
|
||||
HostTriple,
|
||||
}
|
||||
|
||||
fn run(args: Args) -> Result<(), Error> {
|
||||
let action = args.action.unwrap_or_default();
|
||||
|
||||
let workspace_root = std::env::current_dir()?;
|
||||
let profile = if args.release {
|
||||
Profile::Release
|
||||
} else {
|
||||
Profile::Debug
|
||||
};
|
||||
let env = env::BuildEnv::new(profile, args.arch, workspace_root);
|
||||
|
||||
if args.clean_userspace && !matches!(&action, SubArgs::Clean { .. }) {
|
||||
build::clean_userspace(&env)?;
|
||||
}
|
||||
|
||||
match action {
|
||||
SubArgs::Build => build::build_all(env).map(|_| ()),
|
||||
SubArgs::Check => build::check_all(env, CheckAction::Check),
|
||||
SubArgs::Clippy => build::check_all(env, CheckAction::Clippy),
|
||||
SubArgs::Test => build::test_all(env),
|
||||
SubArgs::Clean { toolchain } => build::clean_all(&env, toolchain),
|
||||
// SubArgs::GitStatus => util::git_status_all(&env),
|
||||
SubArgs::Qemu { qemu, extra_args } => qemu::run(env, qemu, extra_args),
|
||||
SubArgs::Toolchain { branch } => build::build_toolchain(env, &branch),
|
||||
SubArgs::HostTriple => {
|
||||
println!("{}", env.host_triple);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn main() -> ExitCode {
|
||||
env_logger::builder()
|
||||
.filter_level(log::LevelFilter::Info)
|
||||
.parse_default_env()
|
||||
.init();
|
||||
|
||||
let args = Args::parse();
|
||||
|
||||
match run(args) {
|
||||
Ok(()) => ExitCode::SUCCESS,
|
||||
Err(Error::MissingTools(list)) => {
|
||||
eprintln!("Missing some required tools:");
|
||||
for (tool, guide) in list {
|
||||
eprintln!(" * {}: {}", tool, guide);
|
||||
}
|
||||
ExitCode::FAILURE
|
||||
}
|
||||
Err(err) => {
|
||||
eprintln!("Error: {}", err);
|
||||
ExitCode::FAILURE
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,206 @@
|
||||
use std::{
|
||||
path::{Path, PathBuf},
|
||||
process::Command,
|
||||
};
|
||||
|
||||
use qemu::{
|
||||
aarch64,
|
||||
device::{QemuDevice, QemuNic, QemuSerialTarget},
|
||||
x86_64, Qemu,
|
||||
};
|
||||
|
||||
use crate::{
|
||||
build::{self, AllBuilt, ImageBuilt, InitrdGenerated, KernelBuilt, KernelProcessed},
|
||||
env::BuildEnv,
|
||||
error::Error,
|
||||
util::run_external_command,
|
||||
};
|
||||
|
||||
const X86_64_UEFI_PATH: &str = "/usr/share/edk2-ovmf/x64/OVMF_CODE.fd";
|
||||
|
||||
#[derive(Debug, serde::Deserialize)]
|
||||
#[serde(rename_all = "kebab-case", default)]
|
||||
struct QemuNetworkConfig {
|
||||
enable: bool,
|
||||
interface_name: String,
|
||||
mac: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, serde::Deserialize)]
|
||||
#[serde(rename_all = "kebab-case", default)]
|
||||
struct QemuX86_64MachineConfig {
|
||||
enable_kvm: bool,
|
||||
memory: usize,
|
||||
}
|
||||
|
||||
#[derive(Debug, serde::Deserialize)]
|
||||
#[serde(rename_all = "kebab-case", default)]
|
||||
struct QemuAArch64MachineConfig {
|
||||
memory: usize,
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, serde::Deserialize)]
|
||||
#[serde(default)]
|
||||
struct QemuMachineConfig {
|
||||
x86_64: QemuX86_64MachineConfig,
|
||||
aarch64: QemuAArch64MachineConfig,
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, serde::Deserialize)]
|
||||
#[serde(rename_all = "kebab-case", default)]
|
||||
struct QemuConfig {
|
||||
network: QemuNetworkConfig,
|
||||
machine: QemuMachineConfig,
|
||||
}
|
||||
|
||||
impl Default for QemuAArch64MachineConfig {
|
||||
fn default() -> Self {
|
||||
Self { memory: 512 }
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for QemuX86_64MachineConfig {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
enable_kvm: true,
|
||||
memory: 512,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for QemuNetworkConfig {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
enable: true,
|
||||
interface_name: "qemu-tap0".into(),
|
||||
mac: "12:34:56:65:43:21".into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn make_kernel_bin<S: AsRef<Path>, D: AsRef<Path>>(src: S, dst: D) -> Result<(), Error> {
|
||||
run_external_command(
|
||||
"llvm-objcopy",
|
||||
[
|
||||
"-O".as_ref(),
|
||||
"binary".as_ref(),
|
||||
src.as_ref().as_os_str(),
|
||||
dst.as_ref().as_os_str(),
|
||||
],
|
||||
false,
|
||||
)
|
||||
}
|
||||
|
||||
// TODO device settings
|
||||
|
||||
fn run_aarch64(
|
||||
config: &QemuConfig,
|
||||
qemu_bin: Option<PathBuf>,
|
||||
devices: Vec<QemuDevice>,
|
||||
kernel_bin: PathBuf,
|
||||
initrd: PathBuf,
|
||||
) -> Result<Command, Error> {
|
||||
let mut qemu = Qemu::new_aarch64();
|
||||
if let Some(qemu_bin) = qemu_bin {
|
||||
qemu.override_qemu(qemu_bin);
|
||||
}
|
||||
qemu.with_serial(QemuSerialTarget::MonStdio)
|
||||
.with_cpu(aarch64::Cpu::CortexA57)
|
||||
.with_machine(aarch64::Machine::Virt { virtualize: true })
|
||||
.with_boot_image(aarch64::Image::Kernel {
|
||||
kernel: kernel_bin,
|
||||
initrd: Some(initrd),
|
||||
})
|
||||
.with_memory_megabytes(config.machine.aarch64.memory)
|
||||
.disable_display();
|
||||
|
||||
for device in devices {
|
||||
qemu.with_device(device);
|
||||
}
|
||||
|
||||
Ok(qemu.into_command())
|
||||
}
|
||||
|
||||
fn run_x86_64(
|
||||
config: &QemuConfig,
|
||||
qemu_bin: Option<PathBuf>,
|
||||
devices: Vec<QemuDevice>,
|
||||
image: PathBuf,
|
||||
) -> Result<Command, Error> {
|
||||
let mut qemu = Qemu::new_x86_64();
|
||||
if let Some(qemu_bin) = qemu_bin {
|
||||
qemu.override_qemu(qemu_bin);
|
||||
}
|
||||
qemu.with_serial(QemuSerialTarget::MonStdio)
|
||||
.with_cpu(x86_64::Cpu::Host {
|
||||
enable_kvm: config.machine.x86_64.enable_kvm,
|
||||
})
|
||||
.with_machine(x86_64::Machine::Q35)
|
||||
.with_boot_slot('a')
|
||||
.with_bios_image(X86_64_UEFI_PATH.into())
|
||||
.with_boot_image(x86_64::Image::Drive(image))
|
||||
.with_memory_megabytes(config.machine.x86_64.memory);
|
||||
|
||||
for device in devices {
|
||||
qemu.with_device(device);
|
||||
}
|
||||
|
||||
Ok(qemu.into_command())
|
||||
}
|
||||
|
||||
fn load_qemu_config<P: AsRef<Path>>(path: P) -> Result<QemuConfig, Error> {
|
||||
let path = path.as_ref();
|
||||
|
||||
if path.exists() {
|
||||
let config = std::fs::read_to_string(path)?;
|
||||
let config = toml::from_str(&config).map_err(Error::InvalidQemuConfig)?;
|
||||
|
||||
Ok(config)
|
||||
} else {
|
||||
Ok(QemuConfig::default())
|
||||
}
|
||||
}
|
||||
|
||||
fn add_devices_from_config(
|
||||
devices: &mut Vec<QemuDevice>,
|
||||
config: &QemuConfig,
|
||||
) -> Result<(), Error> {
|
||||
if config.network.enable {
|
||||
devices.push(QemuDevice::NetworkTap {
|
||||
nic: QemuNic::VirtioPci {
|
||||
mac: Some(config.network.mac.clone()),
|
||||
},
|
||||
script: Some("xtask/scripts/qemu-ifup".into()),
|
||||
ifname: Some(config.network.interface_name.clone()),
|
||||
});
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn run(env: BuildEnv, qemu: Option<PathBuf>, extra_args: Vec<String>) -> Result<(), Error> {
|
||||
let config = load_qemu_config(env.workspace_root.join("qemu.toml"))?;
|
||||
|
||||
let kernel_output_dir = env.kernel_output_dir.clone();
|
||||
let kernel_bin = kernel_output_dir.join("kernel.bin");
|
||||
// Rebuild the image
|
||||
let built = build::build_all(env)?;
|
||||
|
||||
let mut devices = vec![];
|
||||
add_devices_from_config(&mut devices, &config)?;
|
||||
|
||||
let mut command = match built {
|
||||
AllBuilt::AArch64(KernelProcessed(KernelBuilt(kernel)), InitrdGenerated(initrd)) => {
|
||||
make_kernel_bin(kernel, &kernel_bin)?;
|
||||
run_aarch64(&config, qemu, devices, kernel_bin, initrd)?
|
||||
}
|
||||
AllBuilt::X86_64(ImageBuilt(image)) => run_x86_64(&config, qemu, devices, image)?,
|
||||
};
|
||||
|
||||
command.args(extra_args);
|
||||
|
||||
log::trace!("Run QEMU: {:?}", command);
|
||||
|
||||
command.status()?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
use std::{
|
||||
ffi::OsStr,
|
||||
fs,
|
||||
path::Path,
|
||||
process::{Command, Stdio},
|
||||
};
|
||||
|
||||
use walkdir::WalkDir;
|
||||
|
||||
use crate::error::Error;
|
||||
|
||||
pub fn run_external_command<S0: AsRef<OsStr>, S1: AsRef<OsStr>, I: IntoIterator<Item = S1>>(
|
||||
cmd: S0,
|
||||
args: I,
|
||||
mute: bool,
|
||||
) -> Result<(), Error> {
|
||||
let mut command = Command::new(cmd);
|
||||
command.args(args);
|
||||
if mute {
|
||||
command.stderr(Stdio::null()).stdout(Stdio::null());
|
||||
}
|
||||
log::trace!("Run external: {:?}", command);
|
||||
let status = command.status()?;
|
||||
if status.success() {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(Error::ExternalCommandFailed)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn copy_dir_recursive<S: AsRef<Path>, D: AsRef<Path>>(src: S, dst: D) -> Result<(), Error> {
|
||||
let src = src.as_ref();
|
||||
let dst = dst.as_ref();
|
||||
|
||||
for entry in WalkDir::new(src).follow_links(false) {
|
||||
let entry = entry?;
|
||||
let src_path = entry.path();
|
||||
let rel_path = src_path
|
||||
.strip_prefix(src)
|
||||
.map_err(|_| Error::InvalidPath(src_path.into()))?;
|
||||
let dst_path = dst.join(rel_path);
|
||||
|
||||
if entry.file_type().is_dir() {
|
||||
fs::create_dir_all(dst_path)?;
|
||||
} else {
|
||||
log::trace!("Copy {} -> {}", src_path.display(), dst_path.display());
|
||||
fs::copy(src_path, dst_path)?;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
Reference in New Issue
Block a user