From c445810da453c4ff88a891f7d6fd9247445bf0e8 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Tue, 6 Aug 2019 11:56:41 +0200 Subject: [PATCH 001/108] Update changelog for #45 --- Changelog.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Changelog.md b/Changelog.md index 4c21e12..630f237 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,3 +1,5 @@ +- Pass location of kernel's Cargo.toml to bootloader ([#45](https://github.com/rust-osdev/bootimage/pull/45)) + # 0.7.6 - If the bootloader has a feature named `binary`, enable it ([#43](https://github.com/rust-osdev/bootimage/pull/43)) From 736ca1bf571f4745e49606017d6cf4e4216605d7 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Tue, 6 Aug 2019 11:58:14 +0200 Subject: [PATCH 002/108] bootimage 0.7.7 --- Cargo.lock | 2 +- Cargo.toml | 2 +- Changelog.md | 2 ++ 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index fc9a4fd..9d5378d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -10,7 +10,7 @@ dependencies = [ [[package]] name = "bootimage" -version = "0.7.6" +version = "0.7.7" dependencies = [ "cargo_metadata 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)", "json 0.11.13 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/Cargo.toml b/Cargo.toml index 7f01bd3..9755210 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,7 +3,7 @@ authors = ["Philipp Oppermann "] description = "Tool to create a bootable OS image from a kernel binary." license = "MIT/Apache-2.0" name = "bootimage" -version = "0.7.6" +version = "0.7.7" repository = "https://github.com/rust-osdev/bootimage" edition = "2018" diff --git a/Changelog.md b/Changelog.md index 630f237..39dc8e7 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,3 +1,5 @@ +# 0.7.7 + - Pass location of kernel's Cargo.toml to bootloader ([#45](https://github.com/rust-osdev/bootimage/pull/45)) # 0.7.6 From 329e8a9246843923b0b2f60e844e662914f1047d Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Sat, 2 Nov 2019 16:22:39 +0100 Subject: [PATCH 003/108] Don't exit with expected exit code when failed to read QEMU exit code --- src/subcommand/runner.rs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/subcommand/runner.rs b/src/subcommand/runner.rs index 90bf4e8..f63004d 100644 --- a/src/subcommand/runner.rs +++ b/src/subcommand/runner.rs @@ -72,10 +72,13 @@ pub(crate) fn runner(args: RunnerArgs) -> Result { .map_err(|e| format!("Failed to wait for QEMU process: {}", e))?; return Err(ErrorMessage::from("Timed Out")); } - Some(exit_status) => match config.test_success_exit_code { - Some(code) if exit_status.code() == Some(code) => 0, - other => other.unwrap_or(1), - }, + Some(exit_status) => { + let qemu_exit_code = exit_status.code().ok_or("Failed to read QEMU exit code")?; + match config.test_success_exit_code { + Some(code) if qemu_exit_code == code => 0, + _ => qemu_exit_code, + } + } } } else { let status = command From 8f4257246b77ada9d1fa56d05ca812ae98afcf55 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Sat, 2 Nov 2019 16:51:24 +0100 Subject: [PATCH 004/108] Print a debug message when QEMU was terminated by a signal on Unix --- src/subcommand/runner.rs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/subcommand/runner.rs b/src/subcommand/runner.rs index f63004d..a453851 100644 --- a/src/subcommand/runner.rs +++ b/src/subcommand/runner.rs @@ -73,6 +73,15 @@ pub(crate) fn runner(args: RunnerArgs) -> Result { return Err(ErrorMessage::from("Timed Out")); } Some(exit_status) => { + #[cfg(unix)] + { + if exit_status.code().is_none() { + use std::os::unix::process::ExitStatusExt; + if let Some(signal) = exit_status.signal() { + eprintln!("QEMU process was terminated by signal {}", signal); + } + } + } let qemu_exit_code = exit_status.code().ok_or("Failed to read QEMU exit code")?; match config.test_success_exit_code { Some(code) if qemu_exit_code == code => 0, From dc81dcfa68b5419eb3d5267025ddecab8fc85f6b Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Wed, 20 Nov 2019 15:10:25 +0100 Subject: [PATCH 005/108] Update changelog for #47 --- Changelog.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Changelog.md b/Changelog.md index 39dc8e7..1fc4cec 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,3 +1,5 @@ +- Don't exit with expected exit code when failed to read QEMU exit code ([#47](https://github.com/rust-osdev/bootimage/pull/47)) + # 0.7.7 - Pass location of kernel's Cargo.toml to bootloader ([#45](https://github.com/rust-osdev/bootimage/pull/45)) From 3462674b005b90e643bcb42e0c7ea96e8bc8f11a Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Wed, 20 Nov 2019 15:12:38 +0100 Subject: [PATCH 006/108] bootimage 0.7.8 --- Cargo.lock | 2 +- Cargo.toml | 2 +- Changelog.md | 2 ++ 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9d5378d..dad9da6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -10,7 +10,7 @@ dependencies = [ [[package]] name = "bootimage" -version = "0.7.7" +version = "0.7.8" dependencies = [ "cargo_metadata 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)", "json 0.11.13 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/Cargo.toml b/Cargo.toml index 9755210..3c5744e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,7 +3,7 @@ authors = ["Philipp Oppermann "] description = "Tool to create a bootable OS image from a kernel binary." license = "MIT/Apache-2.0" name = "bootimage" -version = "0.7.7" +version = "0.7.8" repository = "https://github.com/rust-osdev/bootimage" edition = "2018" diff --git a/Changelog.md b/Changelog.md index 1fc4cec..f0864dc 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,3 +1,5 @@ +# 0.7.8 + - Don't exit with expected exit code when failed to read QEMU exit code ([#47](https://github.com/rust-osdev/bootimage/pull/47)) # 0.7.7 From 510971ac75fed673ef392f36e2aa1726f4caf682 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Wed, 1 Apr 2020 11:57:04 +0200 Subject: [PATCH 007/108] Set empty RUSTFLAGS to ensure that no .cargo/config applies Without the `RUSTFLAGS` environment variable set, cargo looks at `.cargo/config` files in all parent directories. Such a file can contain a `build.rustflags` key that would then be applied to the bootloader build too. Since some rustflags can break the build (e.g. `-C target-cpu=native`), we should prevent that. Creating a `cargo/.config` file with an empty `build.rustflags` key in the bootloader repository does not suffice for fixing this because cargo unifies arrays with the values defined in parent directories. So the only way to ensure that no rustflags are passed is to set the RUSTFLAGS environment variable to the empty string, exploiting the fact that it takes precedence over any `build.rustflags` key. --- src/builder.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/builder.rs b/src/builder.rs index db78c58..3a75847 100644 --- a/src/builder.rs +++ b/src/builder.rs @@ -233,7 +233,7 @@ impl Builder { cmd.arg("--release"); cmd.env("KERNEL", kernel_bin_path); cmd.env("KERNEL_MANIFEST", &self.kernel_manifest_path); - cmd.env_remove("RUSTFLAGS"); + cmd.env("RUSTFLAGS", ""); cmd.env("XBUILD_SYSROOT_PATH", target_dir.join("bootloader-sysroot")); // for cargo-xbuild cmd }; From a4d30e3a941f07e3b56fe5cbcb50a3f23c2cbaf8 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Wed, 1 Apr 2020 12:04:31 +0200 Subject: [PATCH 008/108] Run rustfmt --- src/builder.rs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/builder.rs b/src/builder.rs index 3a75847..2d6a66f 100644 --- a/src/builder.rs +++ b/src/builder.rs @@ -477,10 +477,11 @@ impl fmt::Display for CreateBootimageError { "Could not find required key `{}` in cargo metadata output", key ), - CreateBootimageError::BootloaderNotFound => { - writeln!(f, "Bootloader dependency not found\n\n\ - You need to add a dependency on a crate named `bootloader` in your Cargo.toml.") - } + CreateBootimageError::BootloaderNotFound => writeln!( + f, + "Bootloader dependency not found\n\n\ + You need to add a dependency on a crate named `bootloader` in your Cargo.toml." + ), CreateBootimageError::BootloaderInvalid(err) => writeln!( f, "The `bootloader` dependency has not the right format: {}", From 2ba0f8190d3bb39842fc6f6ca47bd76272f1d2ae Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Wed, 1 Apr 2020 12:59:17 +0200 Subject: [PATCH 009/108] Update macOS image The 10.13 image was removed by Azure and no longer builds. --- azure-pipelines.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 4e659e0..3ddca01 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -16,7 +16,7 @@ jobs: image_name: 'ubuntu-16.04' rustup_toolchain: stable mac: - image_name: 'macos-10.13' + image_name: 'macOS-10.15' rustup_toolchain: stable windows: image_name: 'vs2017-win2016' @@ -75,7 +75,7 @@ jobs: image_name: 'ubuntu-16.04' rustup_toolchain: nightly mac: - image_name: 'macos-10.13' + image_name: 'macos-10.15' rustup_toolchain: nightly windows: image_name: 'vs2017-win2016' From 4e5400b791d40843b5fad376c5e846a39e241626 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Wed, 1 Apr 2020 14:45:01 +0200 Subject: [PATCH 010/108] Update changelog for #51 --- Changelog.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Changelog.md b/Changelog.md index f0864dc..ccde6db 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,3 +1,5 @@ +- Set empty RUSTFLAGS to ensure that no .cargo/config applies ([#51](https://github.com/rust-osdev/bootimage/pull/51)) + # 0.7.8 - Don't exit with expected exit code when failed to read QEMU exit code ([#47](https://github.com/rust-osdev/bootimage/pull/47)) From 4e1650242c0c541a5a64ceadf8e94c957b37f425 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Wed, 1 Apr 2020 14:46:29 +0200 Subject: [PATCH 011/108] bootimage 0.7.9 --- Cargo.lock | 2 +- Cargo.toml | 2 +- Changelog.md | 2 ++ 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index dad9da6..0fa4fc1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -10,7 +10,7 @@ dependencies = [ [[package]] name = "bootimage" -version = "0.7.8" +version = "0.7.9" dependencies = [ "cargo_metadata 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)", "json 0.11.13 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/Cargo.toml b/Cargo.toml index 3c5744e..5993ea9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,7 +3,7 @@ authors = ["Philipp Oppermann "] description = "Tool to create a bootable OS image from a kernel binary." license = "MIT/Apache-2.0" name = "bootimage" -version = "0.7.8" +version = "0.7.9" repository = "https://github.com/rust-osdev/bootimage" edition = "2018" diff --git a/Changelog.md b/Changelog.md index ccde6db..0e59bce 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,3 +1,5 @@ +# 0.7.9 + - Set empty RUSTFLAGS to ensure that no .cargo/config applies ([#51](https://github.com/rust-osdev/bootimage/pull/51)) # 0.7.8 From d2936f99482a3df45fe0195dc421fe60ae395ebc Mon Sep 17 00:00:00 2001 From: Tom Dohrmann Date: Thu, 30 Apr 2020 11:02:11 +0200 Subject: [PATCH 012/108] Add support for doctests (#52) --- azure-pipelines.yml | 4 + example-kernels/Cargo.lock | 46 +++++----- example-kernels/Cargo.toml | 1 + example-kernels/runner-doctest/.cargo/config | 5 ++ example-kernels/runner-doctest/.gitignore | 2 + example-kernels/runner-doctest/Cargo.toml | 13 +++ example-kernels/runner-doctest/src/lib.rs | 90 ++++++++++++++++++++ src/subcommand/runner.rs | 8 +- 8 files changed, 145 insertions(+), 24 deletions(-) create mode 100644 example-kernels/runner-doctest/.cargo/config create mode 100644 example-kernels/runner-doctest/.gitignore create mode 100644 example-kernels/runner-doctest/Cargo.toml create mode 100644 example-kernels/runner-doctest/src/lib.rs diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 3ddca01..d2f93d4 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -191,6 +191,10 @@ jobs: workingDirectory: example-kernels/runner displayName: 'Run `cargo xrun` for "runner" kernel' + - script: cargo xtest -Z doctest-xcompile + workingDirectory: example-kernels/runner-doctest + displayName: 'Run `cargo xtest -Z doctest-xcompile` for "runner-doctest" kernel' + - script: cargo xtest workingDirectory: example-kernels/runner-test displayName: 'Run `cargo xtest` for "runner-test" kernel' diff --git a/example-kernels/Cargo.lock b/example-kernels/Cargo.lock index 8549198..c04784c 100644 --- a/example-kernels/Cargo.lock +++ b/example-kernels/Cargo.lock @@ -12,7 +12,7 @@ dependencies = [ name = "basic" version = "0.1.0" dependencies = [ - "bootloader 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "bootloader 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", "x86_64 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -28,14 +28,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "bootloader" -version = "0.5.3" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "fixedvec 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "font8x8 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", "llvm-tools 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "usize_conversions 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "x86_64 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", + "x86_64 0.7.7 (registry+https://github.com/rust-lang/crates.io-index)", "xmas-elf 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -53,7 +52,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" name = "default-target-bootimage" version = "0.1.0" dependencies = [ - "bootloader 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "bootloader 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", "x86_64 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -61,7 +60,7 @@ dependencies = [ name = "default-target-cargo" version = "0.1.0" dependencies = [ - "bootloader 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "bootloader 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", "x86_64 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -73,11 +72,6 @@ dependencies = [ "skeptic 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "font8x8" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "fuchsia-cprng" version = "0.1.1" @@ -182,7 +176,15 @@ dependencies = [ name = "runner" version = "0.1.0" dependencies = [ - "bootloader 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "bootloader 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", + "x86_64 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "runner-doctest" +version = "0.1.0" +dependencies = [ + "bootloader 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", "x86_64 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -190,7 +192,7 @@ dependencies = [ name = "runner-test" version = "0.1.0" dependencies = [ - "bootloader 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "bootloader 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", "x86_64 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -247,7 +249,7 @@ dependencies = [ name = "testing-qemu-exit-code" version = "0.1.0" dependencies = [ - "bootloader 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "bootloader 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", "x86_64 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -255,7 +257,7 @@ dependencies = [ name = "testing-serial-result" version = "0.1.0" dependencies = [ - "bootloader 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "bootloader 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "spin 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", "uart_16550 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -319,27 +321,26 @@ dependencies = [ [[package]] name = "x86_64" -version = "0.3.6" +version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "array-init 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "bit_field 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "os_bootinfo 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "usize_conversions 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "cast 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "raw-cpuid 6.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "ux 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "x86_64" -version = "0.5.5" +version = "0.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "array-init 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "bit_field 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "cast 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "raw-cpuid 6.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "ux 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -360,11 +361,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum array-init 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "23589ecb866b460d3a0f1278834750268c607e8e28a1b982c907219f3178cd72" "checksum bit_field 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ed8765909f9009617974ab6b7d332625b320b33c326b1e9321382ef1999b5d56" "checksum bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3d155346769a6855b86399e9bc3814ab343cd3d62c7e985113d46a0ec3c281fd" -"checksum bootloader 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a8f7c11b70b5781deec899276f7d67611eaf296a8bd7dcc9b9d37c71a5389c52" +"checksum bootloader 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b15e5b7b9d9a8e427cf4270894f51ce288632a3a1a2cc6f8fda669d5446f98bd" "checksum cast 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "926013f2860c46252efceabb19f4a6b308197505082c609025aa6706c011d427" "checksum cc 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)" = "39f75544d7bbaf57560d2168f28fd649ff9c76153874db88bdbdfd839b1a7e7d" "checksum fixedvec 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7c6c16d316ccdac21a4dd648e314e76facbbaf316e83ca137d0857a9c07419d0" -"checksum font8x8 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "44226c40489fb1d602344a1d8f1b544570c3435e396dda1eda7b5ef010d8f1be" "checksum fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" "checksum getopts 0.2.19 (registry+https://github.com/rust-lang/crates.io-index)" = "72327b15c228bfe31f1390f93dd5e9279587f0463836393c9df719ce62a3e450" "checksum lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bc5729f27f159ddd61f4df6228e827e86643d4d3e7c32183cb30a1c08f604a14" @@ -394,7 +394,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" "checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" "checksum x86_64 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "2bd647af1614659e1febec1d681231aea4ebda4818bf55a578aff02f3e4db4b4" -"checksum x86_64 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "f9258d7e2dd25008d69e8c9e9ee37865887a5e1e3d06a62f1cb3f6c209e6f177" "checksum x86_64 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)" = "bb8f09c32a991cc758ebcb9b7984f530095d32578a4e7b85db6ee1f0bbe4c9c6" +"checksum x86_64 0.7.7 (registry+https://github.com/rust-lang/crates.io-index)" = "1f27d9168654aee1b0c1b73746caeb4aa33248f8b8c8f6e100e697fcc2a794b2" "checksum xmas-elf 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "22678df5df766e8d1e5d609da69f0c3132d794edf6ab5e75e7abcd2270d4cf58" "checksum zero 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "5f1bc8a6b2005884962297587045002d8cfb8dcec9db332f4ca216ddc5de82c5" diff --git a/example-kernels/Cargo.toml b/example-kernels/Cargo.toml index ee84626..e2ee131 100644 --- a/example-kernels/Cargo.toml +++ b/example-kernels/Cargo.toml @@ -4,6 +4,7 @@ members = [ "default-target-bootimage", "default-target-cargo", "runner", + "runner-doctest", "runner-test", "testing-qemu-exit-code", "testing-serial-result", diff --git a/example-kernels/runner-doctest/.cargo/config b/example-kernels/runner-doctest/.cargo/config new file mode 100644 index 0000000..3b4d89e --- /dev/null +++ b/example-kernels/runner-doctest/.cargo/config @@ -0,0 +1,5 @@ +[build] +target = "../x86_64-bootimage-example-kernels.json" + +[target.'cfg(target_os = "none")'] +runner = "bootimage runner" diff --git a/example-kernels/runner-doctest/.gitignore b/example-kernels/runner-doctest/.gitignore new file mode 100644 index 0000000..eccd7b4 --- /dev/null +++ b/example-kernels/runner-doctest/.gitignore @@ -0,0 +1,2 @@ +/target/ +**/*.rs.bk diff --git a/example-kernels/runner-doctest/Cargo.toml b/example-kernels/runner-doctest/Cargo.toml new file mode 100644 index 0000000..d3c440f --- /dev/null +++ b/example-kernels/runner-doctest/Cargo.toml @@ -0,0 +1,13 @@ +[package] +name = "runner-doctest" +version = "0.1.0" +authors = ["Philipp Oppermann "] +edition = "2018" + +[dependencies] +bootloader = "0.6.4" +x86_64 = "0.5.3" + +[package.metadata.bootimage] +test-success-exit-code = 33 # (0x10 << 1) | 1 +test-args = ["-device", "isa-debug-exit,iobase=0xf4,iosize=0x04", "-display", "none"] diff --git a/example-kernels/runner-doctest/src/lib.rs b/example-kernels/runner-doctest/src/lib.rs new file mode 100644 index 0000000..3cdb90f --- /dev/null +++ b/example-kernels/runner-doctest/src/lib.rs @@ -0,0 +1,90 @@ +#![no_std] +#![cfg_attr(test, no_main)] +#![feature(custom_test_frameworks)] +#![test_runner(crate::test_runner)] +#![reexport_test_harness_main = "test_main"] + +/// add two numbers +/// +/// ``` +/// #![no_std] +/// #![no_main] +/// use runner_doctest::{add, exit_qemu, ExitCode}; +/// #[export_name = "_start"] +/// extern "C" fn start() { +/// assert_eq!(add(1, 2), 3); +/// unsafe { exit_qemu(ExitCode::Success); } +/// } +/// ``` +pub fn add(a: u32, b: u32) -> u32 { + a + b +} + +/// multiply two numbers +/// +/// ``` +/// #![no_std] +/// #![no_main] +/// use runner_doctest::{mul, exit_qemu, ExitCode}; +/// #[export_name = "_start"] +/// extern "C" fn start() { +/// assert_eq!(mul(2, 3), 6); +/// unsafe { exit_qemu(ExitCode::Success); } +/// } +/// ``` +pub fn mul(a: u32, b: u32) -> u32 { + a * b +} + +#[cfg(test)] +fn test_runner(tests: &[&dyn Fn()]) { + for test in tests.iter() { + test(); + } + + unsafe { + exit_qemu(ExitCode::Success); + } +} + +pub enum ExitCode { + Success, + Failed, +} + +impl ExitCode { + fn code(&self) -> u32 { + match self { + ExitCode::Success => 0x10, + ExitCode::Failed => 0x11, + } + } +} + +/// exit QEMU (see https://os.phil-opp.com/integration-tests/#shutting-down-qemu) +pub unsafe fn exit_qemu(exit_code: ExitCode) { + use x86_64::instructions::port::Port; + + let mut port = Port::::new(0xf4); + port.write(exit_code.code()); +} + +#[cfg(test)] +#[no_mangle] +pub extern "C" fn _start() -> ! { + test_main(); + + unsafe { + exit_qemu(ExitCode::Failed); + } + + loop {} +} + +#[panic_handler] +fn panic(_info: &core::panic::PanicInfo) -> ! { + unsafe { + exit_qemu(ExitCode::Failed); + } + loop {} +} diff --git a/src/subcommand/runner.rs b/src/subcommand/runner.rs index a453851..e5ee486 100644 --- a/src/subcommand/runner.rs +++ b/src/subcommand/runner.rs @@ -9,7 +9,13 @@ pub(crate) fn runner(args: RunnerArgs) -> Result { .executable .parent() .ok_or("kernel executable has no parent")?; - let is_test = exe_parent.ends_with("deps"); + let is_doctest = exe_parent + .file_name() + .ok_or("kernel executable's parent has no file name")? + .to_str() + .ok_or("kernel executable's parent file name is not valid UTF-8")? + .starts_with("rustdoctest"); + let is_test = is_doctest || exe_parent.ends_with("deps"); let bootimage_bin = { let file_stem = args From 060dce85b711c923269f0c9938a7e77e282f7359 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Thu, 30 Apr 2020 11:03:10 +0200 Subject: [PATCH 013/108] Update changelog for #52 --- Changelog.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Changelog.md b/Changelog.md index 0e59bce..c9949c0 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,3 +1,5 @@ +- Add support for doctests ([#52](https://github.com/rust-osdev/bootimage/pull/52)) + # 0.7.9 - Set empty RUSTFLAGS to ensure that no .cargo/config applies ([#51](https://github.com/rust-osdev/bootimage/pull/51)) From 64652dcbeb625da7eae4ca9995cf89969fad9702 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Thu, 30 Apr 2020 11:05:00 +0200 Subject: [PATCH 014/108] bootimage 0.7.10 --- Cargo.lock | 2 +- Cargo.toml | 2 +- Changelog.md | 2 ++ 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0fa4fc1..63933ff 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -10,7 +10,7 @@ dependencies = [ [[package]] name = "bootimage" -version = "0.7.9" +version = "0.7.10" dependencies = [ "cargo_metadata 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)", "json 0.11.13 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/Cargo.toml b/Cargo.toml index 5993ea9..d75e7d3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,7 +3,7 @@ authors = ["Philipp Oppermann "] description = "Tool to create a bootable OS image from a kernel binary." license = "MIT/Apache-2.0" name = "bootimage" -version = "0.7.9" +version = "0.7.10" repository = "https://github.com/rust-osdev/bootimage" edition = "2018" diff --git a/Changelog.md b/Changelog.md index c9949c0..2d3ad0d 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,3 +1,5 @@ +# 0.7.10 + - Add support for doctests ([#52](https://github.com/rust-osdev/bootimage/pull/52)) # 0.7.9 From cd16aad1be99fe0c973d89057f3cfc5359fd9952 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Wed, 6 May 2020 16:56:30 +0200 Subject: [PATCH 015/108] Remove `bootimage run` and `bootimage test` commands We only support running/testing through the runner executable from now on. --- src/help/run_help.txt | 23 ------ src/help/test_help.txt | 26 ------ src/subcommand.rs | 2 - src/subcommand/run.rs | 59 -------------- src/subcommand/test.rs | 175 ----------------------------------------- 5 files changed, 285 deletions(-) delete mode 100644 src/help/run_help.txt delete mode 100644 src/help/test_help.txt delete mode 100644 src/subcommand/run.rs delete mode 100644 src/subcommand/test.rs diff --git a/src/help/run_help.txt b/src/help/run_help.txt deleted file mode 100644 index f6c0857..0000000 --- a/src/help/run_help.txt +++ /dev/null @@ -1,23 +0,0 @@ -Creates a bootable disk image from a Rust kernel and launches it in QEMU - -USAGE: - bootimage run [BUILD_OPTS] -- [RUN_OPTS] Build and run a disk image - - (for other forms of usage see `bootimage --help`) - (for BUILD_OPTS see `bootimage build --help`) - -RUN_OPTS: - Any options are directly passed to the run command. Note that the run - options must be separated from the build options by a "--". - -CONFIGURATION: - The behavior of `bootimage run` can be configured through a - `[package.metadata.bootimage]` table in the `Cargo.toml`. The - following options are available to configure run behavior: - - [package.metadata.bootimage] - # The command invoked with the created bootimage (the "{}" will be replaced - # with the path to the bootable disk image) - run-command = ["qemu-system-x86_64", "-drive", "format=raw,file={}"] - # Additional arguments passed to the run command for non-test executables - run-args = [] \ No newline at end of file diff --git a/src/help/test_help.txt b/src/help/test_help.txt deleted file mode 100644 index a9fa8e1..0000000 --- a/src/help/test_help.txt +++ /dev/null @@ -1,26 +0,0 @@ -Runs integration tests of a Rust kernel - -The following conventions are used: - -- All executables starting with `test-` are treated as unit test. -- Tests must print either ok or failed over the serial port. When printing - failed they can print additional information such as a panic message (in the - next lines). -- Tests are run with a timeout of 1 minute. If the test has not completed in - time, it is reported as "timed out". - - -USAGE: - bootimage test [BUILD_OPTS] Runs integration tests - - (for other forms of usage see `bootimage --help`) - (for BUILD_OPTS see `bootimage build --help`) - -CONFIGURATION: - The behavior of `bootimage test` can be configured through a - `[package.metadata.bootimage]` table in the `Cargo.toml`. The - following options are available to configure test behavior: - - [package.metadata.bootimage] - # The timeout for running an integration test in seconds - test-timeout = 300 \ No newline at end of file diff --git a/src/subcommand.rs b/src/subcommand.rs index f848c46..b72654c 100644 --- a/src/subcommand.rs +++ b/src/subcommand.rs @@ -1,4 +1,2 @@ pub mod build; -pub mod run; pub mod runner; -pub mod test; diff --git a/src/subcommand/run.rs b/src/subcommand/run.rs deleted file mode 100644 index 3d23ab2..0000000 --- a/src/subcommand/run.rs +++ /dev/null @@ -1,59 +0,0 @@ -use crate::{args::Args, builder::Builder, config, ErrorMessage}; -use std::process; - -pub(crate) fn run(mut args: Args) -> Result { - use crate::subcommand::build; - - let builder = Builder::new(args.manifest_path().clone())?; - let config = config::read_config(builder.kernel_manifest_path())?; - args.apply_default_target(&config, builder.kernel_root()); - - if args.bin_name().is_none() { - let kernel_package = builder - .kernel_package() - .map_err(|key| format!("Kernel package not found it cargo metadata (`{}`)", key))?; - let bins = kernel_package.targets.iter().filter(|t| t.kind == ["bin"]); - let mut not_test = bins.filter(|t| !t.name.starts_with("test-")); - let bin_name = not_test - .next() - .ok_or("no kernel executable found")? - .name - .to_owned(); - if not_test.count() > 0 { - Err("Multiple kernel executables found. \ - Please specify the binary you want to run as a `--bin` argument")?; - } - args.set_bin_name(bin_name); - } - - let quiet = args.quiet; - let bootimages = build::build_impl(&builder, &mut args, quiet)?; - let bootimage_path = bootimages.first().ok_or("no bootimages created")?; - if bootimages.len() > 1 { - Err("more than one bootimage created")?; - } - - let command = &config.run_command[0]; - let mut command = process::Command::new(command); - for arg in &config.run_command[1..] { - command.arg( - arg.replace( - "{}", - bootimage_path - .to_str() - .ok_or(ErrorMessage::from("bootimage path is not valid unicode"))?, - ), - ); - } - if let Some(run_args) = config.run_args { - command.args(run_args); - } - command.args(&args.run_args); - let exit_status = command.status().map_err(|err| { - ErrorMessage::from(format!( - "Failed to execute run command `{:?}`: {}", - command, err - )) - })?; - Ok(exit_status.code().unwrap_or(1)) -} diff --git a/src/subcommand/test.rs b/src/subcommand/test.rs deleted file mode 100644 index 7bf06b1..0000000 --- a/src/subcommand/test.rs +++ /dev/null @@ -1,175 +0,0 @@ -use crate::{args::Args, builder::Builder, config, subcommand::build, ErrorMessage}; -use rayon::prelude::*; -use std::{fs, io, io::Write, process, time::Duration}; -use wait_timeout::ChildExt; - -pub(crate) fn test(mut args: Args) -> Result<(), ErrorMessage> { - let builder = Builder::new(args.manifest_path().clone())?; - let config = config::read_config(builder.kernel_manifest_path())?; - args.apply_default_target(&config, builder.kernel_root()); - - let test_args = args.clone(); - - let kernel_package = builder - .kernel_package() - .map_err(|key| format!("Kernel package not found it cargo metadata (`{}`)", key))?; - let test_target_iter = kernel_package - .targets - .iter() - .filter(|t| t.kind == ["bin"] && t.name.starts_with("test-")); - - let mut test_targets = Vec::new(); - for target in test_target_iter { - println!("BUILD: {}", target.name); - - let mut target_args = test_args.clone(); - target_args.set_bin_name(target.name.clone()); - let executables = build::build_impl(&builder, &mut target_args, true) - .expect(&format!("Failed to build test: {}", target.name)); - let test_bin_path = executables - .first() - .ok_or("no test executable built")? - .to_owned(); - if executables.len() > 1 { - Err("more than one test executables built")?; - } - - test_targets.push((target, test_bin_path)); - } - - let tests = test_targets - .par_iter() - .map(|(target, test_path)| { - println!("RUN: {}", target.name); - - let test_result; - let output_file = format!("{}-output.txt", test_path.display()); - - let mut command = process::Command::new("qemu-system-x86_64"); - command.arg("-drive"); - command.arg(format!("format=raw,file={}", test_path.display())); - command.arg("-device"); - command.arg("isa-debug-exit,iobase=0xf4,iosize=0x04"); - command.arg("-display"); - command.arg("none"); - command.arg("-serial"); - command.arg(format!("file:{}", output_file)); - command.stderr(process::Stdio::null()); - let mut child = command - .spawn() - .map_err(|e| format!("Failed to launch QEMU: {:?}\n{}", command, e))?; - let timeout = Duration::from_secs(config.test_timeout.into()); - match child - .wait_timeout(timeout) - .map_err(|e| format!("Failed to wait with timeout: {}", e))? - { - None => { - child - .kill() - .map_err(|e| format!("Failed to kill QEMU: {}", e))?; - child - .wait() - .map_err(|e| format!("Failed to wait for QEMU process: {}", e))?; - test_result = TestResult::TimedOut; - writeln!(io::stderr(), "Timed Out")?; - } - Some(exit_status) => { - let output = fs::read_to_string(&output_file).map_err(|e| { - format!("Failed to read test output file {}: {}", output_file, e) - })?; - test_result = handle_exit_status(exit_status, &output, &target.name)?; - } - } - - Ok((target.name.clone(), test_result)) - }) - .collect::, ErrorMessage>>()?; - - println!(""); - if tests.iter().all(|t| t.1 == TestResult::Ok) { - println!("All tests succeeded."); - Ok(()) - } else { - writeln!(io::stderr(), "The following tests failed:")?; - for test in tests.iter().filter(|t| t.1 != TestResult::Ok) { - writeln!(io::stderr(), " {}: {:?}", test.0, test.1)?; - } - Err("Some tests failed".into()) - } -} - -fn handle_exit_status( - exit_status: process::ExitStatus, - output: &str, - target_name: &str, -) -> Result { - match exit_status.code() { - None => { - writeln!(io::stderr(), "FAIL: No Exit Code.")?; - for line in output.lines() { - writeln!(io::stderr(), " {}", line)?; - } - Ok(TestResult::Invalid) - } - Some(code) => { - match code { - // 0 << 1 | 1 - 1 => { - if output.starts_with("ok\n") { - println!("OK: {}", target_name); - Ok(TestResult::Ok) - } else if output.starts_with("failed\n") { - writeln!(io::stderr(), "FAIL:")?; - for line in output[7..].lines() { - writeln!(io::stderr(), " {}", line)?; - } - Ok(TestResult::Failed) - } else { - writeln!(io::stderr(), "FAIL: Invalid Output:")?; - for line in output.lines() { - writeln!(io::stderr(), " {}", line)?; - } - Ok(TestResult::Invalid) - } - } - - // 2 << 1 | 1 - 5 => { - println!("OK: {}", target_name); - Ok(TestResult::Ok) - } - - // 3 << 1 | 1 - 7 => { - let fail_index = output.find("failed\n"); - if fail_index.is_some() { - writeln!(io::stderr(), "FAIL:")?; - let fail_output = output.split_at(fail_index.unwrap()).1; - for line in fail_output[7..].lines() { - writeln!(io::stderr(), " {}", line)?; - } - } else { - writeln!(io::stderr(), "FAIL: {}", target_name)?; - } - Ok(TestResult::Failed) - } - - _ => { - writeln!(io::stderr(), "FAIL: Invalid Exit Code {}:", code)?; - for line in output.lines() { - writeln!(io::stderr(), " {}", line)?; - } - Ok(TestResult::Invalid) - } - } - } - } -} - -#[derive(Debug, PartialEq, Eq)] -enum TestResult { - Ok, - Failed, - TimedOut, - Invalid, -} From 4e1ed85ead62a870a8ca3888ee76c3cdb77f6c71 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Wed, 6 May 2020 17:00:02 +0200 Subject: [PATCH 016/108] Remove support for the `default-target` config key Set a default target in a `.cargo/config` file instead. --- Readme.md | 3 --- src/args.rs | 9 --------- src/config.rs | 5 ----- src/help/build_help.txt | 8 -------- src/help/cargo_bootimage_help.txt | 7 ------- src/subcommand/build.rs | 3 --- 6 files changed, 35 deletions(-) diff --git a/Readme.md b/Readme.md index 41099c7..67585b4 100644 --- a/Readme.md +++ b/Readme.md @@ -64,9 +64,6 @@ Configuration is done through a through a `[package.metadata.bootimage]` table i ```toml [package.metadata.bootimage] - # This target is used if no `--target` is passed - default-target = "" - # The command invoked with the created bootimage (the "{}" will be replaced # with the path to the bootable disk image) # Applies to `bootimage run` and `bootimage runner` diff --git a/src/args.rs b/src/args.rs index 3c2fb0f..965ee6f 100644 --- a/src/args.rs +++ b/src/args.rs @@ -201,15 +201,6 @@ impl Args { self.cargo_args.push("--bin".into()); self.cargo_args.push(bin_name); } - - pub fn apply_default_target(&mut self, config: &Config, crate_root: &Path) { - if self.target().is_none() { - if let Some(ref target) = config.default_target { - let canonicalized_target = crate_root.join(target); - self.set_target(canonicalized_target.to_string_lossy().into_owned()); - } - } - } } fn parse_runner_args(args: A) -> Result diff --git a/src/config.rs b/src/config.rs index ce7e964..8661360 100644 --- a/src/config.rs +++ b/src/config.rs @@ -11,8 +11,6 @@ use toml::Value; /// options. #[derive(Debug, Clone)] pub struct Config { - /// This target is used if no `--target` argument is passed - pub default_target: Option, /// The run command that is invoked on `bootimage run` or `bootimage runner` /// /// The substring "{}" will be replaced with the path to the bootable disk image. @@ -69,7 +67,6 @@ pub(crate) fn read_config_inner(manifest_path: &Path) -> Result config.default_target = From::from(s), ("test-timeout", Value::Integer(timeout)) if timeout.is_negative() => { Err(format!("test-timeout must not be negative"))? } @@ -121,7 +118,6 @@ pub(crate) fn read_config_inner(manifest_path: &Path) -> Result, run_command: Option>, run_args: Option>, test_args: Option>, @@ -132,7 +128,6 @@ struct ConfigBuilder { impl Into for ConfigBuilder { fn into(self) -> Config { Config { - default_target: self.default_target, run_command: self.run_command.unwrap_or(vec![ "qemu-system-x86_64".into(), "-drive".into(), diff --git a/src/help/build_help.txt b/src/help/build_help.txt index e623053..572c8d4 100644 --- a/src/help/build_help.txt +++ b/src/help/build_help.txt @@ -10,11 +10,3 @@ BUILD_OPTS: `cargo build --help` for possible options). After building, a bootloader is downloaded and built, and then combined with the kernel into a bootable disk image. - -CONFIGURATION: - The behavior of `bootimage build` can be configured through a - `[package.metadata.bootimage]` table in the `Cargo.toml`. The following - options are available to configure the build: - - [package.metadata.bootimage] - default-target = "" This target is used if no `--target` is passed diff --git a/src/help/cargo_bootimage_help.txt b/src/help/cargo_bootimage_help.txt index b257c10..f8cabbf 100644 --- a/src/help/cargo_bootimage_help.txt +++ b/src/help/cargo_bootimage_help.txt @@ -11,10 +11,3 @@ BUILD_OPTS: is downloaded and built, and then combined with the kernel into a bootable disk image. -CONFIGURATION: - The behavior of `cargo bootimage` can be configured through a - `[package.metadata.bootimage]` table in the `Cargo.toml`. The following - options are available to configure the build: - - [package.metadata.bootimage] - default-target = "" This target is used if no `--target` is passed diff --git a/src/subcommand/build.rs b/src/subcommand/build.rs index 4a85a42..1831cb5 100644 --- a/src/subcommand/build.rs +++ b/src/subcommand/build.rs @@ -3,9 +3,6 @@ use std::path::PathBuf; pub(crate) fn build(mut args: Args) -> Result<(), ErrorMessage> { let builder = Builder::new(args.manifest_path().clone())?; - let config = config::read_config(builder.kernel_manifest_path())?; - args.apply_default_target(&config, builder.kernel_root()); - let quiet = args.quiet; build_impl(&builder, &mut args, quiet).map(|_| ()) } From 2f76568d3b35df71ad5911abb5100fb49c17bf04 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Wed, 6 May 2020 21:40:02 +0200 Subject: [PATCH 017/108] Rewrite and simplify crate --- Cargo.lock | 244 ++++++---------- Cargo.toml | 16 +- src/args.rs | 257 ----------------- src/args/build.rs | 110 ++++++++ src/args/mod.rs | 7 + src/args/runner.rs | 73 +++++ src/bin/cargo-bootimage.rs | 67 ++++- src/builder.rs | 554 ------------------------------------- src/builder/bootloader.rs | 154 +++++++++++ src/builder/disk_image.rs | 62 +++++ src/builder/error.rs | 154 +++++++++++ src/builder/mod.rs | 183 ++++++++++++ src/config.rs | 35 ++- src/help/build_help.txt | 12 - src/help/help.txt | 28 +- src/help/mod.rs | 34 +-- src/lib.rs | 96 +------ src/main.rs | 161 ++++++++++- src/subcommand.rs | 2 - src/subcommand/build.rs | 36 --- src/subcommand/runner.rs | 106 ------- 21 files changed, 1084 insertions(+), 1307 deletions(-) delete mode 100644 src/args.rs create mode 100644 src/args/build.rs create mode 100644 src/args/mod.rs create mode 100644 src/args/runner.rs delete mode 100644 src/builder.rs create mode 100644 src/builder/bootloader.rs create mode 100644 src/builder/disk_image.rs create mode 100644 src/builder/error.rs create mode 100644 src/builder/mod.rs delete mode 100644 src/help/build_help.txt delete mode 100644 src/subcommand.rs delete mode 100644 src/subcommand/build.rs delete mode 100644 src/subcommand/runner.rs diff --git a/Cargo.lock b/Cargo.lock index 63933ff..51f6e57 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,107 +1,48 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. [[package]] -name = "arrayvec" -version = "0.4.7" +name = "anyhow" +version = "1.0.28" source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)", -] [[package]] name = "bootimage" version = "0.7.10" dependencies = [ - "cargo_metadata 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)", - "json 0.11.13 (registry+https://github.com/rust-lang/crates.io-index)", + "anyhow 1.0.28 (registry+https://github.com/rust-lang/crates.io-index)", + "cargo_metadata 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", + "json 0.12.4 (registry+https://github.com/rust-lang/crates.io-index)", "llvm-tools 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "locate-cargo-manifest 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rayon 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", - "toml 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "locate-cargo-manifest 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "thiserror 1.0.16 (registry+https://github.com/rust-lang/crates.io-index)", + "toml 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", "wait-timeout 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "cargo_metadata" -version = "0.7.4" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.106 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.106 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.52 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "cfg-if" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "crossbeam-deque" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "crossbeam-epoch 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "crossbeam-epoch" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "cfg-if 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)", - "scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "crossbeam-utils" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "cfg-if 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "dtoa" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "either" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "error-chain" -version = "0.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "itoa" -version = "0.4.2" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "json" -version = "0.11.13" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "lazy_static" -version = "1.2.0" +version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "libc" -version = "0.2.42" +version = "0.2.69" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -111,70 +52,32 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "locate-cargo-manifest" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "json 0.11.13 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "memoffset" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "nodrop" -version = "0.1.13" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "num_cpus" -version = "1.8.0" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)", + "json 0.12.4 (registry+https://github.com/rust-lang/crates.io-index)", + "thiserror 1.0.16 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "proc-macro2" -version = "0.4.8" +version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "quote" -version = "0.6.3" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro2 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.12 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] -name = "rayon" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "crossbeam-deque 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "either 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rayon-core 1.4.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "rayon-core" -version = "1.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "crossbeam-deque 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)", - "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "scopeguard" -version = "0.3.3" +name = "ryu" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -183,7 +86,7 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.106 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -193,50 +96,68 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "serde" -version = "1.0.89" +version = "1.0.106" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "serde_derive" -version = "1.0.89" +version = "1.0.106" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro2 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.29 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.12 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "serde_json" -version = "1.0.24" +version = "1.0.52" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "dtoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", - "itoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", + "itoa 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", + "ryu 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.106 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "syn" -version = "0.15.29" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 1.0.12 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "thiserror" +version = "1.0.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "thiserror-impl 1.0.16 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.16" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro2 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)", - "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.12 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "toml" -version = "0.5.0" +version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.106 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "unicode-xid" -version = "0.1.0" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -244,39 +165,28 @@ name = "wait-timeout" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.69 (registry+https://github.com/rust-lang/crates.io-index)", ] [metadata] -"checksum arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)" = "a1e964f9e24d588183fcb43503abda40d288c8657dfc27311516ce2f05675aef" -"checksum cargo_metadata 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)" = "178d62b240c34223f265a4c1e275e37d62da163d421fc8d7f7e3ee340f803c57" -"checksum cfg-if 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "efe5c877e17a9c717a0bf3613b2709f723202c4e4675cc8f12926ded29bcb17e" -"checksum crossbeam-deque 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f739f8c5363aca78cfb059edf753d8f0d36908c348f3d8d1503f03d8b75d9cf3" -"checksum crossbeam-epoch 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "927121f5407de9956180ff5e936fe3cf4324279280001cd56b669d28ee7e9150" -"checksum crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2760899e32a1d58d5abb31129f8fae5de75220bc2176e77ff7c627ae45c918d9" -"checksum dtoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "6d301140eb411af13d3115f9a562c85cc6b541ade9dfa314132244aaee7489dd" -"checksum either 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3be565ca5c557d7f59e7cfcf1844f9e3033650c929c6566f511e8005f205c1d0" -"checksum error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "07e791d3be96241c77c43846b665ef1384606da2cd2a48730abe606a12906e02" -"checksum itoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "5adb58558dcd1d786b5f0bd15f3226ee23486e24b7b58304b60f64dc68e62606" -"checksum json 0.11.13 (registry+https://github.com/rust-lang/crates.io-index)" = "9ad0485404155f45cce53a40d4b2d6ac356418300daed05273d9e26f91c390be" -"checksum lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a374c89b9db55895453a74c1e38861d9deec0b01b405a82516e9d5de4820dea1" -"checksum libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)" = "b685088df2b950fccadf07a7187c8ef846a959c142338a48f9dc0b94517eb5f1" +"checksum anyhow 1.0.28 (registry+https://github.com/rust-lang/crates.io-index)" = "d9a60d744a80c30fcb657dfe2c1b22bcb3e814c1a1e3674f32bf5820b570fbff" +"checksum cargo_metadata 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "46e3374c604fb39d1a2f35ed5e4a4e30e60d01fab49446e08f1b3e9a90aef202" +"checksum itoa 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "b8b7a7c0c47db5545ed3fef7468ee7bb5b74691498139e4b3f6a20685dc6dd8e" +"checksum json 0.12.4 (registry+https://github.com/rust-lang/crates.io-index)" = "078e285eafdfb6c4b434e0d31e8cfcb5115b651496faca5749b88fafd4f23bfd" +"checksum libc 0.2.69 (registry+https://github.com/rust-lang/crates.io-index)" = "99e85c08494b21a9054e7fe1374a732aeadaff3980b6990b94bfd3a70f690005" "checksum llvm-tools 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "955be5d0ca0465caf127165acb47964f911e2bc26073e865deb8be7189302faf" -"checksum locate-cargo-manifest 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9d87d2c1ca6d2636268f961e70b024866db2d8244a46687527e7ed1a9360b8de" -"checksum memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0f9dc261e2b62d7a622bf416ea3c5245cdd5d9a7fcc428c0d06804dfce1775b3" -"checksum nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "2f9667ddcc6cc8a43afc9b7917599d7216aa09c463919ea32c59ed6cac8bc945" -"checksum num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c51a3322e4bca9d212ad9a158a02abc6934d005490c054a2778df73a70aa0a30" -"checksum proc-macro2 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "c65b1ea15bb859d922cade2d1765b4b88beac339cbfad545ef2d2ef8c8215ee6" -"checksum quote 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "e44651a0dc4cdd99f71c83b561e221f714912d11af1a4dff0631f923d53af035" -"checksum rayon 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "373814f27745b2686b350dd261bfd24576a6fb0e2c5919b3a2b6005f820b0473" -"checksum rayon-core 1.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b055d1e92aba6877574d8fe604a63c8b5df60f60e5982bf7ccbb1338ea527356" -"checksum scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27" +"checksum locate-cargo-manifest 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d264d672563b20c0a2eb9045f4072e1352002f6c316cc0677bed8b767e17b7e1" +"checksum proc-macro2 1.0.12 (registry+https://github.com/rust-lang/crates.io-index)" = "8872cf6f48eee44265156c111456a700ab3483686b3f96df4cf5481c89157319" +"checksum quote 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "4c1f4b0efa5fc5e8ceb705136bfee52cfdb6a4e3509f770b478cd6ed434232a7" +"checksum ryu 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "ed3d612bc64430efeb3f7ee6ef26d590dce0c43249217bddc62112540c7941e1" "checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" "checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" -"checksum serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)" = "92514fb95f900c9b5126e32d020f5c6d40564c27a5ea6d1d7d9f157a96623560" -"checksum serde_derive 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)" = "bb6eabf4b5914e88e24eea240bb7c9f9a2cbc1bbbe8d961d381975ec3c6b806c" -"checksum serde_json 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)" = "c3c6908c7b925cd6c590358a4034de93dbddb20c45e1d021931459fd419bf0e2" -"checksum syn 0.15.29 (registry+https://github.com/rust-lang/crates.io-index)" = "1825685f977249735d510a242a6727b46efe914bb67e38d30c071b1b72b1d5c2" -"checksum toml 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "87c5890a989fa47ecdc7bcb4c63a77a82c18f306714104b1decfd722db17b39e" -"checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" +"checksum serde 1.0.106 (registry+https://github.com/rust-lang/crates.io-index)" = "36df6ac6412072f67cf767ebbde4133a5b2e88e76dc6187fa7104cd16f783399" +"checksum serde_derive 1.0.106 (registry+https://github.com/rust-lang/crates.io-index)" = "9e549e3abf4fb8621bd1609f11dfc9f5e50320802273b12f3811a67e6716ea6c" +"checksum serde_json 1.0.52 (registry+https://github.com/rust-lang/crates.io-index)" = "a7894c8ed05b7a3a279aeb79025fdec1d3158080b75b98a08faf2806bb799edd" +"checksum syn 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)" = "410a7488c0a728c7ceb4ad59b9567eb4053d02e8cc7f5c0e0eeeb39518369213" +"checksum thiserror 1.0.16 (registry+https://github.com/rust-lang/crates.io-index)" = "d12a1dae4add0f0d568eebc7bf142f145ba1aa2544cafb195c76f0f409091b60" +"checksum thiserror-impl 1.0.16 (registry+https://github.com/rust-lang/crates.io-index)" = "3f34e0c1caaa462fd840ec6b768946ea1e7842620d94fe29d5b847138f521269" +"checksum toml 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "ffc92d160b1eef40665be3a05630d003936a3bc7da7421277846c2613e92c71a" +"checksum unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c" "checksum wait-timeout 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9f200f5b12eb75f8c1ed65abd4b2db8a6e1b138a20de009dacee265a2498f3f6" diff --git a/Cargo.toml b/Cargo.toml index d75e7d3..f3686e5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,13 +8,11 @@ repository = "https://github.com/rust-osdev/bootimage" edition = "2018" [dependencies] -rayon = "1.0" -toml = "0.5.0" -wait-timeout = "0.2" +toml = "0.5.6" +wait-timeout = "0.2.0" llvm-tools = "0.1.1" -locate-cargo-manifest = "0.1.0" -json = "0.11.13" - -[dependencies.cargo_metadata] -version = "0.7.4" -default-features = false +locate-cargo-manifest = "0.2.0" +json = "0.12.4" +anyhow = "1.0.28" +thiserror = "1.0.16" +cargo_metadata = "0.9.1" diff --git a/src/args.rs b/src/args.rs deleted file mode 100644 index 965ee6f..0000000 --- a/src/args.rs +++ /dev/null @@ -1,257 +0,0 @@ -//! Parses command line arguments. - -use crate::{config::Config, Command, ErrorMessage}; -use std::path::{Path, PathBuf}; -use std::{env, mem}; - -pub(crate) fn parse_args() -> Result { - let mut args = env::args(); - let is_cargo_bootimage = { - let executable_name = args.next().ok_or("no first argument (executable name)")?; - let file_stem = Path::new(&executable_name) - .file_stem() - .and_then(|s| s.to_str()); - file_stem == Some("cargo-bootimage") - }; - let first = args.next(); - match first.as_ref().map(|s| s.as_str()) { - Some("build") => parse_build_args(args), - Some("bootimage") if is_cargo_bootimage => parse_build_args(args).map(|cmd| match cmd { - Command::BuildHelp => Command::CargoBootimageHelp, - cmd => cmd, - }), - Some("run") => parse_build_args(args).map(|cmd| match cmd { - Command::Build(args) => Command::Run(args), - Command::BuildHelp => Command::RunHelp, - cmd => cmd, - }), - Some("test") => parse_build_args(args).map(|cmd| match cmd { - Command::Build(args) => { - assert_eq!( - args.bin_name, None, - "No `--bin` argument allowed for `bootimage test`" - ); - Command::Test(args) - } - Command::BuildHelp => Command::TestHelp, - cmd => cmd, - }), - Some("runner") => parse_runner_args(args), - Some("--help") | Some("-h") => Ok(Command::Help), - Some("--version") => Ok(Command::Version), - _ => Ok(Command::NoSubcommand), - } -} - -fn parse_build_args(args: A) -> Result -where - A: Iterator, -{ - let mut manifest_path: Option = None; - let mut bin_name: Option = None; - let mut target: Option = None; - let mut release: Option = None; - let mut cargo_args = Vec::new(); - let mut run_args = Vec::new(); - let mut run_args_started = false; - let mut quiet = false; - { - fn set(arg: &mut Option, value: Option) -> Result<(), ErrorMessage> { - let previous = mem::replace(arg, value); - if previous.is_some() { - Err("multiple arguments of same type provided")? - } - Ok(()) - }; - - let mut arg_iter = args.into_iter(); - while let Some(arg) = arg_iter.next() { - if run_args_started { - run_args.push(arg); - continue; - } - match arg.as_ref() { - "--help" | "-h" => { - return Ok(Command::BuildHelp); - } - "--version" => { - return Ok(Command::Version); - } - "--quiet" => { - quiet = true; - } - "--bin" => { - let next = arg_iter.next(); - set(&mut bin_name, next.clone())?; - cargo_args.push(arg); - if let Some(next) = next { - cargo_args.push(next); - } - } - _ if arg.starts_with("--bin=") => { - set( - &mut bin_name, - Some(String::from(arg.trim_start_matches("--bin="))), - )?; - cargo_args.push(arg); - } - "--target" => { - let next = arg_iter.next(); - set(&mut target, next.clone())?; - cargo_args.push(arg); - if let Some(next) = next { - cargo_args.push(next); - } - } - _ if arg.starts_with("--target=") => { - set( - &mut target, - Some(String::from(arg.trim_start_matches("--target="))), - )?; - cargo_args.push(arg); - } - "--manifest-path" => { - let next = arg_iter.next(); - set( - &mut manifest_path, - next.as_ref().map(|p| { - Path::new(&p) - .canonicalize() - .expect("--manifest-path invalid") - }), - )?; - cargo_args.push(arg); - if let Some(next) = next { - cargo_args.push(next); - } - } - _ if arg.starts_with("--manifest-path=") => { - let path = Path::new(arg.trim_start_matches("--manifest-path=")) - .canonicalize() - .expect("--manifest-path invalid"); - set(&mut manifest_path, Some(path))?; - cargo_args.push(arg); - } - "--release" => { - set(&mut release, Some(true))?; - cargo_args.push(arg); - } - "--" => { - run_args_started = true; - } - _ => { - cargo_args.push(arg); - } - }; - } - } - - Ok(Command::Build(Args { - cargo_args, - run_args, - bin_name, - target, - manifest_path, - release: release.unwrap_or(false), - quiet, - })) -} - -#[derive(Debug, Clone)] -pub struct Args { - /// All arguments that are passed to cargo. - pub cargo_args: Vec, - /// All arguments that are passed to the runner. - pub run_args: Vec, - /// Suppress any output to stdout. - pub quiet: bool, - /// The manifest path (also present in `cargo_args`). - manifest_path: Option, - /// The name of the binary (passed `--bin` argument) (also present in `cargo_args`). - bin_name: Option, - /// The target triple (also present in `cargo_args`). - target: Option, - /// The release flag (also present in `cargo_args`). - release: bool, -} - -impl Args { - pub fn manifest_path(&self) -> &Option { - &self.manifest_path - } - - pub fn target(&self) -> &Option { - &self.target - } - - pub fn set_target(&mut self, target: String) { - assert!(self.target.is_none()); - self.target = Some(target.clone()); - self.cargo_args.push("--target".into()); - self.cargo_args.push(target); - } - - pub fn bin_name(&self) -> Option<&str> { - self.bin_name.as_ref().map(String::as_str) - } - - pub fn set_bin_name(&mut self, bin_name: String) { - assert!(self.bin_name.is_none()); - self.bin_name = Some(bin_name.clone()); - self.cargo_args.push("--bin".into()); - self.cargo_args.push(bin_name); - } -} - -fn parse_runner_args(args: A) -> Result -where - A: Iterator, -{ - let mut executable = None; - let mut quiet = false; - let mut runner_args = None; - - let mut arg_iter = args.into_iter().fuse(); - - loop { - if executable.is_some() { - let args: Vec<_> = arg_iter.collect(); - if args.len() > 0 { - runner_args = Some(args); - } - break; - } - let next = match arg_iter.next() { - Some(next) => next, - None => break, - }; - match next.as_str() { - "--help" | "-h" => { - return Ok(Command::RunnerHelp); - } - "--version" => { - return Ok(Command::Version); - } - "--quiet" => { - quiet = true; - } - exe => { - executable = Some(PathBuf::from(exe)); - } - } - } - - Ok(Command::Runner(RunnerArgs { - executable: executable.ok_or("excepted path to kernel executable as first argument")?, - quiet, - runner_args, - })) -} - -#[derive(Debug, Clone)] -pub struct RunnerArgs { - pub executable: PathBuf, - /// Suppress any output to stdout. - pub quiet: bool, - pub runner_args: Option>, -} diff --git a/src/args/build.rs b/src/args/build.rs new file mode 100644 index 0000000..94e82cf --- /dev/null +++ b/src/args/build.rs @@ -0,0 +1,110 @@ +use anyhow::{anyhow, Result}; +use std::{ + mem, + path::{Path, PathBuf}, +}; + +/// Internal representation of the `cargo bootimage` command. +pub enum BuildCommand { + /// A normal invocation (i.e. no `--help` or `--version`) + Build(BuildArgs), + /// The `--version` command + Version, + /// The `--help` command + Help, +} + +impl BuildCommand { + /// Parse the command line args into a `BuildCommand`. + pub fn parse_args(args: A) -> Result + where + A: Iterator, + { + let mut manifest_path: Option = None; + let mut cargo_args = Vec::new(); + let mut quiet = false; + { + fn set(arg: &mut Option, value: Option) -> Result<()> { + let previous = mem::replace(arg, value); + if previous.is_some() { + return Err(anyhow!("multiple arguments of same type provided")); + } + Ok(()) + }; + + let mut arg_iter = args.into_iter(); + while let Some(arg) = arg_iter.next() { + match arg.as_ref() { + "--help" | "-h" => { + return Ok(BuildCommand::Help); + } + "--version" => { + return Ok(BuildCommand::Version); + } + "--quiet" => { + quiet = true; + } + "--manifest-path" => { + let next = arg_iter.next(); + set( + &mut manifest_path, + next.as_ref().map(|p| { + Path::new(&p) + .canonicalize() + .expect("--manifest-path invalid") + }), + )?; + cargo_args.push(arg); + if let Some(next) = next { + cargo_args.push(next); + } + } + _ if arg.starts_with("--manifest-path=") => { + let path = Path::new(arg.trim_start_matches("--manifest-path=")) + .canonicalize() + .expect("--manifest-path invalid"); + set(&mut manifest_path, Some(path))?; + cargo_args.push(arg); + } + _ => { + cargo_args.push(arg); + } + }; + } + } + + Ok(BuildCommand::Build(BuildArgs { + manifest_path, + cargo_args, + quiet, + })) + } +} + +/// Arguments passed to `cargo bootimage`. +#[derive(Debug, Clone)] +pub struct BuildArgs { + /// The manifest path (also present in `cargo_args`). + manifest_path: Option, + /// All arguments that are passed to cargo. + cargo_args: Vec, + /// Suppress any output to stdout. + quiet: bool, +} + +impl BuildArgs { + /// The value of the `--manifest-path` argument, if any. + pub fn manifest_path(&self) -> Option<&Path> { + self.manifest_path.as_deref() + } + + /// Arguments that should be forwarded to `cargo build`. + pub fn cargo_args(&self) -> &[String] { + &self.cargo_args.as_ref() + } + + /// Whether a `--quiet` flag was passed. + pub fn quiet(&self) -> bool { + self.quiet + } +} diff --git a/src/args/mod.rs b/src/args/mod.rs new file mode 100644 index 0000000..e491c92 --- /dev/null +++ b/src/args/mod.rs @@ -0,0 +1,7 @@ +//! Parses command line arguments. + +pub use build::*; +pub use runner::*; + +mod build; +mod runner; diff --git a/src/args/runner.rs b/src/args/runner.rs new file mode 100644 index 0000000..1336853 --- /dev/null +++ b/src/args/runner.rs @@ -0,0 +1,73 @@ +use anyhow::{anyhow, Result}; +use std::path::PathBuf; + +/// Internal representation of the `bootimage runner` command. +pub enum RunnerCommand { + /// A normal invocation of `bootimage runner` (i.e. no `--help` or `--version`) + Runner(RunnerArgs), + /// A command containing `--version` + Version, + /// A command containing `--help` + Help, +} + +impl RunnerCommand { + /// Parse the given argument set into the internal representation. + pub fn parse_args(args: A) -> Result + where + A: Iterator, + { + let mut executable = None; + let mut quiet = false; + let mut runner_args = None; + + let mut arg_iter = args.into_iter().fuse(); + + loop { + if executable.is_some() { + let args: Vec<_> = arg_iter.collect(); + if args.len() > 0 { + runner_args = Some(args); + } + break; + } + let next = match arg_iter.next() { + Some(next) => next, + None => break, + }; + match next.as_str() { + "--help" | "-h" => { + return Ok(RunnerCommand::Help); + } + "--version" => { + return Ok(RunnerCommand::Version); + } + "--quiet" => { + quiet = true; + } + exe => { + executable = Some(PathBuf::from(exe)); + } + } + } + + Ok(Self::Runner(RunnerArgs { + executable: executable.ok_or(anyhow!( + "excepted path to kernel executable as first argument" + ))?, + quiet, + runner_args, + })) + } +} + +/// Arguments for the `bootimage runner` command +#[derive(Debug, Clone)] +pub struct RunnerArgs { + /// Path to the executable binary + pub executable: PathBuf, + /// Suppress any output to stdout. + pub quiet: bool, + /// Additional arguments passed to the runner + pub runner_args: Option>, +} diff --git a/src/bin/cargo-bootimage.rs b/src/bin/cargo-bootimage.rs index 5349675..4644020 100644 --- a/src/bin/cargo-bootimage.rs +++ b/src/bin/cargo-bootimage.rs @@ -1,3 +1,66 @@ -pub fn main() { - bootimage::lib_main(); +use anyhow::{anyhow, Result}; +use bootimage::{ + args::{BuildArgs, BuildCommand}, + builder::Builder, + help, +}; +use std::{env, path::{PathBuf, Path}}; + +pub fn main() -> Result<()> { + let mut raw_args = env::args(); + + let executable_name = raw_args + .next() + .ok_or(anyhow!("no first argument (executable name)"))?; + let file_stem = Path::new(&executable_name) + .file_stem() + .and_then(|s| s.to_str()); + if file_stem != Some("cargo-bootimage") { + return Err(anyhow!( + "Unexpected executable name: expected `cargo-bootimage`, got: `{:?}`", + file_stem + )); + } + if raw_args.next().as_deref() != Some("bootimage") { + return Err(anyhow!("Please invoke this as `cargo bootimage`")); + } + + match BuildCommand::parse_args(raw_args)? { + BuildCommand::Build(args) => build(args), + BuildCommand::Version => Ok(help::print_version()), + BuildCommand::Help => Ok(help::print_cargo_bootimage_help()), + } +} + +fn build(args: BuildArgs) -> Result<()> { + let builder = Builder::new(args.manifest_path().map(PathBuf::from))?; + let quiet = args.quiet(); + + let executables = builder.build_kernel(&args.cargo_args(), quiet)?; + if executables.len() == 0 { + return Err(anyhow!("no executables built")); + } + + for executable in executables { + let out_dir = executable + .parent() + .ok_or(anyhow!("executable has no parent path"))?; + let bin_name = &executable + .file_stem() + .ok_or(anyhow!("executable has no file stem"))? + .to_str() + .ok_or(anyhow!("executable file stem not valid utf8"))?; + + let bootimage_path = out_dir.join(format!("bootimage-{}.bin", bin_name)); + builder.create_bootimage(bin_name, &executable, &bootimage_path, quiet)?; + if !args.quiet() { + println!( + "Created bootimage for `{}` at `{}`", + bin_name, + bootimage_path.display() + ); + } + } + + Ok(()) } diff --git a/src/builder.rs b/src/builder.rs deleted file mode 100644 index 2d6a66f..0000000 --- a/src/builder.rs +++ /dev/null @@ -1,554 +0,0 @@ -//! Provides functions to build the kernel and the bootloader. - -use std::{ - fmt, fs, io, - path::{Path, PathBuf}, - process::{self, Command}, -}; - -/// Abstracts a build environment and provides methods for building the kernel and creating a -/// bootimage. -pub struct Builder { - kernel_manifest_path: PathBuf, - kernel_metadata: cargo_metadata::Metadata, -} - -impl Builder { - /// Creates a new Builder by searching for the kernel's Cargo manifest and running - /// `cargo metadata` on it. - pub fn new(manifest_path: Option) -> Result { - let kernel_manifest_path = - manifest_path.unwrap_or(locate_cargo_manifest::locate_manifest()?); - let kernel_metadata = cargo_metadata::MetadataCommand::new() - .manifest_path(&kernel_manifest_path) - .exec()?; - Ok(Builder { - kernel_manifest_path, - kernel_metadata, - }) - } - - /// Returns the path to the `Cargo.toml` file of the kernel. - pub fn kernel_manifest_path(&self) -> &Path { - &self.kernel_manifest_path - } - - /// Returns the directory that contains the `Cargo.toml` of the kernel. - pub fn kernel_root(&self) -> &Path { - self.kernel_manifest_path - .parent() - .expect("kernel manifest has no parent directory") - } - - /// Returns a reference to the cargo metadata object. - pub fn kernel_metadata(&self) -> &cargo_metadata::Metadata { - &self.kernel_metadata - } - - /// Returns a reference to the kernel package in the `cargo metadata` output. - pub fn kernel_package(&self) -> Result<&cargo_metadata::Package, String> { - let mut packages = self.kernel_metadata.packages.iter(); - let kernel_package = packages.find(|p| &p.manifest_path == &self.kernel_manifest_path); - kernel_package.ok_or(format!( - "packages[manifest_path = `{}`]", - &self.kernel_manifest_path.display() - )) - } - - /// Builds the kernel by executing `cargo xbuild` with the given arguments. - /// - /// Returns a list of paths to all built executables. For crates with only a single binary, - /// the returned list contains only a single element. - /// - /// If the quiet argument is set to true, all output to stdout is suppressed. - pub fn build_kernel( - &self, - args: &[String], - quiet: bool, - ) -> Result, BuildKernelError> { - if !quiet { - println!("Building kernel"); - } - - let cargo = std::env::var("CARGO").unwrap_or("cargo".to_owned()); - let mut cmd = process::Command::new(&cargo); - cmd.arg("xbuild"); - cmd.args(args); - if !quiet { - cmd.stdout(process::Stdio::inherit()); - cmd.stderr(process::Stdio::inherit()); - } - let output = cmd.output().map_err(|err| BuildKernelError::Io { - message: "failed to execute kernel build", - error: err, - })?; - if !output.status.success() { - let mut help_command = process::Command::new("cargo"); - help_command.arg("xbuild").arg("--help"); - help_command.stdout(process::Stdio::null()); - help_command.stderr(process::Stdio::null()); - if let Ok(help_exit_status) = help_command.status() { - if !help_exit_status.success() { - return Err(BuildKernelError::XbuildNotFound); - } - } - return Err(BuildKernelError::XbuildFailed { - stderr: output.stderr, - }); - } - - // Retrieve binary paths - let mut cmd = process::Command::new(cargo); - cmd.arg("xbuild"); - cmd.args(args); - cmd.arg("--message-format").arg("json"); - let output = cmd.output().map_err(|err| BuildKernelError::Io { - message: "failed to execute kernel build with json output", - error: err, - })?; - if !output.status.success() { - return Err(BuildKernelError::XbuildFailed { - stderr: output.stderr, - }); - } - let mut executables = Vec::new(); - for line in String::from_utf8(output.stdout) - .map_err(BuildKernelError::XbuildJsonOutputInvalidUtf8)? - .lines() - { - let mut artifact = - json::parse(line).map_err(BuildKernelError::XbuildJsonOutputInvalidJson)?; - if let Some(executable) = artifact["executable"].take_string() { - executables.push(PathBuf::from(executable)); - } - } - - Ok(executables) - } - - /// Creates a bootimage by combining the given kernel binary with the bootloader. - /// - /// Places the resulting bootable disk image at the given `output_bin_path`. - /// - /// If the quiet argument is set to true, all output to stdout is suppressed. - pub fn create_bootimage( - &self, - kernel_bin_path: &Path, - output_bin_path: &Path, - quiet: bool, - ) -> Result<(), CreateBootimageError> { - let metadata = self.kernel_metadata(); - - let bootloader_name = { - let kernel_package = self - .kernel_package() - .map_err(|key| CreateBootimageError::CargoMetadataIncomplete { key })?; - let mut dependencies = kernel_package.dependencies.iter(); - let bootloader_package = dependencies - .find(|p| p.rename.as_ref().unwrap_or(&p.name) == "bootloader") - .ok_or(CreateBootimageError::BootloaderNotFound)?; - bootloader_package.name.clone() - }; - let target_dir = metadata - .target_directory - .join("bootimage") - .join(&bootloader_name); - - let bootloader_pkg = metadata - .packages - .iter() - .find(|p| p.name == bootloader_name) - .ok_or(CreateBootimageError::CargoMetadataIncomplete { - key: format!("packages[name = `{}`", &bootloader_name), - })?; - let bootloader_root = bootloader_pkg.manifest_path.parent().ok_or( - CreateBootimageError::BootloaderInvalid( - "bootloader manifest has no target directory".into(), - ), - )?; - let (bootloader_target, binary_feature) = { - let cargo_toml_content = fs::read_to_string(&bootloader_pkg.manifest_path) - .map_err(|err| format!("bootloader has no valid Cargo.toml: {}", err)) - .map_err(CreateBootimageError::BootloaderInvalid)?; - let cargo_toml = cargo_toml_content - .parse::() - .map_err(|e| format!("Failed to parse Cargo.toml of bootloader: {}", e)) - .map_err(CreateBootimageError::BootloaderInvalid)?; - let metadata = cargo_toml.get("package").and_then(|t| t.get("metadata")); - let target = metadata - .and_then(|t| t.get("bootloader")) - .and_then(|t| t.get("target")); - let target_str = target - .and_then(|v| v.as_str()) - .ok_or(CreateBootimageError::BootloaderInvalid( - "No `package.metadata.bootloader.target` key found in Cargo.toml of bootloader\n\n\ - (If you're using the official bootloader crate, you need at least version 0.5.1)" - .into(), - ))?; - - let binary_feature = cargo_toml - .get("features") - .and_then(|f| f.get("binary")) - .is_some(); - - (bootloader_root.join(target_str), binary_feature) - }; - let bootloader_features = - { - let resolve = metadata.resolve.as_ref().ok_or( - CreateBootimageError::CargoMetadataIncomplete { - key: "resolve".into(), - }, - )?; - let bootloader_resolve = resolve - .nodes - .iter() - .find(|n| n.id == bootloader_pkg.id) - .ok_or(CreateBootimageError::CargoMetadataIncomplete { - key: format!("resolve[\"{}\"]", bootloader_name), - })?; - let mut features = bootloader_resolve.features.clone(); - if binary_feature { - features.push("binary".into()); - } - features - }; - - // build bootloader - if !quiet { - println!("Building bootloader"); - } - - let cargo = std::env::var("CARGO").unwrap_or("cargo".to_owned()); - let build_command = || { - let mut cmd = process::Command::new(&cargo); - cmd.arg("xbuild"); - cmd.arg("--manifest-path"); - cmd.arg(&bootloader_pkg.manifest_path); - cmd.arg("--bin").arg(&bootloader_name); - cmd.arg("--target-dir").arg(&target_dir); - cmd.arg("--features") - .arg(bootloader_features.as_slice().join(" ")); - cmd.arg("--target").arg(&bootloader_target); - cmd.arg("--release"); - cmd.env("KERNEL", kernel_bin_path); - cmd.env("KERNEL_MANIFEST", &self.kernel_manifest_path); - cmd.env("RUSTFLAGS", ""); - cmd.env("XBUILD_SYSROOT_PATH", target_dir.join("bootloader-sysroot")); // for cargo-xbuild - cmd - }; - - let mut cmd = build_command(); - if !quiet { - cmd.stdout(process::Stdio::inherit()); - cmd.stderr(process::Stdio::inherit()); - } - let output = cmd.output().map_err(|err| CreateBootimageError::Io { - message: "failed to execute bootloader build command", - error: err, - })?; - if !output.status.success() { - return Err(CreateBootimageError::BootloaderBuildFailed { - stderr: output.stderr, - }); - } - - // Retrieve binary path - let mut cmd = build_command(); - cmd.arg("--message-format").arg("json"); - let output = cmd.output().map_err(|err| CreateBootimageError::Io { - message: "failed to execute bootloader build command with json output", - error: err, - })?; - if !output.status.success() { - return Err(CreateBootimageError::BootloaderBuildFailed { - stderr: output.stderr, - }); - } - let mut bootloader_elf_path = None; - for line in String::from_utf8(output.stdout) - .map_err(CreateBootimageError::XbuildJsonOutputInvalidUtf8)? - .lines() - { - let mut artifact = - json::parse(line).map_err(CreateBootimageError::XbuildJsonOutputInvalidJson)?; - if let Some(executable) = artifact["executable"].take_string() { - if bootloader_elf_path - .replace(PathBuf::from(executable)) - .is_some() - { - return Err(CreateBootimageError::BootloaderInvalid( - "bootloader has multiple executables".into(), - )); - } - } - } - let bootloader_elf_path = bootloader_elf_path.ok_or( - CreateBootimageError::BootloaderInvalid("bootloader has no executable".into()), - )?; - - let llvm_tools = llvm_tools::LlvmTools::new()?; - let objcopy = llvm_tools - .tool(&llvm_tools::exe("llvm-objcopy")) - .ok_or(CreateBootimageError::LlvmObjcopyNotFound)?; - - // convert bootloader to binary - let mut cmd = Command::new(objcopy); - cmd.arg("-I").arg("elf64-x86-64"); - cmd.arg("-O").arg("binary"); - cmd.arg("--binary-architecture=i386:x86-64"); - cmd.arg(&bootloader_elf_path); - cmd.arg(&output_bin_path); - let output = cmd.output().map_err(|err| CreateBootimageError::Io { - message: "failed to execute llvm-objcopy command", - error: err, - })?; - if !output.status.success() { - return Err(CreateBootimageError::ObjcopyFailed { - stderr: output.stderr, - }); - } - - // Pad to nearest block size - { - const BLOCK_SIZE: u64 = 512; - use std::fs::OpenOptions; - let file = OpenOptions::new() - .write(true) - .open(&output_bin_path) - .map_err(|err| CreateBootimageError::Io { - message: "failed to open boot image", - error: err, - })?; - let file_size = file - .metadata() - .map_err(|err| CreateBootimageError::Io { - message: "failed to get size of boot image", - error: err, - })? - .len(); - let remainder = file_size % BLOCK_SIZE; - let padding = if remainder > 0 { - BLOCK_SIZE - remainder - } else { - 0 - }; - file.set_len(file_size + padding) - .map_err(|err| CreateBootimageError::Io { - message: "failed to pad boot image to a multiple of the block size", - error: err, - })?; - } - - Ok(()) - } -} - -/// Represents an error that occurred while creating a new `Builder`. -#[derive(Debug)] -pub enum BuilderError { - /// Failed to locate cargo manifest - LocateCargoManifest(locate_cargo_manifest::LocateManifestError), - /// Error while running `cargo metadata` - CargoMetadata(cargo_metadata::Error), -} - -impl fmt::Display for BuilderError { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match self { - BuilderError::LocateCargoManifest(err) => writeln!( - f, - "Could not find Cargo.toml file starting from current folder: {:?}", - err - ), - BuilderError::CargoMetadata(err) => writeln!( - f, - "Error while running `cargo metadata` for current project: {:?}", - err - ), - } - } -} - -/// Represents an error that occurred when building the kernel. -#[derive(Debug)] -pub enum BuildKernelError { - /// Could not find kernel package in cargo metadata, required for retrieving kernel crate name - KernelPackageNotFound, - /// An unexpected I/O error occurred - Io { - /// Desciption of the failed I/O operation - message: &'static str, - /// The I/O error that occured - error: io::Error, - }, - /// Could not find the `cargo xbuild` tool. Perhaps it is not installed? - XbuildNotFound, - /// Running `cargo xbuild` failed. - XbuildFailed { - /// The standard error output. - stderr: Vec, - }, - /// The output of `cargo xbuild --message-format=json` was not valid UTF-8 - XbuildJsonOutputInvalidUtf8(std::string::FromUtf8Error), - /// The output of `cargo xbuild --message-format=json` was not valid JSON - XbuildJsonOutputInvalidJson(json::Error), - #[doc(hidden)] - __NonExhaustive, -} - -impl fmt::Display for BuildKernelError { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match self { - BuildKernelError::KernelPackageNotFound => { - writeln!(f, "Could not find kernel package in cargo metadata, required for retrieving kernel crate name") - } - BuildKernelError::Io {message, error} => { - writeln!(f, "I/O error: {}:\n{}", message, error) - } - BuildKernelError::XbuildNotFound => { - writeln!(f, "Failed to run `cargo xbuild`. Perhaps it is not installed?\n\ - Run `cargo install cargo-xbuild` to install it.") - } - BuildKernelError::XbuildFailed{stderr} => { - writeln!(f, "Kernel build failed")?; - if !stderr.is_empty() { - writeln!(f, "\n{}", String::from_utf8_lossy(stderr))?; - } - Ok(()) - } - BuildKernelError::XbuildJsonOutputInvalidUtf8(err) => { - writeln!(f, "Output of kernel build with --message-format=json is not valid UTF-8:\n{}", err) - } - BuildKernelError::XbuildJsonOutputInvalidJson(err) => { - writeln!(f, "Output of kernel build with --message-format=json is not valid JSON:\n{}", err) - } - BuildKernelError::__NonExhaustive => panic!("__NonExhaustive variant constructed"), - } - } -} - -/// Represents an error that occurred when creating a bootimage. -#[derive(Debug)] -pub enum CreateBootimageError { - /// Could not find some required information in the `cargo metadata` output - CargoMetadataIncomplete { - /// The required key that was not found - key: String, - }, - /// Bootloader dependency not found - BootloaderNotFound, - /// Bootloader dependency has not the right format - BootloaderInvalid(String), - /// Building the bootloader failed - BootloaderBuildFailed { - /// The `cargo xbuild` output to standard error - stderr: Vec, - }, - /// An unexpected I/O error occurred - Io { - /// Desciption of the failed I/O operation - message: &'static str, - /// The I/O error that occured - error: io::Error, - }, - /// There was a problem retrieving the `llvm-tools-preview` rustup component - LlvmTools(llvm_tools::Error), - /// The llvm-tools component did not contain the required `llvm-objcopy` executable - LlvmObjcopyNotFound, - /// The `llvm-objcopy` command failed - ObjcopyFailed { - /// The output of `llvm-objcopy` to standard error - stderr: Vec, - }, - /// The output of `cargo xbuild --message-format=json` was not valid UTF-8 - XbuildJsonOutputInvalidUtf8(std::string::FromUtf8Error), - /// The output of `cargo xbuild --message-format=json` was not valid JSON - XbuildJsonOutputInvalidJson(json::Error), - #[doc(hidden)] - __NonExhaustive, -} - -impl fmt::Display for CreateBootimageError { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match self { - CreateBootimageError::CargoMetadataIncomplete { key } => writeln!( - f, - "Could not find required key `{}` in cargo metadata output", - key - ), - CreateBootimageError::BootloaderNotFound => writeln!( - f, - "Bootloader dependency not found\n\n\ - You need to add a dependency on a crate named `bootloader` in your Cargo.toml." - ), - CreateBootimageError::BootloaderInvalid(err) => writeln!( - f, - "The `bootloader` dependency has not the right format: {}", - err - ), - CreateBootimageError::BootloaderBuildFailed { stderr } => { - writeln!(f, "Bootloader build failed")?; - if !stderr.is_empty() { - writeln!(f, "\n{}", String::from_utf8_lossy(stderr))?; - } - Ok(()) - } - CreateBootimageError::Io { message, error } => { - writeln!(f, "I/O error: {}: {}", message, error) - } - CreateBootimageError::LlvmTools(err) => match err { - llvm_tools::Error::NotFound => writeln!( - f, - "Could not find the `llvm-tools-preview` rustup component.\n\n\ - You can install by executing `rustup component add llvm-tools-preview`." - ), - err => writeln!( - f, - "Failed to locate the `llvm-tools-preview` rustup component: {:?}", - err - ), - }, - CreateBootimageError::LlvmObjcopyNotFound => writeln!( - f, - "Could not find `llvm-objcopy` in the `llvm-tools-preview` rustup component." - ), - CreateBootimageError::ObjcopyFailed { stderr } => writeln!( - f, - "Failed to run `llvm-objcopy`: {}", - String::from_utf8_lossy(stderr) - ), - CreateBootimageError::XbuildJsonOutputInvalidUtf8(err) => writeln!( - f, - "Output of bootloader build with --message-format=json is not valid UTF-8:\n{}", - err - ), - CreateBootimageError::XbuildJsonOutputInvalidJson(err) => writeln!( - f, - "Output of bootloader build with --message-format=json is not valid JSON:\n{}", - err - ), - CreateBootimageError::__NonExhaustive => panic!("__NonExhaustive variant constructed"), - } - } -} - -// from implementations - -impl From for BuilderError { - fn from(err: locate_cargo_manifest::LocateManifestError) -> Self { - BuilderError::LocateCargoManifest(err) - } -} - -impl From for BuilderError { - fn from(err: cargo_metadata::Error) -> Self { - BuilderError::CargoMetadata(err) - } -} - -impl From for CreateBootimageError { - fn from(err: llvm_tools::Error) -> Self { - CreateBootimageError::LlvmTools(err) - } -} diff --git a/src/builder/bootloader.rs b/src/builder/bootloader.rs new file mode 100644 index 0000000..526dd11 --- /dev/null +++ b/src/builder/bootloader.rs @@ -0,0 +1,154 @@ +use super::error::BootloaderError; +use cargo_metadata::{Metadata, Package}; +use std::{ + fs, + path::{Path, PathBuf}, + process::Command, +}; + +pub struct BuildConfig { + manifest_path: PathBuf, + bootloader_name: String, + target: PathBuf, + features: Vec, + target_dir: PathBuf, + kernel_bin_path: PathBuf, + kernel_manifest_path: PathBuf, +} + +impl BuildConfig { + /// Derives the bootloader build config from the project's metadata. + pub fn from_metadata( + project_metadata: &Metadata, + kernel_bin_name: &str, + kernel_bin_path: &Path, + ) -> Result { + let kernel_pkg = kernel_package(project_metadata, kernel_bin_name)?; + let bootloader_pkg = bootloader_package(project_metadata, kernel_pkg)?; + let bootloader_root = + bootloader_pkg + .manifest_path + .parent() + .ok_or(BootloaderError::BootloaderInvalid( + "bootloader manifest has no target directory".into(), + ))?; + + let cargo_toml_content = fs::read_to_string(&bootloader_pkg.manifest_path) + .map_err(|err| format!("bootloader has no valid Cargo.toml: {}", err)) + .map_err(BootloaderError::BootloaderInvalid)?; + let cargo_toml = cargo_toml_content + .parse::() + .map_err(|e| format!("Failed to parse Cargo.toml of bootloader: {}", e)) + .map_err(BootloaderError::BootloaderInvalid)?; + let metadata = cargo_toml.get("package").and_then(|t| t.get("metadata")); + let target = metadata + .and_then(|t| t.get("bootloader")) + .and_then(|t| t.get("target")); + let target_str = + target + .and_then(|v| v.as_str()) + .ok_or(BootloaderError::BootloaderInvalid( + "No `package.metadata.bootloader.target` key found in Cargo.toml of bootloader\n\n\ + (If you're using the official bootloader crate, you need at least version 0.5.1)" + .into(), + ))?; + + let binary_feature = cargo_toml + .get("features") + .and_then(|f| f.get("binary")) + .is_some(); + + let resolve_opt = project_metadata.resolve.as_ref(); + let resolve = resolve_opt.ok_or(BootloaderError::CargoMetadataIncomplete { + key: "resolve".into(), + })?; + let bootloader_resolve = resolve + .nodes + .iter() + .find(|n| n.id == bootloader_pkg.id) + .ok_or(BootloaderError::CargoMetadataIncomplete { + key: format!("resolve[\"{}\"]", bootloader_pkg.name), + })?; + let mut features = bootloader_resolve.features.clone(); + if binary_feature { + features.push("binary".into()); + } + + let bootloader_name = &bootloader_pkg.name; + let target_dir = project_metadata + .target_directory + .join("bootimage") + .join(bootloader_name); + + Ok(BuildConfig { + manifest_path: bootloader_pkg.manifest_path.clone(), + target: bootloader_root.join(target_str), + features, + bootloader_name: bootloader_name.clone(), + target_dir, + kernel_manifest_path: kernel_pkg.manifest_path.clone(), + kernel_bin_path: kernel_bin_path.to_owned(), + }) + } + + /// Creates the cargo build command for building the bootloader. + pub fn build_command(&self) -> Command { + let cargo = std::env::var("CARGO").unwrap_or("cargo".to_owned()); + let mut cmd = Command::new(&cargo); + cmd.arg("xbuild"); + cmd.arg("--manifest-path"); + cmd.arg(&self.manifest_path); + cmd.arg("--bin").arg(&self.bootloader_name); + cmd.arg("--target-dir").arg(&self.target_dir); + cmd.arg("--features") + .arg(self.features.as_slice().join(" ")); + cmd.arg("--target").arg(&self.target); + cmd.arg("--release"); + cmd.env("KERNEL", &self.kernel_bin_path); + cmd.env("KERNEL_MANIFEST", &self.kernel_manifest_path); + cmd.env("RUSTFLAGS", ""); + cmd.env( + "XBUILD_SYSROOT_PATH", + self.target_dir.join("bootloader-sysroot"), + ); // for cargo-xbuild + cmd + } +} + +/// Returns the package metadata for the kernel crate +fn kernel_package<'a>( + project_metadata: &'a Metadata, + kernel_bin_name: &str, +) -> Result<&'a Package, BootloaderError> { + let contains_bin = |p: &&Package| { + p.targets + .iter() + .any(|t| t.name == kernel_bin_name && t.kind.iter().any(|k| k == "bin")) + }; + let bin_metadata_opt = project_metadata.packages.iter().find(contains_bin); + bin_metadata_opt.ok_or_else(|| BootloaderError::KernelBinPackageNotFound { + bin_name: kernel_bin_name.to_owned(), + }) +} + +/// Returns the package metadata for the bootloader crate +fn bootloader_package<'a>( + project_metadata: &'a Metadata, + kernel_package: &Package, +) -> Result<&'a Package, BootloaderError> { + let bootloader_name = { + let mut dependencies = kernel_package.dependencies.iter(); + let bootloader_package = dependencies + .find(|p| p.rename.as_ref().unwrap_or(&p.name) == "bootloader") + .ok_or(BootloaderError::BootloaderNotFound)?; + bootloader_package.name.clone() + }; + + project_metadata + .packages + .iter() + .find(|p| p.name == bootloader_name) + .ok_or(BootloaderError::CargoMetadataIncomplete { + key: format!("packages[name = `{}`", &bootloader_name), + }) +} diff --git a/src/builder/disk_image.rs b/src/builder/disk_image.rs new file mode 100644 index 0000000..2f3cfab --- /dev/null +++ b/src/builder/disk_image.rs @@ -0,0 +1,62 @@ +use super::error::DiskImageError; +use std::{path::Path, process::Command}; + +pub fn create_disk_image( + bootloader_elf_path: &Path, + output_bin_path: &Path, +) -> Result<(), DiskImageError> { + let llvm_tools = llvm_tools::LlvmTools::new()?; + let objcopy = llvm_tools + .tool(&llvm_tools::exe("llvm-objcopy")) + .ok_or(DiskImageError::LlvmObjcopyNotFound)?; + + // convert bootloader to binary + let mut cmd = Command::new(objcopy); + cmd.arg("-I").arg("elf64-x86-64"); + cmd.arg("-O").arg("binary"); + cmd.arg("--binary-architecture=i386:x86-64"); + cmd.arg(bootloader_elf_path); + cmd.arg(output_bin_path); + let output = cmd.output().map_err(|err| DiskImageError::Io { + message: "failed to execute llvm-objcopy command", + error: err, + })?; + if !output.status.success() { + return Err(DiskImageError::ObjcopyFailed { + stderr: output.stderr, + }); + } + + pad_to_nearest_block_size(output_bin_path)?; + Ok(()) +} + +fn pad_to_nearest_block_size(output_bin_path: &Path) -> Result<(), DiskImageError> { + const BLOCK_SIZE: u64 = 512; + use std::fs::OpenOptions; + let file = OpenOptions::new() + .write(true) + .open(&output_bin_path) + .map_err(|err| DiskImageError::Io { + message: "failed to open boot image", + error: err, + })?; + let file_size = file + .metadata() + .map_err(|err| DiskImageError::Io { + message: "failed to get size of boot image", + error: err, + })? + .len(); + let remainder = file_size % BLOCK_SIZE; + let padding = if remainder > 0 { + BLOCK_SIZE - remainder + } else { + 0 + }; + file.set_len(file_size + padding) + .map_err(|err| DiskImageError::Io { + message: "failed to pad boot image to a multiple of the block size", + error: err, + }) +} diff --git a/src/builder/error.rs b/src/builder/error.rs new file mode 100644 index 0000000..a3018fe --- /dev/null +++ b/src/builder/error.rs @@ -0,0 +1,154 @@ +use std::io; +use thiserror::Error; + +/// Represents an error that occurred while creating a new `Builder`. +#[derive(Debug, Error)] +pub enum BuilderError { + /// Failed to locate cargo manifest + #[error("Could not find Cargo.toml file starting from current folder: {0:?}")] + LocateCargoManifest(#[from] locate_cargo_manifest::LocateManifestError), +} + +/// Represents an error that occurred when building the kernel. +#[derive(Debug, Error)] +#[non_exhaustive] +pub enum BuildKernelError { + /// An unexpected I/O error occurred + #[error("I/O error: {message}:\n{error}")] + Io { + /// Desciption of the failed I/O operation + message: &'static str, + /// The I/O error that occured + error: io::Error, + }, + + /// Could not find the `cargo xbuild` tool. Perhaps it is not installed? + #[error( + "Failed to run `cargo xbuild`. Perhaps it is not installed?\n\ + Run `cargo install cargo-xbuild` to install it." + )] + XbuildNotFound, + + /// Running `cargo xbuild` failed. + #[error("Kernel build failed.\nStderr: {}", String::from_utf8_lossy(.stderr))] + XbuildFailed { + /// The standard error output. + stderr: Vec, + }, + + /// The output of `cargo xbuild --message-format=json` was not valid UTF-8 + #[error("Output of kernel build with --message-format=json is not valid UTF-8:\n{0}")] + XbuildJsonOutputInvalidUtf8(std::string::FromUtf8Error), + /// The output of `cargo xbuild --message-format=json` was not valid JSON + #[error("Output of kernel build with --message-format=json is not valid JSON:\n{0}")] + XbuildJsonOutputInvalidJson(json::Error), +} + +/// Represents an error that occurred when creating a bootimage. +#[derive(Debug, Error)] +#[non_exhaustive] +pub enum CreateBootimageError { + /// Failed to build the bootloader. + #[error("An error occured while trying to build the bootloader: {0}")] + Bootloader(#[from] BootloaderError), + + /// Error while running `cargo metadata` + #[error("Error while running `cargo metadata` for current project: {0:?}")] + CargoMetadata(#[from] cargo_metadata::Error), + + /// Building the bootloader failed + #[error("Bootloader build failed.\nStderr: {}", String::from_utf8_lossy(.stderr))] + BootloaderBuildFailed { + /// The `cargo xbuild` output to standard error + stderr: Vec, + }, + + /// Disk image creation failed + #[error("An error occured while trying to create the disk image: {0}")] + DiskImage(#[from] DiskImageError), + + /// An unexpected I/O error occurred + #[error("I/O error: {message}:\n{error}")] + Io { + /// Desciption of the failed I/O operation + message: &'static str, + /// The I/O error that occured + error: io::Error, + }, + + /// The output of `cargo xbuild --message-format=json` was not valid UTF-8 + #[error("Output of bootloader build with --message-format=json is not valid UTF-8:\n{0}")] + XbuildJsonOutputInvalidUtf8(std::string::FromUtf8Error), + /// The output of `cargo xbuild --message-format=json` was not valid JSON + #[error("Output of bootloader build with --message-format=json is not valid JSON:\n{0}")] + XbuildJsonOutputInvalidJson(json::Error), +} + +/// There is something wrong with the bootloader dependency. +#[derive(Debug, Error)] +pub enum BootloaderError { + /// Bootloader dependency not found + #[error( + "Bootloader dependency not found\n\n\ + You need to add a dependency on a crate named `bootloader` in your Cargo.toml." + )] + BootloaderNotFound, + /// Bootloader dependency has not the right format + #[error("The `bootloader` dependency has not the right format: {0}")] + BootloaderInvalid(String), + /// Could not find kernel package in cargo metadata + #[error("Could not find package for binary `{bin_name}` in cargo metadata output")] + KernelBinPackageNotFound { + /// The name of the kernel binary + bin_name: String + }, + /// Could not find some required information in the `cargo metadata` output + #[error("Could not find required key `{key}` in cargo metadata output")] + CargoMetadataIncomplete { + /// The required key that was not found + key: String, + }, +} + +/// Creating the disk image failed. +#[derive(Debug, Error)] +pub enum DiskImageError { + /// The `llvm-tools-preview` rustup component was not found + #[error( + "Could not find the `llvm-tools-preview` rustup component.\n\n\ + You can install by executing `rustup component add llvm-tools-preview`." + )] + LlvmToolsNotFound, + + /// There was another problem locating the `llvm-tools-preview` rustup component + #[error("Failed to locate the `llvm-tools-preview` rustup component: {0:?}")] + LlvmTools(llvm_tools::Error), + + /// The llvm-tools component did not contain the required `llvm-objcopy` executable + #[error("Could not find `llvm-objcopy` in the `llvm-tools-preview` rustup component.")] + LlvmObjcopyNotFound, + /// The `llvm-objcopy` command failed + #[error("Failed to run `llvm-objcopy`: {}", String::from_utf8_lossy(.stderr))] + ObjcopyFailed { + /// The output of `llvm-objcopy` to standard error + stderr: Vec, + }, + + /// An unexpected I/O error occurred + #[error("I/O error: {message}:\n{error}")] + Io { + /// Desciption of the failed I/O operation + message: &'static str, + /// The I/O error that occured + error: io::Error, + }, +} + +impl From for DiskImageError { + fn from(err: llvm_tools::Error) -> Self { + match err { + llvm_tools::Error::NotFound => DiskImageError::LlvmToolsNotFound, + other => DiskImageError::LlvmTools(other), + } + } +} diff --git a/src/builder/mod.rs b/src/builder/mod.rs new file mode 100644 index 0000000..be22687 --- /dev/null +++ b/src/builder/mod.rs @@ -0,0 +1,183 @@ +//! Provides functions to build the kernel and the bootloader. + +use error::{BootloaderError, BuildKernelError, BuilderError, CreateBootimageError}; +use std::{ + path::{Path, PathBuf}, + process, +}; + +/// Provides the build command for the bootloader. +mod bootloader; +/// Provides a function to create the bootable disk image. +mod disk_image; +/// Contains the errors types returned by the `Builder` methods. +pub mod error; + +/// Allows building the kernel and creating a bootable disk image with it. +pub struct Builder { + manifest_path: PathBuf, +} + +impl Builder { + /// Creates a new builder for the project at the given manifest path + /// + /// If None is passed for `manifest_path`, it is automatically searched. + pub fn new(manifest_path: Option) -> Result { + let manifest_path = manifest_path.unwrap_or(locate_cargo_manifest::locate_manifest()?); + Ok(Builder { manifest_path }) + } + + /// Returns the path to the Cargo.toml file of the project. + pub fn manifest_path(&self) -> &Path { + &self.manifest_path + } + + /// Builds the kernel by executing `cargo xbuild` with the given arguments. + /// + /// Returns a list of paths to all built executables. For crates with only a single binary, + /// the returned list contains only a single element. + /// + /// If the quiet argument is set to true, all output to stdout is suppressed. + pub fn build_kernel( + &self, + args: &[String], + quiet: bool, + ) -> Result, BuildKernelError> { + if !quiet { + println!("Building kernel"); + } + + // try to run cargo xbuild + let cargo = std::env::var("CARGO").unwrap_or("cargo".to_owned()); + let mut cmd = process::Command::new(&cargo); + cmd.arg("xbuild"); + cmd.args(args); + if !quiet { + cmd.stdout(process::Stdio::inherit()); + cmd.stderr(process::Stdio::inherit()); + } + let output = cmd.output().map_err(|err| BuildKernelError::Io { + message: "failed to execute kernel build", + error: err, + })?; + if !output.status.success() { + // try executing `cargo xbuild --help` to check whether cargo-xbuild is installed + let mut help_command = process::Command::new("cargo"); + help_command.arg("xbuild").arg("--help"); + help_command.stdout(process::Stdio::null()); + help_command.stderr(process::Stdio::null()); + if let Ok(help_exit_status) = help_command.status() { + if !help_exit_status.success() { + return Err(BuildKernelError::XbuildNotFound); + } + } + return Err(BuildKernelError::XbuildFailed { + stderr: output.stderr, + }); + } + + // Retrieve binary paths + let mut cmd = process::Command::new(cargo); + cmd.arg("xbuild"); + cmd.args(args); + cmd.arg("--message-format").arg("json"); + let output = cmd.output().map_err(|err| BuildKernelError::Io { + message: "failed to execute kernel build with json output", + error: err, + })?; + if !output.status.success() { + return Err(BuildKernelError::XbuildFailed { + stderr: output.stderr, + }); + } + let mut executables = Vec::new(); + for line in String::from_utf8(output.stdout) + .map_err(BuildKernelError::XbuildJsonOutputInvalidUtf8)? + .lines() + { + let mut artifact = + json::parse(line).map_err(BuildKernelError::XbuildJsonOutputInvalidJson)?; + if let Some(executable) = artifact["executable"].take_string() { + executables.push(PathBuf::from(executable)); + } + } + + Ok(executables) + } + + /// Creates a bootimage by combining the given kernel binary with the bootloader. + /// + /// Places the resulting bootable disk image at the given `output_bin_path`. + /// + /// If the quiet argument is set to true, all output to stdout is suppressed. + pub fn create_bootimage( + &self, + bin_name: &str, + bin_path: &Path, + output_bin_path: &Path, + quiet: bool, + ) -> Result<(), CreateBootimageError> { + let project_metadata = cargo_metadata::MetadataCommand::new() + .manifest_path(&self.manifest_path) + .exec()?; + let bootloader_build_config = + bootloader::BuildConfig::from_metadata(&project_metadata, bin_name, bin_path)?; + + // build bootloader + if !quiet { + println!("Building bootloader"); + } + let mut cmd = bootloader_build_config.build_command(); + if !quiet { + cmd.stdout(process::Stdio::inherit()); + cmd.stderr(process::Stdio::inherit()); + } + let output = cmd.output().map_err(|err| CreateBootimageError::Io { + message: "failed to execute bootloader build command", + error: err, + })?; + if !output.status.success() { + return Err(CreateBootimageError::BootloaderBuildFailed { + stderr: output.stderr, + }); + } + + // Retrieve binary path + let mut cmd = bootloader_build_config.build_command(); + cmd.arg("--message-format").arg("json"); + let output = cmd.output().map_err(|err| CreateBootimageError::Io { + message: "failed to execute bootloader build command with json output", + error: err, + })?; + if !output.status.success() { + return Err(CreateBootimageError::BootloaderBuildFailed { + stderr: output.stderr, + }); + } + let mut bootloader_elf_path = None; + for line in String::from_utf8(output.stdout) + .map_err(CreateBootimageError::XbuildJsonOutputInvalidUtf8)? + .lines() + { + let mut artifact = + json::parse(line).map_err(CreateBootimageError::XbuildJsonOutputInvalidJson)?; + if let Some(executable) = artifact["executable"].take_string() { + if bootloader_elf_path + .replace(PathBuf::from(executable)) + .is_some() + { + Err(BootloaderError::BootloaderInvalid( + "bootloader has multiple executables".into(), + ))?; + } + } + } + let bootloader_elf_path = bootloader_elf_path.ok_or(BootloaderError::BootloaderInvalid( + "bootloader has no executable".into(), + ))?; + + disk_image::create_disk_image(&bootloader_elf_path, output_bin_path)?; + + Ok(()) + } +} diff --git a/src/config.rs b/src/config.rs index 8661360..8768123 100644 --- a/src/config.rs +++ b/src/config.rs @@ -1,6 +1,6 @@ //! Parses the `package.metadata.bootimage` configuration table -use crate::ErrorMessage; +use anyhow::{anyhow, Context, Result}; use std::path::Path; use toml::Value; @@ -10,6 +10,7 @@ use toml::Value; /// in the `Cargo.toml` file of the kernel. This struct represents the parsed configuration /// options. #[derive(Debug, Clone)] +#[non_exhaustive] pub struct Config { /// The run command that is invoked on `bootimage run` or `bootimage runner` /// @@ -28,26 +29,24 @@ pub struct Config { /// An exit code that should be considered as success for test executables (applies to /// `bootimage runner`) pub test_success_exit_code: Option, - non_exhaustive: (), } -pub(crate) fn read_config(manifest_path: &Path) -> Result { - let config = read_config_inner(manifest_path) - .map_err(|err| format!("Failed to read bootimage configuration: {:?}", err))?; - Ok(config) +/// Reads the configuration from a `package.metadata.bootimage` in the given Cargo.toml. +pub fn read_config(manifest_path: &Path) -> Result { + read_config_inner(manifest_path).context("Failed to read bootimage configuration") } -pub(crate) fn read_config_inner(manifest_path: &Path) -> Result { +fn read_config_inner(manifest_path: &Path) -> Result { use std::{fs::File, io::Read}; let cargo_toml: Value = { let mut content = String::new(); File::open(manifest_path) - .map_err(|e| format!("Failed to open Cargo.toml: {}", e))? + .context("Failed to open Cargo.toml")? .read_to_string(&mut content) - .map_err(|e| format!("Failed to read Cargo.toml: {}", e))?; + .context("Failed to read Cargo.toml")?; content .parse::() - .map_err(|e| format!("Failed to parse Cargo.toml: {}", e))? + .context("Failed to parse Cargo.toml")? }; let metadata = cargo_toml @@ -60,7 +59,7 @@ pub(crate) fn read_config_inner(manifest_path: &Path) -> Result metadata .as_table() - .ok_or(format!("Bootimage configuration invalid: {:?}", metadata))?, + .ok_or(anyhow!("Bootimage configuration invalid: {:?}", metadata))?, }; let mut config = ConfigBuilder::default(); @@ -68,7 +67,7 @@ pub(crate) fn read_config_inner(manifest_path: &Path) -> Result { - Err(format!("test-timeout must not be negative"))? + Err(anyhow!("test-timeout must not be negative"))? } ("test-timeout", Value::Integer(timeout)) => { config.test_timeout = Some(timeout as u32); @@ -81,7 +80,7 @@ pub(crate) fn read_config_inner(manifest_path: &Path) -> Result command.push(s), - _ => Err(format!("run-command must be a list of strings"))?, + _ => Err(anyhow!("run-command must be a list of strings"))?, } } config.run_command = Some(command); @@ -91,7 +90,7 @@ pub(crate) fn read_config_inner(manifest_path: &Path) -> Result args.push(s), - _ => Err(format!("run-args must be a list of strings"))?, + _ => Err(anyhow!("run-args must be a list of strings"))?, } } config.run_args = Some(args); @@ -101,15 +100,16 @@ pub(crate) fn read_config_inner(manifest_path: &Path) -> Result args.push(s), - _ => Err(format!("test-args must be a list of strings"))?, + _ => Err(anyhow!("test-args must be a list of strings"))?, } } config.test_args = Some(args); } - (key, value) => Err(format!( + (key, value) => Err(anyhow!( "unexpected `package.metadata.bootimage` \ key `{}` with value `{}`", - key, value + key, + value ))?, } } @@ -137,7 +137,6 @@ impl Into for ConfigBuilder { test_args: self.test_args, test_timeout: self.test_timeout.unwrap_or(60 * 5), test_success_exit_code: self.test_success_exit_code, - non_exhaustive: (), } } } diff --git a/src/help/build_help.txt b/src/help/build_help.txt deleted file mode 100644 index 572c8d4..0000000 --- a/src/help/build_help.txt +++ /dev/null @@ -1,12 +0,0 @@ -Creates a bootable disk image from a Rust kernel - -USAGE: - bootimage build [BUILD_OPTS] Create a bootable disk image - - (for other forms of usage see `bootimage --help`) - -BUILD_OPTS: - Any options are directly passed to `cargo build` (see - `cargo build --help` for possible options). After building, a bootloader - is downloaded and built, and then combined with the kernel into a bootable - disk image. diff --git a/src/help/help.txt b/src/help/help.txt index 3d265b9..1325a18 100644 --- a/src/help/help.txt +++ b/src/help/help.txt @@ -1,31 +1,11 @@ Creates a bootable disk image from a Rust kernel USAGE: - bootimage [OPTIONS] Help and version information - bootimage build [BUILD_OPTS] Create a bootable disk image - bootimage run [BUILD_OPTS] -- [RUN_OPTS] Build and run a disk image - bootimage test [BUILD_OPTS] Runs integration tests - bootimage runner EXECUTABLE Convert and run an executable - cargo bootimage [BUILD_OPTS] Create a bootable disk image - (equivalent to bootimage build) + bootimage runner EXECUTABLE [RUN_OPTS] Convert and run an executable -For more information about a subcommand run `bootimage [subcommand] --help`. +For more information about a subcommand run `[subcommand] --help`. -OPTIONS: - -h, --help Prints help information and exit +GENERAL OPTIONS: + -h, --help Prints help information and exit --version Prints version information and exit - -BUILD_OPTS: - Any options are directly passed to `cargo build` (see - `cargo build --help` for possible options). After building, a bootloader - is downloaded and built, and then combined with the kernel into a bootable - disk image. - - For configuration options see `bootimage build --help`. - -RUN_OPTS: - Any options are directly passed to the run command. Note that the run - options must be separated from the build options by a "--". - - For configuration options see `bootimage run --help`. diff --git a/src/help/mod.rs b/src/help/mod.rs index 60991db..d29dd9b 100644 --- a/src/help/mod.rs +++ b/src/help/mod.rs @@ -1,38 +1,22 @@ -use crate::ErrorMessage; - const HELP: &str = include_str!("help.txt"); -const BUILD_HELP: &str = include_str!("build_help.txt"); const CARGO_BOOTIMAGE_HELP: &str = include_str!("cargo_bootimage_help.txt"); -const RUN_HELP: &str = include_str!("run_help.txt"); const RUNNER_HELP: &str = include_str!("runner_help.txt"); -const TEST_HELP: &str = include_str!("test_help.txt"); -pub(crate) fn help() { +/// Prints a general help text. +pub fn print_help() { print!("{}", HELP); } -pub(crate) fn build_help() { - print!("{}", BUILD_HELP); -} - -pub(crate) fn cargo_bootimage_help() { +/// Prints the help for the `cargo bootimage` command. +pub fn print_cargo_bootimage_help() { print!("{}", CARGO_BOOTIMAGE_HELP); } - -pub(crate) fn run_help() { - print!("{}", RUN_HELP); -} - -pub(crate) fn runner_help() { +/// Prints the help for the `bootimage runner` command. +pub fn print_runner_help() { print!("{}", RUNNER_HELP); } -pub(crate) fn test_help() { - print!("{}", TEST_HELP); -} - -pub(crate) fn no_subcommand() -> ErrorMessage { - "Please invoke `bootimage` with a subcommand (e.g. `bootimage build`).\n\n\ - See `bootimage --help` for more information." - .into() +/// Prints the version of this crate. +pub fn print_version() { + println!("bootimage {}", env!("CARGO_PKG_VERSION")); } diff --git a/src/lib.rs b/src/lib.rs index 6d6ce73..2e2d74d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -4,99 +4,9 @@ #![warn(missing_docs)] -use args::{Args, RunnerArgs}; -use std::{fmt, process}; - -mod args; +pub mod args; pub mod builder; pub mod config; -mod help; - -mod subcommand; - -enum Command { - NoSubcommand, - Build(Args), - Run(Args), - Test(Args), - Runner(RunnerArgs), - Help, - BuildHelp, - RunHelp, - TestHelp, - CargoBootimageHelp, - RunnerHelp, - Version, -} - -/// The entry point for the binaries. -/// -/// We support two binaries, `bootimage` and `cargo-bootimage` that both just -/// call into this function. -/// -/// This function is just a small wrapper around [`run`] that prints error messages -/// and exits with the correct exit code. -pub fn lib_main() { - match run() { - Err(err) => { - eprintln!("Error: {}", err.message); - process::exit(1); - } - Ok(Some(exit_code)) => { - process::exit(exit_code); - } - Ok(None) => {} - } -} - -/// Run the invoked command. -/// -/// This function parses the arguments and invokes the chosen subcommand. -/// -/// On success, it optionally returns an exit code. This feature is used by the -/// `run` and `runner` subcommand to pass through the exit code of the invoked -/// run command. -pub fn run() -> Result, ErrorMessage> { - let command = args::parse_args()?; - let none = |()| None; - match command { - Command::Build(args) => subcommand::build::build(args).map(none), - Command::Run(args) => subcommand::run::run(args).map(Some), - Command::Test(args) => subcommand::test::test(args).map(none), - Command::Runner(args) => subcommand::runner::runner(args).map(Some), - Command::Help => Ok(help::help()).map(none), - Command::BuildHelp => Ok(help::build_help()).map(none), - Command::CargoBootimageHelp => Ok(help::cargo_bootimage_help()).map(none), - Command::RunHelp => Ok(help::run_help()).map(none), - Command::RunnerHelp => Ok(help::runner_help()).map(none), - Command::TestHelp => Ok(help::test_help()).map(none), - Command::Version => Ok(println!("bootimage {}", env!("CARGO_PKG_VERSION"))).map(none), - Command::NoSubcommand => Err(help::no_subcommand()), - } -} - -/// A simple error message that can be created from every type that implements `fmt::Display`. -/// -/// We use this error type for the CLI interface, where text based, human readable error messages -/// make sense. For the library part of this crate, we use custom error enums. -pub struct ErrorMessage { - /// The actual error message - pub message: Box, -} - -impl fmt::Debug for ErrorMessage { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - self.message.fmt(f) - } -} -impl From for ErrorMessage -where - T: fmt::Display + Send + 'static, -{ - fn from(err: T) -> Self { - ErrorMessage { - message: Box::new(err), - } - } -} +/// Contains help messages for the command line application. +pub mod help; diff --git a/src/main.rs b/src/main.rs index 5349675..7754d3a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,3 +1,160 @@ -pub fn main() { - bootimage::lib_main(); +/// Executable for `bootimage runner`. +use anyhow::{anyhow, Context, Result}; +use bootimage::{ + args::{RunnerArgs, RunnerCommand}, + builder::Builder, + config, help, +}; +use std::{env, path::Path}; +use std::{process, time::Duration}; +use wait_timeout::ChildExt; + +pub fn main() -> Result<()> { + let mut raw_args = env::args(); + + let executable_name = raw_args + .next() + .ok_or(anyhow!("no first argument (executable name)"))?; + let file_stem = Path::new(&executable_name) + .file_stem() + .and_then(|s| s.to_str()); + if file_stem != Some("bootimage") { + return Err(anyhow!( + "Unexpected executable name: expected `bootimage`, got: `{:?}`", + file_stem + )); + } + match raw_args.next().as_deref() { + Some("runner") => {}, + Some("--help") | Some("-h") => { + help::print_help(); + return Ok(()) + } + other => return Err(anyhow!( + "Unsupported subcommand `{:?}`. See `bootimage --help` for an overview of supported programs.", other + )) + } + + let exit_code = match RunnerCommand::parse_args(raw_args)? { + RunnerCommand::Runner(args) => Some(runner(args)?), + RunnerCommand::Version => { + help::print_version(); + None + } + RunnerCommand::Help => { + help::print_runner_help(); + None + } + }; + + if let Some(code) = exit_code { + process::exit(code); + } + + Ok(()) +} + +pub(crate) fn runner(args: RunnerArgs) -> Result { + let builder = Builder::new(None)?; + let config = config::read_config(builder.manifest_path())?; + let exe_parent = args + .executable + .parent() + .ok_or(anyhow!("kernel executable has no parent"))?; + let is_doctest = exe_parent + .file_name() + .ok_or(anyhow!("kernel executable's parent has no file name"))? + .to_str() + .ok_or(anyhow!( + "kernel executable's parent file name is not valid UTF-8" + ))? + .starts_with("rustdoctest"); + let is_test = is_doctest || exe_parent.ends_with("deps"); + + let bin_name = args + .executable + .file_stem() + .ok_or(anyhow!("kernel executable has no file stem"))? + .to_str() + .ok_or(anyhow!("kernel executable file stem is not valid UTF-8"))?; + + let output_bin_path = exe_parent.join(format!("bootimage-{}.bin", bin_name)); + let executable_canonicalized = args.executable.canonicalize().with_context(|| { + format!( + "failed to canonicalize executable path `{}`", + args.executable.display(), + ) + })?; + builder.create_bootimage( + bin_name, + &executable_canonicalized, + &output_bin_path, + args.quiet, + )?; + + let mut run_command: Vec<_> = config + .run_command + .iter() + .map(|arg| arg.replace("{}", &format!("{}", output_bin_path.display()))) + .collect(); + if is_test { + if let Some(args) = config.test_args { + run_command.extend(args); + } + } else { + if let Some(args) = config.run_args { + run_command.extend(args); + } + } + if let Some(args) = args.runner_args { + run_command.extend(args); + } + + if !args.quiet { + println!("Running: `{}`", run_command.join(" ")); + } + let mut command = process::Command::new(&run_command[0]); + command.args(&run_command[1..]); + + let exit_code = if is_test { + let mut child = command + .spawn() + .with_context(|| format!("Failed to launch QEMU: {:?}", command))?; + let timeout = Duration::from_secs(config.test_timeout.into()); + match child + .wait_timeout(timeout) + .context("Failed to wait with timeout")? + { + None => { + child.kill().context("Failed to kill QEMU")?; + child.wait().context("Failed to wait for QEMU process")?; + return Err(anyhow!("Timed Out")); + } + Some(exit_status) => { + #[cfg(unix)] + { + if exit_status.code().is_none() { + use std::os::unix::process::ExitStatusExt; + if let Some(signal) = exit_status.signal() { + eprintln!("QEMU process was terminated by signal {}", signal); + } + } + } + let qemu_exit_code = exit_status + .code() + .ok_or(anyhow!("Failed to read QEMU exit code"))?; + match config.test_success_exit_code { + Some(code) if qemu_exit_code == code => 0, + _ => qemu_exit_code, + } + } + } + } else { + let status = command + .status() + .with_context(|| format!("Failed to execute `{:?}`", command))?; + status.code().unwrap_or(1) + }; + + Ok(exit_code) } diff --git a/src/subcommand.rs b/src/subcommand.rs deleted file mode 100644 index b72654c..0000000 --- a/src/subcommand.rs +++ /dev/null @@ -1,2 +0,0 @@ -pub mod build; -pub mod runner; diff --git a/src/subcommand/build.rs b/src/subcommand/build.rs deleted file mode 100644 index 1831cb5..0000000 --- a/src/subcommand/build.rs +++ /dev/null @@ -1,36 +0,0 @@ -use crate::{args::Args, builder::Builder, config, ErrorMessage}; -use std::path::PathBuf; - -pub(crate) fn build(mut args: Args) -> Result<(), ErrorMessage> { - let builder = Builder::new(args.manifest_path().clone())?; - let quiet = args.quiet; - build_impl(&builder, &mut args, quiet).map(|_| ()) -} - -pub(crate) fn build_impl( - builder: &Builder, - args: &Args, - quiet: bool, -) -> Result, ErrorMessage> { - let executables = builder.build_kernel(&args.cargo_args, quiet)?; - if executables.len() == 0 { - Err("no executables built")?; - } - - let mut bootimages = Vec::new(); - - for executable in executables { - let out_dir = executable.parent().ok_or("executable has no parent path")?; - let file_stem = executable - .file_stem() - .ok_or("executable has no file stem")? - .to_str() - .ok_or("executable file stem not valid utf8")?; - - let bootimage_path = out_dir.join(format!("bootimage-{}.bin", file_stem)); - builder.create_bootimage(&executable, &bootimage_path, quiet)?; - bootimages.push(bootimage_path); - } - - Ok(bootimages) -} diff --git a/src/subcommand/runner.rs b/src/subcommand/runner.rs deleted file mode 100644 index e5ee486..0000000 --- a/src/subcommand/runner.rs +++ /dev/null @@ -1,106 +0,0 @@ -use crate::{args::RunnerArgs, builder::Builder, config, ErrorMessage}; -use std::{process, time::Duration}; -use wait_timeout::ChildExt; - -pub(crate) fn runner(args: RunnerArgs) -> Result { - let builder = Builder::new(None)?; - let config = config::read_config(builder.kernel_manifest_path())?; - let exe_parent = args - .executable - .parent() - .ok_or("kernel executable has no parent")?; - let is_doctest = exe_parent - .file_name() - .ok_or("kernel executable's parent has no file name")? - .to_str() - .ok_or("kernel executable's parent file name is not valid UTF-8")? - .starts_with("rustdoctest"); - let is_test = is_doctest || exe_parent.ends_with("deps"); - - let bootimage_bin = { - let file_stem = args - .executable - .file_stem() - .ok_or("kernel executable has no file stem")? - .to_str() - .ok_or("kernel executable file stem is not valid UTF-8")?; - exe_parent.join(format!("bootimage-{}.bin", file_stem)) - }; - - let executable_canonicalized = args.executable.canonicalize().map_err(|err| { - format!( - "failed to canonicalize executable path `{}`: {}", - args.executable.display(), - err - ) - })?; - builder.create_bootimage(&executable_canonicalized, &bootimage_bin, args.quiet)?; - - let mut run_command: Vec<_> = config - .run_command - .iter() - .map(|arg| arg.replace("{}", &format!("{}", bootimage_bin.display()))) - .collect(); - if is_test { - if let Some(args) = config.test_args { - run_command.extend(args); - } - } else { - if let Some(args) = config.run_args { - run_command.extend(args); - } - } - if let Some(args) = args.runner_args { - run_command.extend(args); - } - - if !args.quiet { - println!("Running: `{}`", run_command.join(" ")); - } - let mut command = process::Command::new(&run_command[0]); - command.args(&run_command[1..]); - - let exit_code = if is_test { - let mut child = command - .spawn() - .map_err(|e| format!("Failed to launch QEMU: {:?}\n{}", command, e))?; - let timeout = Duration::from_secs(config.test_timeout.into()); - match child - .wait_timeout(timeout) - .map_err(|e| format!("Failed to wait with timeout: {}", e))? - { - None => { - child - .kill() - .map_err(|e| format!("Failed to kill QEMU: {}", e))?; - child - .wait() - .map_err(|e| format!("Failed to wait for QEMU process: {}", e))?; - return Err(ErrorMessage::from("Timed Out")); - } - Some(exit_status) => { - #[cfg(unix)] - { - if exit_status.code().is_none() { - use std::os::unix::process::ExitStatusExt; - if let Some(signal) = exit_status.signal() { - eprintln!("QEMU process was terminated by signal {}", signal); - } - } - } - let qemu_exit_code = exit_status.code().ok_or("Failed to read QEMU exit code")?; - match config.test_success_exit_code { - Some(code) if qemu_exit_code == code => 0, - _ => qemu_exit_code, - } - } - } - } else { - let status = command - .status() - .map_err(|e| format!("Failed to execute `{:?}`: {}", command, e))?; - status.code().unwrap_or(1) - }; - - Ok(exit_code) -} From 0ef3724a0c8f80a3976e7c79552fa5a4b78f9e9a Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Thu, 7 May 2020 09:54:59 +0200 Subject: [PATCH 018/108] Run cargo fmt --- src/bin/cargo-bootimage.rs | 5 ++++- src/builder/error.rs | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/bin/cargo-bootimage.rs b/src/bin/cargo-bootimage.rs index 4644020..e335ea3 100644 --- a/src/bin/cargo-bootimage.rs +++ b/src/bin/cargo-bootimage.rs @@ -4,7 +4,10 @@ use bootimage::{ builder::Builder, help, }; -use std::{env, path::{PathBuf, Path}}; +use std::{ + env, + path::{Path, PathBuf}, +}; pub fn main() -> Result<()> { let mut raw_args = env::args(); diff --git a/src/builder/error.rs b/src/builder/error.rs index a3018fe..75ec4e8 100644 --- a/src/builder/error.rs +++ b/src/builder/error.rs @@ -100,7 +100,7 @@ pub enum BootloaderError { #[error("Could not find package for binary `{bin_name}` in cargo metadata output")] KernelBinPackageNotFound { /// The name of the kernel binary - bin_name: String + bin_name: String, }, /// Could not find some required information in the `cargo metadata` output #[error("Could not find required key `{key}` in cargo metadata output")] From 19b183a3213fd389d682e57169921c2fc39d33f7 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Thu, 7 May 2020 09:55:16 +0200 Subject: [PATCH 019/108] Improve error message for unsupported subcommand --- src/main.rs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/main.rs b/src/main.rs index 7754d3a..8a9c759 100644 --- a/src/main.rs +++ b/src/main.rs @@ -30,9 +30,12 @@ pub fn main() -> Result<()> { help::print_help(); return Ok(()) } - other => return Err(anyhow!( - "Unsupported subcommand `{:?}`. See `bootimage --help` for an overview of supported programs.", other - )) + Some(other) => return Err(anyhow!( + "Unsupported subcommand `{:?}`. See `bootimage --help` for an overview of supported subcommands.", other + )), + None => return Err(anyhow!( + "Please invoke bootimage with a subcommand. See `bootimage --help` for more information." + )), } let exit_code = match RunnerCommand::parse_args(raw_args)? { From 401e82e77d4ffc0c7f5a5d2d63902b2ccd59a993 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Thu, 7 May 2020 10:19:09 +0200 Subject: [PATCH 020/108] Delete tests of removed functionality --- .../default-target-bootimage/.gitignore | 2 - .../default-target-bootimage/Cargo.toml | 12 ---- .../default-target-bootimage/src/main.rs | 28 --------- .../default-target-cargo/.cargo/config | 2 - .../default-target-cargo/.gitignore | 2 - .../default-target-cargo/Cargo.toml | 9 --- .../default-target-cargo/src/main.rs | 28 --------- .../testing-qemu-exit-code/.gitignore | 2 - .../testing-qemu-exit-code/Cargo.toml | 12 ---- .../src/bin/test-basic-boot.rs | 27 --------- .../src/bin/test-panic.rs | 21 ------- .../testing-qemu-exit-code/src/lib.rs | 21 ------- .../testing-serial-result/.gitignore | 2 - .../testing-serial-result/Cargo.toml | 18 ------ .../src/bin/test-basic-boot-serial.rs | 33 ----------- .../src/bin/test-panic-serial.rs | 23 -------- .../testing-serial-result/src/lib.rs | 58 ------------------- .../testing-serial-result/src/main.rs | 28 --------- 18 files changed, 328 deletions(-) delete mode 100644 example-kernels/default-target-bootimage/.gitignore delete mode 100644 example-kernels/default-target-bootimage/Cargo.toml delete mode 100644 example-kernels/default-target-bootimage/src/main.rs delete mode 100644 example-kernels/default-target-cargo/.cargo/config delete mode 100644 example-kernels/default-target-cargo/.gitignore delete mode 100644 example-kernels/default-target-cargo/Cargo.toml delete mode 100644 example-kernels/default-target-cargo/src/main.rs delete mode 100644 example-kernels/testing-qemu-exit-code/.gitignore delete mode 100644 example-kernels/testing-qemu-exit-code/Cargo.toml delete mode 100644 example-kernels/testing-qemu-exit-code/src/bin/test-basic-boot.rs delete mode 100644 example-kernels/testing-qemu-exit-code/src/bin/test-panic.rs delete mode 100644 example-kernels/testing-qemu-exit-code/src/lib.rs delete mode 100644 example-kernels/testing-serial-result/.gitignore delete mode 100644 example-kernels/testing-serial-result/Cargo.toml delete mode 100644 example-kernels/testing-serial-result/src/bin/test-basic-boot-serial.rs delete mode 100644 example-kernels/testing-serial-result/src/bin/test-panic-serial.rs delete mode 100644 example-kernels/testing-serial-result/src/lib.rs delete mode 100644 example-kernels/testing-serial-result/src/main.rs diff --git a/example-kernels/default-target-bootimage/.gitignore b/example-kernels/default-target-bootimage/.gitignore deleted file mode 100644 index eccd7b4..0000000 --- a/example-kernels/default-target-bootimage/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -/target/ -**/*.rs.bk diff --git a/example-kernels/default-target-bootimage/Cargo.toml b/example-kernels/default-target-bootimage/Cargo.toml deleted file mode 100644 index befa7ff..0000000 --- a/example-kernels/default-target-bootimage/Cargo.toml +++ /dev/null @@ -1,12 +0,0 @@ -[package] -name = "default-target-bootimage" -version = "0.1.0" -authors = ["Philipp Oppermann "] -edition = "2018" - -[dependencies] -bootloader = "0.6.4" -x86_64 = "0.5.3" - -[package.metadata.bootimage] -default-target = "../x86_64-bootimage-example-kernels.json" \ No newline at end of file diff --git a/example-kernels/default-target-bootimage/src/main.rs b/example-kernels/default-target-bootimage/src/main.rs deleted file mode 100644 index 44b77a9..0000000 --- a/example-kernels/default-target-bootimage/src/main.rs +++ /dev/null @@ -1,28 +0,0 @@ -#![no_std] // don't link the Rust standard library -#![no_main] // disable all Rust-level entry points - -use core::panic::PanicInfo; - -/// This function is called on panic. -#[panic_handler] -fn panic(_info: &PanicInfo) -> ! { - loop {} -} - -#[no_mangle] // don't mangle the name of this function -pub extern "C" fn _start() -> ! { - // this function is the entry point, since the linker looks for a function - // named `_start` by default - - // exit QEMU (see https://os.phil-opp.com/integration-tests/#shutting-down-qemu) - unsafe { exit_qemu(); } - - loop {} -} - -pub unsafe fn exit_qemu() { - use x86_64::instructions::port::Port; - - let mut port = Port::::new(0xf4); - port.write(52); // exit code is (52 << 1) | 1 = 105 -} diff --git a/example-kernels/default-target-cargo/.cargo/config b/example-kernels/default-target-cargo/.cargo/config deleted file mode 100644 index 79fdf34..0000000 --- a/example-kernels/default-target-cargo/.cargo/config +++ /dev/null @@ -1,2 +0,0 @@ -[build] -target = "../x86_64-bootimage-example-kernels.json" \ No newline at end of file diff --git a/example-kernels/default-target-cargo/.gitignore b/example-kernels/default-target-cargo/.gitignore deleted file mode 100644 index eccd7b4..0000000 --- a/example-kernels/default-target-cargo/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -/target/ -**/*.rs.bk diff --git a/example-kernels/default-target-cargo/Cargo.toml b/example-kernels/default-target-cargo/Cargo.toml deleted file mode 100644 index bb08c52..0000000 --- a/example-kernels/default-target-cargo/Cargo.toml +++ /dev/null @@ -1,9 +0,0 @@ -[package] -name = "default-target-cargo" -version = "0.1.0" -authors = ["Philipp Oppermann "] -edition = "2018" - -[dependencies] -bootloader = "0.6.4" -x86_64 = "0.5.3" diff --git a/example-kernels/default-target-cargo/src/main.rs b/example-kernels/default-target-cargo/src/main.rs deleted file mode 100644 index 14aead9..0000000 --- a/example-kernels/default-target-cargo/src/main.rs +++ /dev/null @@ -1,28 +0,0 @@ -#![no_std] // don't link the Rust standard library -#![no_main] // disable all Rust-level entry points - -use core::panic::PanicInfo; - -/// This function is called on panic. -#[panic_handler] -fn panic(_info: &PanicInfo) -> ! { - loop {} -} - -#[no_mangle] // don't mangle the name of this function -pub extern "C" fn _start() -> ! { - // this function is the entry point, since the linker looks for a function - // named `_start` by default - - // exit QEMU (see https://os.phil-opp.com/integration-tests/#shutting-down-qemu) - unsafe { exit_qemu(); } - - loop {} -} - -pub unsafe fn exit_qemu() { - use x86_64::instructions::port::Port; - - let mut port = Port::::new(0xf4); - port.write(53); // exit code is (53 << 1) | 1 = 107 -} diff --git a/example-kernels/testing-qemu-exit-code/.gitignore b/example-kernels/testing-qemu-exit-code/.gitignore deleted file mode 100644 index eccd7b4..0000000 --- a/example-kernels/testing-qemu-exit-code/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -/target/ -**/*.rs.bk diff --git a/example-kernels/testing-qemu-exit-code/Cargo.toml b/example-kernels/testing-qemu-exit-code/Cargo.toml deleted file mode 100644 index 4abfbe8..0000000 --- a/example-kernels/testing-qemu-exit-code/Cargo.toml +++ /dev/null @@ -1,12 +0,0 @@ -[package] -name = "testing-qemu-exit-code" -version = "0.1.0" -authors = ["Philipp Oppermann "] -edition = "2018" - -[dependencies] -bootloader = "0.6.4" -x86_64 = "0.5.3" - -[package.metadata.bootimage] -default-target = "../x86_64-bootimage-example-kernels.json" \ No newline at end of file diff --git a/example-kernels/testing-qemu-exit-code/src/bin/test-basic-boot.rs b/example-kernels/testing-qemu-exit-code/src/bin/test-basic-boot.rs deleted file mode 100644 index 1a506f1..0000000 --- a/example-kernels/testing-qemu-exit-code/src/bin/test-basic-boot.rs +++ /dev/null @@ -1,27 +0,0 @@ -#![cfg_attr(not(test), no_std)] -#![cfg_attr(not(test), no_main)] // disable all Rust-level entry points -#![cfg_attr(test, allow(unused_imports))] - -use testing_qemu_exit_code::{exit_qemu, ExitCode}; -use core::panic::PanicInfo; - -/// This function is the entry point, since the linker looks for a function -/// named `_start` by default. -#[cfg(not(test))] -#[no_mangle] // don't mangle the name of this function -pub extern "C" fn _start() -> ! { - unsafe { - exit_qemu(ExitCode::Success); - } - loop {} -} - -/// This function is called on panic. -#[cfg(not(test))] -#[panic_handler] -fn panic(info: &PanicInfo) -> ! { - unsafe { - exit_qemu(ExitCode::Failure); - } - loop {} -} diff --git a/example-kernels/testing-qemu-exit-code/src/bin/test-panic.rs b/example-kernels/testing-qemu-exit-code/src/bin/test-panic.rs deleted file mode 100644 index a1c05f8..0000000 --- a/example-kernels/testing-qemu-exit-code/src/bin/test-panic.rs +++ /dev/null @@ -1,21 +0,0 @@ -#![cfg_attr(not(test), no_std)] -#![cfg_attr(not(test), no_main)] -#![cfg_attr(test, allow(unused_imports))] - -use testing_qemu_exit_code::{exit_qemu, ExitCode}; -use core::panic::PanicInfo; - -#[cfg(not(test))] -#[no_mangle] -pub extern "C" fn _start() -> ! { - panic!(); -} - -#[cfg(not(test))] -#[panic_handler] -fn panic(_info: &PanicInfo) -> ! { - unsafe { - exit_qemu(ExitCode::Success); - } - loop {} -} diff --git a/example-kernels/testing-qemu-exit-code/src/lib.rs b/example-kernels/testing-qemu-exit-code/src/lib.rs deleted file mode 100644 index cdc0ba8..0000000 --- a/example-kernels/testing-qemu-exit-code/src/lib.rs +++ /dev/null @@ -1,21 +0,0 @@ -#![cfg_attr(not(test), no_std)] -#![feature(abi_x86_interrupt)] - -#[repr(u32)] -pub enum ExitCode { - Success = 2, - Failure = 3, -} - -pub unsafe fn exit_qemu(exit_code: ExitCode) { - use x86_64::instructions::port::Port; - - let mut port = Port::::new(0xf4); - port.write(exit_code as u32); -} - -pub fn hlt_loop() -> ! { - loop { - x86_64::instructions::hlt(); - } -} diff --git a/example-kernels/testing-serial-result/.gitignore b/example-kernels/testing-serial-result/.gitignore deleted file mode 100644 index eccd7b4..0000000 --- a/example-kernels/testing-serial-result/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -/target/ -**/*.rs.bk diff --git a/example-kernels/testing-serial-result/Cargo.toml b/example-kernels/testing-serial-result/Cargo.toml deleted file mode 100644 index f280008..0000000 --- a/example-kernels/testing-serial-result/Cargo.toml +++ /dev/null @@ -1,18 +0,0 @@ -[package] -name = "testing-serial-result" -version = "0.1.0" -authors = ["Philipp Oppermann "] -edition = "2018" - -[dependencies] -bootloader = "0.6.4" -x86_64 = "0.5.3" -spin = "0.4.9" -uart_16550 = "0.1.0" - -[dependencies.lazy_static] -version = "1.3.0" -features = ["spin_no_std"] - -[package.metadata.bootimage] -default-target = "../x86_64-bootimage-example-kernels.json" diff --git a/example-kernels/testing-serial-result/src/bin/test-basic-boot-serial.rs b/example-kernels/testing-serial-result/src/bin/test-basic-boot-serial.rs deleted file mode 100644 index d6982d0..0000000 --- a/example-kernels/testing-serial-result/src/bin/test-basic-boot-serial.rs +++ /dev/null @@ -1,33 +0,0 @@ -#![cfg_attr(not(test), no_std)] -#![cfg_attr(not(test), no_main)] // disable all Rust-level entry points -#![cfg_attr(test, allow(unused_imports))] - -use testing_serial_result::{exit_qemu, serial_println}; -use core::panic::PanicInfo; - -/// This function is the entry point, since the linker looks for a function -/// named `_start` by default. -#[cfg(not(test))] -#[no_mangle] // don't mangle the name of this function -pub extern "C" fn _start() -> ! { - serial_println!("ok"); - - unsafe { - exit_qemu(); - } - loop {} -} - -/// This function is called on panic. -#[cfg(not(test))] -#[panic_handler] -fn panic(info: &PanicInfo) -> ! { - serial_println!("failed"); - - serial_println!("{}", info); - - unsafe { - exit_qemu(); - } - loop {} -} diff --git a/example-kernels/testing-serial-result/src/bin/test-panic-serial.rs b/example-kernels/testing-serial-result/src/bin/test-panic-serial.rs deleted file mode 100644 index 324a28f..0000000 --- a/example-kernels/testing-serial-result/src/bin/test-panic-serial.rs +++ /dev/null @@ -1,23 +0,0 @@ -#![cfg_attr(not(test), no_std)] -#![cfg_attr(not(test), no_main)] -#![cfg_attr(test, allow(unused_imports))] - -use testing_serial_result::{exit_qemu, serial_println}; -use core::panic::PanicInfo; - -#[cfg(not(test))] -#[no_mangle] -pub extern "C" fn _start() -> ! { - panic!(); -} - -#[cfg(not(test))] -#[panic_handler] -fn panic(_info: &PanicInfo) -> ! { - serial_println!("ok"); - - unsafe { - exit_qemu(); - } - loop {} -} diff --git a/example-kernels/testing-serial-result/src/lib.rs b/example-kernels/testing-serial-result/src/lib.rs deleted file mode 100644 index 6bd2578..0000000 --- a/example-kernels/testing-serial-result/src/lib.rs +++ /dev/null @@ -1,58 +0,0 @@ -#![cfg_attr(not(test), no_std)] -#![feature(abi_x86_interrupt)] - -pub unsafe fn exit_qemu() { - use x86_64::instructions::port::Port; - - let mut port = Port::::new(0xf4); - port.write(0); -} - -pub fn hlt_loop() -> ! { - loop { - x86_64::instructions::hlt(); - } -} - -pub mod serial { - use lazy_static::lazy_static; - use spin::Mutex; - use uart_16550::SerialPort; - - lazy_static! { - pub static ref SERIAL1: Mutex = { - let mut serial_port = SerialPort::new(0x3F8); - serial_port.init(); - Mutex::new(serial_port) - }; - } - - #[doc(hidden)] - pub fn _print(args: ::core::fmt::Arguments) { - use core::fmt::Write; - use x86_64::instructions::interrupts; - - interrupts::without_interrupts(|| { - SERIAL1 - .lock() - .write_fmt(args) - .expect("Printing to serial failed"); - }); - } - - /// Prints to the host through the serial interface. - #[macro_export] - macro_rules! serial_print { - ($($arg:tt)*) => { - $crate::serial::_print(format_args!($($arg)*)); - }; - } - - /// Prints to the host through the serial interface, appending a newline. - #[macro_export] - macro_rules! serial_println { - () => ($crate::serial_print!("\n")); - ($fmt:expr) => ($crate::serial_print!(concat!($fmt, "\n"))); - ($fmt:expr, $($arg:tt)*) => ($crate::serial_print!(concat!($fmt, "\n"), $($arg)*)); - } -} \ No newline at end of file diff --git a/example-kernels/testing-serial-result/src/main.rs b/example-kernels/testing-serial-result/src/main.rs deleted file mode 100644 index f0352e2..0000000 --- a/example-kernels/testing-serial-result/src/main.rs +++ /dev/null @@ -1,28 +0,0 @@ -#![no_std] // don't link the Rust standard library -#![no_main] // disable all Rust-level entry points - -use core::panic::PanicInfo; - -/// This function is called on panic. -#[panic_handler] -fn panic(_info: &PanicInfo) -> ! { - loop {} -} - -#[no_mangle] // don't mangle the name of this function -pub extern "C" fn _start() -> ! { - // this function is the entry point, since the linker looks for a function - // named `_start` by default - - // exit QEMU (see https://os.phil-opp.com/integration-tests/#shutting-down-qemu) - unsafe { exit_qemu(); } - - loop {} -} - -pub unsafe fn exit_qemu() { - use x86_64::instructions::port::Port; - - let mut port = Port::::new(0xf4); - port.write(61); // exit code is (61 << 1) | 1 = 123 -} From 6aebafdf61a46a6549e9b00968d888fda9ed57f6 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Thu, 7 May 2020 10:19:34 +0200 Subject: [PATCH 021/108] Delete azure pipelines CI script --- azure-pipelines.yml | 245 -------------------------------------------- 1 file changed, 245 deletions(-) delete mode 100644 azure-pipelines.yml diff --git a/azure-pipelines.yml b/azure-pipelines.yml deleted file mode 100644 index d2f93d4..0000000 --- a/azure-pipelines.yml +++ /dev/null @@ -1,245 +0,0 @@ -# Documentation: https://aka.ms/yaml - -trigger: - branches: - include: - - '*' - exclude: - - 'staging.tmp' - -jobs: -- job: build - displayName: Build - strategy: - matrix: - linux: - image_name: 'ubuntu-16.04' - rustup_toolchain: stable - mac: - image_name: 'macOS-10.15' - rustup_toolchain: stable - windows: - image_name: 'vs2017-win2016' - rustup_toolchain: stable - - pool: - vmImage: $(image_name) - - steps: - - bash: | - echo "Hello world from $AGENT_NAME running on $AGENT_OS" - echo "Reason: $BUILD_REASON" - case "$BUILD_REASON" in - "Manual") echo "$BUILD_REQUESTEDFOR manually queued the build." ;; - "PullRequest") echo "This is a CI build for a pull request on $BUILD_REQUESTEDFOR." ;; - "IndividualCI") echo "This is a CI build for $BUILD_REQUESTEDFOR." ;; - "BatchedCI") echo "This is a batched CI build for $BUILD_REQUESTEDFOR." ;; - *) "$BUILD_REASON" ;; - esac - displayName: 'Build Info' - continueOnError: true - - - script: | - set -euxo pipefail - curl https://sh.rustup.rs -sSf | sh -s -- -y --default-toolchain $RUSTUP_TOOLCHAIN - echo "##vso[task.setvariable variable=PATH;]$PATH:$HOME/.cargo/bin" - condition: or(eq( variables['Agent.OS'], 'Linux' ), eq( variables['Agent.OS'], 'Darwin' )) - displayName: 'Install Rust (Linux/macOS)' - - - bash: rustup default $RUSTUP_TOOLCHAIN - condition: eq( variables['Agent.OS'], 'Windows_NT' ) - displayName: 'Set Rust Toolchain (Windows)' - - - bash: rustup update $RUSTUP_TOOLCHAIN - displayName: 'Run Rustup Update' - - - script: | - rustc -Vv - cargo -V - displayName: 'Print Rust Version' - continueOnError: true - - - script: cargo build - displayName: 'Build' - - - script: cargo test - displayName: 'Test' - - -- job: test - displayName: Test - - strategy: - matrix: - linux: - image_name: 'ubuntu-16.04' - rustup_toolchain: nightly - mac: - image_name: 'macos-10.15' - rustup_toolchain: nightly - windows: - image_name: 'vs2017-win2016' - rustup_toolchain: nightly - - pool: - vmImage: $(image_name) - - steps: - - bash: | - echo "Hello world from $AGENT_NAME running on $AGENT_OS" - echo "Reason: $BUILD_REASON" - case "$BUILD_REASON" in - "Manual") echo "$BUILD_REQUESTEDFOR manually queued the build." ;; - "PullRequest") echo "This is a CI build for a pull request on $BUILD_REQUESTEDFOR." ;; - "IndividualCI") echo "This is a CI build for $BUILD_REQUESTEDFOR." ;; - "BatchedCI") echo "This is a batched CI build for $BUILD_REQUESTEDFOR." ;; - *) "$BUILD_REASON" ;; - esac - displayName: 'Build Info' - continueOnError: true - - - script: | - set -euxo pipefail - curl https://sh.rustup.rs -sSf | sh -s -- -y --default-toolchain $RUSTUP_TOOLCHAIN - echo "##vso[task.setvariable variable=PATH;]$PATH:$HOME/.cargo/bin" - condition: or(eq( variables['Agent.OS'], 'Linux' ), eq( variables['Agent.OS'], 'Darwin' )) - displayName: 'Install Rust (Linux/macOS)' - - - bash: rustup default $RUSTUP_TOOLCHAIN - condition: eq( variables['Agent.OS'], 'Windows_NT' ) - displayName: 'Set Rust Toolchain (Windows)' - - - bash: rustup update $RUSTUP_TOOLCHAIN - displayName: 'Run Rustup Update' - - - script: | - rustc -Vv - cargo -V - displayName: 'Print Rust Version' - continueOnError: true - - - script: rustup component add rust-src llvm-tools-preview - displayName: 'Install Rustup Components' - - - script: cargo install cargo-xbuild --debug - displayName: 'Install cargo-xbuild' - - - script: sudo apt update && sudo apt install qemu-system-x86 - condition: eq( variables['Agent.OS'], 'Linux' ) - displayName: 'Install QEMU (Linux)' - - - script: | - set -euxo pipefail - export HOMEBREW_NO_AUTO_UPDATE=1 - export HOMEBREW_NO_BOTTLE_SOURCE_FALLBACK=1 - export HOMEBREW_NO_INSTALL_CLEANUP=1 - brew install qemu - condition: eq( variables['Agent.OS'], 'Darwin' ) - displayName: 'Install QEMU (macOS)' - - - script: | - choco install qemu --limit-output --no-progress - echo ##vso[task.setvariable variable=PATH;]%PATH%;C:\Program Files\qemu - set PATH=%PATH%;C:\Program Files\qemu - qemu-system-x86_64 --version - condition: eq( variables['Agent.OS'], 'Windows_NT' ) - failOnStderr: true - displayName: 'Install QEMU (Windows)' - - - script: cargo install --path . --force --debug - displayName: 'Install this bootimage version' - - - script: bootimage build --target ../x86_64-bootimage-example-kernels.json - workingDirectory: example-kernels/basic - displayName: 'Build "basic" Kernel' - - - bash: | - qemu-system-x86_64 -drive format=raw,file=target/x86_64-bootimage-example-kernels/debug/bootimage-basic.bin -device isa-debug-exit,iobase=0xf4,iosize=0x04 -display none - if [ $? -eq 103 ]; then (exit 0); else (exit 1); fi - workingDirectory: example-kernels - displayName: 'Run QEMU with "basic" Kernel' - - - bash: | - bootimage run --target ../x86_64-bootimage-example-kernels.json -- -device isa-debug-exit,iobase=0xf4,iosize=0x04 -display none - if [ $? -eq 103 ]; then (exit 0); else (exit 1); fi - workingDirectory: example-kernels/basic - displayName: 'Check Exit Code of `bootimage run` for "basic" kernel' - - - bash: | - bootimage run -- -device isa-debug-exit,iobase=0xf4,iosize=0x04 -display none - if [ $? -eq 105 ]; then (exit 0); else (exit 1); fi - workingDirectory: example-kernels/default-target-bootimage - displayName: 'Check Exit Code of `bootimage run` for "default-target-bootimage" kernel' - - - bash: | - bootimage run -- -device isa-debug-exit,iobase=0xf4,iosize=0x04 -display none - if [ $? -eq 107 ]; then (exit 0); else (exit 1); fi - workingDirectory: example-kernels/default-target-cargo - displayName: 'Check Exit Code of `bootimage run` for "default-target-cargo" kernel' - - - script: bootimage test - workingDirectory: example-kernels/testing-serial-result - displayName: 'Run `bootimage test` for "testing-serial-result" kernel' - - - script: bootimage test - workingDirectory: example-kernels/testing-qemu-exit-code - displayName: 'Run `bootimage test` for "testing-qemu-exit-code" kernel' - - - bash: | - cargo xrun - if [ $? -eq 109 ]; then (exit 0); else (exit 1); fi - workingDirectory: example-kernels/runner - displayName: 'Run `cargo xrun` for "runner" kernel' - - - script: cargo xtest -Z doctest-xcompile - workingDirectory: example-kernels/runner-doctest - displayName: 'Run `cargo xtest -Z doctest-xcompile` for "runner-doctest" kernel' - - - script: cargo xtest - workingDirectory: example-kernels/runner-test - displayName: 'Run `cargo xtest` for "runner-test" kernel' - -- job: formatting - displayName: Check Formatting - - strategy: - matrix: - linux: - image_name: 'ubuntu-16.04' - rustup_toolchain: stable - - pool: - vmImage: $(image_name) - - steps: - - bash: | - echo "Hello world from $AGENT_NAME running on $AGENT_OS" - echo "Reason: $BUILD_REASON" - case "$BUILD_REASON" in - "Manual") echo "$BUILD_REQUESTEDFOR manually queued the build." ;; - "PullRequest") echo "This is a CI build for a pull request on $BUILD_REQUESTEDFOR." ;; - "IndividualCI") echo "This is a CI build for $BUILD_REQUESTEDFOR." ;; - "BatchedCI") echo "This is a batched CI build for $BUILD_REQUESTEDFOR." ;; - *) "$BUILD_REASON" ;; - esac - displayName: 'Build Info' - continueOnError: true - - - script: | - set -euxo pipefail - curl https://sh.rustup.rs -sSf | sh -s -- -y --default-toolchain $RUSTUP_TOOLCHAIN - echo "##vso[task.setvariable variable=PATH;]$PATH:$HOME/.cargo/bin" - condition: or(eq( variables['Agent.OS'], 'Linux' ), eq( variables['Agent.OS'], 'Darwin' )) - displayName: 'Install Rust' - - - script: | - rustc -Vv - cargo -V - displayName: 'Print Rust Version' - continueOnError: true - - - script: rustup component add rustfmt - displayName: 'Install Rustfmt' - - - script: cargo fmt -- --check - displayName: 'Check Formatting' From dbdbfba29c5fd9f16499023c73d1944494a6bd95 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Thu, 7 May 2020 10:19:45 +0200 Subject: [PATCH 022/108] Add GitHub actions workflow --- .github/workflows/build.yml | 176 ++++++++++++++++++++++++++++++++++++ 1 file changed, 176 insertions(+) create mode 100644 .github/workflows/build.yml diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..d2660c4 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,176 @@ +name: Build + +on: + push: + branches: + - 'master' + tags: + - '*' + schedule: + - cron: '40 4 * * *' # every day at 4:40 + pull_request: + +jobs: + build: + name: "Build" + + strategy: + matrix: + platform: [ + ubuntu-latest, + macos-latest, + windows-latest + ] + + runs-on: ${{ matrix.platform }} + timeout-minutes: 15 + + steps: + - name: "Checkout Repository" + uses: actions/checkout@v1 + + - name: Install Rustup (macOS) + run: | + curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y + echo ::add-path::$HOME/.cargo/bin + if: runner.os == 'macOS' + + - name: Set Rustup profile to minimal + run: rustup set profile minimal + + - name: Install musl target on Linux + run: | + rustup target add x86_64-unknown-linux-musl + sudo apt-get install musl-tools musl-dev + if: runner.os == 'Linux' + + - name: "Print Rust Version" + run: | + rustc -Vv + cargo -Vv + + - name: "Run cargo build" + run: cargo build + + - name: "Run cargo test" + run: cargo test + + - name: "Deny Warnings" + run: cargo build + env: + RUSTFLAGS: "-D warnings" + + - name: "Install it" + run: cargo install --path . --debug + + - name: "Upload Artifact" + uses: actions/upload-artifact@v2 + with: + name: ${{ env.name }}-bootimage + path: ~/.cargo/bin/bootimage + + test: + name: "Test" + + strategy: + matrix: + platform: [ + ubuntu-latest, + macos-latest, + windows-latest + ] + + runs-on: ${{ matrix.platform }} + timeout-minutes: 15 + + steps: + - name: "Checkout Repository" + uses: actions/checkout@v1 + + - name: "Download Bootimage Artifact" + uses: actions/download-artifact@v2 + with: + name: ${{ env.name }}-bootimage + path: ~/.cargo/bin/bootimage + + - name: Install Rustup (macOS) + run: | + curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y + echo ::add-path::$HOME/.cargo/bin + if: runner.os == 'macOS' + + - name: "Install Rustup Components" + run: rustup component add rust-src llvm-tools-preview + - name: "Install cargo-xbuild" + run: cargo install cargo-xbuild --debug + + # install QEMU + - name: Install QEMU (Linux) + run: | + sudo apt update + sudo apt install qemu-system-x86 + if: runner.os == 'Linux' + - name: Install QEMU (macOS) + run: brew install qemu + if: runner.os == 'macOS' + env: + HOMEBREW_NO_AUTO_UPDATE: 1 + HOMEBREW_NO_BOTTLE_SOURCE_FALLBACK: 1 + HOMEBREW_NO_INSTALL_CLEANUP: 1 + - name: Install Scoop (Windows) + run: | + Invoke-Expression (New-Object System.Net.WebClient).DownloadString('https://get.scoop.sh') + echo ::add-path::$HOME\scoop\shims + if: runner.os == 'Windows' + shell: pwsh + - name: Install QEMU (Windows) + run: scoop install qemu + if: runner.os == 'Windows' + shell: pwsh + + - name: "Print QEMU Version" + run: qemu-system-x86_64 --version + + - name: 'Build "basic" Kernel' + run: cargo bootimage --target ../x86_64-bootimage-example-kernels.json + working-directory: example-kernels/basic + + - name: 'Run QEMU with "basic" Kernel' + run: | + qemu-system-x86_64 -drive format=raw,file=target/x86_64-bootimage-example-kernels/debug/bootimage-basic.bin -device isa-debug-exit,iobase=0xf4,iosize=0x04 -display none + if [ $? -eq 103 ]; then (exit 0); else (exit 1); fi + shell: bash + working-directory: example-kernels + + - name: 'Run `cargo xrun` for "runner" kernel' + run: | + cargo xrun + if [ $? -eq 109 ]; then (exit 0); else (exit 1); fi + shell: bash + working-directory: example-kernels/runner + + - run: cargo xtest -Z doctest-xcompile + working-directory: example-kernels/runner-doctest + name: 'Run `cargo xtest -Z doctest-xcompile` for "runner-doctest" kernel' + + - run: cargo xtest + working-directory: example-kernels/runner-test + name: 'Run `cargo xtest` for "runner-test" kernel' + + check_formatting: + name: "Check Formatting" + runs-on: ubuntu-latest + timeout-minutes: 2 + steps: + - uses: actions/checkout@v1 + - run: rustup toolchain install nightly --profile minimal --component rustfmt + - run: cargo +nightly fmt -- --check + + clippy: + name: "Clippy" + runs-on: ubuntu-latest + timeout-minutes: 10 + steps: + - uses: actions/checkout@v1 + - run: rustup toolchain install nightly --profile minimal --component clippy + - run: cargo +nightly clippy -- -D warnings From dadba2110c8f7f3d634b0c858176fbba904a3f3b Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Thu, 7 May 2020 10:38:59 +0200 Subject: [PATCH 023/108] Test workflow requires artifact from build workflow --- .github/workflows/build.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index d2660c4..daadafc 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -71,6 +71,7 @@ jobs: test: name: "Test" + needs: build strategy: matrix: From 970f8c3f7ed0c8622a81129fe03d53c98352acce Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Thu, 7 May 2020 10:40:05 +0200 Subject: [PATCH 024/108] Remove musl installation --- .github/workflows/build.yml | 6 ------ 1 file changed, 6 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index daadafc..1fb19aa 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -38,12 +38,6 @@ jobs: - name: Set Rustup profile to minimal run: rustup set profile minimal - - name: Install musl target on Linux - run: | - rustup target add x86_64-unknown-linux-musl - sudo apt-get install musl-tools musl-dev - if: runner.os == 'Linux' - - name: "Print Rust Version" run: | rustc -Vv From 79064d582b33bce8008277878ad146bd443e2b39 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Thu, 7 May 2020 10:43:40 +0200 Subject: [PATCH 025/108] CI: Install bootimage in release mode --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 1fb19aa..41c6c88 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -55,7 +55,7 @@ jobs: RUSTFLAGS: "-D warnings" - name: "Install it" - run: cargo install --path . --debug + run: cargo install --path . - name: "Upload Artifact" uses: actions/upload-artifact@v2 From ebfd09a23fe26259abc0773aa04f3dcccf2b2c3c Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Thu, 7 May 2020 10:53:19 +0200 Subject: [PATCH 026/108] Run cargo clippy --fix --- src/args/build.rs | 2 +- src/args/runner.rs | 4 ++-- src/bin/cargo-bootimage.rs | 2 +- src/builder/mod.rs | 4 ++-- src/config.rs | 12 ++++++------ src/main.rs | 6 ++---- 6 files changed, 14 insertions(+), 16 deletions(-) diff --git a/src/args/build.rs b/src/args/build.rs index 94e82cf..9cb0db9 100644 --- a/src/args/build.rs +++ b/src/args/build.rs @@ -32,7 +32,7 @@ impl BuildCommand { Ok(()) }; - let mut arg_iter = args.into_iter(); + let mut arg_iter = args; while let Some(arg) = arg_iter.next() { match arg.as_ref() { "--help" | "-h" => { diff --git a/src/args/runner.rs b/src/args/runner.rs index 1336853..32cf2a3 100644 --- a/src/args/runner.rs +++ b/src/args/runner.rs @@ -21,12 +21,12 @@ impl RunnerCommand { let mut quiet = false; let mut runner_args = None; - let mut arg_iter = args.into_iter().fuse(); + let mut arg_iter = args.fuse(); loop { if executable.is_some() { let args: Vec<_> = arg_iter.collect(); - if args.len() > 0 { + if !args.is_empty() { runner_args = Some(args); } break; diff --git a/src/bin/cargo-bootimage.rs b/src/bin/cargo-bootimage.rs index e335ea3..f767962 100644 --- a/src/bin/cargo-bootimage.rs +++ b/src/bin/cargo-bootimage.rs @@ -40,7 +40,7 @@ fn build(args: BuildArgs) -> Result<()> { let quiet = args.quiet(); let executables = builder.build_kernel(&args.cargo_args(), quiet)?; - if executables.len() == 0 { + if executables.is_empty() { return Err(anyhow!("no executables built")); } diff --git a/src/builder/mod.rs b/src/builder/mod.rs index be22687..28213fe 100644 --- a/src/builder/mod.rs +++ b/src/builder/mod.rs @@ -166,9 +166,9 @@ impl Builder { .replace(PathBuf::from(executable)) .is_some() { - Err(BootloaderError::BootloaderInvalid( + return Err(BootloaderError::BootloaderInvalid( "bootloader has multiple executables".into(), - ))?; + ).into()); } } } diff --git a/src/config.rs b/src/config.rs index 8768123..c8eac0d 100644 --- a/src/config.rs +++ b/src/config.rs @@ -67,7 +67,7 @@ fn read_config_inner(manifest_path: &Path) -> Result { for (key, value) in metadata { match (key.as_str(), value.clone()) { ("test-timeout", Value::Integer(timeout)) if timeout.is_negative() => { - Err(anyhow!("test-timeout must not be negative"))? + return Err(anyhow!("test-timeout must not be negative")) } ("test-timeout", Value::Integer(timeout)) => { config.test_timeout = Some(timeout as u32); @@ -80,7 +80,7 @@ fn read_config_inner(manifest_path: &Path) -> Result { for value in array { match value { Value::String(s) => command.push(s), - _ => Err(anyhow!("run-command must be a list of strings"))?, + _ => return Err(anyhow!("run-command must be a list of strings")), } } config.run_command = Some(command); @@ -90,7 +90,7 @@ fn read_config_inner(manifest_path: &Path) -> Result { for value in array { match value { Value::String(s) => args.push(s), - _ => Err(anyhow!("run-args must be a list of strings"))?, + _ => return Err(anyhow!("run-args must be a list of strings")), } } config.run_args = Some(args); @@ -100,17 +100,17 @@ fn read_config_inner(manifest_path: &Path) -> Result { for value in array { match value { Value::String(s) => args.push(s), - _ => Err(anyhow!("test-args must be a list of strings"))?, + _ => return Err(anyhow!("test-args must be a list of strings")), } } config.test_args = Some(args); } - (key, value) => Err(anyhow!( + (key, value) => return Err(anyhow!( "unexpected `package.metadata.bootimage` \ key `{}` with value `{}`", key, value - ))?, + )), } } Ok(config.into()) diff --git a/src/main.rs b/src/main.rs index 8a9c759..b52fda1 100644 --- a/src/main.rs +++ b/src/main.rs @@ -104,10 +104,8 @@ pub(crate) fn runner(args: RunnerArgs) -> Result { if let Some(args) = config.test_args { run_command.extend(args); } - } else { - if let Some(args) = config.run_args { - run_command.extend(args); - } + } else if let Some(args) = config.run_args { + run_command.extend(args); } if let Some(args) = args.runner_args { run_command.extend(args); From e88d3401d8923b3d10e026ab629d549983b8df77 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Thu, 7 May 2020 10:59:59 +0200 Subject: [PATCH 027/108] Fix remaining clippy warnings --- src/args/runner.rs | 2 +- src/bin/cargo-bootimage.rs | 17 +++++++++++------ src/builder/bootloader.rs | 6 +++--- src/builder/mod.rs | 4 ++-- src/config.rs | 4 ++-- src/main.rs | 14 +++++++------- 6 files changed, 26 insertions(+), 21 deletions(-) diff --git a/src/args/runner.rs b/src/args/runner.rs index 32cf2a3..66c1407 100644 --- a/src/args/runner.rs +++ b/src/args/runner.rs @@ -52,7 +52,7 @@ impl RunnerCommand { } Ok(Self::Runner(RunnerArgs { - executable: executable.ok_or(anyhow!( + executable: executable.ok_or_else(|| anyhow!( "excepted path to kernel executable as first argument" ))?, quiet, diff --git a/src/bin/cargo-bootimage.rs b/src/bin/cargo-bootimage.rs index f767962..c7f3218 100644 --- a/src/bin/cargo-bootimage.rs +++ b/src/bin/cargo-bootimage.rs @@ -14,7 +14,7 @@ pub fn main() -> Result<()> { let executable_name = raw_args .next() - .ok_or(anyhow!("no first argument (executable name)"))?; + .ok_or_else(|| anyhow!("no first argument (executable name)"))?; let file_stem = Path::new(&executable_name) .file_stem() .and_then(|s| s.to_str()); @@ -30,8 +30,13 @@ pub fn main() -> Result<()> { match BuildCommand::parse_args(raw_args)? { BuildCommand::Build(args) => build(args), - BuildCommand::Version => Ok(help::print_version()), - BuildCommand::Help => Ok(help::print_cargo_bootimage_help()), + BuildCommand::Version => { + help::print_version(); Ok(()) + }, + BuildCommand::Help => { + help::print_cargo_bootimage_help(); + Ok(()) + }, } } @@ -47,12 +52,12 @@ fn build(args: BuildArgs) -> Result<()> { for executable in executables { let out_dir = executable .parent() - .ok_or(anyhow!("executable has no parent path"))?; + .ok_or_else(|| anyhow!("executable has no parent path"))?; let bin_name = &executable .file_stem() - .ok_or(anyhow!("executable has no file stem"))? + .ok_or_else(|| anyhow!("executable has no file stem"))? .to_str() - .ok_or(anyhow!("executable file stem not valid utf8"))?; + .ok_or_else(|| anyhow!("executable file stem not valid utf8"))?; let bootimage_path = out_dir.join(format!("bootimage-{}.bin", bin_name)); builder.create_bootimage(bin_name, &executable, &bootimage_path, quiet)?; diff --git a/src/builder/bootloader.rs b/src/builder/bootloader.rs index 526dd11..2fb6a2e 100644 --- a/src/builder/bootloader.rs +++ b/src/builder/bootloader.rs @@ -29,7 +29,7 @@ impl BuildConfig { bootloader_pkg .manifest_path .parent() - .ok_or(BootloaderError::BootloaderInvalid( + .ok_or_else(|| BootloaderError::BootloaderInvalid( "bootloader manifest has no target directory".into(), ))?; @@ -47,7 +47,7 @@ impl BuildConfig { let target_str = target .and_then(|v| v.as_str()) - .ok_or(BootloaderError::BootloaderInvalid( + .ok_or_else(|| BootloaderError::BootloaderInvalid( "No `package.metadata.bootloader.target` key found in Cargo.toml of bootloader\n\n\ (If you're using the official bootloader crate, you need at least version 0.5.1)" .into(), @@ -93,7 +93,7 @@ impl BuildConfig { /// Creates the cargo build command for building the bootloader. pub fn build_command(&self) -> Command { - let cargo = std::env::var("CARGO").unwrap_or("cargo".to_owned()); + let cargo = std::env::var("CARGO").unwrap_or_else(|_| "cargo".to_owned()); let mut cmd = Command::new(&cargo); cmd.arg("xbuild"); cmd.arg("--manifest-path"); diff --git a/src/builder/mod.rs b/src/builder/mod.rs index 28213fe..f147810 100644 --- a/src/builder/mod.rs +++ b/src/builder/mod.rs @@ -48,7 +48,7 @@ impl Builder { } // try to run cargo xbuild - let cargo = std::env::var("CARGO").unwrap_or("cargo".to_owned()); + let cargo = std::env::var("CARGO").unwrap_or_else(|_| "cargo".to_owned()); let mut cmd = process::Command::new(&cargo); cmd.arg("xbuild"); cmd.args(args); @@ -172,7 +172,7 @@ impl Builder { } } } - let bootloader_elf_path = bootloader_elf_path.ok_or(BootloaderError::BootloaderInvalid( + let bootloader_elf_path = bootloader_elf_path.ok_or_else(|| BootloaderError::BootloaderInvalid( "bootloader has no executable".into(), ))?; diff --git a/src/config.rs b/src/config.rs index c8eac0d..4babe57 100644 --- a/src/config.rs +++ b/src/config.rs @@ -59,7 +59,7 @@ fn read_config_inner(manifest_path: &Path) -> Result { } Some(metadata) => metadata .as_table() - .ok_or(anyhow!("Bootimage configuration invalid: {:?}", metadata))?, + .ok_or_else(|| anyhow!("Bootimage configuration invalid: {:?}", metadata))?, }; let mut config = ConfigBuilder::default(); @@ -128,7 +128,7 @@ struct ConfigBuilder { impl Into for ConfigBuilder { fn into(self) -> Config { Config { - run_command: self.run_command.unwrap_or(vec![ + run_command: self.run_command.unwrap_or_else(|| vec![ "qemu-system-x86_64".into(), "-drive".into(), "format=raw,file={}".into(), diff --git a/src/main.rs b/src/main.rs index b52fda1..e4cb9c3 100644 --- a/src/main.rs +++ b/src/main.rs @@ -14,7 +14,7 @@ pub fn main() -> Result<()> { let executable_name = raw_args .next() - .ok_or(anyhow!("no first argument (executable name)"))?; + .ok_or_else(|| anyhow!("no first argument (executable name)"))?; let file_stem = Path::new(&executable_name) .file_stem() .and_then(|s| s.to_str()); @@ -63,12 +63,12 @@ pub(crate) fn runner(args: RunnerArgs) -> Result { let exe_parent = args .executable .parent() - .ok_or(anyhow!("kernel executable has no parent"))?; + .ok_or_else(|| anyhow!("kernel executable has no parent"))?; let is_doctest = exe_parent .file_name() - .ok_or(anyhow!("kernel executable's parent has no file name"))? + .ok_or_else(|| anyhow!("kernel executable's parent has no file name"))? .to_str() - .ok_or(anyhow!( + .ok_or_else(|| anyhow!( "kernel executable's parent file name is not valid UTF-8" ))? .starts_with("rustdoctest"); @@ -77,9 +77,9 @@ pub(crate) fn runner(args: RunnerArgs) -> Result { let bin_name = args .executable .file_stem() - .ok_or(anyhow!("kernel executable has no file stem"))? + .ok_or_else(|| anyhow!("kernel executable has no file stem"))? .to_str() - .ok_or(anyhow!("kernel executable file stem is not valid UTF-8"))?; + .ok_or_else(|| anyhow!("kernel executable file stem is not valid UTF-8"))?; let output_bin_path = exe_parent.join(format!("bootimage-{}.bin", bin_name)); let executable_canonicalized = args.executable.canonicalize().with_context(|| { @@ -143,7 +143,7 @@ pub(crate) fn runner(args: RunnerArgs) -> Result { } let qemu_exit_code = exit_status .code() - .ok_or(anyhow!("Failed to read QEMU exit code"))?; + .ok_or_else(|| anyhow!("Failed to read QEMU exit code"))?; match config.test_success_exit_code { Some(code) if qemu_exit_code == code => 0, _ => qemu_exit_code, From 120d6e6be04c3b71c33a547a4bb7483a9fd36f3d Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Thu, 7 May 2020 11:00:23 +0200 Subject: [PATCH 028/108] Run cargo fmt --- src/args/runner.rs | 5 ++--- src/bin/cargo-bootimage.rs | 7 ++++--- src/builder/bootloader.rs | 19 +++++++------------ src/builder/mod.rs | 9 +++++---- src/config.rs | 24 ++++++++++++++---------- src/main.rs | 4 +--- 6 files changed, 33 insertions(+), 35 deletions(-) diff --git a/src/args/runner.rs b/src/args/runner.rs index 66c1407..bfaf2ed 100644 --- a/src/args/runner.rs +++ b/src/args/runner.rs @@ -52,9 +52,8 @@ impl RunnerCommand { } Ok(Self::Runner(RunnerArgs { - executable: executable.ok_or_else(|| anyhow!( - "excepted path to kernel executable as first argument" - ))?, + executable: executable + .ok_or_else(|| anyhow!("excepted path to kernel executable as first argument"))?, quiet, runner_args, })) diff --git a/src/bin/cargo-bootimage.rs b/src/bin/cargo-bootimage.rs index c7f3218..3359c3c 100644 --- a/src/bin/cargo-bootimage.rs +++ b/src/bin/cargo-bootimage.rs @@ -31,12 +31,13 @@ pub fn main() -> Result<()> { match BuildCommand::parse_args(raw_args)? { BuildCommand::Build(args) => build(args), BuildCommand::Version => { - help::print_version(); Ok(()) - }, + help::print_version(); + Ok(()) + } BuildCommand::Help => { help::print_cargo_bootimage_help(); Ok(()) - }, + } } } diff --git a/src/builder/bootloader.rs b/src/builder/bootloader.rs index 2fb6a2e..c2cbc97 100644 --- a/src/builder/bootloader.rs +++ b/src/builder/bootloader.rs @@ -25,13 +25,9 @@ impl BuildConfig { ) -> Result { let kernel_pkg = kernel_package(project_metadata, kernel_bin_name)?; let bootloader_pkg = bootloader_package(project_metadata, kernel_pkg)?; - let bootloader_root = - bootloader_pkg - .manifest_path - .parent() - .ok_or_else(|| BootloaderError::BootloaderInvalid( - "bootloader manifest has no target directory".into(), - ))?; + let bootloader_root = bootloader_pkg.manifest_path.parent().ok_or_else(|| { + BootloaderError::BootloaderInvalid("bootloader manifest has no target directory".into()) + })?; let cargo_toml_content = fs::read_to_string(&bootloader_pkg.manifest_path) .map_err(|err| format!("bootloader has no valid Cargo.toml: {}", err)) @@ -44,14 +40,13 @@ impl BuildConfig { let target = metadata .and_then(|t| t.get("bootloader")) .and_then(|t| t.get("target")); - let target_str = - target - .and_then(|v| v.as_str()) - .ok_or_else(|| BootloaderError::BootloaderInvalid( + let target_str = target.and_then(|v| v.as_str()).ok_or_else(|| { + BootloaderError::BootloaderInvalid( "No `package.metadata.bootloader.target` key found in Cargo.toml of bootloader\n\n\ (If you're using the official bootloader crate, you need at least version 0.5.1)" .into(), - ))?; + ) + })?; let binary_feature = cargo_toml .get("features") diff --git a/src/builder/mod.rs b/src/builder/mod.rs index f147810..d6a1b54 100644 --- a/src/builder/mod.rs +++ b/src/builder/mod.rs @@ -168,13 +168,14 @@ impl Builder { { return Err(BootloaderError::BootloaderInvalid( "bootloader has multiple executables".into(), - ).into()); + ) + .into()); } } } - let bootloader_elf_path = bootloader_elf_path.ok_or_else(|| BootloaderError::BootloaderInvalid( - "bootloader has no executable".into(), - ))?; + let bootloader_elf_path = bootloader_elf_path.ok_or_else(|| { + BootloaderError::BootloaderInvalid("bootloader has no executable".into()) + })?; disk_image::create_disk_image(&bootloader_elf_path, output_bin_path)?; diff --git a/src/config.rs b/src/config.rs index 4babe57..44479d6 100644 --- a/src/config.rs +++ b/src/config.rs @@ -105,12 +105,14 @@ fn read_config_inner(manifest_path: &Path) -> Result { } config.test_args = Some(args); } - (key, value) => return Err(anyhow!( - "unexpected `package.metadata.bootimage` \ + (key, value) => { + return Err(anyhow!( + "unexpected `package.metadata.bootimage` \ key `{}` with value `{}`", - key, - value - )), + key, + value + )) + } } } Ok(config.into()) @@ -128,11 +130,13 @@ struct ConfigBuilder { impl Into for ConfigBuilder { fn into(self) -> Config { Config { - run_command: self.run_command.unwrap_or_else(|| vec![ - "qemu-system-x86_64".into(), - "-drive".into(), - "format=raw,file={}".into(), - ]), + run_command: self.run_command.unwrap_or_else(|| { + vec![ + "qemu-system-x86_64".into(), + "-drive".into(), + "format=raw,file={}".into(), + ] + }), run_args: self.run_args, test_args: self.test_args, test_timeout: self.test_timeout.unwrap_or(60 * 5), diff --git a/src/main.rs b/src/main.rs index e4cb9c3..154b047 100644 --- a/src/main.rs +++ b/src/main.rs @@ -68,9 +68,7 @@ pub(crate) fn runner(args: RunnerArgs) -> Result { .file_name() .ok_or_else(|| anyhow!("kernel executable's parent has no file name"))? .to_str() - .ok_or_else(|| anyhow!( - "kernel executable's parent file name is not valid UTF-8" - ))? + .ok_or_else(|| anyhow!("kernel executable's parent file name is not valid UTF-8"))? .starts_with("rustdoctest"); let is_test = is_doctest || exe_parent.ends_with("deps"); From 25ff3d9a49daea4601fff9b362ac7aa9e848ffda Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Thu, 7 May 2020 11:16:41 +0200 Subject: [PATCH 029/108] Try to fix artifact upload/download --- .github/workflows/build.yml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 41c6c88..008836a 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -61,7 +61,7 @@ jobs: uses: actions/upload-artifact@v2 with: name: ${{ env.name }}-bootimage - path: ~/.cargo/bin/bootimage + path: ~/.cargo/bin/ test: name: "Test" @@ -86,7 +86,10 @@ jobs: uses: actions/download-artifact@v2 with: name: ${{ env.name }}-bootimage - path: ~/.cargo/bin/bootimage + path: bin/ + + - name: "Add `bin` to PATH" + run: echo ::add-path::bin - name: Install Rustup (macOS) run: | From 2c914334f4e2ad7447bf606e3b8c0e238b4b3224 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Thu, 7 May 2020 11:23:37 +0200 Subject: [PATCH 030/108] CI: Merge build and test jobs to avoid artifact upload --- .github/workflows/build.yml | 45 ++++--------------------------------- 1 file changed, 4 insertions(+), 41 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 008836a..9ef3d95 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -11,8 +11,8 @@ on: pull_request: jobs: - build: - name: "Build" + test: + name: "Test" strategy: matrix: @@ -57,45 +57,8 @@ jobs: - name: "Install it" run: cargo install --path . - - name: "Upload Artifact" - uses: actions/upload-artifact@v2 - with: - name: ${{ env.name }}-bootimage - path: ~/.cargo/bin/ - - test: - name: "Test" - needs: build - - strategy: - matrix: - platform: [ - ubuntu-latest, - macos-latest, - windows-latest - ] - - runs-on: ${{ matrix.platform }} - timeout-minutes: 15 - - steps: - - name: "Checkout Repository" - uses: actions/checkout@v1 - - - name: "Download Bootimage Artifact" - uses: actions/download-artifact@v2 - with: - name: ${{ env.name }}-bootimage - path: bin/ - - - name: "Add `bin` to PATH" - run: echo ::add-path::bin - - - name: Install Rustup (macOS) - run: | - curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y - echo ::add-path::$HOME/.cargo/bin - if: runner.os == 'macOS' + - name: "Switch to Rust nightly" + run: rustup default nightly - name: "Install Rustup Components" run: rustup component add rust-src llvm-tools-preview From 224dfdb433694d7568016e1ccf8a0abceca373f3 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Thu, 7 May 2020 12:18:16 +0200 Subject: [PATCH 031/108] Remove old examples kernels from workspace definition --- example-kernels/Cargo.toml | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/example-kernels/Cargo.toml b/example-kernels/Cargo.toml index e2ee131..3375f98 100644 --- a/example-kernels/Cargo.toml +++ b/example-kernels/Cargo.toml @@ -1,11 +1,7 @@ [workspace] members = [ "basic", - "default-target-bootimage", - "default-target-cargo", "runner", "runner-doctest", "runner-test", - "testing-qemu-exit-code", - "testing-serial-result", -] \ No newline at end of file +] From 5063af713250644b6a95da44a1cbebe7105cdba2 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Thu, 7 May 2020 12:18:38 +0200 Subject: [PATCH 032/108] Move runner code into new `run` module --- src/lib.rs | 1 + src/main.rs | 67 ++---------------------- src/run.rs | 143 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 147 insertions(+), 64 deletions(-) create mode 100644 src/run.rs diff --git a/src/lib.rs b/src/lib.rs index 2e2d74d..d682726 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -7,6 +7,7 @@ pub mod args; pub mod builder; pub mod config; +pub mod run; /// Contains help messages for the command line application. pub mod help; diff --git a/src/main.rs b/src/main.rs index 154b047..7a126a8 100644 --- a/src/main.rs +++ b/src/main.rs @@ -3,11 +3,10 @@ use anyhow::{anyhow, Context, Result}; use bootimage::{ args::{RunnerArgs, RunnerCommand}, builder::Builder, - config, help, + config, help, run, }; +use std::process; use std::{env, path::Path}; -use std::{process, time::Duration}; -use wait_timeout::ChildExt; pub fn main() -> Result<()> { let mut raw_args = env::args(); @@ -93,67 +92,7 @@ pub(crate) fn runner(args: RunnerArgs) -> Result { args.quiet, )?; - let mut run_command: Vec<_> = config - .run_command - .iter() - .map(|arg| arg.replace("{}", &format!("{}", output_bin_path.display()))) - .collect(); - if is_test { - if let Some(args) = config.test_args { - run_command.extend(args); - } - } else if let Some(args) = config.run_args { - run_command.extend(args); - } - if let Some(args) = args.runner_args { - run_command.extend(args); - } - - if !args.quiet { - println!("Running: `{}`", run_command.join(" ")); - } - let mut command = process::Command::new(&run_command[0]); - command.args(&run_command[1..]); - - let exit_code = if is_test { - let mut child = command - .spawn() - .with_context(|| format!("Failed to launch QEMU: {:?}", command))?; - let timeout = Duration::from_secs(config.test_timeout.into()); - match child - .wait_timeout(timeout) - .context("Failed to wait with timeout")? - { - None => { - child.kill().context("Failed to kill QEMU")?; - child.wait().context("Failed to wait for QEMU process")?; - return Err(anyhow!("Timed Out")); - } - Some(exit_status) => { - #[cfg(unix)] - { - if exit_status.code().is_none() { - use std::os::unix::process::ExitStatusExt; - if let Some(signal) = exit_status.signal() { - eprintln!("QEMU process was terminated by signal {}", signal); - } - } - } - let qemu_exit_code = exit_status - .code() - .ok_or_else(|| anyhow!("Failed to read QEMU exit code"))?; - match config.test_success_exit_code { - Some(code) if qemu_exit_code == code => 0, - _ => qemu_exit_code, - } - } - } - } else { - let status = command - .status() - .with_context(|| format!("Failed to execute `{:?}`", command))?; - status.code().unwrap_or(1) - }; + let exit_code = run::run(config, args, &output_bin_path, is_test)?; Ok(exit_code) } diff --git a/src/run.rs b/src/run.rs new file mode 100644 index 0000000..7ca4f30 --- /dev/null +++ b/src/run.rs @@ -0,0 +1,143 @@ +//! Provides a function for running a disk image in QEMU. + +use crate::{args::RunnerArgs, config::Config}; +use std::{io, path::Path, process, time::Duration}; +use thiserror::Error; +use wait_timeout::ChildExt; + +/// Run the given disk image in QEMU. +/// +/// Automatically takes into account the runner arguments and the run/test +/// commands defined in the given `Config`. Since test executables are treated +/// differently (run with a timeout and match exit status), the caller needs to +/// specify whether the given disk image is a test or not. +pub fn run( + config: Config, + args: RunnerArgs, + image_path: &Path, + is_test: bool, +) -> Result { + let mut run_command: Vec<_> = config + .run_command + .iter() + .map(|arg| arg.replace("{}", &format!("{}", image_path.display()))) + .collect(); + if is_test { + if let Some(args) = config.test_args { + run_command.extend(args); + } + } else if let Some(args) = config.run_args { + run_command.extend(args); + } + if let Some(args) = args.runner_args { + run_command.extend(args); + } + + if !args.quiet { + println!("Running: `{}`", run_command.join(" ")); + } + let mut command = process::Command::new(&run_command[0]); + command.args(&run_command[1..]); + + let exit_code = if is_test { + let mut child = command.spawn().map_err(|error| RunError::Io { + context: IoErrorContext::QemuTestCommand { + command: format!("{:?}", command), + }, + error, + })?; + let timeout = Duration::from_secs(config.test_timeout.into()); + match child + .wait_timeout(timeout) + .map_err(context(IoErrorContext::WaitWithTimeout))? + { + None => { + child.kill().map_err(context(IoErrorContext::KillQemu))?; + child.wait().map_err(context(IoErrorContext::WaitForQemu))?; + return Err(RunError::TestTimedOut); + } + Some(exit_status) => { + #[cfg(unix)] + { + if exit_status.code().is_none() { + use std::os::unix::process::ExitStatusExt; + if let Some(signal) = exit_status.signal() { + eprintln!("QEMU process was terminated by signal {}", signal); + } + } + } + let qemu_exit_code = exit_status.code().ok_or(RunError::NoQemuExitCode)?; + match config.test_success_exit_code { + Some(code) if qemu_exit_code == code => 0, + _ => qemu_exit_code, + } + } + } + } else { + let status = command.status().map_err(|error| RunError::Io { + context: IoErrorContext::QemuRunCommand { + command: format!("{:?}", command), + }, + error, + })?; + status.code().unwrap_or(1) + }; + + Ok(exit_code) +} + +/// Running the disk image failed. +#[derive(Debug, Error)] +pub enum RunError { + /// Test timed out + #[error("Test timed out")] + TestTimedOut, + + /// Failed to read QEMU exit code + #[error("Failed to read QEMU exit code")] + NoQemuExitCode, + + /// An I/O error occured + #[error("{context}: An I/O error occured: {error}")] + Io { + /// The operation that caused the I/O error. + context: IoErrorContext, + /// The I/O error that occured. + error: io::Error, + }, +} + +/// An I/O error occured while trying to run the disk image. +#[derive(Debug, Error)] +pub enum IoErrorContext { + /// QEMU command for non-test failed + #[error("Failed to execute QEMU run command `{command}`")] + QemuRunCommand { + /// The QEMU command that was executed + command: String, + }, + + /// QEMU command for test failed + #[error("Failed to execute QEMU test command `{command}`")] + QemuTestCommand { + /// The QEMU command that was executed + command: String, + }, + + /// Waiting for test with timeout failed + #[error("Failed to wait with timeout")] + WaitWithTimeout, + + /// Failed to kill QEMU + #[error("Failed to kill QEMU")] + KillQemu, + + /// Failed to wait for QEMU process + #[error("Failed to wait for QEMU process")] + WaitForQemu, +} + +/// Helper function for IO error construction +fn context(context: IoErrorContext) -> impl FnOnce(io::Error) -> RunError { + |error| RunError::Io { context, error } +} From f1f994a367b0e2759ab2874b3ead02cfe8ce2418 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Thu, 7 May 2020 12:27:17 +0200 Subject: [PATCH 033/108] Ci: Disable `set -e o pipefail` for commands that are expeted to return non-zero exit code --- .github/workflows/build.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 9ef3d95..6c406db 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -100,14 +100,14 @@ jobs: run: | qemu-system-x86_64 -drive format=raw,file=target/x86_64-bootimage-example-kernels/debug/bootimage-basic.bin -device isa-debug-exit,iobase=0xf4,iosize=0x04 -display none if [ $? -eq 103 ]; then (exit 0); else (exit 1); fi - shell: bash + shell: bash {0} working-directory: example-kernels - name: 'Run `cargo xrun` for "runner" kernel' run: | cargo xrun if [ $? -eq 109 ]; then (exit 0); else (exit 1); fi - shell: bash + shell: bash {0} working-directory: example-kernels/runner - run: cargo xtest -Z doctest-xcompile From e34e8e9aeed1fc7965b64e52332aefb0ba931b68 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Thu, 7 May 2020 13:36:08 +0200 Subject: [PATCH 034/108] Fix `Builder::kernel_package` for tests and doctests --- src/builder/bootloader.rs | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/src/builder/bootloader.rs b/src/builder/bootloader.rs index c2cbc97..e0e2326 100644 --- a/src/builder/bootloader.rs +++ b/src/builder/bootloader.rs @@ -115,13 +115,35 @@ fn kernel_package<'a>( project_metadata: &'a Metadata, kernel_bin_name: &str, ) -> Result<&'a Package, BootloaderError> { + // look for exact match with binary name first let contains_bin = |p: &&Package| { p.targets .iter() .any(|t| t.name == kernel_bin_name && t.kind.iter().any(|k| k == "bin")) }; - let bin_metadata_opt = project_metadata.packages.iter().find(contains_bin); - bin_metadata_opt.ok_or_else(|| BootloaderError::KernelBinPackageNotFound { + let package = project_metadata.packages.iter().find(contains_bin); + + // then look for exact match with integration test binary + let contains_test_bin = |p: &&Package| { + p.targets + .iter() + .any(|t| t.name == kernel_bin_name && t.kind.iter().any(|k| k == "test")) + }; + let package = package.or_else(|| project_metadata.packages.iter().find(contains_test_bin)); + + // then look for match with appended hash (e.g. for library tests) + let contains_test = |p: &&Package| { + let package_name = match kernel_bin_name.rsplitn(2, "-").skip(1).next() { + Some(name) => name, + None => return false, + }; + p.targets + .iter() + .any(|t| t.name.replace("-", "_") == package_name) + }; + let package = package.or_else(|| project_metadata.packages.iter().find(contains_test)); + + package.ok_or_else(|| BootloaderError::KernelBinPackageNotFound { bin_name: kernel_bin_name.to_owned(), }) } From 4058c546eaab3daa2ca2cc4c43501185676d9fe2 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Thu, 7 May 2020 13:42:19 +0200 Subject: [PATCH 035/108] Update dependencies for example kernels --- example-kernels/Cargo.lock | 361 +--------------------- example-kernels/basic/Cargo.toml | 4 +- example-kernels/runner-doctest/Cargo.toml | 4 +- example-kernels/runner-test/Cargo.toml | 4 +- example-kernels/runner/Cargo.toml | 4 +- 5 files changed, 20 insertions(+), 357 deletions(-) diff --git a/example-kernels/Cargo.lock b/example-kernels/Cargo.lock index c04784c..daaa6e5 100644 --- a/example-kernels/Cargo.lock +++ b/example-kernels/Cargo.lock @@ -1,19 +1,11 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -[[package]] -name = "array-init" -version = "0.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "basic" version = "0.1.0" dependencies = [ - "bootloader 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", - "x86_64 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", + "bootloader 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)", + "x86_64 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -28,373 +20,44 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "bootloader" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "fixedvec 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "llvm-tools 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "usize_conversions 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "x86_64 0.7.7 (registry+https://github.com/rust-lang/crates.io-index)", - "xmas-elf 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "cast" -version = "0.2.2" +version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "cc" -version = "1.0.37" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "default-target-bootimage" -version = "0.1.0" -dependencies = [ - "bootloader 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", - "x86_64 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "default-target-cargo" -version = "0.1.0" -dependencies = [ - "bootloader 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", - "x86_64 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "fixedvec" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "skeptic 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "fuchsia-cprng" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "getopts" -version = "0.2.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "lazy_static" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "spin 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "libc" -version = "0.2.60" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "llvm-tools" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "nodrop" -version = "0.1.13" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "os_bootinfo" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "pulldown-cmark" -version = "0.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "getopts 0.2.19 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "rand" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "rand_core" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "rand_core" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "raw-cpuid" -version = "6.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "cc 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "rdrand" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "remove_dir_all" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "runner" version = "0.1.0" dependencies = [ - "bootloader 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", - "x86_64 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", + "bootloader 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)", + "x86_64 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "runner-doctest" version = "0.1.0" dependencies = [ - "bootloader 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", - "x86_64 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", + "bootloader 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)", + "x86_64 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "runner-test" version = "0.1.0" dependencies = [ - "bootloader 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", - "x86_64 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "rustc_version" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "semver" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "semver-parser" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "skeptic" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "pulldown-cmark 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", - "tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "spin" -version = "0.4.10" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "spin" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "tempdir" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "rand 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "remove_dir_all 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "testing-qemu-exit-code" -version = "0.1.0" -dependencies = [ - "bootloader 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", - "x86_64 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "testing-serial-result" -version = "0.1.0" -dependencies = [ - "bootloader 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "spin 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", - "uart_16550 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "x86_64 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "uart_16550" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "x86_64 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "unicode-width" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "usize_conversions" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "ux" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "winapi" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "x86_64" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "bit_field 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", - "bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "os_bootinfo 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "usize_conversions 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "ux 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "x86_64" -version = "0.5.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "array-init 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "bit_field 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", - "bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "cast 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "raw-cpuid 6.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "ux 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "bootloader 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)", + "x86_64 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "x86_64" -version = "0.7.7" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "array-init 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "bit_field 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "cast 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "ux 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "xmas-elf" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "zero 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "zero" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" - [metadata] -"checksum array-init 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "23589ecb866b460d3a0f1278834750268c607e8e28a1b982c907219f3178cd72" "checksum bit_field 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ed8765909f9009617974ab6b7d332625b320b33c326b1e9321382ef1999b5d56" "checksum bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3d155346769a6855b86399e9bc3814ab343cd3d62c7e985113d46a0ec3c281fd" -"checksum bootloader 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b15e5b7b9d9a8e427cf4270894f51ce288632a3a1a2cc6f8fda669d5446f98bd" -"checksum cast 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "926013f2860c46252efceabb19f4a6b308197505082c609025aa6706c011d427" -"checksum cc 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)" = "39f75544d7bbaf57560d2168f28fd649ff9c76153874db88bdbdfd839b1a7e7d" -"checksum fixedvec 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7c6c16d316ccdac21a4dd648e314e76facbbaf316e83ca137d0857a9c07419d0" -"checksum fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" -"checksum getopts 0.2.19 (registry+https://github.com/rust-lang/crates.io-index)" = "72327b15c228bfe31f1390f93dd5e9279587f0463836393c9df719ce62a3e450" -"checksum lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bc5729f27f159ddd61f4df6228e827e86643d4d3e7c32183cb30a1c08f604a14" -"checksum libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)" = "d44e80633f007889c7eff624b709ab43c92d708caad982295768a7b13ca3b5eb" -"checksum llvm-tools 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "955be5d0ca0465caf127165acb47964f911e2bc26073e865deb8be7189302faf" -"checksum nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "2f9667ddcc6cc8a43afc9b7917599d7216aa09c463919ea32c59ed6cac8bc945" -"checksum os_bootinfo 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "66481dbeb5e773e7bd85b63cd6042c30786f834338288c5ec4f3742673db360a" -"checksum pulldown-cmark 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8361e81576d2e02643b04950e487ec172b687180da65c731c03cf336784e6c07" -"checksum rand 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "552840b97013b1a26992c11eac34bdd778e464601a4c2054b5f0bff7c6761293" -"checksum rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" -"checksum rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d0e7a549d590831370895ab7ba4ea0c1b6b011d106b5ff2da6eee112615e6dc0" -"checksum raw-cpuid 6.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "30a9d219c32c9132f7be513c18be77c9881c7107d2ab5569d205a6a0f0e6dc7d" -"checksum rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" -"checksum remove_dir_all 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4a83fa3702a688b9359eccba92d153ac33fd2e8462f9e0e3fdf155239ea7792e" -"checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" -"checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" -"checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" -"checksum skeptic 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "061203a849117b0f7090baf8157aa91dac30545208fbb85166ac58b4ca33d89c" -"checksum spin 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)" = "ceac490aa12c567115b40b7b7fceca03a6c9d53d5defea066123debc83c5dc1f" -"checksum spin 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "44363f6f51401c34e7be73db0db371c04705d35efbe9f7d6082e03a921a32c55" -"checksum tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "15f2b5fb00ccdf689e0149d1b1b3c03fead81c2b37735d812fa8bddbbf41b6d8" -"checksum uart_16550 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "269f953d8de3226f7c065c589c7b4a3e83d10a419c7c3b5e2e0f197e6acc966e" -"checksum unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "882386231c45df4700b275c7ff55b6f3698780a650026380e72dabe76fa46526" -"checksum usize_conversions 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f70329e2cbe45d6c97a5112daad40c34cd9a4e18edb5a2a18fefeb584d8d25e5" -"checksum ux 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "88dfeb711b61ce620c0cb6fd9f8e3e678622f0c971da2a63c4b3e25e88ed012f" -"checksum winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "f10e386af2b13e47c89e7236a7a14a086791a2b88ebad6df9bf42040195cf770" -"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" -"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" -"checksum x86_64 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "2bd647af1614659e1febec1d681231aea4ebda4818bf55a578aff02f3e4db4b4" -"checksum x86_64 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)" = "bb8f09c32a991cc758ebcb9b7984f530095d32578a4e7b85db6ee1f0bbe4c9c6" -"checksum x86_64 0.7.7 (registry+https://github.com/rust-lang/crates.io-index)" = "1f27d9168654aee1b0c1b73746caeb4aa33248f8b8c8f6e100e697fcc2a794b2" -"checksum xmas-elf 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "22678df5df766e8d1e5d609da69f0c3132d794edf6ab5e75e7abcd2270d4cf58" -"checksum zero 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "5f1bc8a6b2005884962297587045002d8cfb8dcec9db332f4ca216ddc5de82c5" +"checksum bootloader 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dd5c4922d54a9033cfdf75d4fd23945461e9d2c1d979c8f5b237e5471f11dddc" +"checksum x86_64 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)" = "074fe17c2586dd646602287854514c5cb3b6c3b5e63cd3970ecddbbb9c01468d" diff --git a/example-kernels/basic/Cargo.toml b/example-kernels/basic/Cargo.toml index 76b9db0..81c7a14 100644 --- a/example-kernels/basic/Cargo.toml +++ b/example-kernels/basic/Cargo.toml @@ -5,5 +5,5 @@ authors = ["Philipp Oppermann "] edition = "2018" [dependencies] -bootloader = "0.6.4" -x86_64 = "0.5.3" +bootloader = "0.9.2" +x86_64 = "0.10.2" diff --git a/example-kernels/runner-doctest/Cargo.toml b/example-kernels/runner-doctest/Cargo.toml index d3c440f..9f3dce2 100644 --- a/example-kernels/runner-doctest/Cargo.toml +++ b/example-kernels/runner-doctest/Cargo.toml @@ -5,8 +5,8 @@ authors = ["Philipp Oppermann "] edition = "2018" [dependencies] -bootloader = "0.6.4" -x86_64 = "0.5.3" +bootloader = "0.9.2" +x86_64 = "0.10.2" [package.metadata.bootimage] test-success-exit-code = 33 # (0x10 << 1) | 1 diff --git a/example-kernels/runner-test/Cargo.toml b/example-kernels/runner-test/Cargo.toml index 27989c8..8a80f76 100644 --- a/example-kernels/runner-test/Cargo.toml +++ b/example-kernels/runner-test/Cargo.toml @@ -9,8 +9,8 @@ name = "no-harness" harness = false [dependencies] -bootloader = "0.6.4" -x86_64 = "0.5.3" +bootloader = "0.9.2" +x86_64 = "0.10.2" [package.metadata.bootimage] test-success-exit-code = 33 # (0x10 << 1) | 1 diff --git a/example-kernels/runner/Cargo.toml b/example-kernels/runner/Cargo.toml index 7b5de79..bd79c4d 100644 --- a/example-kernels/runner/Cargo.toml +++ b/example-kernels/runner/Cargo.toml @@ -5,8 +5,8 @@ authors = ["Philipp Oppermann "] edition = "2018" [dependencies] -bootloader = "0.6.4" -x86_64 = "0.5.3" +bootloader = "0.9.2" +x86_64 = "0.10.2" [package.metadata.bootimage] run-args = ["-device", "isa-debug-exit,iobase=0xf4,iosize=0x04", "-display", "none"] From b6649fcc6101b1cdd496656d621cb7e21b7d5fef Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Thu, 7 May 2020 13:47:11 +0200 Subject: [PATCH 036/108] Apply clippy suggestions --- src/builder/bootloader.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/builder/bootloader.rs b/src/builder/bootloader.rs index e0e2326..984b209 100644 --- a/src/builder/bootloader.rs +++ b/src/builder/bootloader.rs @@ -133,7 +133,7 @@ fn kernel_package<'a>( // then look for match with appended hash (e.g. for library tests) let contains_test = |p: &&Package| { - let package_name = match kernel_bin_name.rsplitn(2, "-").skip(1).next() { + let package_name = match kernel_bin_name.rsplitn(2, '-').nth(1) { Some(name) => name, None => return false, }; From b6efd391c5e25964a8bb3b40d8791d66cd8600a1 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Thu, 7 May 2020 14:54:50 +0200 Subject: [PATCH 037/108] Move doctest test to the end --- .github/workflows/build.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 6c406db..d2de177 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -110,14 +110,14 @@ jobs: shell: bash {0} working-directory: example-kernels/runner - - run: cargo xtest -Z doctest-xcompile - working-directory: example-kernels/runner-doctest - name: 'Run `cargo xtest -Z doctest-xcompile` for "runner-doctest" kernel' - - run: cargo xtest working-directory: example-kernels/runner-test name: 'Run `cargo xtest` for "runner-test" kernel' + - run: cargo xtest -Z doctest-xcompile + working-directory: example-kernels/runner-doctest + name: 'Run `cargo xtest -Z doctest-xcompile` for "runner-doctest" kernel' + check_formatting: name: "Check Formatting" runs-on: ubuntu-latest From 5b06e8298a13769f38d899ab05eb52a0bc3ac569 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Thu, 7 May 2020 14:59:13 +0200 Subject: [PATCH 038/108] Lazily retrieve cargo metadata and cache it in the Builder --- src/bin/cargo-bootimage.rs | 2 +- src/builder/mod.rs | 29 ++++++++++++++++++++++------- src/main.rs | 2 +- 3 files changed, 24 insertions(+), 9 deletions(-) diff --git a/src/bin/cargo-bootimage.rs b/src/bin/cargo-bootimage.rs index 3359c3c..7e89ef0 100644 --- a/src/bin/cargo-bootimage.rs +++ b/src/bin/cargo-bootimage.rs @@ -42,7 +42,7 @@ pub fn main() -> Result<()> { } fn build(args: BuildArgs) -> Result<()> { - let builder = Builder::new(args.manifest_path().map(PathBuf::from))?; + let mut builder = Builder::new(args.manifest_path().map(PathBuf::from))?; let quiet = args.quiet(); let executables = builder.build_kernel(&args.cargo_args(), quiet)?; diff --git a/src/builder/mod.rs b/src/builder/mod.rs index d6a1b54..1aa72a0 100644 --- a/src/builder/mod.rs +++ b/src/builder/mod.rs @@ -1,5 +1,6 @@ //! Provides functions to build the kernel and the bootloader. +use cargo_metadata::Metadata; use error::{BootloaderError, BuildKernelError, BuilderError, CreateBootimageError}; use std::{ path::{Path, PathBuf}, @@ -16,6 +17,7 @@ pub mod error; /// Allows building the kernel and creating a bootable disk image with it. pub struct Builder { manifest_path: PathBuf, + project_metadata: Option, } impl Builder { @@ -24,7 +26,10 @@ impl Builder { /// If None is passed for `manifest_path`, it is automatically searched. pub fn new(manifest_path: Option) -> Result { let manifest_path = manifest_path.unwrap_or(locate_cargo_manifest::locate_manifest()?); - Ok(Builder { manifest_path }) + Ok(Builder { + manifest_path, + project_metadata: None, + }) } /// Returns the path to the Cargo.toml file of the project. @@ -111,17 +116,17 @@ impl Builder { /// /// If the quiet argument is set to true, all output to stdout is suppressed. pub fn create_bootimage( - &self, + &mut self, bin_name: &str, bin_path: &Path, output_bin_path: &Path, quiet: bool, ) -> Result<(), CreateBootimageError> { - let project_metadata = cargo_metadata::MetadataCommand::new() - .manifest_path(&self.manifest_path) - .exec()?; - let bootloader_build_config = - bootloader::BuildConfig::from_metadata(&project_metadata, bin_name, bin_path)?; + let bootloader_build_config = bootloader::BuildConfig::from_metadata( + self.project_metadata()?, + kernel_manifest_path, + bin_path, + )?; // build bootloader if !quiet { @@ -181,4 +186,14 @@ impl Builder { Ok(()) } + + fn project_metadata(&mut self) -> Result<&Metadata, cargo_metadata::Error> { + if let Some(ref metadata) = self.project_metadata { + return Ok(metadata); + } + let metadata = cargo_metadata::MetadataCommand::new() + .manifest_path(&self.manifest_path) + .exec()?; + Ok(self.project_metadata.get_or_insert(metadata)) + } } diff --git a/src/main.rs b/src/main.rs index 7a126a8..6504d17 100644 --- a/src/main.rs +++ b/src/main.rs @@ -57,7 +57,7 @@ pub fn main() -> Result<()> { } pub(crate) fn runner(args: RunnerArgs) -> Result { - let builder = Builder::new(None)?; + let mut builder = Builder::new(None)?; let config = config::read_config(builder.manifest_path())?; let exe_parent = args .executable From eada9f550f81bc3aac230e291bcdccfe78f5000e Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Thu, 7 May 2020 15:00:37 +0200 Subject: [PATCH 039/108] Let caller specify kernel manifest path Move kernel package location code into a new public function. --- src/builder/bootloader.rs | 47 ++++++--------------------------------- src/builder/mod.rs | 14 +++++++++++- 2 files changed, 20 insertions(+), 41 deletions(-) diff --git a/src/builder/bootloader.rs b/src/builder/bootloader.rs index 984b209..f1e4cce 100644 --- a/src/builder/bootloader.rs +++ b/src/builder/bootloader.rs @@ -20,10 +20,15 @@ impl BuildConfig { /// Derives the bootloader build config from the project's metadata. pub fn from_metadata( project_metadata: &Metadata, - kernel_bin_name: &str, + kernel_manifest_path: &Path, kernel_bin_path: &Path, ) -> Result { - let kernel_pkg = kernel_package(project_metadata, kernel_bin_name)?; + let kernel_pkg = project_metadata + .packages + .iter() + .find(|p| p.manifest_path == kernel_manifest_path) + .unwrap(); + let bootloader_pkg = bootloader_package(project_metadata, kernel_pkg)?; let bootloader_root = bootloader_pkg.manifest_path.parent().ok_or_else(|| { BootloaderError::BootloaderInvalid("bootloader manifest has no target directory".into()) @@ -110,44 +115,6 @@ impl BuildConfig { } } -/// Returns the package metadata for the kernel crate -fn kernel_package<'a>( - project_metadata: &'a Metadata, - kernel_bin_name: &str, -) -> Result<&'a Package, BootloaderError> { - // look for exact match with binary name first - let contains_bin = |p: &&Package| { - p.targets - .iter() - .any(|t| t.name == kernel_bin_name && t.kind.iter().any(|k| k == "bin")) - }; - let package = project_metadata.packages.iter().find(contains_bin); - - // then look for exact match with integration test binary - let contains_test_bin = |p: &&Package| { - p.targets - .iter() - .any(|t| t.name == kernel_bin_name && t.kind.iter().any(|k| k == "test")) - }; - let package = package.or_else(|| project_metadata.packages.iter().find(contains_test_bin)); - - // then look for match with appended hash (e.g. for library tests) - let contains_test = |p: &&Package| { - let package_name = match kernel_bin_name.rsplitn(2, '-').nth(1) { - Some(name) => name, - None => return false, - }; - p.targets - .iter() - .any(|t| t.name.replace("-", "_") == package_name) - }; - let package = package.or_else(|| project_metadata.packages.iter().find(contains_test)); - - package.ok_or_else(|| BootloaderError::KernelBinPackageNotFound { - bin_name: kernel_bin_name.to_owned(), - }) -} - /// Returns the package metadata for the bootloader crate fn bootloader_package<'a>( project_metadata: &'a Metadata, diff --git a/src/builder/mod.rs b/src/builder/mod.rs index 1aa72a0..86afea6 100644 --- a/src/builder/mod.rs +++ b/src/builder/mod.rs @@ -117,7 +117,7 @@ impl Builder { /// If the quiet argument is set to true, all output to stdout is suppressed. pub fn create_bootimage( &mut self, - bin_name: &str, + kernel_manifest_path: &Path, bin_path: &Path, output_bin_path: &Path, quiet: bool, @@ -187,6 +187,18 @@ impl Builder { Ok(()) } + /// Returns the cargo metadata package that contains the given binary. + pub fn kernel_package_for_bin( + &mut self, + kernel_bin_name: &str, + ) -> Result, cargo_metadata::Error> { + Ok(self.project_metadata()?.packages.iter().find(|p| { + p.targets + .iter() + .any(|t| t.name == kernel_bin_name && t.kind.iter().any(|k| k == "bin")) + })) + } + fn project_metadata(&mut self) -> Result<&Metadata, cargo_metadata::Error> { if let Some(ref metadata) = self.project_metadata { return Ok(metadata); From 65a03a88553d57416fea15eb23728ca3b700950c Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Thu, 7 May 2020 15:01:56 +0200 Subject: [PATCH 040/108] Use new `kernel_package_for_bin` method for `cargo bootimage` The `cargo bootimage` command only deals with binaries, so we don't need to try to derive the manifest path for test or doctest executables. --- src/bin/cargo-bootimage.rs | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/src/bin/cargo-bootimage.rs b/src/bin/cargo-bootimage.rs index 7e89ef0..1737866 100644 --- a/src/bin/cargo-bootimage.rs +++ b/src/bin/cargo-bootimage.rs @@ -1,4 +1,4 @@ -use anyhow::{anyhow, Result}; +use anyhow::{anyhow, Context, Result}; use bootimage::{ args::{BuildArgs, BuildCommand}, builder::Builder, @@ -60,8 +60,23 @@ fn build(args: BuildArgs) -> Result<()> { .to_str() .ok_or_else(|| anyhow!("executable file stem not valid utf8"))?; + // We don't have access to a CARGO_MANIFEST_DIR environment variable + // here because `cargo bootimage` is started directly by the user. We + // therefore have to find out the path to the Cargo.toml of the + // executables ourselves. For workspace projects, this can be a + // different Cargo.toml than the Cargo.toml in the current directory. + // + // To retrieve the correct Cargo.toml path, we look for the binary name + // in the `cargo metadata` output and then get the manifest path from + // the corresponding package. + let kernel_package = builder + .kernel_package_for_bin(bin_name) + .context("Failed to run cargo metadata to find out kernel manifest path")? + .ok_or_else(|| anyhow!("Failed to find kernel binary in cargo metadata output"))?; + let kernel_manifest_path = &kernel_package.manifest_path.to_owned(); + let bootimage_path = out_dir.join(format!("bootimage-{}.bin", bin_name)); - builder.create_bootimage(bin_name, &executable, &bootimage_path, quiet)?; + builder.create_bootimage(kernel_manifest_path, &executable, &bootimage_path, quiet)?; if !args.quiet() { println!( "Created bootimage for `{}` at `{}`", From e8355911b643655a29bd5f42ffd86a093bc38c20 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Thu, 7 May 2020 15:04:52 +0200 Subject: [PATCH 041/108] Use CARGO_MANIFEST_DIR variable for `bootimage runner` For doctests it's not possible to derive the manifest path from the executable path and the cargo metadata since doctests live under temp and all use the same name ('rust-out'). Fortunately, cargo sets a `CARGO_MANIFEST_DIR` environment variable for runner executables that points to the manifest path of the executable (which can be different from the root manifest path for workpace projects.) --- src/main.rs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/main.rs b/src/main.rs index 6504d17..28cc054 100644 --- a/src/main.rs +++ b/src/main.rs @@ -85,8 +85,17 @@ pub(crate) fn runner(args: RunnerArgs) -> Result { args.executable.display(), ) })?; + + // Cargo sets a CARGO_MANIFEST_DIR environment variable for all runner + // executables. This variable contains the path to the Cargo.toml of the + // crate that the executable belongs to (i.e. not the project root + // manifest for workspace projects) + let manifest_dir = env::var("CARGO_MANIFEST_DIR") + .context("Failed to read CARGO_MANIFEST_DIR environment variable")?; + let kernel_manifest_path = Path::new(&manifest_dir).join("Cargo.toml"); + builder.create_bootimage( - bin_name, + &kernel_manifest_path, &executable_canonicalized, &output_bin_path, args.quiet, From 2133b334fa290201a311169782c1c9168ee5128e Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Thu, 7 May 2020 15:07:45 +0200 Subject: [PATCH 042/108] Remove unused error variant --- src/builder/error.rs | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/builder/error.rs b/src/builder/error.rs index 75ec4e8..4cf6af8 100644 --- a/src/builder/error.rs +++ b/src/builder/error.rs @@ -96,12 +96,6 @@ pub enum BootloaderError { /// Bootloader dependency has not the right format #[error("The `bootloader` dependency has not the right format: {0}")] BootloaderInvalid(String), - /// Could not find kernel package in cargo metadata - #[error("Could not find package for binary `{bin_name}` in cargo metadata output")] - KernelBinPackageNotFound { - /// The name of the kernel binary - bin_name: String, - }, /// Could not find some required information in the `cargo metadata` output #[error("Could not find required key `{key}` in cargo metadata output")] CargoMetadataIncomplete { @@ -127,6 +121,7 @@ pub enum DiskImageError { /// The llvm-tools component did not contain the required `llvm-objcopy` executable #[error("Could not find `llvm-objcopy` in the `llvm-tools-preview` rustup component.")] LlvmObjcopyNotFound, + /// The `llvm-objcopy` command failed #[error("Failed to run `llvm-objcopy`: {}", String::from_utf8_lossy(.stderr))] ObjcopyFailed { From 697a3841faae263ca958ccfef1dca0e776e14482 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Thu, 7 May 2020 15:14:32 +0200 Subject: [PATCH 043/108] Add a new KernelPackageNotFound error instead of unwrapping --- src/builder/bootloader.rs | 4 +++- src/builder/error.rs | 13 ++++++++++++- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/src/builder/bootloader.rs b/src/builder/bootloader.rs index f1e4cce..859bed7 100644 --- a/src/builder/bootloader.rs +++ b/src/builder/bootloader.rs @@ -27,7 +27,9 @@ impl BuildConfig { .packages .iter() .find(|p| p.manifest_path == kernel_manifest_path) - .unwrap(); + .ok_or_else(|| BootloaderError::KernelPackageNotFound { + manifest_path: kernel_manifest_path.to_owned(), + })?; let bootloader_pkg = bootloader_package(project_metadata, kernel_pkg)?; let bootloader_root = bootloader_pkg.manifest_path.parent().ok_or_else(|| { diff --git a/src/builder/error.rs b/src/builder/error.rs index 4cf6af8..86e6e14 100644 --- a/src/builder/error.rs +++ b/src/builder/error.rs @@ -1,4 +1,4 @@ -use std::io; +use std::{io, path::PathBuf}; use thiserror::Error; /// Represents an error that occurred while creating a new `Builder`. @@ -93,9 +93,20 @@ pub enum BootloaderError { You need to add a dependency on a crate named `bootloader` in your Cargo.toml." )] BootloaderNotFound, + /// Bootloader dependency has not the right format #[error("The `bootloader` dependency has not the right format: {0}")] BootloaderInvalid(String), + + /// Could not find kernel package in cargo metadata + #[error( + "Could not find package with manifest path `{manifest_path}` in cargo metadata output" + )] + KernelPackageNotFound { + /// The manifest path of the kernel package + manifest_path: PathBuf, + }, + /// Could not find some required information in the `cargo metadata` output #[error("Could not find required key `{key}` in cargo metadata output")] CargoMetadataIncomplete { From 1a86a2e6fc6bbeee492c49ccb65e42d6f24ab209 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Thu, 7 May 2020 15:18:21 +0200 Subject: [PATCH 044/108] Replace `expect` calls with proper errors --- src/args/build.rs | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/args/build.rs b/src/args/build.rs index 9cb0db9..02fe739 100644 --- a/src/args/build.rs +++ b/src/args/build.rs @@ -1,4 +1,4 @@ -use anyhow::{anyhow, Result}; +use anyhow::{anyhow, Context, Result}; use std::{ mem, path::{Path, PathBuf}, @@ -48,11 +48,10 @@ impl BuildCommand { let next = arg_iter.next(); set( &mut manifest_path, - next.as_ref().map(|p| { - Path::new(&p) - .canonicalize() - .expect("--manifest-path invalid") - }), + next.as_ref() + .map(|p| Path::new(&p).canonicalize()) + .transpose() + .context("--manifest-path invalid")?, )?; cargo_args.push(arg); if let Some(next) = next { @@ -62,7 +61,7 @@ impl BuildCommand { _ if arg.starts_with("--manifest-path=") => { let path = Path::new(arg.trim_start_matches("--manifest-path=")) .canonicalize() - .expect("--manifest-path invalid"); + .context("--manifest-path invalid")?; set(&mut manifest_path, Some(path))?; cargo_args.push(arg); } From 91efc7f1bdfe6ffc579b696abe11ab2d73d554f7 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Thu, 7 May 2020 16:19:12 +0200 Subject: [PATCH 045/108] Update Readme for rewrite --- Readme.md | 56 ++++++++++++++++++++++++++----------------------------- 1 file changed, 26 insertions(+), 30 deletions(-) diff --git a/Readme.md b/Readme.md index 67585b4..9757b45 100644 --- a/Readme.md +++ b/Readme.md @@ -28,60 +28,56 @@ If you want to use a custom bootloader with a different name, you can use Cargo' Now you can build the kernel project and create a bootable disk image from it by running: ``` -bootimage build --target your_custom_target.json [other_args] +cargo bootimage --target your_custom_target.json [other_args] ``` The command will invoke [`cargo xbuild`](https://github.com/rust-osdev/cargo-xbuild), forwarding all passed options. Then it will build the specified bootloader together with the kernel to create a bootable disk image. -If you prefer a cargo subcommand, you can use the equivalent `cargo bootimage` command: +### Running -``` -cargo bootimage --target your_custom_target.json [other_args] -``` +To run your kernel in QEMU, you can set a `bootimage runner` as a custom runner in a `.cargo/config` file: -### Running +```toml +[target.'cfg(target_os = "none")'] +runner = "bootimage runner" +``` -To run your kernel in QEMU, you can use `bootimage run`: +Then you can run your kernel through: ``` -bootimage run --target your_custom_target.json [other_args] -- [qemu args] +cargo xrun --target your_custom_target.json [other_args] -- [qemu args] ``` All arguments after `--` are passed to QEMU. If you want to use a custom run command, see the _Configuration_ section below. -If you prefer working directly with cargo, you can use `bootimage runner` as a custom runner in your `.cargo/config`: - -```toml -[target.'cfg(target_os = "none")'] -runner = "bootimage runner" -``` +### Testing -Now you can run your kernel through `cargo xrun --target […]`. +The `bootimage` has built-in support for running unit and integration tests of your kernel. For this, you need to use the `custom_tests_framework` feature of Rust as described [here](https://os.phil-opp.com/testing/#custom-test-frameworks). ## Configuration Configuration is done through a through a `[package.metadata.bootimage]` table in the `Cargo.toml` of your kernel. The following options are available: ```toml - [package.metadata.bootimage] - # The command invoked with the created bootimage (the "{}" will be replaced - # with the path to the bootable disk image) - # Applies to `bootimage run` and `bootimage runner` - run-command = ["qemu-system-x86_64", "-drive", "format=raw,file={}"] +[package.metadata.bootimage] +# The command invoked with the created bootimage (the "{}" will be replaced +# with the path to the bootable disk image) +# Applies to `bootimage run` and `bootimage runner` +run-command = ["qemu-system-x86_64", "-drive", "format=raw,file={}"] - # Additional arguments passed to the run command for non-test executables - # Applies to `bootimage run` and `bootimage runner` - run-args = [] +# Additional arguments passed to the run command for non-test executables +# Applies to `bootimage run` and `bootimage runner` +run-args = [] - # Additional arguments passed to the run command for test executables - # Applies to `bootimage runner` - test-args = [] +# Additional arguments passed to the run command for test executables +# Applies to `bootimage runner` +test-args = [] - # An exit code that should be considered as success for test executables - test-success-exit-code = {integer} +# An exit code that should be considered as success for test executables +test-success-exit-code = {integer} - # The timeout for running a test through `bootimage test` or `bootimage runner` (in seconds) - test-timeout = 300 +# The timeout for running a test through `bootimage test` or `bootimage runner` (in seconds) +test-timeout = 300 ``` ## License From 811bd16245df3d577ded5b18f22f1fb6e2c96b69 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Thu, 7 May 2020 16:19:56 +0200 Subject: [PATCH 046/108] Update changelog for #55 --- Changelog.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Changelog.md b/Changelog.md index 2d3ad0d..698d5c6 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,3 +1,5 @@ +- **Breaking:** Rewrite: Remove support for `bootimage {run, test}` ([#55](https://github.com/rust-osdev/bootimage/pull/55)) + # 0.7.10 - Add support for doctests ([#52](https://github.com/rust-osdev/bootimage/pull/52)) From 5465f85899d25743f4d7e73b5e1ec8d496a8b3b4 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Thu, 7 May 2020 16:21:33 +0200 Subject: [PATCH 047/108] bootimage 0.8.0 --- Cargo.lock | 2 +- Cargo.toml | 2 +- Changelog.md | 2 ++ 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 51f6e57..769cca2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7,7 +7,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "bootimage" -version = "0.7.10" +version = "0.8.0" dependencies = [ "anyhow 1.0.28 (registry+https://github.com/rust-lang/crates.io-index)", "cargo_metadata 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/Cargo.toml b/Cargo.toml index f3686e5..b88ad2b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,7 +3,7 @@ authors = ["Philipp Oppermann "] description = "Tool to create a bootable OS image from a kernel binary." license = "MIT/Apache-2.0" name = "bootimage" -version = "0.7.10" +version = "0.8.0" repository = "https://github.com/rust-osdev/bootimage" edition = "2018" diff --git a/Changelog.md b/Changelog.md index 698d5c6..c8db69c 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,3 +1,5 @@ +# 0.8.0 + - **Breaking:** Rewrite: Remove support for `bootimage {run, test}` ([#55](https://github.com/rust-osdev/bootimage/pull/55)) # 0.7.10 From 57983ec7cc76b1698233284b1b5f4d438c7b5276 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Wed, 20 May 2020 10:44:18 +0200 Subject: [PATCH 048/108] Update x86_64 and bootloader dependencies for example kernels --- example-kernels/Cargo.lock | 24 +++++++++++------------ example-kernels/basic/Cargo.toml | 4 ++-- example-kernels/runner-doctest/Cargo.toml | 4 ++-- example-kernels/runner-test/Cargo.toml | 4 ++-- example-kernels/runner/Cargo.toml | 4 ++-- 5 files changed, 20 insertions(+), 20 deletions(-) diff --git a/example-kernels/Cargo.lock b/example-kernels/Cargo.lock index daaa6e5..27d7cb0 100644 --- a/example-kernels/Cargo.lock +++ b/example-kernels/Cargo.lock @@ -4,8 +4,8 @@ name = "basic" version = "0.1.0" dependencies = [ - "bootloader 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)", - "x86_64 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)", + "bootloader 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)", + "x86_64 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -20,36 +20,36 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "bootloader" -version = "0.9.2" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "runner" version = "0.1.0" dependencies = [ - "bootloader 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)", - "x86_64 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)", + "bootloader 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)", + "x86_64 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "runner-doctest" version = "0.1.0" dependencies = [ - "bootloader 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)", - "x86_64 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)", + "bootloader 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)", + "x86_64 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "runner-test" version = "0.1.0" dependencies = [ - "bootloader 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)", - "x86_64 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)", + "bootloader 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)", + "x86_64 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "x86_64" -version = "0.10.2" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bit_field 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -59,5 +59,5 @@ dependencies = [ [metadata] "checksum bit_field 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ed8765909f9009617974ab6b7d332625b320b33c326b1e9321382ef1999b5d56" "checksum bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3d155346769a6855b86399e9bc3814ab343cd3d62c7e985113d46a0ec3c281fd" -"checksum bootloader 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dd5c4922d54a9033cfdf75d4fd23945461e9d2c1d979c8f5b237e5471f11dddc" -"checksum x86_64 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)" = "074fe17c2586dd646602287854514c5cb3b6c3b5e63cd3970ecddbbb9c01468d" +"checksum bootloader 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)" = "44ac0bdf4930c3c4d7f0d04eb6f15d7dcb9d5972b1ff9cd2bee0128112260fc7" +"checksum x86_64 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "365de37eb7c6da582cbb510dd0f3f1235d24ff6309a8a96e8a9909cc9bfd608f" diff --git a/example-kernels/basic/Cargo.toml b/example-kernels/basic/Cargo.toml index 81c7a14..60e18ca 100644 --- a/example-kernels/basic/Cargo.toml +++ b/example-kernels/basic/Cargo.toml @@ -5,5 +5,5 @@ authors = ["Philipp Oppermann "] edition = "2018" [dependencies] -bootloader = "0.9.2" -x86_64 = "0.10.2" +bootloader = "0.9.3" +x86_64 = "0.11.0" diff --git a/example-kernels/runner-doctest/Cargo.toml b/example-kernels/runner-doctest/Cargo.toml index 9f3dce2..2e6dad8 100644 --- a/example-kernels/runner-doctest/Cargo.toml +++ b/example-kernels/runner-doctest/Cargo.toml @@ -5,8 +5,8 @@ authors = ["Philipp Oppermann "] edition = "2018" [dependencies] -bootloader = "0.9.2" -x86_64 = "0.10.2" +bootloader = "0.9.3" +x86_64 = "0.11.0" [package.metadata.bootimage] test-success-exit-code = 33 # (0x10 << 1) | 1 diff --git a/example-kernels/runner-test/Cargo.toml b/example-kernels/runner-test/Cargo.toml index 8a80f76..db005f8 100644 --- a/example-kernels/runner-test/Cargo.toml +++ b/example-kernels/runner-test/Cargo.toml @@ -9,8 +9,8 @@ name = "no-harness" harness = false [dependencies] -bootloader = "0.9.2" -x86_64 = "0.10.2" +bootloader = "0.9.3" +x86_64 = "0.11.0" [package.metadata.bootimage] test-success-exit-code = 33 # (0x10 << 1) | 1 diff --git a/example-kernels/runner/Cargo.toml b/example-kernels/runner/Cargo.toml index bd79c4d..603ebc8 100644 --- a/example-kernels/runner/Cargo.toml +++ b/example-kernels/runner/Cargo.toml @@ -5,8 +5,8 @@ authors = ["Philipp Oppermann "] edition = "2018" [dependencies] -bootloader = "0.9.2" -x86_64 = "0.10.2" +bootloader = "0.9.3" +x86_64 = "0.11.0" [package.metadata.bootimage] run-args = ["-device", "isa-debug-exit,iobase=0xf4,iosize=0x04", "-display", "none"] From c3d422ac9d57033f876c8110626c2b128d863558 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Thu, 16 Jul 2020 13:02:11 +0200 Subject: [PATCH 049/108] Add support for building bootloaders using `-Zbuild-std` Bootloaders can opt-in to the new functionality by setting a `package.metadata.bootloader.build-std` key with a comma-separated string of sysroot crates that should be built. For example, a setting of `build-std = "core"` results in the build command `cargo build -Zbuild-std=core`. If no such key is set, bootimage continues to compile the bootloader using the command `cargo xbuild`. --- src/builder/bootloader.rs | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/src/builder/bootloader.rs b/src/builder/bootloader.rs index 859bed7..059ba30 100644 --- a/src/builder/bootloader.rs +++ b/src/builder/bootloader.rs @@ -14,6 +14,7 @@ pub struct BuildConfig { target_dir: PathBuf, kernel_bin_path: PathBuf, kernel_manifest_path: PathBuf, + build_std: Option, } impl BuildConfig { @@ -54,6 +55,26 @@ impl BuildConfig { .into(), ) })?; + let build_std = { + let key = metadata + .and_then(|t| t.get("bootloader")) + .and_then(|t| t.get("build-std")); + if let Some(key) = key { + Some( + key.as_str() + .ok_or_else(|| { + BootloaderError::BootloaderInvalid( + "A non-string `package.metadata.bootloader.build-std` key found in \ + Cargo.toml of bootloader" + .into(), + ) + })? + .into(), + ) + } else { + None + } + }; let binary_feature = cargo_toml .get("features") @@ -90,6 +111,7 @@ impl BuildConfig { target_dir, kernel_manifest_path: kernel_pkg.manifest_path.clone(), kernel_bin_path: kernel_bin_path.to_owned(), + build_std, }) } @@ -97,7 +119,11 @@ impl BuildConfig { pub fn build_command(&self) -> Command { let cargo = std::env::var("CARGO").unwrap_or_else(|_| "cargo".to_owned()); let mut cmd = Command::new(&cargo); - cmd.arg("xbuild"); + if let Some(build_std) = &self.build_std { + cmd.arg("build").arg(&format!("-Zbuild-std={}", build_std)); + } else { + cmd.arg("xbuild"); + } cmd.arg("--manifest-path"); cmd.arg(&self.manifest_path); cmd.arg("--bin").arg(&self.bootloader_name); From d28fe8c3afa0616079e97c1e8363a9ae34a51048 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Fri, 17 Jul 2020 09:12:27 +0200 Subject: [PATCH 050/108] Improve code formatting by introducing temp bindings --- src/builder/bootloader.rs | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/src/builder/bootloader.rs b/src/builder/bootloader.rs index 059ba30..5753fc1 100644 --- a/src/builder/bootloader.rs +++ b/src/builder/bootloader.rs @@ -60,17 +60,10 @@ impl BuildConfig { .and_then(|t| t.get("bootloader")) .and_then(|t| t.get("build-std")); if let Some(key) = key { - Some( - key.as_str() - .ok_or_else(|| { - BootloaderError::BootloaderInvalid( - "A non-string `package.metadata.bootloader.build-std` key found in \ - Cargo.toml of bootloader" - .into(), - ) - })? - .into(), - ) + let err_msg = "A non-string `package.metadata.bootloader.build-std` key found in \ + Cargo.toml of bootloader"; + let err = || BootloaderError::BootloaderInvalid(err_msg.into()); + Some(key.as_str().ok_or_else(err)?.into()) } else { None } From 3cca94253ba561804ed3073707f6cb24ca31cef8 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Fri, 17 Jul 2020 09:16:01 +0200 Subject: [PATCH 051/108] Set up cargo-release to automate crates.io releases --- Cargo.toml | 7 +++++++ Changelog.md | 2 ++ 2 files changed, 9 insertions(+) diff --git a/Cargo.toml b/Cargo.toml index b88ad2b..47406ff 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,3 +16,10 @@ json = "0.12.4" anyhow = "1.0.28" thiserror = "1.0.16" cargo_metadata = "0.9.1" + +[package.metadata.release] +no-dev-version = true +pre-release-replacements = [ + { file="Changelog.md", search="# Unreleased", replace="# Unreleased\n\n# {{version}} – {{date}}", exactly=1 }, +] +pre-release-commit-message = "Release version {{version}}" diff --git a/Changelog.md b/Changelog.md index c8db69c..d0d4700 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,3 +1,5 @@ +# Unreleased + # 0.8.0 - **Breaking:** Rewrite: Remove support for `bootimage {run, test}` ([#55](https://github.com/rust-osdev/bootimage/pull/55)) From be2628ffb1de24847c8e2f14e111c0ac39adc924 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Fri, 17 Jul 2020 09:23:51 +0200 Subject: [PATCH 052/108] Remove bors from this repo --- bors.toml | 4 ---- 1 file changed, 4 deletions(-) delete mode 100644 bors.toml diff --git a/bors.toml b/bors.toml deleted file mode 100644 index 9c47331..0000000 --- a/bors.toml +++ /dev/null @@ -1,4 +0,0 @@ -status = [ - "rust-osdev.bootimage", -] -delete_merged_branches = true From c422e5e2f0e95ddb0dc9115f59c9a7be5637d879 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Fri, 17 Jul 2020 09:24:21 +0200 Subject: [PATCH 053/108] Update changelog for #62 --- Changelog.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Changelog.md b/Changelog.md index d0d4700..87c205d 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,5 +1,7 @@ # Unreleased +- Add support for building bootloaders using `-Zbuild-std ([#62](https://github.com/rust-osdev/bootimage/pull/62)) + # 0.8.0 - **Breaking:** Rewrite: Remove support for `bootimage {run, test}` ([#55](https://github.com/rust-osdev/bootimage/pull/55)) From c4c9b93abb42dc409c861de6f0710e709363eeee Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Fri, 17 Jul 2020 09:25:23 +0200 Subject: [PATCH 054/108] Release version 0.8.1 --- Cargo.lock | 2 +- Cargo.toml | 2 +- Changelog.md | 2 ++ 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 769cca2..7b1283c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7,7 +7,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "bootimage" -version = "0.8.0" +version = "0.8.1" dependencies = [ "anyhow 1.0.28 (registry+https://github.com/rust-lang/crates.io-index)", "cargo_metadata 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/Cargo.toml b/Cargo.toml index 47406ff..29299c1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,7 +3,7 @@ authors = ["Philipp Oppermann "] description = "Tool to create a bootable OS image from a kernel binary." license = "MIT/Apache-2.0" name = "bootimage" -version = "0.8.0" +version = "0.8.1" repository = "https://github.com/rust-osdev/bootimage" edition = "2018" diff --git a/Changelog.md b/Changelog.md index 87c205d..800bea3 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,5 +1,7 @@ # Unreleased +# 0.8.1 – 2020-07-17 + - Add support for building bootloaders using `-Zbuild-std ([#62](https://github.com/rust-osdev/bootimage/pull/62)) # 0.8.0 From 3ce65d65908715552c68af63f74927ead3bb82d1 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Fri, 17 Jul 2020 08:49:49 +0200 Subject: [PATCH 055/108] Build with `cargo build` instead of `xbuild` if rlibc is a dependencyy --- src/builder/mod.rs | 35 ++++++++++++++++++++++++----------- 1 file changed, 24 insertions(+), 11 deletions(-) diff --git a/src/builder/mod.rs b/src/builder/mod.rs index 86afea6..3687c12 100644 --- a/src/builder/mod.rs +++ b/src/builder/mod.rs @@ -44,7 +44,7 @@ impl Builder { /// /// If the quiet argument is set to true, all output to stdout is suppressed. pub fn build_kernel( - &self, + &mut self, args: &[String], quiet: bool, ) -> Result, BuildKernelError> { @@ -52,10 +52,21 @@ impl Builder { println!("Building kernel"); } + let build_arg = if self + .project_metadata() + .ok() + .and_then(|m| m.packages.iter().find(|p| p.name == "rlibc")) + .is_some() + { + "build" + } else { + "xbuild" + }; + // try to run cargo xbuild let cargo = std::env::var("CARGO").unwrap_or_else(|_| "cargo".to_owned()); let mut cmd = process::Command::new(&cargo); - cmd.arg("xbuild"); + cmd.arg(build_arg); cmd.args(args); if !quiet { cmd.stdout(process::Stdio::inherit()); @@ -66,14 +77,16 @@ impl Builder { error: err, })?; if !output.status.success() { - // try executing `cargo xbuild --help` to check whether cargo-xbuild is installed - let mut help_command = process::Command::new("cargo"); - help_command.arg("xbuild").arg("--help"); - help_command.stdout(process::Stdio::null()); - help_command.stderr(process::Stdio::null()); - if let Ok(help_exit_status) = help_command.status() { - if !help_exit_status.success() { - return Err(BuildKernelError::XbuildNotFound); + if build_arg == "xbuild" { + // try executing `cargo xbuild --help` to check whether cargo-xbuild is installed + let mut help_command = process::Command::new("cargo"); + help_command.arg("xbuild").arg("--help"); + help_command.stdout(process::Stdio::null()); + help_command.stderr(process::Stdio::null()); + if let Ok(help_exit_status) = help_command.status() { + if !help_exit_status.success() { + return Err(BuildKernelError::XbuildNotFound); + } } } return Err(BuildKernelError::XbuildFailed { @@ -83,7 +96,7 @@ impl Builder { // Retrieve binary paths let mut cmd = process::Command::new(cargo); - cmd.arg("xbuild"); + cmd.arg(build_arg); cmd.args(args); cmd.arg("--message-format").arg("json"); let output = cmd.output().map_err(|err| BuildKernelError::Io { From 3f5e718cb8d1553ea8c4ae9353e30dbbe09cd702 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Fri, 17 Jul 2020 08:58:54 +0200 Subject: [PATCH 056/108] Simplify config parsing by creating `parse_string_array` function --- src/config.rs | 38 ++++++++++++++------------------------ 1 file changed, 14 insertions(+), 24 deletions(-) diff --git a/src/config.rs b/src/config.rs index 44479d6..a8a597c 100644 --- a/src/config.rs +++ b/src/config.rs @@ -76,34 +76,13 @@ fn read_config_inner(manifest_path: &Path) -> Result { config.test_success_exit_code = Some(exit_code as i32); } ("run-command", Value::Array(array)) => { - let mut command = Vec::new(); - for value in array { - match value { - Value::String(s) => command.push(s), - _ => return Err(anyhow!("run-command must be a list of strings")), - } - } - config.run_command = Some(command); + config.run_command = Some(parse_string_array(array, "run-command")?); } ("run-args", Value::Array(array)) => { - let mut args = Vec::new(); - for value in array { - match value { - Value::String(s) => args.push(s), - _ => return Err(anyhow!("run-args must be a list of strings")), - } - } - config.run_args = Some(args); + config.run_args = Some(parse_string_array(array, "run-args")?); } ("test-args", Value::Array(array)) => { - let mut args = Vec::new(); - for value in array { - match value { - Value::String(s) => args.push(s), - _ => return Err(anyhow!("test-args must be a list of strings")), - } - } - config.test_args = Some(args); + config.test_args = Some(parse_string_array(array, "test-args")?); } (key, value) => { return Err(anyhow!( @@ -118,6 +97,17 @@ fn read_config_inner(manifest_path: &Path) -> Result { Ok(config.into()) } +fn parse_string_array(array: Vec, prop_name: &str) -> Result> { + let mut parsed = Vec::new(); + for value in array { + match value { + Value::String(s) => parsed.push(s), + _ => return Err(anyhow!("{} must be a list of strings", prop_name)), + } + } + Ok(parsed) +} + #[derive(Default)] struct ConfigBuilder { run_command: Option>, From 2e680f92686980762e417b7e3a204c369eeef264 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Fri, 17 Jul 2020 08:59:21 +0200 Subject: [PATCH 057/108] Add a build-command config option, defaulting to `cargo build` --- src/config.rs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/config.rs b/src/config.rs index a8a597c..72105cc 100644 --- a/src/config.rs +++ b/src/config.rs @@ -12,6 +12,10 @@ use toml::Value; #[derive(Debug, Clone)] #[non_exhaustive] pub struct Config { + /// The command that is used for building the kernel for `cargo bootimage`. + /// + /// Defaults to `cargo build`. + pub build_command: Vec, /// The run command that is invoked on `bootimage run` or `bootimage runner` /// /// The substring "{}" will be replaced with the path to the bootable disk image. @@ -75,6 +79,9 @@ fn read_config_inner(manifest_path: &Path) -> Result { ("test-success-exit-code", Value::Integer(exit_code)) => { config.test_success_exit_code = Some(exit_code as i32); } + ("build-command", Value::Array(array)) => { + config.build_command = Some(parse_string_array(array, "build-command")?); + } ("run-command", Value::Array(array)) => { config.run_command = Some(parse_string_array(array, "run-command")?); } @@ -110,6 +117,7 @@ fn parse_string_array(array: Vec, prop_name: &str) -> Result> #[derive(Default)] struct ConfigBuilder { + build_command: Option>, run_command: Option>, run_args: Option>, test_args: Option>, @@ -120,6 +128,9 @@ struct ConfigBuilder { impl Into for ConfigBuilder { fn into(self) -> Config { Config { + build_command: self + .build_command + .unwrap_or(vec!["cargo".into(), "build".into()]), run_command: self.run_command.unwrap_or_else(|| { vec![ "qemu-system-x86_64".into(), From 11501a40a43461a12da41afc401676ce5dc08578 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Fri, 17 Jul 2020 09:05:07 +0200 Subject: [PATCH 058/108] Use config.build_command instead of rlibc heuristic This is a breaking change since it changes the default build command to `cargo build`. --- src/bin/cargo-bootimage.rs | 5 +++-- src/builder/mod.rs | 19 +++++-------------- src/config.rs | 8 +++----- 3 files changed, 11 insertions(+), 21 deletions(-) diff --git a/src/bin/cargo-bootimage.rs b/src/bin/cargo-bootimage.rs index 1737866..3ea1690 100644 --- a/src/bin/cargo-bootimage.rs +++ b/src/bin/cargo-bootimage.rs @@ -2,7 +2,7 @@ use anyhow::{anyhow, Context, Result}; use bootimage::{ args::{BuildArgs, BuildCommand}, builder::Builder, - help, + config, help, }; use std::{ env, @@ -43,9 +43,10 @@ pub fn main() -> Result<()> { fn build(args: BuildArgs) -> Result<()> { let mut builder = Builder::new(args.manifest_path().map(PathBuf::from))?; + let config = config::read_config(builder.manifest_path())?; let quiet = args.quiet(); - let executables = builder.build_kernel(&args.cargo_args(), quiet)?; + let executables = builder.build_kernel(&args.cargo_args(), &config, quiet)?; if executables.is_empty() { return Err(anyhow!("no executables built")); } diff --git a/src/builder/mod.rs b/src/builder/mod.rs index 3687c12..1474bfd 100644 --- a/src/builder/mod.rs +++ b/src/builder/mod.rs @@ -1,5 +1,6 @@ //! Provides functions to build the kernel and the bootloader. +use crate::config::Config; use cargo_metadata::Metadata; use error::{BootloaderError, BuildKernelError, BuilderError, CreateBootimageError}; use std::{ @@ -46,27 +47,17 @@ impl Builder { pub fn build_kernel( &mut self, args: &[String], + config: &Config, quiet: bool, ) -> Result, BuildKernelError> { if !quiet { println!("Building kernel"); } - let build_arg = if self - .project_metadata() - .ok() - .and_then(|m| m.packages.iter().find(|p| p.name == "rlibc")) - .is_some() - { - "build" - } else { - "xbuild" - }; - // try to run cargo xbuild let cargo = std::env::var("CARGO").unwrap_or_else(|_| "cargo".to_owned()); let mut cmd = process::Command::new(&cargo); - cmd.arg(build_arg); + cmd.args(&config.build_command); cmd.args(args); if !quiet { cmd.stdout(process::Stdio::inherit()); @@ -77,7 +68,7 @@ impl Builder { error: err, })?; if !output.status.success() { - if build_arg == "xbuild" { + if config.build_command.starts_with(&["xbuild".into()]) { // try executing `cargo xbuild --help` to check whether cargo-xbuild is installed let mut help_command = process::Command::new("cargo"); help_command.arg("xbuild").arg("--help"); @@ -96,7 +87,7 @@ impl Builder { // Retrieve binary paths let mut cmd = process::Command::new(cargo); - cmd.arg(build_arg); + cmd.args(&config.build_command); cmd.args(args); cmd.arg("--message-format").arg("json"); let output = cmd.output().map_err(|err| BuildKernelError::Io { diff --git a/src/config.rs b/src/config.rs index 72105cc..bbed314 100644 --- a/src/config.rs +++ b/src/config.rs @@ -12,9 +12,9 @@ use toml::Value; #[derive(Debug, Clone)] #[non_exhaustive] pub struct Config { - /// The command that is used for building the kernel for `cargo bootimage`. + /// The cargo subcommand that is used for building the kernel for `cargo bootimage`. /// - /// Defaults to `cargo build`. + /// Defaults to `build`. pub build_command: Vec, /// The run command that is invoked on `bootimage run` or `bootimage runner` /// @@ -128,9 +128,7 @@ struct ConfigBuilder { impl Into for ConfigBuilder { fn into(self) -> Config { Config { - build_command: self - .build_command - .unwrap_or(vec!["cargo".into(), "build".into()]), + build_command: self.build_command.unwrap_or(vec!["build".into()]), run_command: self.run_command.unwrap_or_else(|| { vec![ "qemu-system-x86_64".into(), From 058439bf825afd9da56d898b85795458c7ab38a7 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Fri, 17 Jul 2020 10:06:06 +0200 Subject: [PATCH 059/108] Update example kernels to use `-Zbuild-std` and bootloader 0.9.7 --- example-kernels/.cargo/config.toml | 2 ++ example-kernels/Cargo.lock | 21 +++++++++++++++------ example-kernels/basic/Cargo.toml | 2 +- example-kernels/runner-doctest/Cargo.toml | 2 +- example-kernels/runner-test/Cargo.toml | 2 +- example-kernels/runner/Cargo.toml | 2 +- 6 files changed, 21 insertions(+), 10 deletions(-) create mode 100644 example-kernels/.cargo/config.toml diff --git a/example-kernels/.cargo/config.toml b/example-kernels/.cargo/config.toml new file mode 100644 index 0000000..92cee48 --- /dev/null +++ b/example-kernels/.cargo/config.toml @@ -0,0 +1,2 @@ +[unstable] +build-std = ["core", "compiler_builtins"] diff --git a/example-kernels/Cargo.lock b/example-kernels/Cargo.lock index 27d7cb0..514e054 100644 --- a/example-kernels/Cargo.lock +++ b/example-kernels/Cargo.lock @@ -4,7 +4,7 @@ name = "basic" version = "0.1.0" dependencies = [ - "bootloader 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)", + "bootloader 0.9.7 (registry+https://github.com/rust-lang/crates.io-index)", "x86_64 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -20,14 +20,22 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "bootloader" -version = "0.9.3" +version = "0.9.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "rlibc 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rlibc" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "runner" version = "0.1.0" dependencies = [ - "bootloader 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)", + "bootloader 0.9.7 (registry+https://github.com/rust-lang/crates.io-index)", "x86_64 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -35,7 +43,7 @@ dependencies = [ name = "runner-doctest" version = "0.1.0" dependencies = [ - "bootloader 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)", + "bootloader 0.9.7 (registry+https://github.com/rust-lang/crates.io-index)", "x86_64 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -43,7 +51,7 @@ dependencies = [ name = "runner-test" version = "0.1.0" dependencies = [ - "bootloader 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)", + "bootloader 0.9.7 (registry+https://github.com/rust-lang/crates.io-index)", "x86_64 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -59,5 +67,6 @@ dependencies = [ [metadata] "checksum bit_field 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ed8765909f9009617974ab6b7d332625b320b33c326b1e9321382ef1999b5d56" "checksum bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3d155346769a6855b86399e9bc3814ab343cd3d62c7e985113d46a0ec3c281fd" -"checksum bootloader 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)" = "44ac0bdf4930c3c4d7f0d04eb6f15d7dcb9d5972b1ff9cd2bee0128112260fc7" +"checksum bootloader 0.9.7 (registry+https://github.com/rust-lang/crates.io-index)" = "1e54086033cef68ed4b1729aeb1383a4d2e7d9bacd70db747a0a0bc0a420c831" +"checksum rlibc 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc874b127765f014d792f16763a81245ab80500e2ad921ed4ee9e82481ee08fe" "checksum x86_64 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "365de37eb7c6da582cbb510dd0f3f1235d24ff6309a8a96e8a9909cc9bfd608f" diff --git a/example-kernels/basic/Cargo.toml b/example-kernels/basic/Cargo.toml index 60e18ca..76ddf5d 100644 --- a/example-kernels/basic/Cargo.toml +++ b/example-kernels/basic/Cargo.toml @@ -5,5 +5,5 @@ authors = ["Philipp Oppermann "] edition = "2018" [dependencies] -bootloader = "0.9.3" +bootloader = "0.9.7" x86_64 = "0.11.0" diff --git a/example-kernels/runner-doctest/Cargo.toml b/example-kernels/runner-doctest/Cargo.toml index 2e6dad8..3a162ec 100644 --- a/example-kernels/runner-doctest/Cargo.toml +++ b/example-kernels/runner-doctest/Cargo.toml @@ -5,7 +5,7 @@ authors = ["Philipp Oppermann "] edition = "2018" [dependencies] -bootloader = "0.9.3" +bootloader = "0.9.7" x86_64 = "0.11.0" [package.metadata.bootimage] diff --git a/example-kernels/runner-test/Cargo.toml b/example-kernels/runner-test/Cargo.toml index db005f8..552ff6b 100644 --- a/example-kernels/runner-test/Cargo.toml +++ b/example-kernels/runner-test/Cargo.toml @@ -9,7 +9,7 @@ name = "no-harness" harness = false [dependencies] -bootloader = "0.9.3" +bootloader = "0.9.7" x86_64 = "0.11.0" [package.metadata.bootimage] diff --git a/example-kernels/runner/Cargo.toml b/example-kernels/runner/Cargo.toml index 603ebc8..f1ab3db 100644 --- a/example-kernels/runner/Cargo.toml +++ b/example-kernels/runner/Cargo.toml @@ -5,7 +5,7 @@ authors = ["Philipp Oppermann "] edition = "2018" [dependencies] -bootloader = "0.9.3" +bootloader = "0.9.7" x86_64 = "0.11.0" [package.metadata.bootimage] From 7e5f34389f264e91111254b6eb931a70f140b0a0 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Fri, 17 Jul 2020 10:07:16 +0200 Subject: [PATCH 060/108] Update Readme and help messages for new build-command config key --- Readme.md | 6 +++++- src/help/cargo_bootimage_help.txt | 10 ++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/Readme.md b/Readme.md index 9757b45..be79a2e 100644 --- a/Readme.md +++ b/Readme.md @@ -31,7 +31,7 @@ Now you can build the kernel project and create a bootable disk image from it by cargo bootimage --target your_custom_target.json [other_args] ``` -The command will invoke [`cargo xbuild`](https://github.com/rust-osdev/cargo-xbuild), forwarding all passed options. Then it will build the specified bootloader together with the kernel to create a bootable disk image. +The command will invoke `cargo build`, forwarding all passed options. Then it will build the specified bootloader together with the kernel to create a bootable disk image. ### Running @@ -60,6 +60,10 @@ Configuration is done through a through a `[package.metadata.bootimage]` table i ```toml [package.metadata.bootimage] +# The cargo subcommand that will be used for building the kernel. +# +# For building using the `cargo-xbuild` crate, set this to `xbuild`. +build-command = ["build"] # The command invoked with the created bootimage (the "{}" will be replaced # with the path to the bootable disk image) # Applies to `bootimage run` and `bootimage runner` diff --git a/src/help/cargo_bootimage_help.txt b/src/help/cargo_bootimage_help.txt index f8cabbf..16647ef 100644 --- a/src/help/cargo_bootimage_help.txt +++ b/src/help/cargo_bootimage_help.txt @@ -11,3 +11,13 @@ BUILD_OPTS: is downloaded and built, and then combined with the kernel into a bootable disk image. +CONFIGURATION: + The behavior of `cargo bootimage` can be configured through a + `[package.metadata.bootimage]` table in the `Cargo.toml`. The + following options are available to configure the build behavior: + + [package.metadata.bootimage] + # The cargo subcommand that will be used for building the kernel. + # + # For building using the `cargo-xbuild` crate, set this to `xbuild`. + build-command = ["build"] From f886c1f874f178500983c8bb47692f2ced4fa1a6 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Fri, 17 Jul 2020 10:08:21 +0200 Subject: [PATCH 061/108] Remove mentions of `xbuild` from error variants and code comments --- src/builder/error.rs | 22 +++++++++++----------- src/builder/mod.rs | 16 ++++++++-------- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/src/builder/error.rs b/src/builder/error.rs index 86e6e14..5c0cab1 100644 --- a/src/builder/error.rs +++ b/src/builder/error.rs @@ -29,19 +29,19 @@ pub enum BuildKernelError { )] XbuildNotFound, - /// Running `cargo xbuild` failed. + /// Running `cargo build` failed. #[error("Kernel build failed.\nStderr: {}", String::from_utf8_lossy(.stderr))] - XbuildFailed { + BuildFailed { /// The standard error output. stderr: Vec, }, - /// The output of `cargo xbuild --message-format=json` was not valid UTF-8 + /// The output of `cargo build --message-format=json` was not valid UTF-8 #[error("Output of kernel build with --message-format=json is not valid UTF-8:\n{0}")] - XbuildJsonOutputInvalidUtf8(std::string::FromUtf8Error), - /// The output of `cargo xbuild --message-format=json` was not valid JSON + BuildJsonOutputInvalidUtf8(std::string::FromUtf8Error), + /// The output of `cargo build --message-format=json` was not valid JSON #[error("Output of kernel build with --message-format=json is not valid JSON:\n{0}")] - XbuildJsonOutputInvalidJson(json::Error), + BuildJsonOutputInvalidJson(json::Error), } /// Represents an error that occurred when creating a bootimage. @@ -59,7 +59,7 @@ pub enum CreateBootimageError { /// Building the bootloader failed #[error("Bootloader build failed.\nStderr: {}", String::from_utf8_lossy(.stderr))] BootloaderBuildFailed { - /// The `cargo xbuild` output to standard error + /// The `cargo build` output to standard error stderr: Vec, }, @@ -76,12 +76,12 @@ pub enum CreateBootimageError { error: io::Error, }, - /// The output of `cargo xbuild --message-format=json` was not valid UTF-8 + /// The output of `cargo build --message-format=json` was not valid UTF-8 #[error("Output of bootloader build with --message-format=json is not valid UTF-8:\n{0}")] - XbuildJsonOutputInvalidUtf8(std::string::FromUtf8Error), - /// The output of `cargo xbuild --message-format=json` was not valid JSON + BuildJsonOutputInvalidUtf8(std::string::FromUtf8Error), + /// The output of `cargo build --message-format=json` was not valid JSON #[error("Output of bootloader build with --message-format=json is not valid JSON:\n{0}")] - XbuildJsonOutputInvalidJson(json::Error), + BuildJsonOutputInvalidJson(json::Error), } /// There is something wrong with the bootloader dependency. diff --git a/src/builder/mod.rs b/src/builder/mod.rs index 1474bfd..46e9361 100644 --- a/src/builder/mod.rs +++ b/src/builder/mod.rs @@ -38,7 +38,7 @@ impl Builder { &self.manifest_path } - /// Builds the kernel by executing `cargo xbuild` with the given arguments. + /// Builds the kernel by executing `cargo build` with the given arguments. /// /// Returns a list of paths to all built executables. For crates with only a single binary, /// the returned list contains only a single element. @@ -54,7 +54,7 @@ impl Builder { println!("Building kernel"); } - // try to run cargo xbuild + // try to build kernel let cargo = std::env::var("CARGO").unwrap_or_else(|_| "cargo".to_owned()); let mut cmd = process::Command::new(&cargo); cmd.args(&config.build_command); @@ -80,7 +80,7 @@ impl Builder { } } } - return Err(BuildKernelError::XbuildFailed { + return Err(BuildKernelError::BuildFailed { stderr: output.stderr, }); } @@ -95,17 +95,17 @@ impl Builder { error: err, })?; if !output.status.success() { - return Err(BuildKernelError::XbuildFailed { + return Err(BuildKernelError::BuildFailed { stderr: output.stderr, }); } let mut executables = Vec::new(); for line in String::from_utf8(output.stdout) - .map_err(BuildKernelError::XbuildJsonOutputInvalidUtf8)? + .map_err(BuildKernelError::BuildJsonOutputInvalidUtf8)? .lines() { let mut artifact = - json::parse(line).map_err(BuildKernelError::XbuildJsonOutputInvalidJson)?; + json::parse(line).map_err(BuildKernelError::BuildJsonOutputInvalidJson)?; if let Some(executable) = artifact["executable"].take_string() { executables.push(PathBuf::from(executable)); } @@ -165,11 +165,11 @@ impl Builder { } let mut bootloader_elf_path = None; for line in String::from_utf8(output.stdout) - .map_err(CreateBootimageError::XbuildJsonOutputInvalidUtf8)? + .map_err(CreateBootimageError::BuildJsonOutputInvalidUtf8)? .lines() { let mut artifact = - json::parse(line).map_err(CreateBootimageError::XbuildJsonOutputInvalidJson)?; + json::parse(line).map_err(CreateBootimageError::BuildJsonOutputInvalidJson)?; if let Some(executable) = artifact["executable"].take_string() { if bootloader_elf_path .replace(PathBuf::from(executable)) From 2cb9a9753890fbe5f407cfa3915311c7b0bb7779 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Fri, 17 Jul 2020 10:06:44 +0200 Subject: [PATCH 062/108] Don't install cargo-xbuild on CI It should be no longer necessary. --- .github/workflows/build.yml | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index d2de177..1c42ab5 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -62,8 +62,6 @@ jobs: - name: "Install Rustup Components" run: rustup component add rust-src llvm-tools-preview - - name: "Install cargo-xbuild" - run: cargo install cargo-xbuild --debug # install QEMU - name: Install QEMU (Linux) @@ -103,20 +101,20 @@ jobs: shell: bash {0} working-directory: example-kernels - - name: 'Run `cargo xrun` for "runner" kernel' + - name: 'Run `cargo run` for "runner" kernel' run: | - cargo xrun + cargo run if [ $? -eq 109 ]; then (exit 0); else (exit 1); fi shell: bash {0} working-directory: example-kernels/runner - - run: cargo xtest + - run: cargo test working-directory: example-kernels/runner-test - name: 'Run `cargo xtest` for "runner-test" kernel' + name: 'Run `cargo test` for "runner-test" kernel' - - run: cargo xtest -Z doctest-xcompile + - run: cargo test -Z doctest-xcompile working-directory: example-kernels/runner-doctest - name: 'Run `cargo xtest -Z doctest-xcompile` for "runner-doctest" kernel' + name: 'Run `cargo test -Z doctest-xcompile` for "runner-doctest" kernel' check_formatting: name: "Check Formatting" From 8271e9e9b57cc2523b46ddbf18aba9100e40881c Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Fri, 17 Jul 2020 10:18:40 +0200 Subject: [PATCH 063/108] Fix clippy warning (`unwrap_or` followed by function call) --- src/config.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/config.rs b/src/config.rs index bbed314..ed909e7 100644 --- a/src/config.rs +++ b/src/config.rs @@ -128,7 +128,7 @@ struct ConfigBuilder { impl Into for ConfigBuilder { fn into(self) -> Config { Config { - build_command: self.build_command.unwrap_or(vec!["build".into()]), + build_command: self.build_command.unwrap_or_else(|| vec!["build".into()]), run_command: self.run_command.unwrap_or_else(|| { vec![ "qemu-system-x86_64".into(), From b3aaf4f1810fe61e3cacd6eae435fdbc5e28dbaa Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Fri, 17 Jul 2020 10:23:47 +0200 Subject: [PATCH 064/108] Add rlibc dependency where needed to example kernels --- example-kernels/runner-doctest/Cargo.toml | 1 + example-kernels/runner-doctest/src/lib.rs | 2 ++ example-kernels/runner-test/Cargo.toml | 1 + example-kernels/runner-test/src/lib.rs | 2 ++ 4 files changed, 6 insertions(+) diff --git a/example-kernels/runner-doctest/Cargo.toml b/example-kernels/runner-doctest/Cargo.toml index 3a162ec..d1610e2 100644 --- a/example-kernels/runner-doctest/Cargo.toml +++ b/example-kernels/runner-doctest/Cargo.toml @@ -7,6 +7,7 @@ edition = "2018" [dependencies] bootloader = "0.9.7" x86_64 = "0.11.0" +rlibc = "1.0.0" [package.metadata.bootimage] test-success-exit-code = 33 # (0x10 << 1) | 1 diff --git a/example-kernels/runner-doctest/src/lib.rs b/example-kernels/runner-doctest/src/lib.rs index 3cdb90f..437f374 100644 --- a/example-kernels/runner-doctest/src/lib.rs +++ b/example-kernels/runner-doctest/src/lib.rs @@ -4,6 +4,8 @@ #![test_runner(crate::test_runner)] #![reexport_test_harness_main = "test_main"] +extern crate rlibc; + /// add two numbers /// /// ``` diff --git a/example-kernels/runner-test/Cargo.toml b/example-kernels/runner-test/Cargo.toml index 552ff6b..854ceb9 100644 --- a/example-kernels/runner-test/Cargo.toml +++ b/example-kernels/runner-test/Cargo.toml @@ -11,6 +11,7 @@ harness = false [dependencies] bootloader = "0.9.7" x86_64 = "0.11.0" +rlibc = "1.0.0" [package.metadata.bootimage] test-success-exit-code = 33 # (0x10 << 1) | 1 diff --git a/example-kernels/runner-test/src/lib.rs b/example-kernels/runner-test/src/lib.rs index 64c2518..740e7a9 100644 --- a/example-kernels/runner-test/src/lib.rs +++ b/example-kernels/runner-test/src/lib.rs @@ -5,6 +5,8 @@ #![test_runner(crate::test_runner)] #![reexport_test_harness_main = "test_main"] +extern crate rlibc; + pub fn test_runner(tests: &[&dyn Fn()]) { for test in tests.iter() { test(); From 6f04c2de3d030c8bfb6686afc851d9aa31349169 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Fri, 17 Jul 2020 10:26:32 +0200 Subject: [PATCH 065/108] Update changelog for #63 --- Changelog.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Changelog.md b/Changelog.md index 800bea3..81903e6 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,5 +1,7 @@ # Unreleased +- **Breaking:** Make `cargo bootimage` use `cargo build` instead of `cargo xbuild` ([#63](https://github.com/rust-osdev/bootimage/pull/63)) + # 0.8.1 – 2020-07-17 - Add support for building bootloaders using `-Zbuild-std ([#62](https://github.com/rust-osdev/bootimage/pull/62)) From 1f48d1ceefb0b3f3298617628b29ea390e438c85 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Fri, 17 Jul 2020 10:39:50 +0200 Subject: [PATCH 066/108] Release version 0.9.0 --- Cargo.lock | 2 +- Cargo.toml | 2 +- Changelog.md | 2 ++ 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7b1283c..9007b76 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7,7 +7,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "bootimage" -version = "0.8.1" +version = "0.9.0" dependencies = [ "anyhow 1.0.28 (registry+https://github.com/rust-lang/crates.io-index)", "cargo_metadata 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/Cargo.toml b/Cargo.toml index 29299c1..99ec701 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,7 +3,7 @@ authors = ["Philipp Oppermann "] description = "Tool to create a bootable OS image from a kernel binary." license = "MIT/Apache-2.0" name = "bootimage" -version = "0.8.1" +version = "0.9.0" repository = "https://github.com/rust-osdev/bootimage" edition = "2018" diff --git a/Changelog.md b/Changelog.md index 81903e6..91f3181 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,5 +1,7 @@ # Unreleased +# 0.9.0 – 2020-07-17 + - **Breaking:** Make `cargo bootimage` use `cargo build` instead of `cargo xbuild` ([#63](https://github.com/rust-osdev/bootimage/pull/63)) # 0.8.1 – 2020-07-17 From 1c3750d5c3d0b6a0ed6ee452c99d164344d1a698 Mon Sep 17 00:00:00 2001 From: Tom Dohrmann Date: Wed, 29 Jul 2020 12:35:25 +0200 Subject: [PATCH 067/108] fix test code check --- src/run.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/run.rs b/src/run.rs index 7ca4f30..8020f10 100644 --- a/src/run.rs +++ b/src/run.rs @@ -69,6 +69,7 @@ pub fn run( let qemu_exit_code = exit_status.code().ok_or(RunError::NoQemuExitCode)?; match config.test_success_exit_code { Some(code) if qemu_exit_code == code => 0, + Some(_) if qemu_exit_code == 0 => 1, _ => qemu_exit_code, } } From a82ccff1115db503a7a3fda90b5d469c83b78778 Mon Sep 17 00:00:00 2001 From: Tom Dohrmann Date: Wed, 29 Jul 2020 13:06:44 +0200 Subject: [PATCH 068/108] add no-reboot --- src/config.rs | 9 +++++++++ src/run.rs | 3 +++ 2 files changed, 12 insertions(+) diff --git a/src/config.rs b/src/config.rs index ed909e7..c507b5c 100644 --- a/src/config.rs +++ b/src/config.rs @@ -33,6 +33,10 @@ pub struct Config { /// An exit code that should be considered as success for test executables (applies to /// `bootimage runner`) pub test_success_exit_code: Option, + /// Whether the `--no-reboot` flag should be passed to test executables + /// + /// Defaults to `true` + pub test_no_reboot: bool, } /// Reads the configuration from a `package.metadata.bootimage` in the given Cargo.toml. @@ -91,6 +95,9 @@ fn read_config_inner(manifest_path: &Path) -> Result { ("test-args", Value::Array(array)) => { config.test_args = Some(parse_string_array(array, "test-args")?); } + ("test-no-reboot", Value::Boolean(no_reboot)) => { + config.test_no_reboot = Some(no_reboot); + } (key, value) => { return Err(anyhow!( "unexpected `package.metadata.bootimage` \ @@ -123,6 +130,7 @@ struct ConfigBuilder { test_args: Option>, test_timeout: Option, test_success_exit_code: Option, + test_no_reboot: Option, } impl Into for ConfigBuilder { @@ -140,6 +148,7 @@ impl Into for ConfigBuilder { test_args: self.test_args, test_timeout: self.test_timeout.unwrap_or(60 * 5), test_success_exit_code: self.test_success_exit_code, + test_no_reboot: self.test_no_reboot.unwrap_or(true), } } } diff --git a/src/run.rs b/src/run.rs index 8020f10..1323473 100644 --- a/src/run.rs +++ b/src/run.rs @@ -23,6 +23,9 @@ pub fn run( .map(|arg| arg.replace("{}", &format!("{}", image_path.display()))) .collect(); if is_test { + if config.test_no_reboot { + run_command.push("--no-reboot".to_owned()); + } if let Some(args) = config.test_args { run_command.extend(args); } From a99fc04b045c8327f8724af32ba0288fc4bb1b4b Mon Sep 17 00:00:00 2001 From: Tom Dohrmann Date: Wed, 29 Jul 2020 13:06:55 +0200 Subject: [PATCH 069/108] update documentation --- Readme.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Readme.md b/Readme.md index be79a2e..04f6398 100644 --- a/Readme.md +++ b/Readme.md @@ -82,6 +82,9 @@ test-success-exit-code = {integer} # The timeout for running a test through `bootimage test` or `bootimage runner` (in seconds) test-timeout = 300 + +# Whether the `--no-reboot` flag should be passed to test executables +test-no-reboot = true ``` ## License From b5fc228701ab8cb5cc2c1124d4750799a7ba2d4f Mon Sep 17 00:00:00 2001 From: Tom Dohrmann Date: Wed, 29 Jul 2020 13:09:44 +0200 Subject: [PATCH 070/108] add tests --- .github/workflows/build.yml | 4 ++ example-kernels/Cargo.lock | 11 +++ example-kernels/Cargo.toml | 1 + .../runner-fail-reboot/.cargo/config | 5 ++ example-kernels/runner-fail-reboot/.gitignore | 2 + example-kernels/runner-fail-reboot/Cargo.toml | 14 ++++ example-kernels/runner-fail-reboot/src/lib.rs | 71 +++++++++++++++++++ 7 files changed, 108 insertions(+) create mode 100644 example-kernels/runner-fail-reboot/.cargo/config create mode 100644 example-kernels/runner-fail-reboot/.gitignore create mode 100644 example-kernels/runner-fail-reboot/Cargo.toml create mode 100644 example-kernels/runner-fail-reboot/src/lib.rs diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 1c42ab5..812dee5 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -116,6 +116,10 @@ jobs: working-directory: example-kernels/runner-doctest name: 'Run `cargo test -Z doctest-xcompile` for "runner-doctest" kernel' + - run: cargo test + working-directory: example-kernels/runner-fail-reboot + name: 'Run `cargo test` for "runner-fail-reboot" kernel' + check_formatting: name: "Check Formatting" runs-on: ubuntu-latest diff --git a/example-kernels/Cargo.lock b/example-kernels/Cargo.lock index 514e054..b408e98 100644 --- a/example-kernels/Cargo.lock +++ b/example-kernels/Cargo.lock @@ -44,6 +44,16 @@ name = "runner-doctest" version = "0.1.0" dependencies = [ "bootloader 0.9.7 (registry+https://github.com/rust-lang/crates.io-index)", + "rlibc 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "x86_64 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "runner-fail-reboot" +version = "0.1.0" +dependencies = [ + "bootloader 0.9.7 (registry+https://github.com/rust-lang/crates.io-index)", + "rlibc 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "x86_64 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -52,6 +62,7 @@ name = "runner-test" version = "0.1.0" dependencies = [ "bootloader 0.9.7 (registry+https://github.com/rust-lang/crates.io-index)", + "rlibc 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "x86_64 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", ] diff --git a/example-kernels/Cargo.toml b/example-kernels/Cargo.toml index 3375f98..e20e2aa 100644 --- a/example-kernels/Cargo.toml +++ b/example-kernels/Cargo.toml @@ -3,5 +3,6 @@ members = [ "basic", "runner", "runner-doctest", + "runner-fail-reboot", "runner-test", ] diff --git a/example-kernels/runner-fail-reboot/.cargo/config b/example-kernels/runner-fail-reboot/.cargo/config new file mode 100644 index 0000000..3b4d89e --- /dev/null +++ b/example-kernels/runner-fail-reboot/.cargo/config @@ -0,0 +1,5 @@ +[build] +target = "../x86_64-bootimage-example-kernels.json" + +[target.'cfg(target_os = "none")'] +runner = "bootimage runner" diff --git a/example-kernels/runner-fail-reboot/.gitignore b/example-kernels/runner-fail-reboot/.gitignore new file mode 100644 index 0000000..eccd7b4 --- /dev/null +++ b/example-kernels/runner-fail-reboot/.gitignore @@ -0,0 +1,2 @@ +/target/ +**/*.rs.bk diff --git a/example-kernels/runner-fail-reboot/Cargo.toml b/example-kernels/runner-fail-reboot/Cargo.toml new file mode 100644 index 0000000..14cb98a --- /dev/null +++ b/example-kernels/runner-fail-reboot/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "runner-fail-reboot" +version = "0.1.0" +authors = ["Philipp Oppermann "] +edition = "2018" + +[dependencies] +bootloader = "0.9.7" +x86_64 = "0.11.0" +rlibc = "1.0.0" + +[package.metadata.bootimage] +test-success-exit-code = 0 # this will test for the reboot +test-args = ["-device", "isa-debug-exit,iobase=0xf4,iosize=0x04", "-display", "none"] diff --git a/example-kernels/runner-fail-reboot/src/lib.rs b/example-kernels/runner-fail-reboot/src/lib.rs new file mode 100644 index 0000000..3472c56 --- /dev/null +++ b/example-kernels/runner-fail-reboot/src/lib.rs @@ -0,0 +1,71 @@ +#![no_std] +#![cfg_attr(test, no_main)] +#![feature(custom_test_frameworks)] +#![test_runner(crate::test_runner)] +#![reexport_test_harness_main = "test_main"] + +extern crate rlibc; + +pub fn test_runner(tests: &[&dyn Fn()]) { + for test in tests.iter() { + test(); + } + + unsafe { + exit_qemu(ExitCode::Success); + } +} + +#[test_case] +fn should_reboot() { + // this overflows the stack which leads to a triple fault + // the as-if rule might allow this to get optimized away on release builds + #[allow(unconditional_recursion)] + fn stack_overflow() { + stack_overflow() + } + stack_overflow() +} + +pub enum ExitCode { + Success, + Failed, +} + +impl ExitCode { + fn code(&self) -> u32 { + match self { + ExitCode::Success => 0x10, + ExitCode::Failed => 0x11, + } + } +} + +/// exit QEMU (see https://os.phil-opp.com/integration-tests/#shutting-down-qemu) +pub unsafe fn exit_qemu(exit_code: ExitCode) { + use x86_64::instructions::port::Port; + + let mut port = Port::::new(0xf4); + port.write(exit_code.code()); +} + +#[cfg(test)] +#[no_mangle] +pub extern "C" fn _start() -> ! { + test_main(); + + unsafe { + exit_qemu(ExitCode::Failed); + } + + loop {} +} + +#[cfg(test)] +#[panic_handler] +fn panic(_info: &core::panic::PanicInfo) -> ! { + unsafe { + exit_qemu(ExitCode::Failed); + } + loop {} +} From 7c686f127240bb2f7ec432c816e984e5e6c6bf2e Mon Sep 17 00:00:00 2001 From: Tom Dohrmann Date: Wed, 29 Jul 2020 13:14:30 +0200 Subject: [PATCH 071/108] change "--no-reboot" to "-no-reboot" --- Readme.md | 2 +- src/config.rs | 2 +- src/run.rs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Readme.md b/Readme.md index 04f6398..59ee0e3 100644 --- a/Readme.md +++ b/Readme.md @@ -83,7 +83,7 @@ test-success-exit-code = {integer} # The timeout for running a test through `bootimage test` or `bootimage runner` (in seconds) test-timeout = 300 -# Whether the `--no-reboot` flag should be passed to test executables +# Whether the `-no-reboot` flag should be passed to test executables test-no-reboot = true ``` diff --git a/src/config.rs b/src/config.rs index c507b5c..3bed52a 100644 --- a/src/config.rs +++ b/src/config.rs @@ -33,7 +33,7 @@ pub struct Config { /// An exit code that should be considered as success for test executables (applies to /// `bootimage runner`) pub test_success_exit_code: Option, - /// Whether the `--no-reboot` flag should be passed to test executables + /// Whether the `-no-reboot` flag should be passed to test executables /// /// Defaults to `true` pub test_no_reboot: bool, diff --git a/src/run.rs b/src/run.rs index 1323473..562b57d 100644 --- a/src/run.rs +++ b/src/run.rs @@ -24,7 +24,7 @@ pub fn run( .collect(); if is_test { if config.test_no_reboot { - run_command.push("--no-reboot".to_owned()); + run_command.push("-no-reboot".to_owned()); } if let Some(args) = config.test_args { run_command.extend(args); From 5257683b6487b22e3b893f1bc32a69ade5b612e4 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Mon, 3 Aug 2020 16:00:19 +0200 Subject: [PATCH 072/108] Update changelog for #65 --- Changelog.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Changelog.md b/Changelog.md index 91f3181..fda6f62 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,5 +1,8 @@ # Unreleased +- **Breaking:** Consider all other exit codes besides 'test-success-exit-code' as failures ([#65](https://github.com/rust-osdev/bootimage/pull/65)) + - Also runs tests with `-no-reboot` by default, configurable through a new `test-no-reboot` config key + # 0.9.0 – 2020-07-17 - **Breaking:** Make `cargo bootimage` use `cargo build` instead of `cargo xbuild` ([#63](https://github.com/rust-osdev/bootimage/pull/63)) From 2135e0a43fe5fded3dd304f65d189b69a56c3e84 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Mon, 3 Aug 2020 16:00:33 +0200 Subject: [PATCH 073/108] Release version 0.10.0 --- Cargo.lock | 2 +- Cargo.toml | 2 +- Changelog.md | 2 ++ 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9007b76..1d418a2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7,7 +7,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "bootimage" -version = "0.9.0" +version = "0.10.0" dependencies = [ "anyhow 1.0.28 (registry+https://github.com/rust-lang/crates.io-index)", "cargo_metadata 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/Cargo.toml b/Cargo.toml index 99ec701..6c2e7e8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,7 +3,7 @@ authors = ["Philipp Oppermann "] description = "Tool to create a bootable OS image from a kernel binary." license = "MIT/Apache-2.0" name = "bootimage" -version = "0.9.0" +version = "0.10.0" repository = "https://github.com/rust-osdev/bootimage" edition = "2018" diff --git a/Changelog.md b/Changelog.md index fda6f62..31fd7e7 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,5 +1,7 @@ # Unreleased +# 0.10.0 – 2020-08-03 + - **Breaking:** Consider all other exit codes besides 'test-success-exit-code' as failures ([#65](https://github.com/rust-osdev/bootimage/pull/65)) - Also runs tests with `-no-reboot` by default, configurable through a new `test-no-reboot` config key From d6dfb49b8de9105cc6e7b5907a58d73e82b7c90d Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Mon, 3 Aug 2020 16:07:18 +0200 Subject: [PATCH 074/108] Parse `--version` argument without subcommand (`bootimage --version`) --- src/main.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main.rs b/src/main.rs index 28cc054..3cb34ed 100644 --- a/src/main.rs +++ b/src/main.rs @@ -29,6 +29,10 @@ pub fn main() -> Result<()> { help::print_help(); return Ok(()) } + Some("--version") => { + help::print_version(); + return Ok(()) + } Some(other) => return Err(anyhow!( "Unsupported subcommand `{:?}`. See `bootimage --help` for an overview of supported subcommands.", other )), From fc04da085967b704196e6965453eedd135df332d Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Mon, 3 Aug 2020 16:09:32 +0200 Subject: [PATCH 075/108] Update changelog for #67 --- Changelog.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Changelog.md b/Changelog.md index 31fd7e7..02bc9c9 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,5 +1,7 @@ # Unreleased +- Parse `--version` argument without subcommand (`bootimage --version`) ([#67](https://github.com/rust-osdev/bootimage/pull/67)) + # 0.10.0 – 2020-08-03 - **Breaking:** Consider all other exit codes besides 'test-success-exit-code' as failures ([#65](https://github.com/rust-osdev/bootimage/pull/65)) From a7bf3b7773ef8445faddc14a5d710333b33be3b7 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Mon, 3 Aug 2020 16:17:28 +0200 Subject: [PATCH 076/108] Release version 0.10.1 --- Cargo.lock | 2 +- Cargo.toml | 2 +- Changelog.md | 2 ++ 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1d418a2..d7bb16b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7,7 +7,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "bootimage" -version = "0.10.0" +version = "0.10.1" dependencies = [ "anyhow 1.0.28 (registry+https://github.com/rust-lang/crates.io-index)", "cargo_metadata 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/Cargo.toml b/Cargo.toml index 6c2e7e8..d080026 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,7 +3,7 @@ authors = ["Philipp Oppermann "] description = "Tool to create a bootable OS image from a kernel binary." license = "MIT/Apache-2.0" name = "bootimage" -version = "0.10.0" +version = "0.10.1" repository = "https://github.com/rust-osdev/bootimage" edition = "2018" diff --git a/Changelog.md b/Changelog.md index 02bc9c9..3db819f 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,5 +1,7 @@ # Unreleased +# 0.10.1 – 2020-08-03 + - Parse `--version` argument without subcommand (`bootimage --version`) ([#67](https://github.com/rust-osdev/bootimage/pull/67)) # 0.10.0 – 2020-08-03 From c6030edf5d2e6139e7622742cd16ea338bcae59d Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Mon, 31 Aug 2020 08:22:43 +0200 Subject: [PATCH 077/108] Run cargo update --- Cargo.lock | 105 ++++++++++++++++++++++++++--------------------------- 1 file changed, 52 insertions(+), 53 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d7bb16b..7380558 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,19 +2,19 @@ # It is not intended for manual editing. [[package]] name = "anyhow" -version = "1.0.28" +version = "1.0.32" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "bootimage" version = "0.10.1" dependencies = [ - "anyhow 1.0.28 (registry+https://github.com/rust-lang/crates.io-index)", + "anyhow 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)", "cargo_metadata 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", "json 0.12.4 (registry+https://github.com/rust-lang/crates.io-index)", "llvm-tools 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "locate-cargo-manifest 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "thiserror 1.0.16 (registry+https://github.com/rust-lang/crates.io-index)", + "locate-cargo-manifest 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "thiserror 1.0.20 (registry+https://github.com/rust-lang/crates.io-index)", "toml 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", "wait-timeout 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -25,14 +25,14 @@ version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.106 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.106 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.52 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.115 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.115 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.57 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "itoa" -version = "0.4.5" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -42,7 +42,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "libc" -version = "0.2.69" +version = "0.2.76" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -52,32 +52,31 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "locate-cargo-manifest" -version = "0.2.0" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "json 0.12.4 (registry+https://github.com/rust-lang/crates.io-index)", - "thiserror 1.0.16 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "proc-macro2" -version = "1.0.12" +version = "1.0.19" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-xid 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "quote" -version = "1.0.4" +version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro2 1.0.12 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "ryu" -version = "1.0.4" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -86,7 +85,7 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.106 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.115 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -96,55 +95,55 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "serde" -version = "1.0.106" +version = "1.0.115" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "serde_derive" -version = "1.0.106" +version = "1.0.115" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro2 1.0.12 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "serde_json" -version = "1.0.52" +version = "1.0.57" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "itoa 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", - "ryu 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.106 (registry+https://github.com/rust-lang/crates.io-index)", + "itoa 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "ryu 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.115 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "syn" -version = "1.0.18" +version = "1.0.39" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro2 1.0.12 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-xid 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "thiserror" -version = "1.0.16" +version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "thiserror-impl 1.0.16 (registry+https://github.com/rust-lang/crates.io-index)", + "thiserror-impl 1.0.20 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "thiserror-impl" -version = "1.0.16" +version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro2 1.0.12 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -152,12 +151,12 @@ name = "toml" version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "serde 1.0.106 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.115 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "unicode-xid" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -165,28 +164,28 @@ name = "wait-timeout" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.69 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.76 (registry+https://github.com/rust-lang/crates.io-index)", ] [metadata] -"checksum anyhow 1.0.28 (registry+https://github.com/rust-lang/crates.io-index)" = "d9a60d744a80c30fcb657dfe2c1b22bcb3e814c1a1e3674f32bf5820b570fbff" +"checksum anyhow 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)" = "6b602bfe940d21c130f3895acd65221e8a61270debe89d628b9cb4e3ccb8569b" "checksum cargo_metadata 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "46e3374c604fb39d1a2f35ed5e4a4e30e60d01fab49446e08f1b3e9a90aef202" -"checksum itoa 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "b8b7a7c0c47db5545ed3fef7468ee7bb5b74691498139e4b3f6a20685dc6dd8e" +"checksum itoa 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "dc6f3ad7b9d11a0c00842ff8de1b60ee58661048eb8049ed33c73594f359d7e6" "checksum json 0.12.4 (registry+https://github.com/rust-lang/crates.io-index)" = "078e285eafdfb6c4b434e0d31e8cfcb5115b651496faca5749b88fafd4f23bfd" -"checksum libc 0.2.69 (registry+https://github.com/rust-lang/crates.io-index)" = "99e85c08494b21a9054e7fe1374a732aeadaff3980b6990b94bfd3a70f690005" +"checksum libc 0.2.76 (registry+https://github.com/rust-lang/crates.io-index)" = "755456fae044e6fa1ebbbd1b3e902ae19e73097ed4ed87bb79934a867c007bc3" "checksum llvm-tools 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "955be5d0ca0465caf127165acb47964f911e2bc26073e865deb8be7189302faf" -"checksum locate-cargo-manifest 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d264d672563b20c0a2eb9045f4072e1352002f6c316cc0677bed8b767e17b7e1" -"checksum proc-macro2 1.0.12 (registry+https://github.com/rust-lang/crates.io-index)" = "8872cf6f48eee44265156c111456a700ab3483686b3f96df4cf5481c89157319" -"checksum quote 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "4c1f4b0efa5fc5e8ceb705136bfee52cfdb6a4e3509f770b478cd6ed434232a7" -"checksum ryu 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "ed3d612bc64430efeb3f7ee6ef26d590dce0c43249217bddc62112540c7941e1" +"checksum locate-cargo-manifest 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "db985b63431fe09e8d71f50aeceffcc31e720cb86be8dad2f38d084c5a328466" +"checksum proc-macro2 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)" = "04f5f085b5d71e2188cb8271e5da0161ad52c3f227a661a3c135fdf28e258b12" +"checksum quote 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)" = "aa563d17ecb180e500da1cfd2b028310ac758de548efdd203e18f283af693f37" +"checksum ryu 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" "checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" "checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" -"checksum serde 1.0.106 (registry+https://github.com/rust-lang/crates.io-index)" = "36df6ac6412072f67cf767ebbde4133a5b2e88e76dc6187fa7104cd16f783399" -"checksum serde_derive 1.0.106 (registry+https://github.com/rust-lang/crates.io-index)" = "9e549e3abf4fb8621bd1609f11dfc9f5e50320802273b12f3811a67e6716ea6c" -"checksum serde_json 1.0.52 (registry+https://github.com/rust-lang/crates.io-index)" = "a7894c8ed05b7a3a279aeb79025fdec1d3158080b75b98a08faf2806bb799edd" -"checksum syn 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)" = "410a7488c0a728c7ceb4ad59b9567eb4053d02e8cc7f5c0e0eeeb39518369213" -"checksum thiserror 1.0.16 (registry+https://github.com/rust-lang/crates.io-index)" = "d12a1dae4add0f0d568eebc7bf142f145ba1aa2544cafb195c76f0f409091b60" -"checksum thiserror-impl 1.0.16 (registry+https://github.com/rust-lang/crates.io-index)" = "3f34e0c1caaa462fd840ec6b768946ea1e7842620d94fe29d5b847138f521269" +"checksum serde 1.0.115 (registry+https://github.com/rust-lang/crates.io-index)" = "e54c9a88f2da7238af84b5101443f0c0d0a3bbdc455e34a5c9497b1903ed55d5" +"checksum serde_derive 1.0.115 (registry+https://github.com/rust-lang/crates.io-index)" = "609feed1d0a73cc36a0182a840a9b37b4a82f0b1150369f0536a9e3f2a31dc48" +"checksum serde_json 1.0.57 (registry+https://github.com/rust-lang/crates.io-index)" = "164eacbdb13512ec2745fb09d51fd5b22b0d65ed294a1dcf7285a360c80a675c" +"checksum syn 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)" = "891d8d6567fe7c7f8835a3a98af4208f3846fba258c1bc3c31d6e506239f11f9" +"checksum thiserror 1.0.20 (registry+https://github.com/rust-lang/crates.io-index)" = "7dfdd070ccd8ccb78f4ad66bf1982dc37f620ef696c6b5028fe2ed83dd3d0d08" +"checksum thiserror-impl 1.0.20 (registry+https://github.com/rust-lang/crates.io-index)" = "bd80fc12f73063ac132ac92aceea36734f04a1d93c1240c6944e23a3b8841793" "checksum toml 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "ffc92d160b1eef40665be3a05630d003936a3bc7da7421277846c2613e92c71a" -"checksum unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c" +"checksum unicode-xid 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564" "checksum wait-timeout 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9f200f5b12eb75f8c1ed65abd4b2db8a6e1b138a20de009dacee265a2498f3f6" From f0052af615b3181f2c37dbdd479d74f554a1d313 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Thu, 24 Sep 2020 10:31:05 +0200 Subject: [PATCH 078/108] Update example kernels to x86_64 v0.12.1 --- example-kernels/Cargo.lock | 51 +++++++++---------- example-kernels/basic/Cargo.toml | 2 +- example-kernels/runner-doctest/Cargo.toml | 2 +- example-kernels/runner-fail-reboot/Cargo.toml | 2 +- example-kernels/runner-test/Cargo.toml | 2 +- example-kernels/runner/Cargo.toml | 2 +- 6 files changed, 28 insertions(+), 33 deletions(-) diff --git a/example-kernels/Cargo.lock b/example-kernels/Cargo.lock index b408e98..01059f1 100644 --- a/example-kernels/Cargo.lock +++ b/example-kernels/Cargo.lock @@ -4,80 +4,75 @@ name = "basic" version = "0.1.0" dependencies = [ - "bootloader 0.9.7 (registry+https://github.com/rust-lang/crates.io-index)", - "x86_64 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", + "bootloader", + "x86_64", ] [[package]] name = "bit_field" version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed8765909f9009617974ab6b7d332625b320b33c326b1e9321382ef1999b5d56" [[package]] name = "bitflags" -version = "1.1.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" [[package]] name = "bootloader" -version = "0.9.7" +version = "0.9.10" source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "rlibc 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", -] +checksum = "8c5c959bf675ba4d842740373760b2aeb5b8f5457451cd18370b4c339d4926e9" [[package]] name = "rlibc" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc874b127765f014d792f16763a81245ab80500e2ad921ed4ee9e82481ee08fe" [[package]] name = "runner" version = "0.1.0" dependencies = [ - "bootloader 0.9.7 (registry+https://github.com/rust-lang/crates.io-index)", - "x86_64 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", + "bootloader", + "x86_64", ] [[package]] name = "runner-doctest" version = "0.1.0" dependencies = [ - "bootloader 0.9.7 (registry+https://github.com/rust-lang/crates.io-index)", - "rlibc 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "x86_64 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", + "bootloader", + "rlibc", + "x86_64", ] [[package]] name = "runner-fail-reboot" version = "0.1.0" dependencies = [ - "bootloader 0.9.7 (registry+https://github.com/rust-lang/crates.io-index)", - "rlibc 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "x86_64 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", + "bootloader", + "rlibc", + "x86_64", ] [[package]] name = "runner-test" version = "0.1.0" dependencies = [ - "bootloader 0.9.7 (registry+https://github.com/rust-lang/crates.io-index)", - "rlibc 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "x86_64 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", + "bootloader", + "rlibc", + "x86_64", ] [[package]] name = "x86_64" -version = "0.11.0" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "238a5798f77641af3c4f242bf985807f312a480cd4e35ed7255fad4b2ccb9d4f" dependencies = [ - "bit_field 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", - "bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "bit_field", + "bitflags", ] - -[metadata] -"checksum bit_field 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ed8765909f9009617974ab6b7d332625b320b33c326b1e9321382ef1999b5d56" -"checksum bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3d155346769a6855b86399e9bc3814ab343cd3d62c7e985113d46a0ec3c281fd" -"checksum bootloader 0.9.7 (registry+https://github.com/rust-lang/crates.io-index)" = "1e54086033cef68ed4b1729aeb1383a4d2e7d9bacd70db747a0a0bc0a420c831" -"checksum rlibc 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc874b127765f014d792f16763a81245ab80500e2ad921ed4ee9e82481ee08fe" -"checksum x86_64 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "365de37eb7c6da582cbb510dd0f3f1235d24ff6309a8a96e8a9909cc9bfd608f" diff --git a/example-kernels/basic/Cargo.toml b/example-kernels/basic/Cargo.toml index 76ddf5d..6c4c797 100644 --- a/example-kernels/basic/Cargo.toml +++ b/example-kernels/basic/Cargo.toml @@ -6,4 +6,4 @@ edition = "2018" [dependencies] bootloader = "0.9.7" -x86_64 = "0.11.0" +x86_64 = "0.12.1" diff --git a/example-kernels/runner-doctest/Cargo.toml b/example-kernels/runner-doctest/Cargo.toml index d1610e2..4f03914 100644 --- a/example-kernels/runner-doctest/Cargo.toml +++ b/example-kernels/runner-doctest/Cargo.toml @@ -6,7 +6,7 @@ edition = "2018" [dependencies] bootloader = "0.9.7" -x86_64 = "0.11.0" +x86_64 = "0.12.1" rlibc = "1.0.0" [package.metadata.bootimage] diff --git a/example-kernels/runner-fail-reboot/Cargo.toml b/example-kernels/runner-fail-reboot/Cargo.toml index 14cb98a..1afe806 100644 --- a/example-kernels/runner-fail-reboot/Cargo.toml +++ b/example-kernels/runner-fail-reboot/Cargo.toml @@ -6,7 +6,7 @@ edition = "2018" [dependencies] bootloader = "0.9.7" -x86_64 = "0.11.0" +x86_64 = "0.12.1" rlibc = "1.0.0" [package.metadata.bootimage] diff --git a/example-kernels/runner-test/Cargo.toml b/example-kernels/runner-test/Cargo.toml index 854ceb9..a92788d 100644 --- a/example-kernels/runner-test/Cargo.toml +++ b/example-kernels/runner-test/Cargo.toml @@ -10,7 +10,7 @@ harness = false [dependencies] bootloader = "0.9.7" -x86_64 = "0.11.0" +x86_64 = "0.12.1" rlibc = "1.0.0" [package.metadata.bootimage] diff --git a/example-kernels/runner/Cargo.toml b/example-kernels/runner/Cargo.toml index f1ab3db..2951418 100644 --- a/example-kernels/runner/Cargo.toml +++ b/example-kernels/runner/Cargo.toml @@ -6,7 +6,7 @@ edition = "2018" [dependencies] bootloader = "0.9.7" -x86_64 = "0.11.0" +x86_64 = "0.12.1" [package.metadata.bootimage] run-args = ["-device", "isa-debug-exit,iobase=0xf4,iosize=0x04", "-display", "none"] From 7bd56f118e69763e35921c35b56bda8720e2e3e5 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Tue, 29 Sep 2020 10:24:06 +0200 Subject: [PATCH 079/108] Run `cargo update` for example kernels to fix nightly breakage --- example-kernels/Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/example-kernels/Cargo.lock b/example-kernels/Cargo.lock index 01059f1..712ea6c 100644 --- a/example-kernels/Cargo.lock +++ b/example-kernels/Cargo.lock @@ -69,9 +69,9 @@ dependencies = [ [[package]] name = "x86_64" -version = "0.12.1" +version = "0.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "238a5798f77641af3c4f242bf985807f312a480cd4e35ed7255fad4b2ccb9d4f" +checksum = "d5b4b42dbabe13b69023e1a1407d395f1a1a33df76e9a9efdbe303acc907e292" dependencies = [ "bit_field", "bitflags", From 516e87a3479d0ca76b0bffe72d3a32c5786629dc Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Tue, 29 Sep 2020 11:37:13 +0200 Subject: [PATCH 080/108] `cargo update` the `bootloader` crate for example kernels to fix nightly breakage --- example-kernels/Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/example-kernels/Cargo.lock b/example-kernels/Cargo.lock index 712ea6c..4cccc24 100644 --- a/example-kernels/Cargo.lock +++ b/example-kernels/Cargo.lock @@ -22,9 +22,9 @@ checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" [[package]] name = "bootloader" -version = "0.9.10" +version = "0.9.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c5c959bf675ba4d842740373760b2aeb5b8f5457451cd18370b4c339d4926e9" +checksum = "83732ad599045a978528e4311539fdcb20c30e406b66d1d08cd4089d4fc8d90f" [[package]] name = "rlibc" From 303ff94b51430648bbffcc7a59c06f9a887f37bf Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Sun, 22 Nov 2020 13:57:23 +0100 Subject: [PATCH 081/108] CI: Use environment files instead of deprecated `set-env` --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 812dee5..659f29d 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -79,7 +79,7 @@ jobs: - name: Install Scoop (Windows) run: | Invoke-Expression (New-Object System.Net.WebClient).DownloadString('https://get.scoop.sh') - echo ::add-path::$HOME\scoop\shims + echo "$HOME\scoop\shims" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append if: runner.os == 'Windows' shell: pwsh - name: Install QEMU (Windows) From 0a5fa3d41baa128bcfa632a633bd4bf3be56d3ef Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Sun, 22 Nov 2020 13:57:39 +0100 Subject: [PATCH 082/108] CI: Use actions-rs for better error reporting --- .github/workflows/build.yml | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 659f29d..cdb4490 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -29,14 +29,11 @@ jobs: - name: "Checkout Repository" uses: actions/checkout@v1 - - name: Install Rustup (macOS) - run: | - curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y - echo ::add-path::$HOME/.cargo/bin - if: runner.os == 'macOS' - - - name: Set Rustup profile to minimal - run: rustup set profile minimal + - name: Set up Rustup + uses: actions-rs/toolchain@v1 + with: + profile: minimal + toolchain: stable - name: "Print Rust Version" run: | @@ -44,13 +41,19 @@ jobs: cargo -Vv - name: "Run cargo build" - run: cargo build + uses: actions-rs/cargo@v1 + with: + command: build - name: "Run cargo test" - run: cargo test + uses: actions-rs/cargo@v1 + with: + command: test - name: "Deny Warnings" - run: cargo build + uses: actions-rs/cargo@v1 + with: + command: build env: RUSTFLAGS: "-D warnings" From 54492a943635f6893a9c7aa21041efec8f3fc7f6 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Thu, 10 Dec 2020 15:29:20 +0100 Subject: [PATCH 083/108] Fix nightly breakage of doctests in workspaces In https://github.com/rust-lang/cargo/pull/8954 the working directory for the runner executable changed for doctests. Before, the working directory was the crate dir, now it is the workspace dir. This lead to a bug in bootimage because it now looked for the `test-args` and other config option in the workpace root `Cargo.toml`, instead of the crate-specific `Cargo.toml`. This commit fixes this by using the `CARGO_MANIFEST_DIR` environment variable for determining the `Cargo.toml` path, instead of directly using `cargo locate-project` as before. --- src/builder/mod.rs | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/builder/mod.rs b/src/builder/mod.rs index 46e9361..3acc5e6 100644 --- a/src/builder/mod.rs +++ b/src/builder/mod.rs @@ -26,7 +26,18 @@ impl Builder { /// /// If None is passed for `manifest_path`, it is automatically searched. pub fn new(manifest_path: Option) -> Result { - let manifest_path = manifest_path.unwrap_or(locate_cargo_manifest::locate_manifest()?); + let manifest_path = match manifest_path.or_else(|| { + std::env::var("CARGO_MANIFEST_DIR") + .ok() + .map(|dir| Path::new(&dir).join("Cargo.toml")) + }) { + Some(path) => path, + None => { + println!("WARNING: `CARGO_MANIFEST_DIR` env variable not set"); + locate_cargo_manifest::locate_manifest()? + } + }; + Ok(Builder { manifest_path, project_metadata: None, From ba94e670c19b2178cf732059e35ca4cbffe74f13 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Thu, 10 Dec 2020 16:05:53 +0100 Subject: [PATCH 084/108] Update changelog for #69 --- Changelog.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Changelog.md b/Changelog.md index 3db819f..9a9be29 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,5 +1,7 @@ # Unreleased +- Fix nightly breakage of doctests in workspaces ([#69](https://github.com/rust-osdev/bootimage/pull/69)) + # 0.10.1 – 2020-08-03 - Parse `--version` argument without subcommand (`bootimage --version`) ([#67](https://github.com/rust-osdev/bootimage/pull/67)) From 2413e59ef1706dc6e5e231f99af5a2e0e5d730e0 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Thu, 10 Dec 2020 16:35:57 +0100 Subject: [PATCH 085/108] Release version 0.10.2 --- Cargo.lock | 110 +++++++++++++++++++++++++-------------------------- Cargo.toml | 2 +- Changelog.md | 2 + 3 files changed, 57 insertions(+), 57 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7380558..73f2cca 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,188 +4,186 @@ name = "anyhow" version = "1.0.32" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b602bfe940d21c130f3895acd65221e8a61270debe89d628b9cb4e3ccb8569b" [[package]] name = "bootimage" -version = "0.10.1" +version = "0.10.2" dependencies = [ - "anyhow 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)", - "cargo_metadata 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", - "json 0.12.4 (registry+https://github.com/rust-lang/crates.io-index)", - "llvm-tools 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "locate-cargo-manifest 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "thiserror 1.0.20 (registry+https://github.com/rust-lang/crates.io-index)", - "toml 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", - "wait-timeout 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "anyhow", + "cargo_metadata", + "json", + "llvm-tools", + "locate-cargo-manifest", + "thiserror", + "toml", + "wait-timeout", ] [[package]] name = "cargo_metadata" version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46e3374c604fb39d1a2f35ed5e4a4e30e60d01fab49446e08f1b3e9a90aef202" dependencies = [ - "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.115 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.115 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.57 (registry+https://github.com/rust-lang/crates.io-index)", + "semver", + "serde", + "serde_derive", + "serde_json", ] [[package]] name = "itoa" version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc6f3ad7b9d11a0c00842ff8de1b60ee58661048eb8049ed33c73594f359d7e6" [[package]] name = "json" version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "078e285eafdfb6c4b434e0d31e8cfcb5115b651496faca5749b88fafd4f23bfd" [[package]] name = "libc" version = "0.2.76" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "755456fae044e6fa1ebbbd1b3e902ae19e73097ed4ed87bb79934a867c007bc3" [[package]] name = "llvm-tools" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "955be5d0ca0465caf127165acb47964f911e2bc26073e865deb8be7189302faf" [[package]] name = "locate-cargo-manifest" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db985b63431fe09e8d71f50aeceffcc31e720cb86be8dad2f38d084c5a328466" dependencies = [ - "json 0.12.4 (registry+https://github.com/rust-lang/crates.io-index)", + "json", ] [[package]] name = "proc-macro2" version = "1.0.19" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04f5f085b5d71e2188cb8271e5da0161ad52c3f227a661a3c135fdf28e258b12" dependencies = [ - "unicode-xid 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-xid", ] [[package]] name = "quote" version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa563d17ecb180e500da1cfd2b028310ac758de548efdd203e18f283af693f37" dependencies = [ - "proc-macro2 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2", ] [[package]] name = "ryu" version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" [[package]] name = "semver" version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" dependencies = [ - "semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.115 (registry+https://github.com/rust-lang/crates.io-index)", + "semver-parser", + "serde", ] [[package]] name = "semver-parser" version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" [[package]] name = "serde" version = "1.0.115" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e54c9a88f2da7238af84b5101443f0c0d0a3bbdc455e34a5c9497b1903ed55d5" [[package]] name = "serde_derive" version = "1.0.115" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "609feed1d0a73cc36a0182a840a9b37b4a82f0b1150369f0536a9e3f2a31dc48" dependencies = [ - "proc-macro2 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2", + "quote", + "syn", ] [[package]] name = "serde_json" version = "1.0.57" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "164eacbdb13512ec2745fb09d51fd5b22b0d65ed294a1dcf7285a360c80a675c" dependencies = [ - "itoa 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "ryu 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.115 (registry+https://github.com/rust-lang/crates.io-index)", + "itoa", + "ryu", + "serde", ] [[package]] name = "syn" version = "1.0.39" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "891d8d6567fe7c7f8835a3a98af4208f3846fba258c1bc3c31d6e506239f11f9" dependencies = [ - "proc-macro2 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)", - "unicode-xid 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2", + "quote", + "unicode-xid", ] [[package]] name = "thiserror" version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7dfdd070ccd8ccb78f4ad66bf1982dc37f620ef696c6b5028fe2ed83dd3d0d08" dependencies = [ - "thiserror-impl 1.0.20 (registry+https://github.com/rust-lang/crates.io-index)", + "thiserror-impl", ] [[package]] name = "thiserror-impl" version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd80fc12f73063ac132ac92aceea36734f04a1d93c1240c6944e23a3b8841793" dependencies = [ - "proc-macro2 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2", + "quote", + "syn", ] [[package]] name = "toml" version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffc92d160b1eef40665be3a05630d003936a3bc7da7421277846c2613e92c71a" dependencies = [ - "serde 1.0.115 (registry+https://github.com/rust-lang/crates.io-index)", + "serde", ] [[package]] name = "unicode-xid" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564" [[package]] name = "wait-timeout" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f200f5b12eb75f8c1ed65abd4b2db8a6e1b138a20de009dacee265a2498f3f6" dependencies = [ - "libc 0.2.76 (registry+https://github.com/rust-lang/crates.io-index)", + "libc", ] - -[metadata] -"checksum anyhow 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)" = "6b602bfe940d21c130f3895acd65221e8a61270debe89d628b9cb4e3ccb8569b" -"checksum cargo_metadata 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "46e3374c604fb39d1a2f35ed5e4a4e30e60d01fab49446e08f1b3e9a90aef202" -"checksum itoa 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "dc6f3ad7b9d11a0c00842ff8de1b60ee58661048eb8049ed33c73594f359d7e6" -"checksum json 0.12.4 (registry+https://github.com/rust-lang/crates.io-index)" = "078e285eafdfb6c4b434e0d31e8cfcb5115b651496faca5749b88fafd4f23bfd" -"checksum libc 0.2.76 (registry+https://github.com/rust-lang/crates.io-index)" = "755456fae044e6fa1ebbbd1b3e902ae19e73097ed4ed87bb79934a867c007bc3" -"checksum llvm-tools 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "955be5d0ca0465caf127165acb47964f911e2bc26073e865deb8be7189302faf" -"checksum locate-cargo-manifest 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "db985b63431fe09e8d71f50aeceffcc31e720cb86be8dad2f38d084c5a328466" -"checksum proc-macro2 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)" = "04f5f085b5d71e2188cb8271e5da0161ad52c3f227a661a3c135fdf28e258b12" -"checksum quote 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)" = "aa563d17ecb180e500da1cfd2b028310ac758de548efdd203e18f283af693f37" -"checksum ryu 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" -"checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" -"checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" -"checksum serde 1.0.115 (registry+https://github.com/rust-lang/crates.io-index)" = "e54c9a88f2da7238af84b5101443f0c0d0a3bbdc455e34a5c9497b1903ed55d5" -"checksum serde_derive 1.0.115 (registry+https://github.com/rust-lang/crates.io-index)" = "609feed1d0a73cc36a0182a840a9b37b4a82f0b1150369f0536a9e3f2a31dc48" -"checksum serde_json 1.0.57 (registry+https://github.com/rust-lang/crates.io-index)" = "164eacbdb13512ec2745fb09d51fd5b22b0d65ed294a1dcf7285a360c80a675c" -"checksum syn 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)" = "891d8d6567fe7c7f8835a3a98af4208f3846fba258c1bc3c31d6e506239f11f9" -"checksum thiserror 1.0.20 (registry+https://github.com/rust-lang/crates.io-index)" = "7dfdd070ccd8ccb78f4ad66bf1982dc37f620ef696c6b5028fe2ed83dd3d0d08" -"checksum thiserror-impl 1.0.20 (registry+https://github.com/rust-lang/crates.io-index)" = "bd80fc12f73063ac132ac92aceea36734f04a1d93c1240c6944e23a3b8841793" -"checksum toml 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "ffc92d160b1eef40665be3a05630d003936a3bc7da7421277846c2613e92c71a" -"checksum unicode-xid 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564" -"checksum wait-timeout 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9f200f5b12eb75f8c1ed65abd4b2db8a6e1b138a20de009dacee265a2498f3f6" diff --git a/Cargo.toml b/Cargo.toml index d080026..74a655f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,7 +3,7 @@ authors = ["Philipp Oppermann "] description = "Tool to create a bootable OS image from a kernel binary." license = "MIT/Apache-2.0" name = "bootimage" -version = "0.10.1" +version = "0.10.2" repository = "https://github.com/rust-osdev/bootimage" edition = "2018" diff --git a/Changelog.md b/Changelog.md index 9a9be29..28662b1 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,5 +1,7 @@ # Unreleased +# 0.10.2 – 2020-12-10 + - Fix nightly breakage of doctests in workspaces ([#69](https://github.com/rust-osdev/bootimage/pull/69)) # 0.10.1 – 2020-08-03 From a5b2b9f83b5d0ecf1d2459e8115e03e48b7b4078 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Tue, 2 Feb 2021 10:02:53 +0100 Subject: [PATCH 086/108] Don't deny warnings for clippy --- .github/workflows/build.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index cdb4490..fbad28e 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -139,4 +139,7 @@ jobs: steps: - uses: actions/checkout@v1 - run: rustup toolchain install nightly --profile minimal --component clippy - - run: cargo +nightly clippy -- -D warnings + - name: "Run `cargo clippy`" + uses: actions-rs/cargo@v1 + with: + command: clippy From 85c974e411fdaab7d7ed4641baea7abd5c45c24e Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Tue, 2 Feb 2021 10:07:17 +0100 Subject: [PATCH 087/108] Update example kernels to x86_64 v0.13.2 --- example-kernels/Cargo.lock | 4 ++-- example-kernels/basic/Cargo.toml | 2 +- example-kernels/runner-doctest/Cargo.toml | 2 +- example-kernels/runner-fail-reboot/Cargo.toml | 2 +- example-kernels/runner-test/Cargo.toml | 2 +- example-kernels/runner/Cargo.toml | 2 +- 6 files changed, 7 insertions(+), 7 deletions(-) diff --git a/example-kernels/Cargo.lock b/example-kernels/Cargo.lock index 4cccc24..ce04c93 100644 --- a/example-kernels/Cargo.lock +++ b/example-kernels/Cargo.lock @@ -69,9 +69,9 @@ dependencies = [ [[package]] name = "x86_64" -version = "0.12.2" +version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5b4b42dbabe13b69023e1a1407d395f1a1a33df76e9a9efdbe303acc907e292" +checksum = "b871116e3c83dad0795580b10b2b1dd05cb52ec719af36180371877b09681f7f" dependencies = [ "bit_field", "bitflags", diff --git a/example-kernels/basic/Cargo.toml b/example-kernels/basic/Cargo.toml index 6c4c797..00e9825 100644 --- a/example-kernels/basic/Cargo.toml +++ b/example-kernels/basic/Cargo.toml @@ -6,4 +6,4 @@ edition = "2018" [dependencies] bootloader = "0.9.7" -x86_64 = "0.12.1" +x86_64 = "0.13.2" diff --git a/example-kernels/runner-doctest/Cargo.toml b/example-kernels/runner-doctest/Cargo.toml index 4f03914..b04989f 100644 --- a/example-kernels/runner-doctest/Cargo.toml +++ b/example-kernels/runner-doctest/Cargo.toml @@ -6,7 +6,7 @@ edition = "2018" [dependencies] bootloader = "0.9.7" -x86_64 = "0.12.1" +x86_64 = "0.13.2" rlibc = "1.0.0" [package.metadata.bootimage] diff --git a/example-kernels/runner-fail-reboot/Cargo.toml b/example-kernels/runner-fail-reboot/Cargo.toml index 1afe806..9eeb9cd 100644 --- a/example-kernels/runner-fail-reboot/Cargo.toml +++ b/example-kernels/runner-fail-reboot/Cargo.toml @@ -6,7 +6,7 @@ edition = "2018" [dependencies] bootloader = "0.9.7" -x86_64 = "0.12.1" +x86_64 = "0.13.2" rlibc = "1.0.0" [package.metadata.bootimage] diff --git a/example-kernels/runner-test/Cargo.toml b/example-kernels/runner-test/Cargo.toml index a92788d..4209b00 100644 --- a/example-kernels/runner-test/Cargo.toml +++ b/example-kernels/runner-test/Cargo.toml @@ -10,7 +10,7 @@ harness = false [dependencies] bootloader = "0.9.7" -x86_64 = "0.12.1" +x86_64 = "0.13.2" rlibc = "1.0.0" [package.metadata.bootimage] diff --git a/example-kernels/runner/Cargo.toml b/example-kernels/runner/Cargo.toml index 2951418..da7c43c 100644 --- a/example-kernels/runner/Cargo.toml +++ b/example-kernels/runner/Cargo.toml @@ -6,7 +6,7 @@ edition = "2018" [dependencies] bootloader = "0.9.7" -x86_64 = "0.12.1" +x86_64 = "0.13.2" [package.metadata.bootimage] run-args = ["-device", "isa-debug-exit,iobase=0xf4,iosize=0x04", "-display", "none"] From 3bd1dbffa02a190b1e9b4693fcab5a4162dc706a Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Tue, 2 Feb 2021 10:23:01 +0100 Subject: [PATCH 088/108] Update example kernels to bootloader v0.9.12 --- example-kernels/Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/example-kernels/Cargo.lock b/example-kernels/Cargo.lock index ce04c93..72a963b 100644 --- a/example-kernels/Cargo.lock +++ b/example-kernels/Cargo.lock @@ -22,9 +22,9 @@ checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" [[package]] name = "bootloader" -version = "0.9.11" +version = "0.9.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83732ad599045a978528e4311539fdcb20c30e406b66d1d08cd4089d4fc8d90f" +checksum = "452bbab4eae8767805ff09386c9e26d42ceb6964916ab3c64425469342473f91" [[package]] name = "rlibc" From ad838365fd4803c3703df8e73ccb0b6696fe2b04 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Wed, 10 Mar 2021 09:19:51 +0100 Subject: [PATCH 089/108] Ci: Don't fail fast --- .github/workflows/build.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index fbad28e..27c2a86 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -15,6 +15,7 @@ jobs: name: "Test" strategy: + fail-fast: false matrix: platform: [ ubuntu-latest, From 9ade8cec32067d952f54fa10e2c76a6fc00e09b6 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Wed, 10 Mar 2021 09:20:39 +0100 Subject: [PATCH 090/108] Run cargo update for bootloader crate --- example-kernels/Cargo.lock | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/example-kernels/Cargo.lock b/example-kernels/Cargo.lock index 72a963b..ed82a74 100644 --- a/example-kernels/Cargo.lock +++ b/example-kernels/Cargo.lock @@ -1,5 +1,7 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. +version = 3 + [[package]] name = "basic" version = "0.1.0" @@ -22,9 +24,9 @@ checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" [[package]] name = "bootloader" -version = "0.9.12" +version = "0.9.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "452bbab4eae8767805ff09386c9e26d42ceb6964916ab3c64425469342473f91" +checksum = "8cb1dc91ba8f16c89133c569bc2516833a632a654d61d228b16ae8d2bad5ed8a" [[package]] name = "rlibc" From 5eea7088149c1f7c6eaa7edb5781dfd66bd89468 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Thu, 1 Apr 2021 10:31:41 +0200 Subject: [PATCH 091/108] Fix "unnecessary trailing semicolon" warning on Rust 1.51 --- Changelog.md | 2 ++ src/args/build.rs | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/Changelog.md b/Changelog.md index 28662b1..0cdb7f2 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,5 +1,7 @@ # Unreleased +- Fix "unnnecessary trailing semicolon" warning on Rust 1.51 + # 0.10.2 – 2020-12-10 - Fix nightly breakage of doctests in workspaces ([#69](https://github.com/rust-osdev/bootimage/pull/69)) diff --git a/src/args/build.rs b/src/args/build.rs index 02fe739..c3d18a9 100644 --- a/src/args/build.rs +++ b/src/args/build.rs @@ -30,7 +30,7 @@ impl BuildCommand { return Err(anyhow!("multiple arguments of same type provided")); } Ok(()) - }; + } let mut arg_iter = args; while let Some(arg) = arg_iter.next() { From 5139e867e0e8a0b4b6ba15b97e2998f6395d950e Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Thu, 1 Apr 2021 10:32:10 +0200 Subject: [PATCH 092/108] Release version 0.10.3 --- Cargo.lock | 2 +- Cargo.toml | 2 +- Changelog.md | 2 ++ 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 73f2cca..ec54604 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8,7 +8,7 @@ checksum = "6b602bfe940d21c130f3895acd65221e8a61270debe89d628b9cb4e3ccb8569b" [[package]] name = "bootimage" -version = "0.10.2" +version = "0.10.3" dependencies = [ "anyhow", "cargo_metadata", diff --git a/Cargo.toml b/Cargo.toml index 74a655f..f2fbf21 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,7 +3,7 @@ authors = ["Philipp Oppermann "] description = "Tool to create a bootable OS image from a kernel binary." license = "MIT/Apache-2.0" name = "bootimage" -version = "0.10.2" +version = "0.10.3" repository = "https://github.com/rust-osdev/bootimage" edition = "2018" diff --git a/Changelog.md b/Changelog.md index 0cdb7f2..63326a4 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,5 +1,7 @@ # Unreleased +# 0.10.3 – 2021-04-01 + - Fix "unnnecessary trailing semicolon" warning on Rust 1.51 # 0.10.2 – 2020-12-10 From 250346db9573aa2fafddc9e6c6cf4a77908012b7 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Thu, 6 May 2021 14:30:19 +0200 Subject: [PATCH 093/108] Update `x86_64` to v0.14.1 in example kernels --- example-kernels/Cargo.lock | 11 +++++++++-- example-kernels/basic/Cargo.toml | 2 +- example-kernels/runner-doctest/Cargo.toml | 2 +- example-kernels/runner-fail-reboot/Cargo.toml | 2 +- example-kernels/runner-test/Cargo.toml | 2 +- example-kernels/runner/Cargo.toml | 2 +- 6 files changed, 14 insertions(+), 7 deletions(-) diff --git a/example-kernels/Cargo.lock b/example-kernels/Cargo.lock index ed82a74..c4b8b0d 100644 --- a/example-kernels/Cargo.lock +++ b/example-kernels/Cargo.lock @@ -69,12 +69,19 @@ dependencies = [ "x86_64", ] +[[package]] +name = "volatile" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4c2dbd44eb8b53973357e6e207e370f0c1059990df850aca1eca8947cf464f0" + [[package]] name = "x86_64" -version = "0.13.2" +version = "0.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b871116e3c83dad0795580b10b2b1dd05cb52ec719af36180371877b09681f7f" +checksum = "e9ce25c8b91769cf3522618360482d4fe8e2abf7056958ae88b1f039d6cf6bc2" dependencies = [ "bit_field", "bitflags", + "volatile", ] diff --git a/example-kernels/basic/Cargo.toml b/example-kernels/basic/Cargo.toml index 00e9825..5a9a509 100644 --- a/example-kernels/basic/Cargo.toml +++ b/example-kernels/basic/Cargo.toml @@ -6,4 +6,4 @@ edition = "2018" [dependencies] bootloader = "0.9.7" -x86_64 = "0.13.2" +x86_64 = "0.14.1" diff --git a/example-kernels/runner-doctest/Cargo.toml b/example-kernels/runner-doctest/Cargo.toml index b04989f..ff240ec 100644 --- a/example-kernels/runner-doctest/Cargo.toml +++ b/example-kernels/runner-doctest/Cargo.toml @@ -6,7 +6,7 @@ edition = "2018" [dependencies] bootloader = "0.9.7" -x86_64 = "0.13.2" +x86_64 = "0.14.1" rlibc = "1.0.0" [package.metadata.bootimage] diff --git a/example-kernels/runner-fail-reboot/Cargo.toml b/example-kernels/runner-fail-reboot/Cargo.toml index 9eeb9cd..c15f396 100644 --- a/example-kernels/runner-fail-reboot/Cargo.toml +++ b/example-kernels/runner-fail-reboot/Cargo.toml @@ -6,7 +6,7 @@ edition = "2018" [dependencies] bootloader = "0.9.7" -x86_64 = "0.13.2" +x86_64 = "0.14.1" rlibc = "1.0.0" [package.metadata.bootimage] diff --git a/example-kernels/runner-test/Cargo.toml b/example-kernels/runner-test/Cargo.toml index 4209b00..83bcb52 100644 --- a/example-kernels/runner-test/Cargo.toml +++ b/example-kernels/runner-test/Cargo.toml @@ -10,7 +10,7 @@ harness = false [dependencies] bootloader = "0.9.7" -x86_64 = "0.13.2" +x86_64 = "0.14.1" rlibc = "1.0.0" [package.metadata.bootimage] diff --git a/example-kernels/runner/Cargo.toml b/example-kernels/runner/Cargo.toml index da7c43c..17d0be9 100644 --- a/example-kernels/runner/Cargo.toml +++ b/example-kernels/runner/Cargo.toml @@ -6,7 +6,7 @@ edition = "2018" [dependencies] bootloader = "0.9.7" -x86_64 = "0.13.2" +x86_64 = "0.14.1" [package.metadata.bootimage] run-args = ["-device", "isa-debug-exit,iobase=0xf4,iosize=0x04", "-display", "none"] From 8f3d6192157a17d9c6078bda9ef49c3b13cb1d1a Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Thu, 6 May 2021 14:39:47 +0200 Subject: [PATCH 094/108] Run cargo update for bootloader crate --- example-kernels/Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/example-kernels/Cargo.lock b/example-kernels/Cargo.lock index c4b8b0d..f86eaa3 100644 --- a/example-kernels/Cargo.lock +++ b/example-kernels/Cargo.lock @@ -24,9 +24,9 @@ checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" [[package]] name = "bootloader" -version = "0.9.16" +version = "0.9.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8cb1dc91ba8f16c89133c569bc2516833a632a654d61d228b16ae8d2bad5ed8a" +checksum = "bfe7a297d22859b1cb0b939cfa0b01288d77804c8544acefd2c1135135587f7d" [[package]] name = "rlibc" From 01d4622a8fff041c9f7efe58e280a6c1c0a7113f Mon Sep 17 00:00:00 2001 From: Paulo Elienay II <48896572+paulo-e@users.noreply.github.com> Date: Sat, 15 May 2021 03:14:18 -0300 Subject: [PATCH 095/108] Updated dependency version Updated `bootloader` dependency version, matching the blog post https://os.phil-opp.com/minimal-rust-kernel/#printing-to-screen --- Readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Readme.md b/Readme.md index 59ee0e3..a569690 100644 --- a/Readme.md +++ b/Readme.md @@ -16,7 +16,7 @@ First you need to add a dependency on the [`bootloader`](https://github.com/rust # in your Cargo.toml [dependencies] -bootloader = "0.6.4" +bootloader = "0.9.8" ``` **Note**: At least bootloader version `0.5.1` is required since `bootimage 0.7.0`. For earlier bootloader versions, use `bootimage 0.6.6`. From ffc53d5d34cfcf0648b5220e9ec61622853fa08a Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Sat, 22 May 2021 15:03:49 +0200 Subject: [PATCH 096/108] Run `cargo update` for bootloader --- example-kernels/Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/example-kernels/Cargo.lock b/example-kernels/Cargo.lock index f86eaa3..e543632 100644 --- a/example-kernels/Cargo.lock +++ b/example-kernels/Cargo.lock @@ -24,9 +24,9 @@ checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" [[package]] name = "bootloader" -version = "0.9.17" +version = "0.9.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfe7a297d22859b1cb0b939cfa0b01288d77804c8544acefd2c1135135587f7d" +checksum = "7a3c1ceed1cd9e61c7998100cc18c13d413aa40d018992b871ab8e7435ce6372" [[package]] name = "rlibc" From d5900984ee9576882b3b4a40ce29f697f2b9bb7b Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Sun, 22 Aug 2021 14:33:59 +0200 Subject: [PATCH 097/108] CI: Use choco to install QEMU 6.0.0 This should fix our CI build errors. We install a pinned version of QEMU since the latest 6.1 pre-releases appear to have some problems too. --- .github/workflows/build.yml | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 27c2a86..fcf00c2 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -80,14 +80,10 @@ jobs: HOMEBREW_NO_AUTO_UPDATE: 1 HOMEBREW_NO_BOTTLE_SOURCE_FALLBACK: 1 HOMEBREW_NO_INSTALL_CLEANUP: 1 - - name: Install Scoop (Windows) - run: | - Invoke-Expression (New-Object System.Net.WebClient).DownloadString('https://get.scoop.sh') - echo "$HOME\scoop\shims" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append - if: runner.os == 'Windows' - shell: pwsh - name: Install QEMU (Windows) - run: scoop install qemu + run: | + choco install qemu --version 2021.5.5 + echo "$Env:Programfiles\qemu" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append if: runner.os == 'Windows' shell: pwsh From 0f8865d199a267f9bf666ddfd6caaeb004838bef Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Tue, 21 Dec 2021 12:41:20 +0100 Subject: [PATCH 098/108] Run cargo update for bootloader and x86_64 crates --- example-kernels/Cargo.lock | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/example-kernels/Cargo.lock b/example-kernels/Cargo.lock index e543632..bb805a0 100644 --- a/example-kernels/Cargo.lock +++ b/example-kernels/Cargo.lock @@ -12,9 +12,9 @@ dependencies = [ [[package]] name = "bit_field" -version = "0.9.0" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed8765909f9009617974ab6b7d332625b320b33c326b1e9321382ef1999b5d56" +checksum = "dcb6dd1c2376d2e096796e234a70e17e94cc2d5d54ff8ce42b28cef1d0d359a4" [[package]] name = "bitflags" @@ -24,9 +24,9 @@ checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" [[package]] name = "bootloader" -version = "0.9.18" +version = "0.9.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a3c1ceed1cd9e61c7998100cc18c13d413aa40d018992b871ab8e7435ce6372" +checksum = "6b0718f186cd449b21f044683933284ed90fb83f3e13949ff0e03b0b6f02e38e" [[package]] name = "rlibc" @@ -77,9 +77,9 @@ checksum = "e4c2dbd44eb8b53973357e6e207e370f0c1059990df850aca1eca8947cf464f0" [[package]] name = "x86_64" -version = "0.14.1" +version = "0.14.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9ce25c8b91769cf3522618360482d4fe8e2abf7056958ae88b1f039d6cf6bc2" +checksum = "fb611915c917c6296d11e23f71ff1ecfe49c5766daba92cd3df52df6b58285b6" dependencies = [ "bit_field", "bitflags", From dae6e75abfd60dfe66d46a1566840b5595b53b69 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Tue, 18 Jan 2022 10:09:36 +0100 Subject: [PATCH 099/108] Run cargo update for bootloader crate --- example-kernels/Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/example-kernels/Cargo.lock b/example-kernels/Cargo.lock index bb805a0..54af36c 100644 --- a/example-kernels/Cargo.lock +++ b/example-kernels/Cargo.lock @@ -24,9 +24,9 @@ checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" [[package]] name = "bootloader" -version = "0.9.20" +version = "0.9.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b0718f186cd449b21f044683933284ed90fb83f3e13949ff0e03b0b6f02e38e" +checksum = "a62c8f6168cd106687ee36a2b71a46c4144d73399f72814104d33094b8092fd2" [[package]] name = "rlibc" From 05ec88494a18b7babcb567629ffdd8d21b67ba6d Mon Sep 17 00:00:00 2001 From: Daniel Vasquez Date: Fri, 22 Jul 2022 20:51:47 -0400 Subject: [PATCH 100/108] Fixed typo --- Readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Readme.md b/Readme.md index a569690..852f25d 100644 --- a/Readme.md +++ b/Readme.md @@ -56,7 +56,7 @@ The `bootimage` has built-in support for running unit and integration tests of y ## Configuration -Configuration is done through a through a `[package.metadata.bootimage]` table in the `Cargo.toml` of your kernel. The following options are available: +Configuration is done through a `[package.metadata.bootimage]` table in the `Cargo.toml` of your kernel. The following options are available: ```toml [package.metadata.bootimage] From 3cd7e17fcf1cd9ce4a7e83e38043c09f4d91d6d6 Mon Sep 17 00:00:00 2001 From: Fractal-Tess Date: Mon, 7 Nov 2022 18:23:23 +0200 Subject: [PATCH 101/108] correct typo --- src/builder/error.rs | 10 +++++----- src/run.rs | 8 ++++---- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/builder/error.rs b/src/builder/error.rs index 5c0cab1..5d091fb 100644 --- a/src/builder/error.rs +++ b/src/builder/error.rs @@ -18,7 +18,7 @@ pub enum BuildKernelError { Io { /// Desciption of the failed I/O operation message: &'static str, - /// The I/O error that occured + /// The I/O error that occurred error: io::Error, }, @@ -49,7 +49,7 @@ pub enum BuildKernelError { #[non_exhaustive] pub enum CreateBootimageError { /// Failed to build the bootloader. - #[error("An error occured while trying to build the bootloader: {0}")] + #[error("An error occurred while trying to build the bootloader: {0}")] Bootloader(#[from] BootloaderError), /// Error while running `cargo metadata` @@ -64,7 +64,7 @@ pub enum CreateBootimageError { }, /// Disk image creation failed - #[error("An error occured while trying to create the disk image: {0}")] + #[error("An error occurred while trying to create the disk image: {0}")] DiskImage(#[from] DiskImageError), /// An unexpected I/O error occurred @@ -72,7 +72,7 @@ pub enum CreateBootimageError { Io { /// Desciption of the failed I/O operation message: &'static str, - /// The I/O error that occured + /// The I/O error that occurred error: io::Error, }, @@ -145,7 +145,7 @@ pub enum DiskImageError { Io { /// Desciption of the failed I/O operation message: &'static str, - /// The I/O error that occured + /// The I/O error that occurred error: io::Error, }, } diff --git a/src/run.rs b/src/run.rs index 562b57d..e77c0f9 100644 --- a/src/run.rs +++ b/src/run.rs @@ -101,17 +101,17 @@ pub enum RunError { #[error("Failed to read QEMU exit code")] NoQemuExitCode, - /// An I/O error occured - #[error("{context}: An I/O error occured: {error}")] + /// An I/O error occurred + #[error("{context}: An I/O error occurred: {error}")] Io { /// The operation that caused the I/O error. context: IoErrorContext, - /// The I/O error that occured. + /// The I/O error that occurred. error: io::Error, }, } -/// An I/O error occured while trying to run the disk image. +/// An I/O error occurred while trying to run the disk image. #[derive(Debug, Error)] pub enum IoErrorContext { /// QEMU command for non-test failed From d954562e99d74e56ea3463d22760f30e3108fdf1 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Sun, 28 Jan 2024 12:08:47 +0100 Subject: [PATCH 102/108] Update to latest bootloader version --- example-kernels/Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/example-kernels/Cargo.lock b/example-kernels/Cargo.lock index 54af36c..3939c74 100644 --- a/example-kernels/Cargo.lock +++ b/example-kernels/Cargo.lock @@ -24,9 +24,9 @@ checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" [[package]] name = "bootloader" -version = "0.9.21" +version = "0.9.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a62c8f6168cd106687ee36a2b71a46c4144d73399f72814104d33094b8092fd2" +checksum = "c6f4dd3d0a9b440470ea52afcb5f9f09eeefbe36d1d0c29bae397f493d9fddb1" [[package]] name = "rlibc" From 55a5c4b7cd8d84dd43beb320e8bb937f4d2525b3 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Sun, 28 Jan 2024 12:15:10 +0100 Subject: [PATCH 103/108] Update data layout in example kernels target --- example-kernels/x86_64-bootimage-example-kernels.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/example-kernels/x86_64-bootimage-example-kernels.json b/example-kernels/x86_64-bootimage-example-kernels.json index 9afe809..bcb4c8b 100644 --- a/example-kernels/x86_64-bootimage-example-kernels.json +++ b/example-kernels/x86_64-bootimage-example-kernels.json @@ -1,6 +1,6 @@ { "llvm-target": "x86_64-unknown-none", - "data-layout": "e-m:e-i64:64-f80:128-n8:16:32:64-S128", + "data-layout": "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128", "arch": "x86_64", "target-endian": "little", "target-pointer-width": "64", From f9640f7f4a62cc577b60f58dfb00c975d86cf4af Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Tue, 27 Feb 2024 07:30:28 +0100 Subject: [PATCH 104/108] Fix data layout for example kernel target --- example-kernels/x86_64-bootimage-example-kernels.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/example-kernels/x86_64-bootimage-example-kernels.json b/example-kernels/x86_64-bootimage-example-kernels.json index bcb4c8b..7a0cd61 100644 --- a/example-kernels/x86_64-bootimage-example-kernels.json +++ b/example-kernels/x86_64-bootimage-example-kernels.json @@ -1,6 +1,6 @@ { "llvm-target": "x86_64-unknown-none", - "data-layout": "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128", + "data-layout": "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128", "arch": "x86_64", "target-endian": "little", "target-pointer-width": "64", From bbb65dad77a17a76970bf1dfad6c45821b86d51f Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Tue, 27 Feb 2024 07:31:23 +0100 Subject: [PATCH 105/108] Update bootloader version to v0.9.27 in Cargo.lock --- example-kernels/Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/example-kernels/Cargo.lock b/example-kernels/Cargo.lock index 3939c74..96f1c0e 100644 --- a/example-kernels/Cargo.lock +++ b/example-kernels/Cargo.lock @@ -24,9 +24,9 @@ checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" [[package]] name = "bootloader" -version = "0.9.24" +version = "0.9.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6f4dd3d0a9b440470ea52afcb5f9f09eeefbe36d1d0c29bae397f493d9fddb1" +checksum = "ca7c184781ceb5660872f833fc6bd64ec9ae2500f8c65354705af541e4c28f7f" [[package]] name = "rlibc" From 0cce3336bb63c39b7a7cabd64987be66a05f5407 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Mon, 10 Feb 2025 11:03:50 +0100 Subject: [PATCH 106/108] Run cargo update for bootloader crate --- example-kernels/Cargo.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/example-kernels/Cargo.lock b/example-kernels/Cargo.lock index 96f1c0e..0dd87bc 100644 --- a/example-kernels/Cargo.lock +++ b/example-kernels/Cargo.lock @@ -1,6 +1,6 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 +version = 4 [[package]] name = "basic" @@ -24,9 +24,9 @@ checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" [[package]] name = "bootloader" -version = "0.9.27" +version = "0.9.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca7c184781ceb5660872f833fc6bd64ec9ae2500f8c65354705af541e4c28f7f" +checksum = "8a9c8b93781debeb5bc44a12adc4be812aa9feb659d60eeafcd7e9bedb549561" [[package]] name = "rlibc" From d3428c33627ef1e0aaeba0adc546c3e50c506a2d Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Mon, 10 Feb 2025 12:31:11 +0100 Subject: [PATCH 107/108] Fix target spec JSON for example kernel by adding `rustc-abi` field --- example-kernels/x86_64-bootimage-example-kernels.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/example-kernels/x86_64-bootimage-example-kernels.json b/example-kernels/x86_64-bootimage-example-kernels.json index 7a0cd61..6f5613c 100644 --- a/example-kernels/x86_64-bootimage-example-kernels.json +++ b/example-kernels/x86_64-bootimage-example-kernels.json @@ -11,5 +11,6 @@ "linker": "rust-lld", "panic-strategy": "abort", "disable-redzone": true, - "features": "-mmx,-sse,+soft-float" + "features": "-mmx,-sse,+soft-float", + "rustc-abi": "x86-softfloat" } From ed0150fdec56d194db3925beed4153c82b8bf10d Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Mon, 24 Mar 2025 11:10:32 +0100 Subject: [PATCH 108/108] Delete Cargo.lock for example kernels Ensure that we always use the latest bootloader version. --- example-kernels/Cargo.lock | 87 -------------------------------------- 1 file changed, 87 deletions(-) delete mode 100644 example-kernels/Cargo.lock diff --git a/example-kernels/Cargo.lock b/example-kernels/Cargo.lock deleted file mode 100644 index 0dd87bc..0000000 --- a/example-kernels/Cargo.lock +++ /dev/null @@ -1,87 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 4 - -[[package]] -name = "basic" -version = "0.1.0" -dependencies = [ - "bootloader", - "x86_64", -] - -[[package]] -name = "bit_field" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcb6dd1c2376d2e096796e234a70e17e94cc2d5d54ff8ce42b28cef1d0d359a4" - -[[package]] -name = "bitflags" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" - -[[package]] -name = "bootloader" -version = "0.9.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a9c8b93781debeb5bc44a12adc4be812aa9feb659d60eeafcd7e9bedb549561" - -[[package]] -name = "rlibc" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc874b127765f014d792f16763a81245ab80500e2ad921ed4ee9e82481ee08fe" - -[[package]] -name = "runner" -version = "0.1.0" -dependencies = [ - "bootloader", - "x86_64", -] - -[[package]] -name = "runner-doctest" -version = "0.1.0" -dependencies = [ - "bootloader", - "rlibc", - "x86_64", -] - -[[package]] -name = "runner-fail-reboot" -version = "0.1.0" -dependencies = [ - "bootloader", - "rlibc", - "x86_64", -] - -[[package]] -name = "runner-test" -version = "0.1.0" -dependencies = [ - "bootloader", - "rlibc", - "x86_64", -] - -[[package]] -name = "volatile" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4c2dbd44eb8b53973357e6e207e370f0c1059990df850aca1eca8947cf464f0" - -[[package]] -name = "x86_64" -version = "0.14.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb611915c917c6296d11e23f71ff1ecfe49c5766daba92cd3df52df6b58285b6" -dependencies = [ - "bit_field", - "bitflags", - "volatile", -]