From 5139c0b1ffbde7105df7f5bb1c7f802e3cd8525b Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Tue, 12 Jun 2018 19:59:48 +0200 Subject: [PATCH 001/271] Print message on success --- src/test.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/test.rs b/src/test.rs index eb7455a..686dc28 100644 --- a/src/test.rs +++ b/src/test.rs @@ -87,6 +87,7 @@ pub(crate) fn test(args: Args) -> Result<(), Error> { } if tests.iter().all(|t| t.1 == TestResult::Ok) { + println!("All tests succeeded."); Ok(()) } else { writeln!(io::stderr(), "The following tests failed:")?; From 3ff43103d5888537c98bbcea2fd71be6aa4721b0 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Tue, 12 Jun 2018 20:09:35 +0200 Subject: [PATCH 002/271] Implement `bootimage test --help` --- src/help/help.txt | 3 +++ src/help/mod.rs | 5 +++++ src/help/run_help.txt | 2 +- src/help/test_help.txt | 17 +++++++++++++++++ src/main.rs | 2 +- 5 files changed, 27 insertions(+), 2 deletions(-) create mode 100644 src/help/test_help.txt diff --git a/src/help/help.txt b/src/help/help.txt index 9cc5845..aa3bcd9 100644 --- a/src/help/help.txt +++ b/src/help/help.txt @@ -4,6 +4,9 @@ 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 + +For more information about a subcommand run `bootimage [subcommand] --help`. OPTIONS: -h, --help Prints help information and exit diff --git a/src/help/mod.rs b/src/help/mod.rs index 279b9a9..63bd8a1 100644 --- a/src/help/mod.rs +++ b/src/help/mod.rs @@ -3,6 +3,7 @@ use std::process; const HELP: &str = include_str!("help.txt"); const BUILD_HELP: &str = include_str!("build_help.txt"); const RUN_HELP: &str = include_str!("run_help.txt"); +const TEST_HELP: &str = include_str!("test_help.txt"); pub(crate) fn help() { print!("{}", HELP); @@ -16,6 +17,10 @@ pub(crate) fn run_help() { print!("{}", RUN_HELP); } +pub(crate) fn test_help() { + print!("{}", TEST_HELP); +} + pub(crate) fn no_subcommand() -> ! { println!("Please invoke `bootimage` with a subcommand (e.g. `bootimage build`)."); println!(); diff --git a/src/help/run_help.txt b/src/help/run_help.txt index 2105125..09dfdce 100644 --- a/src/help/run_help.txt +++ b/src/help/run_help.txt @@ -1,4 +1,4 @@ -Creates a bootable disk image from a Rust kernel +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 diff --git a/src/help/test_help.txt b/src/help/test_help.txt new file mode 100644 index 0000000..18c5b91 --- /dev/null +++ b/src/help/test_help.txt @@ -0,0 +1,17 @@ +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`) diff --git a/src/main.rs b/src/main.rs index cfcf9c3..fe6b4ec 100644 --- a/src/main.rs +++ b/src/main.rs @@ -71,7 +71,7 @@ fn run() -> Result<(), Error> { Command::Help => Ok(help::help()), Command::BuildHelp => Ok(help::build_help()), Command::RunHelp => Ok(help::run_help()), - Command::TestHelp => unimplemented!(), + Command::TestHelp => Ok(help::test_help()), Command::Version => Ok(println!("bootimage {}", env!("CARGO_PKG_VERSION"))), } } From faaaededb41d6d96aa9936b077e544b68936f4cd Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Tue, 12 Jun 2018 20:19:17 +0200 Subject: [PATCH 003/271] bootimage 0.4.0 --- Cargo.lock | 2 +- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a860c59..e0931ad 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -26,7 +26,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "bootimage" -version = "0.3.0" +version = "0.4.0" dependencies = [ "byteorder 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "cargo_metadata 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/Cargo.toml b/Cargo.toml index eef7c77..551c371 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.3.0" +version = "0.4.0" repository = "https://github.com/rust-osdev/bootimage" [dependencies] From 2c2f1ab58ea596b66c89ae096ac0e661a880ce86 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Wed, 13 Jun 2018 11:27:44 +0200 Subject: [PATCH 004/271] Canonicalize passed manifest path --- src/args.rs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/args.rs b/src/args.rs index 7d5c8ef..4be2f57 100644 --- a/src/args.rs +++ b/src/args.rs @@ -1,5 +1,5 @@ use std::{env, mem}; -use std::path::PathBuf; +use std::path::{Path, PathBuf}; use Command; pub(crate) fn parse_args() -> Command { @@ -92,14 +92,17 @@ where } "--manifest-path" => { let next = arg_iter.next(); - set(&mut manifest_path, next.as_ref().map(|p| PathBuf::from(&p))); + 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 = PathBuf::from(arg.trim_left_matches("--manifest-path=")); + let path = Path::new(arg.trim_left_matches("--manifest-path=")) + .canonicalize().expect("--manifest-path invalid"); set(&mut manifest_path, Some(path)); cargo_args.push(arg); } From a28cd77eb9381bbb15dc5897e8d0d8fdb1fe79cd Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Wed, 13 Jun 2018 11:28:00 +0200 Subject: [PATCH 005/271] Canonicalize default target --- src/build.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/build.rs b/src/build.rs index c0e40a1..8372e22 100644 --- a/src/build.rs +++ b/src/build.rs @@ -52,7 +52,9 @@ pub(crate) fn common_setup(mut args: Args) -> Result<(Args, Config, CargoMetadat if args.target().is_none() { if let Some(ref target) = config.default_target { - args.set_target(target.clone()); + let mut canonicalized_target = crate_root.clone(); + canonicalized_target.push(target); + args.set_target(canonicalized_target.to_string_lossy().into_owned()); } } From 092b1a27fe26180aca684e2650284a5b5c29f387 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Wed, 13 Jun 2018 11:30:12 +0200 Subject: [PATCH 006/271] bootimage 0.4.1 --- Cargo.lock | 2 +- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e0931ad..1503b15 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -26,7 +26,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "bootimage" -version = "0.4.0" +version = "0.4.1" dependencies = [ "byteorder 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "cargo_metadata 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/Cargo.toml b/Cargo.toml index 551c371..17f5a1a 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.4.0" +version = "0.4.1" repository = "https://github.com/rust-osdev/bootimage" [dependencies] From ff644e3a6b7fb1dae937c2bd94e88551c0fe5534 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Wed, 13 Jun 2018 13:47:09 +0200 Subject: [PATCH 007/271] Use failure crate to improve error messages --- Cargo.lock | 64 +++++++++++++++++++++++++++++++++ Cargo.toml | 1 + src/build.rs | 97 ++++++++++++++++++++++++++++----------------------- src/config.rs | 27 +++++++------- src/main.rs | 31 ++-------------- src/test.rs | 12 +++---- 6 files changed, 142 insertions(+), 90 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1503b15..1671465 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -30,6 +30,7 @@ version = "0.4.1" dependencies = [ "byteorder 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "cargo_metadata 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", + "failure 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", "toml 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "wait-timeout 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", @@ -76,6 +77,25 @@ dependencies = [ "backtrace 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "failure" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "backtrace 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", + "failure_derive 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "failure_derive" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)", + "synstructure 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "fuchsia-zircon" version = "0.3.3" @@ -113,6 +133,11 @@ dependencies = [ "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "quote" +version = "0.3.15" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "quote" version = "0.5.1" @@ -194,6 +219,16 @@ dependencies = [ "serde 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "syn" +version = "0.11.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", + "synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "syn" version = "0.13.1" @@ -204,6 +239,23 @@ dependencies = [ "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "synom" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "synstructure" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "tempdir" version = "0.3.7" @@ -221,6 +273,11 @@ dependencies = [ "serde 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "unicode-xid" +version = "0.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "unicode-xid" version = "0.1.0" @@ -276,12 +333,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d4c819a1287eb618df47cc647173c5c4c66ba19d888a6e50d605672aed3140de" "checksum dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "09c3753c3db574d215cba4ea76018483895d7bff25a31b49ba45db21c48e50ab" "checksum error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ff511d5dc435d703f4971bc399647c9bc38e20cb41452e3b9feb4765419ed3f3" +"checksum failure 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "934799b6c1de475a012a02dab0ace1ace43789ee4b99bcfbf1a2e3e8ced5de82" +"checksum failure_derive 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c7cdda555bb90c9bb67a3b670a0f42de8e73f5981524123ad8578aafec8ddb8b" "checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82" "checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" "checksum itoa 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c069bbec61e1ca5a596166e55dfe4773ff745c3d16b700013bcaff9a6df2c682" "checksum libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)" = "6fd41f331ac7c5b8ac259b8bf82c75c0fb2e469bbf37d2becbba9a6a2221965b" "checksum num-traits 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dee092fcdf725aee04dd7da1d21debff559237d49ef1cb3e69bcb8ece44c7364" "checksum proc-macro2 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "49b6a521dc81b643e9a51e0d1cf05df46d5a2f3c0280ea72bcb68276ba64a118" +"checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a" "checksum quote 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7b0ff51282f28dc1b53fd154298feaa2e77c5ea0dba68e1fd8b03b72fbe13d2a" "checksum rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "eba5f8cb59cc50ed56be8880a5c7b496bfd9bd26394e176bc67884094145c2c5" "checksum remove_dir_all 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3488ba1b9a2084d38645c4c08276a1752dcbf2c7130d74f1569681ad5d2799c5" @@ -292,9 +352,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum serde_derive 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)" = "f1711ab8b208541fa8de00425f6a577d90f27bb60724d2bb5fd911314af9668f" "checksum serde_derive_internals 0.23.0 (registry+https://github.com/rust-lang/crates.io-index)" = "89b340a48245bc03ddba31d0ff1709c118df90edc6adabaca4aac77aea181cce" "checksum serde_json 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)" = "5c508584d9913df116b91505eec55610a2f5b16e9ed793c46e4d0152872b3e74" +"checksum syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d3b891b9015c88c576343b9b3e41c2c11a51c219ef067b264bd9c8aa9b441dad" "checksum syn 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)" = "91b52877572087400e83d24b9178488541e3d535259e04ff17a63df1e5ceff59" +"checksum synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a393066ed9010ebaed60b9eafa373d4b1baac186dd7e008555b0f702b51945b6" +"checksum synstructure 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3a761d12e6d8dcb4dcf952a7a89b475e3a9d69e4a69307e01a470977642914bd" "checksum tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "15f2b5fb00ccdf689e0149d1b1b3c03fead81c2b37735d812fa8bddbbf41b6d8" "checksum toml 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "a0263c6c02c4db6c8f7681f9fd35e90de799ebd4cfdeab77a38f4ff6b3d8c0d9" +"checksum unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f860d7d29cf02cb2f3f359fd35991af3d30bac52c57d265a3c461074cb4dc" "checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" "checksum wait-timeout 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "b9f3bf741a801531993db6478b95682117471f76916f5e690dd8d45395b09349" "checksum winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "04e3bd221fcbe8a271359c04f21a76db7d0c6028862d1bb5512d85e1e2eb5bb3" diff --git a/Cargo.toml b/Cargo.toml index 17f5a1a..0cd5732 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,3 +13,4 @@ xmas-elf = "0.6.1" cargo_metadata = "0.5.3" tempdir = "0.3.7" wait-timeout = "0.1" +failure = "0.1.1" diff --git a/src/build.rs b/src/build.rs index 8372e22..9d4e0cc 100644 --- a/src/build.rs +++ b/src/build.rs @@ -1,11 +1,13 @@ use std::fs::{self, File}; use std::{io, process}; use std::path::{Path, PathBuf}; +use std::sync::Mutex; +use std::io::Write; use byteorder::{ByteOrder, LittleEndian}; use args::{self, Args}; use config::{self, Config}; use cargo_metadata::{self, Metadata as CargoMetadata, Package as CrateMetadata}; -use Error; +use failure::{Error, ResultExt}; use xmas_elf; use tempdir::TempDir; @@ -94,7 +96,7 @@ pub(crate) fn build_impl( let kernel = build_kernel(&out_dir, &bin_name, &args, verbose)?; - let kernel_size = kernel.metadata()?.len(); + let kernel_size = kernel.metadata().context("Failed to read kernel output file")?.len(); let kernel_info_block = create_kernel_info_block(kernel_size); if args.update_bootloader() { @@ -102,12 +104,12 @@ pub(crate) fn build_impl( bootloader_cargo_lock.push("bootloader"); bootloader_cargo_lock.push("Cargo.lock"); - fs::remove_file(bootloader_cargo_lock)?; + fs::remove_file(bootloader_cargo_lock).context("Failed to remove Cargo.lock")?; } - let tmp_dir = TempDir::new("bootloader")?; - let bootloader = build_bootloader(tmp_dir.path(), &config)?; - tmp_dir.close()?; + let tmp_dir = TempDir::new("bootloader").context("Failed to create a temporary directory")?; + let bootloader = build_bootloader(tmp_dir.path(), &config).context("Failed to build bootloader")?; + tmp_dir.close().context("Failed to close temporary directory")?; create_disk_image(root_dir, out_dir, &bin_name, &config, kernel, kernel_info_block, &bootloader, verbose) } @@ -126,12 +128,18 @@ fn run_impl(args: &Args, config: &Config, output_path: &Path) -> Result<(), Erro ); } command.args(&args.run_args); - command.status()?; + command.status().context("Failed to execute run command")?; Ok(()) } -fn read_cargo_metadata(args: &Args) -> Result { - cargo_metadata::metadata(args.manifest_path().as_ref().map(PathBuf::as_path)) +#[derive(Debug, Fail)] +#[fail(display = "Failed to execute `cargo metadata`")] +pub struct CargoMetadataError(Mutex); + +fn read_cargo_metadata(args: &Args) -> Result { + let metadata = cargo_metadata::metadata(args.manifest_path().as_ref().map(PathBuf::as_path)) + .map_err(|e| CargoMetadataError(Mutex::new(e)))?; + Ok(metadata) } fn build_kernel( @@ -144,14 +152,17 @@ fn build_kernel( if verbose { println!("Building kernel"); } - let exit_status = run_xbuild(&args.cargo_args)?; + let exit_status = run_xbuild(&args.cargo_args) + .context("Failed to run `cargo xbuild`")?; if !exit_status.success() { + writeln!(io::stderr(), "Failed to run `cargo xbuild`. Perhaps it is not installed?")?; + writeln!(io::stderr(), "Run `cargo install cargo-xbuild` to install it.")?; process::exit(1) } let mut kernel_path = out_dir.to_owned(); kernel_path.push(bin_name); - let kernel = File::open(kernel_path)?; + let kernel = File::open(kernel_path).context("Failed to open kernel output file")?; Ok(kernel) } @@ -186,13 +197,15 @@ fn download_bootloader(bootloader_dir: &Path, config: &Config) -> Result Result Result Result Result Result Result Result, ]; println!("Building bootloader"); - let exit_status = run_xbuild(args)?; + let exit_status = run_xbuild(args).context("Failed to run `cargo xbuild`")?; if !exit_status.success() { + writeln!(io::stderr(), "Failed to run `cargo xbuild`. Perhaps it is not installed?")?; + writeln!(io::stderr(), "Run `cargo install cargo-xbuild` to install it.")?; process::exit(1) } @@ -315,16 +334,8 @@ fn build_bootloader(bootloader_dir: &Path, config: &Config) -> Result, }; let mut bootloader_elf_bytes = Vec::new(); - let mut bootloader = File::open(&bootloader_elf_path).map_err(|err| { - Error::Bootloader( - format!( - "Could not open bootloader at {}", - bootloader_elf_path.display() - ), - err, - ) - })?; - bootloader.read_to_end(&mut bootloader_elf_bytes)?; + let mut bootloader = File::open(&bootloader_elf_path).context("Could not open bootloader")?; + bootloader.read_to_end(&mut bootloader_elf_bytes).context("Could not read bootloader")?; // copy bootloader section of ELF file to bootloader_path let elf_file = xmas_elf::ElfFile::new(&bootloader_elf_bytes).unwrap(); @@ -360,9 +371,9 @@ fn create_disk_image( println!("Creating disk image at {}", output_path.strip_prefix(root_dir).unwrap_or(output_path.as_path()).display()); } - let mut output = File::create(&output_path)?; - output.write_all(&bootloader_data)?; - output.write_all(&kernel_info_block)?; + let mut output = File::create(&output_path).context("Could not create output bootimage file")?; + output.write_all(&bootloader_data).context("Could not write output bootimage file")?; + output.write_all(&kernel_info_block).context("Could not write output bootimage file")?; // write out kernel elf file let kernel_size = kernel.metadata()?.len(); @@ -381,7 +392,7 @@ fn create_disk_image( let padding_size = ((512 - (kernel_size % 512)) % 512) as usize; let padding = [0u8; 512]; - output.write_all(&padding[..padding_size])?; + output.write_all(&padding[..padding_size]).context("Could not write output bootimage file")?; if let Some(min_size) = config.minimum_image_size { // we already wrote to output successfully, diff --git a/src/config.rs b/src/config.rs index 54ed547..48497d2 100644 --- a/src/config.rs +++ b/src/config.rs @@ -1,5 +1,5 @@ use std::path::{Path, PathBuf}; -use Error; +use failure::{Error, ResultExt}; use toml::Value; #[derive(Debug, Clone)] @@ -27,8 +27,9 @@ pub(crate) fn read_config(manifest_path: PathBuf) -> Result { use std::{fs::File, io::Read}; let cargo_toml: Value = { let mut content = String::new(); - File::open(&manifest_path)?.read_to_string(&mut content)?; - content.parse()? + File::open(&manifest_path).context("Failed to open Cargo.toml")? + .read_to_string(&mut content).context("Failed to read Cargo.toml")?; + content.parse::().context("Failed to parse Cargo.toml")? }; let metadata = cargo_toml @@ -42,10 +43,10 @@ pub(crate) fn read_config(manifest_path: PathBuf) -> Result { ..Default::default() }.into()) } - Some(metadata) => metadata.as_table().ok_or(Error::Config(format!( + Some(metadata) => metadata.as_table().ok_or(format_err!( "Bootimage configuration invalid: {:?}", metadata - )))?, + ))?, }; let mut config = ConfigBuilder { @@ -74,11 +75,11 @@ pub(crate) fn read_config(manifest_path: PathBuf) -> Result { ("path", Value::String(s)) => { bootloader_config.path = Some(Path::new(&s).canonicalize()?); } - (key, value) => Err(Error::Config(format!( + (key, value) => Err(format_err!( "unexpected \ `package.metadata.bootimage.bootloader` key `{}` with value `{}`", key, value - )))?, + ))?, } } config.bootloader = Some(bootloader_config); @@ -87,11 +88,11 @@ pub(crate) fn read_config(manifest_path: PathBuf) -> Result { if x >= 0 { config.minimum_image_size = Some((x * 1024 * 1024) as u64); // MiB -> Byte } else { - Err(Error::Config(format!( + Err(format_err!( "unexpected `package.metadata.bootimage` \ key `minimum-image-size` with negative value `{}`", value - )))? + ))? } } ("run-command", Value::Array(array)) => { @@ -99,18 +100,18 @@ pub(crate) fn read_config(manifest_path: PathBuf) -> Result { for value in array { match value { Value::String(s) => command.push(s), - _ => Err(Error::Config(format!( + _ => Err(format_err!( "run-command must be a list of strings" - )))?, + ))?, } } config.run_command = Some(command); } - (key, value) => Err(Error::Config(format!( + (key, value) => Err(format_err!( "unexpected `package.metadata.bootimage` \ key `{}` with value `{}`", key, value - )))?, + ))?, } } Ok(config.into()) diff --git a/src/main.rs b/src/main.rs index fe6b4ec..c2e61e7 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,6 +4,8 @@ extern crate tempdir; extern crate toml; extern crate xmas_elf; extern crate wait_timeout; +#[macro_use] +extern crate failure; use std::{io, process}; use args::Args; @@ -34,34 +36,7 @@ pub fn main() { } } -#[derive(Debug)] -pub enum Error { - Config(String), - Bootloader(String, io::Error), - Io(io::Error), - Toml(toml::de::Error), - CargoMetadata(cargo_metadata::Error), -} - -impl From for Error { - fn from(other: io::Error) -> Self { - Error::Io(other) - } -} - -impl From for Error { - fn from(other: toml::de::Error) -> Self { - Error::Toml(other) - } -} - -impl From for Error { - fn from(other: cargo_metadata::Error) -> Self { - Error::CargoMetadata(other) - } -} - -fn run() -> Result<(), Error> { +fn run() -> Result<(), failure::Error> { let command = args::parse_args(); match command { Command::NoSubcommand => help::no_subcommand(), diff --git a/src/test.rs b/src/test.rs index 686dc28..0ece2e3 100644 --- a/src/test.rs +++ b/src/test.rs @@ -1,5 +1,5 @@ use std::{fs, io, process}; -use Error; +use failure::{Error, ResultExt}; use args::Args; use build; use wait_timeout::ChildExt; @@ -52,17 +52,17 @@ pub(crate) fn test(args: Args) -> Result<(), Error> { command.arg("-serial"); command.arg(format!("file:{}", output_file)); command.stderr(process::Stdio::null()); - let mut child = command.spawn()?; + let mut child = command.spawn().context("Failed to launch QEMU")?; let timeout = Duration::from_secs(60); - match child.wait_timeout(timeout)? { + match child.wait_timeout(timeout).context("Failed to wait with timeout")? { None => { - child.kill()?; - child.wait()?; + child.kill().context("Failed to kill QEMU")?; + child.wait().context("Failed to wait for QEMU process")?; test_result = TestResult::TimedOut; writeln!(io::stderr(), "Timed Out")?; } Some(_) => { - let output = fs::read_to_string(output_file)?; + let output = fs::read_to_string(output_file).context("Failed to read test output file")?; if output.starts_with("ok\n") { test_result = TestResult::Ok; println!("Ok"); From 7ab12730cd545aa5018e0bab076f07b421b0a728 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Wed, 13 Jun 2018 14:35:11 +0200 Subject: [PATCH 008/271] bootimage 0.4.2 --- Cargo.lock | 2 +- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1671465..96c6c48 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -26,7 +26,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "bootimage" -version = "0.4.1" +version = "0.4.2" dependencies = [ "byteorder 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "cargo_metadata 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/Cargo.toml b/Cargo.toml index 0cd5732..922b67e 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.4.1" +version = "0.4.2" repository = "https://github.com/rust-osdev/bootimage" [dependencies] From ab045c372b5b6851b16a3e6543535ab7df026c9f Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Wed, 13 Jun 2018 15:42:56 +0200 Subject: [PATCH 009/271] Only suggest to install cargo-xbuild if cargo xbuild --help fails --- src/build.rs | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/src/build.rs b/src/build.rs index 9d4e0cc..63782d0 100644 --- a/src/build.rs +++ b/src/build.rs @@ -155,8 +155,6 @@ fn build_kernel( let exit_status = run_xbuild(&args.cargo_args) .context("Failed to run `cargo xbuild`")?; if !exit_status.success() { - writeln!(io::stderr(), "Failed to run `cargo xbuild`. Perhaps it is not installed?")?; - writeln!(io::stderr(), "Run `cargo install cargo-xbuild` to install it.")?; process::exit(1) } @@ -170,7 +168,23 @@ fn run_xbuild(args: &[String]) -> io::Result { let mut command = process::Command::new("cargo"); command.arg("xbuild"); command.args(args); - command.status() + let exit_status = command.status()?; + + if !exit_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() { + let mut stderr = io::stderr(); + writeln!(stderr, "Failed to run `cargo xbuild`. Perhaps it is not installed?")?; + writeln!(stderr, "Run `cargo install cargo-xbuild` to install it.")?; + } + } + } + + Ok(exit_status) } fn create_kernel_info_block(kernel_size: u64) -> KernelInfoBlock { @@ -316,8 +330,6 @@ fn build_bootloader(bootloader_dir: &Path, config: &Config) -> Result, println!("Building bootloader"); let exit_status = run_xbuild(args).context("Failed to run `cargo xbuild`")?; if !exit_status.success() { - writeln!(io::stderr(), "Failed to run `cargo xbuild`. Perhaps it is not installed?")?; - writeln!(io::stderr(), "Run `cargo install cargo-xbuild` to install it.")?; process::exit(1) } From 10b57209cac74345ec15905964565b7edb495d0f Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Wed, 13 Jun 2018 15:49:48 +0200 Subject: [PATCH 010/271] Improve error messages for QEMU run and test output read --- src/build.rs | 2 +- src/test.rs | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/build.rs b/src/build.rs index 63782d0..4639483 100644 --- a/src/build.rs +++ b/src/build.rs @@ -128,7 +128,7 @@ fn run_impl(args: &Args, config: &Config, output_path: &Path) -> Result<(), Erro ); } command.args(&args.run_args); - command.status().context("Failed to execute run command")?; + command.status().context(format_err!("Failed to execute run command: {:?}", command))?; Ok(()) } diff --git a/src/test.rs b/src/test.rs index 0ece2e3..0a24143 100644 --- a/src/test.rs +++ b/src/test.rs @@ -52,7 +52,8 @@ pub(crate) fn test(args: Args) -> Result<(), Error> { command.arg("-serial"); command.arg(format!("file:{}", output_file)); command.stderr(process::Stdio::null()); - let mut child = command.spawn().context("Failed to launch QEMU")?; + let mut child = command.spawn() + .context(format_err!("Failed to launch QEMU: {:?}", command))?; let timeout = Duration::from_secs(60); match child.wait_timeout(timeout).context("Failed to wait with timeout")? { None => { @@ -62,7 +63,8 @@ pub(crate) fn test(args: Args) -> Result<(), Error> { writeln!(io::stderr(), "Timed Out")?; } Some(_) => { - let output = fs::read_to_string(output_file).context("Failed to read test output file")?; + let output = fs::read_to_string(&output_file) + .context(format_err!("Failed to read test output file {}", output_file))?; if output.starts_with("ok\n") { test_result = TestResult::Ok; println!("Ok"); From 27f80ebbcfc8f19d1c3f1cef599211e20eb1f19d Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Wed, 13 Jun 2018 15:50:04 +0200 Subject: [PATCH 011/271] bootimage 0.4.3 --- Cargo.lock | 2 +- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 96c6c48..2358904 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -26,7 +26,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "bootimage" -version = "0.4.2" +version = "0.4.3" dependencies = [ "byteorder 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "cargo_metadata 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/Cargo.toml b/Cargo.toml index 922b67e..1f89fba 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.4.2" +version = "0.4.3" repository = "https://github.com/rust-osdev/bootimage" [dependencies] From 270c4e170134a54beb15050d9db5bf95d3052f99 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Wed, 18 Jul 2018 11:04:36 +0200 Subject: [PATCH 012/271] Always use a version for bootloader download; default to 0.2.0-alpha (#15) --- src/build.rs | 13 ++----------- src/config.rs | 4 ++-- 2 files changed, 4 insertions(+), 13 deletions(-) diff --git a/src/build.rs b/src/build.rs index 4639483..2fb6d47 100644 --- a/src/build.rs +++ b/src/build.rs @@ -233,20 +233,11 @@ fn download_bootloader(bootloader_dir: &Path, config: &Config) -> Result, + pub version: String, pub git: Option, pub branch: Option, pub path: Option, @@ -172,7 +172,7 @@ impl Into for BootloaderConfigBuilder { precompiled, target: self.target .unwrap_or(PathBuf::from("x86_64-bootloader.json")), - version: self.version, + version: self.version.unwrap_or("0.2.0-alpha".into()), git: self.git, branch: self.branch, path: self.path, From 14a7f85ca2185d18e472b243fb623cf1bdfc5088 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Wed, 18 Jul 2018 11:06:28 +0200 Subject: [PATCH 013/271] bootimage 0.4.4 --- Cargo.lock | 2 +- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2358904..3ede1bc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -26,7 +26,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "bootimage" -version = "0.4.3" +version = "0.4.4" dependencies = [ "byteorder 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "cargo_metadata 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/Cargo.toml b/Cargo.toml index 1f89fba..dc1f0fd 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.4.3" +version = "0.4.4" repository = "https://github.com/rust-osdev/bootimage" [dependencies] From fb59dc25f880e6530647e389594916b6735f4b94 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Wed, 18 Jul 2018 19:03:47 +0200 Subject: [PATCH 014/271] Implement new bootloader dependency resolution; run rustfmt --- Cargo.lock | 53 ---------- Cargo.toml | 1 - src/args.rs | 23 +++-- src/build.rs | 208 +++++++++++++--------------------------- src/config.rs | 69 +++++-------- src/help/build_help.txt | 9 +- src/help/help.txt | 4 +- src/main.rs | 9 +- src/test.rs | 39 +++++--- 9 files changed, 141 insertions(+), 274 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3ede1bc..025b5f4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -19,11 +19,6 @@ dependencies = [ "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "bitflags" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "bootimage" version = "0.4.4" @@ -31,7 +26,6 @@ dependencies = [ "byteorder 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "cargo_metadata 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", "failure 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", "toml 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "wait-timeout 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "xmas-elf 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -96,20 +90,6 @@ dependencies = [ "synstructure 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "fuchsia-zircon" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "fuchsia-zircon-sys" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "itoa" version = "0.4.1" @@ -146,24 +126,6 @@ dependencies = [ "proc-macro2 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "rand" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "remove_dir_all" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "rustc-demangle" version = "0.1.7" @@ -256,15 +218,6 @@ dependencies = [ "syn 0.11.11 (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.2 (registry+https://github.com/rust-lang/crates.io-index)", - "remove_dir_all 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "toml" version = "0.4.6" @@ -326,7 +279,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [metadata] "checksum backtrace 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "ebbbf59b1c43eefa8c3ede390fcc36820b4999f7914104015be25025e0d62af2" "checksum backtrace-sys 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "44585761d6161b0f57afc49482ab6bd067e4edef48c12a152c237eb0203f7661" -"checksum bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b3c30d3802dfb7281680d6285f2ccdaa8c2d8fee41f93805dba5c4cf50dc23cf" "checksum byteorder 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "73b5bdfe7ee3ad0b99c9801d58807a9dbc9e09196365b0203853b99889ab3c87" "checksum cargo_metadata 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)" = "6ebd6272a2ca4fd39dbabbd6611eb03df45c2259b3b80b39a9ff8fbdcf42a4b3" "checksum cc 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)" = "2b4911e4bdcb4100c7680e7e854ff38e23f1b34d4d9e079efae3da2801341ffc" @@ -335,16 +287,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ff511d5dc435d703f4971bc399647c9bc38e20cb41452e3b9feb4765419ed3f3" "checksum failure 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "934799b6c1de475a012a02dab0ace1ace43789ee4b99bcfbf1a2e3e8ced5de82" "checksum failure_derive 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c7cdda555bb90c9bb67a3b670a0f42de8e73f5981524123ad8578aafec8ddb8b" -"checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82" -"checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" "checksum itoa 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c069bbec61e1ca5a596166e55dfe4773ff745c3d16b700013bcaff9a6df2c682" "checksum libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)" = "6fd41f331ac7c5b8ac259b8bf82c75c0fb2e469bbf37d2becbba9a6a2221965b" "checksum num-traits 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dee092fcdf725aee04dd7da1d21debff559237d49ef1cb3e69bcb8ece44c7364" "checksum proc-macro2 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "49b6a521dc81b643e9a51e0d1cf05df46d5a2f3c0280ea72bcb68276ba64a118" "checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a" "checksum quote 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7b0ff51282f28dc1b53fd154298feaa2e77c5ea0dba68e1fd8b03b72fbe13d2a" -"checksum rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "eba5f8cb59cc50ed56be8880a5c7b496bfd9bd26394e176bc67884094145c2c5" -"checksum remove_dir_all 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3488ba1b9a2084d38645c4c08276a1752dcbf2c7130d74f1569681ad5d2799c5" "checksum rustc-demangle 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "11fb43a206a04116ffd7cfcf9bcb941f8eb6cc7ff667272246b0a1c74259a3cb" "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" @@ -356,7 +304,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum syn 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)" = "91b52877572087400e83d24b9178488541e3d535259e04ff17a63df1e5ceff59" "checksum synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a393066ed9010ebaed60b9eafa373d4b1baac186dd7e008555b0f702b51945b6" "checksum synstructure 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3a761d12e6d8dcb4dcf952a7a89b475e3a9d69e4a69307e01a470977642914bd" -"checksum tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "15f2b5fb00ccdf689e0149d1b1b3c03fead81c2b37735d812fa8bddbbf41b6d8" "checksum toml 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "a0263c6c02c4db6c8f7681f9fd35e90de799ebd4cfdeab77a38f4ff6b3d8c0d9" "checksum unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f860d7d29cf02cb2f3f359fd35991af3d30bac52c57d265a3c461074cb4dc" "checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" diff --git a/Cargo.toml b/Cargo.toml index dc1f0fd..9463579 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,6 +11,5 @@ byteorder = "1.2.1" toml = "0.4.5" xmas-elf = "0.6.1" cargo_metadata = "0.5.3" -tempdir = "0.3.7" wait-timeout = "0.1" failure = "0.1.1" diff --git a/src/args.rs b/src/args.rs index 4be2f57..b346885 100644 --- a/src/args.rs +++ b/src/args.rs @@ -1,5 +1,5 @@ -use std::{env, mem}; use std::path::{Path, PathBuf}; +use std::{env, mem}; use Command; pub(crate) fn parse_args() -> Command { @@ -14,9 +14,12 @@ pub(crate) fn parse_args() -> Command { }, Some("test") => match parse_build_args(args) { Command::Build(args) => { - assert_eq!(args.bin_name, None, "No `--bin` argument allowed for `bootimage test`"); + assert_eq!( + args.bin_name, None, + "No `--bin` argument allowed for `bootimage test`" + ); Command::Test(args) - }, + } Command::BuildHelp => Command::TestHelp, cmd => cmd, }, @@ -92,9 +95,14 @@ where } "--manifest-path" => { let next = arg_iter.next(); - set(&mut manifest_path, next.as_ref().map(|p| { - Path::new(&p).canonicalize().expect("--manifest-path invalid") - })); + 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); @@ -102,7 +110,8 @@ where } _ if arg.starts_with("--manifest-path=") => { let path = Path::new(arg.trim_left_matches("--manifest-path=")) - .canonicalize().expect("--manifest-path invalid"); + .canonicalize() + .expect("--manifest-path invalid"); set(&mut manifest_path, Some(path)); cargo_args.push(arg); } diff --git a/src/build.rs b/src/build.rs index 2fb6d47..15aa97b 100644 --- a/src/build.rs +++ b/src/build.rs @@ -1,15 +1,14 @@ -use std::fs::{self, File}; -use std::{io, process}; -use std::path::{Path, PathBuf}; -use std::sync::Mutex; -use std::io::Write; -use byteorder::{ByteOrder, LittleEndian}; use args::{self, Args}; +use byteorder::{ByteOrder, LittleEndian}; +use cargo_metadata::{self, Metadata as CargoMetadata}; use config::{self, Config}; -use cargo_metadata::{self, Metadata as CargoMetadata, Package as CrateMetadata}; use failure::{Error, ResultExt}; +use std::fs::{self, File}; +use std::io::Write; +use std::path::{Path, PathBuf}; +use std::sync::Mutex; +use std::{io, process}; use xmas_elf; -use tempdir::TempDir; const BLOCK_SIZE: usize = 512; type KernelInfoBlock = [u8; BLOCK_SIZE]; @@ -28,7 +27,9 @@ pub(crate) fn run(args: Args) -> Result<(), Error> { run_impl(&args, &config, &output_path) } -pub(crate) fn common_setup(mut args: Args) -> Result<(Args, Config, CargoMetadata, PathBuf, PathBuf), Error> { +pub(crate) fn common_setup( + mut args: Args, +) -> Result<(Args, Config, CargoMetadata, PathBuf, PathBuf), Error> { fn out_dir(args: &Args, metadata: &CargoMetadata) -> PathBuf { let target_dir = PathBuf::from(&metadata.target_directory); let mut out_dir = target_dir; @@ -96,7 +97,10 @@ pub(crate) fn build_impl( let kernel = build_kernel(&out_dir, &bin_name, &args, verbose)?; - let kernel_size = kernel.metadata().context("Failed to read kernel output file")?.len(); + let kernel_size = kernel + .metadata() + .context("Failed to read kernel output file")? + .len(); let kernel_info_block = create_kernel_info_block(kernel_size); if args.update_bootloader() { @@ -107,28 +111,33 @@ pub(crate) fn build_impl( fs::remove_file(bootloader_cargo_lock).context("Failed to remove Cargo.lock")?; } - let tmp_dir = TempDir::new("bootloader").context("Failed to create a temporary directory")?; - let bootloader = build_bootloader(tmp_dir.path(), &config).context("Failed to build bootloader")?; - tmp_dir.close().context("Failed to close temporary directory")?; - - create_disk_image(root_dir, out_dir, &bin_name, &config, kernel, kernel_info_block, &bootloader, verbose) + let bootloader = build_bootloader(&metadata, &config).context("Failed to build bootloader")?; + + create_disk_image( + root_dir, + out_dir, + &bin_name, + &config, + kernel, + kernel_info_block, + &bootloader, + verbose, + ) } fn run_impl(args: &Args, config: &Config, output_path: &Path) -> Result<(), Error> { let command = &config.run_command[0]; let mut command = process::Command::new(command); for arg in &config.run_command[1..] { - command.arg( - arg.replace( - "{}", - output_path - .to_str() - .expect("output must be valid unicode"), - ), - ); + command.arg(arg.replace( + "{}", + output_path.to_str().expect("output must be valid unicode"), + )); } command.args(&args.run_args); - command.status().context(format_err!("Failed to execute run command: {:?}", command))?; + command + .status() + .context(format_err!("Failed to execute run command: {:?}", command))?; Ok(()) } @@ -137,8 +146,9 @@ fn run_impl(args: &Args, config: &Config, output_path: &Path) -> Result<(), Erro pub struct CargoMetadataError(Mutex); fn read_cargo_metadata(args: &Args) -> Result { - let metadata = cargo_metadata::metadata(args.manifest_path().as_ref().map(PathBuf::as_path)) - .map_err(|e| CargoMetadataError(Mutex::new(e)))?; + let metadata = + cargo_metadata::metadata_deps(args.manifest_path().as_ref().map(PathBuf::as_path), true) + .map_err(|e| CargoMetadataError(Mutex::new(e)))?; Ok(metadata) } @@ -152,8 +162,7 @@ fn build_kernel( if verbose { println!("Building kernel"); } - let exit_status = run_xbuild(&args.cargo_args) - .context("Failed to run `cargo xbuild`")?; + let exit_status = run_xbuild(&args.cargo_args).context("Failed to run `cargo xbuild`")?; if !exit_status.success() { process::exit(1) } @@ -178,7 +187,10 @@ fn run_xbuild(args: &[String]) -> io::Result { if let Ok(help_exit_status) = help_command.status() { if !help_exit_status.success() { let mut stderr = io::stderr(); - writeln!(stderr, "Failed to run `cargo xbuild`. Perhaps it is not installed?")?; + writeln!( + stderr, + "Failed to run `cargo xbuild`. Perhaps it is not installed?" + )?; writeln!(stderr, "Run `cargo install cargo-xbuild` to install it.")?; } } @@ -200,108 +212,13 @@ fn create_kernel_info_block(kernel_size: u64) -> KernelInfoBlock { kernel_info_block } -fn download_bootloader(bootloader_dir: &Path, config: &Config) -> Result { - use std::io::Write; - - let cargo_toml = { - let mut dir = bootloader_dir.to_owned(); - dir.push("Cargo.toml"); - dir - }; - let src_lib = { - let mut dir = bootloader_dir.to_owned(); - dir.push("src"); - fs::create_dir_all(dir.as_path()) - .context("Failed to create directory for bootloader download crate")?; - dir.push("lib.rs"); - dir - }; - - { - let mut cargo_toml_file = File::create(&cargo_toml) - .context("Failed to create Cargo.toml for bootloader download crate")?; - cargo_toml_file.write_all( - r#" - [package] - authors = ["author@example.com>"] - name = "bootloader_download_helper" - version = "0.0.0" - - "#.as_bytes(), - ).context("Failed to write to Cargo.toml for bootloader download crate")?; - cargo_toml_file.write_all( - format!( - r#" - [dependencies.{}] - version = "{}" - "#, - config.bootloader.name, config.bootloader.version - ).as_bytes(), - ).context("Failed to write to Cargo.toml for bootloader download crate")?; - if let &Some(ref git) = &config.bootloader.git { - cargo_toml_file.write_all( - format!( - r#" - git = "{}" - "#, - git - ).as_bytes(), - ).context("Failed to write to Cargo.toml for bootloader download crate")?; - } - if let &Some(ref branch) = &config.bootloader.branch { - cargo_toml_file.write_all( - format!( - r#" - branch = "{}" - "#, - branch - ).as_bytes(), - ).context("Failed to write to Cargo.toml for bootloader download crate")?; - } - if let &Some(ref path) = &config.bootloader.path { - cargo_toml_file.write_all( - format!( - r#" - path = "{}" - "#, - path.display() - ).as_bytes(), - ).context("Failed to write to Cargo.toml for bootloader download crate")?; - } - - File::create(src_lib).context("Failed to create lib.rs for bootloader download crate")? - .write_all( - r#" - #![no_std] - "#.as_bytes(), - ).context("Failed to write to lib.rs for bootloader download crate")?; - } - - let mut command = process::Command::new("cargo"); - command.arg("fetch"); - command.current_dir(bootloader_dir); - if !command.status()?.success() { - Err(format_err!("Bootloader download failed."))? - } - - let metadata = cargo_metadata::metadata_deps(Some(&cargo_toml), true) - .map_err(|e| CargoMetadataError(Mutex::new(e)))?; - let bootloader = metadata - .packages - .iter() - .find(|p| p.name == config.bootloader.name) - .ok_or(format_err!( - "Could not find crate named “{}”", - config.bootloader.name - ))?; - - Ok(bootloader.clone()) -} - -fn build_bootloader(bootloader_dir: &Path, config: &Config) -> Result, Error> { +fn build_bootloader(metadata: &CargoMetadata, config: &Config) -> Result, Error> { use std::io::Read; - let bootloader_metadata = download_bootloader(bootloader_dir, config)?; + let bootloader_metadata = match metadata.packages.iter().find(|p| p.name == "bootloader") { + Some(package_metadata) => package_metadata.clone(), + None => Err(format_err!("Bootloader dependency not found"))?, + }; let bootloader_dir = Path::new(&bootloader_metadata.manifest_path) .parent() .unwrap(); @@ -309,7 +226,7 @@ fn build_bootloader(bootloader_dir: &Path, config: &Config) -> Result, let mut bootloader_target_path = PathBuf::from(bootloader_dir); bootloader_target_path.push(&config.bootloader.target); - let bootloader_elf_path = if !config.bootloader.precompiled { + let bootloader_elf_path = { let args = &[ String::from("--manifest-path"), bootloader_metadata.manifest_path.clone(), @@ -318,7 +235,7 @@ fn build_bootloader(bootloader_dir: &Path, config: &Config) -> Result, String::from("--release"), ]; - println!("Building bootloader"); + println!("Building bootloader v{}", bootloader_metadata.version); let exit_status = run_xbuild(args).context("Failed to run `cargo xbuild`")?; if !exit_status.success() { process::exit(1) @@ -330,15 +247,13 @@ fn build_bootloader(bootloader_dir: &Path, config: &Config) -> Result, bootloader_elf_path.push("release"); bootloader_elf_path.push("bootloader"); bootloader_elf_path - } else { - let mut bootloader_elf_path = bootloader_dir.to_path_buf(); - bootloader_elf_path.push("bootloader"); - bootloader_elf_path }; let mut bootloader_elf_bytes = Vec::new(); let mut bootloader = File::open(&bootloader_elf_path).context("Could not open bootloader")?; - bootloader.read_to_end(&mut bootloader_elf_bytes).context("Could not read bootloader")?; + bootloader + .read_to_end(&mut bootloader_elf_bytes) + .context("Could not read bootloader")?; // copy bootloader section of ELF file to bootloader_path let elf_file = xmas_elf::ElfFile::new(&bootloader_elf_bytes).unwrap(); @@ -371,12 +286,21 @@ fn create_disk_image( } if verbose { - println!("Creating disk image at {}", - output_path.strip_prefix(root_dir).unwrap_or(output_path.as_path()).display()); + println!( + "Creating disk image at {}", + output_path + .strip_prefix(root_dir) + .unwrap_or(output_path.as_path()) + .display() + ); } let mut output = File::create(&output_path).context("Could not create output bootimage file")?; - output.write_all(&bootloader_data).context("Could not write output bootimage file")?; - output.write_all(&kernel_info_block).context("Could not write output bootimage file")?; + output + .write_all(&bootloader_data) + .context("Could not write output bootimage file")?; + output + .write_all(&kernel_info_block) + .context("Could not write output bootimage file")?; // write out kernel elf file let kernel_size = kernel.metadata()?.len(); @@ -395,7 +319,9 @@ fn create_disk_image( let padding_size = ((512 - (kernel_size % 512)) % 512) as usize; let padding = [0u8; 512]; - output.write_all(&padding[..padding_size]).context("Could not write output bootimage file")?; + output + .write_all(&padding[..padding_size]) + .context("Could not write output bootimage file")?; if let Some(min_size) = config.minimum_image_size { // we already wrote to output successfully, diff --git a/src/config.rs b/src/config.rs index 0071806..b312110 100644 --- a/src/config.rs +++ b/src/config.rs @@ -1,5 +1,5 @@ -use std::path::{Path, PathBuf}; use failure::{Error, ResultExt}; +use std::path::PathBuf; use toml::Value; #[derive(Debug, Clone)] @@ -15,21 +15,20 @@ pub struct Config { #[derive(Debug, Clone)] pub struct BootloaderConfig { pub name: String, - pub precompiled: bool, pub target: PathBuf, - pub version: String, - pub git: Option, - pub branch: Option, - pub path: Option, } pub(crate) fn read_config(manifest_path: PathBuf) -> Result { use std::{fs::File, io::Read}; let cargo_toml: Value = { let mut content = String::new(); - File::open(&manifest_path).context("Failed to open Cargo.toml")? - .read_to_string(&mut content).context("Failed to read Cargo.toml")?; - content.parse::().context("Failed to parse Cargo.toml")? + File::open(&manifest_path) + .context("Failed to open Cargo.toml")? + .read_to_string(&mut content) + .context("Failed to read Cargo.toml")?; + content + .parse::() + .context("Failed to parse Cargo.toml")? }; let metadata = cargo_toml @@ -63,22 +62,23 @@ pub(crate) fn read_config(manifest_path: PathBuf) -> Result { for (key, value) in t { match (key.as_str(), value) { ("name", Value::String(s)) => bootloader_config.name = From::from(s), - ("precompiled", Value::Boolean(b)) => { - bootloader_config.precompiled = From::from(b) - } ("target", Value::String(s)) => { bootloader_config.target = Some(PathBuf::from(s)) } - ("version", Value::String(s)) => bootloader_config.version = From::from(s), - ("git", Value::String(s)) => bootloader_config.git = From::from(s), - ("branch", Value::String(s)) => bootloader_config.branch = From::from(s), - ("path", Value::String(s)) => { - bootloader_config.path = Some(Path::new(&s).canonicalize()?); - } + (k @ "precompiled", _) + | (k @ "version", _) + | (k @ "git", _) + | (k @ "branch", _) + | (k @ "path", _) => Err(format_err!( + "the \ + `package.metadata.bootimage.bootloader` key `{}` was deprecated", + k + ))?, (key, value) => Err(format_err!( "unexpected \ `package.metadata.bootimage.bootloader` key `{}` with value `{}`", - key, value + key, + value ))?, } } @@ -100,9 +100,7 @@ pub(crate) fn read_config(manifest_path: PathBuf) -> Result { for value in array { match value { Value::String(s) => command.push(s), - _ => Err(format_err!( - "run-command must be a list of strings" - ))?, + _ => Err(format_err!("run-command must be a list of strings"))?, } } config.run_command = Some(command); @@ -110,7 +108,8 @@ pub(crate) fn read_config(manifest_path: PathBuf) -> Result { (key, value) => Err(format_err!( "unexpected `package.metadata.bootimage` \ key `{}` with value `{}`", - key, value + key, + value ))?, } } @@ -130,25 +129,16 @@ struct ConfigBuilder { #[derive(Default)] struct BootloaderConfigBuilder { name: Option, - precompiled: Option, target: Option, - version: Option, - branch: Option, - git: Option, - path: Option, } impl Into for ConfigBuilder { fn into(self) -> Config { - let default_bootloader_config = BootloaderConfigBuilder { - precompiled: Some(true), - ..Default::default() - }; Config { manifest_path: self.manifest_path.expect("manifest path must be set"), default_target: self.default_target, output: self.output, - bootloader: self.bootloader.unwrap_or(default_bootloader_config).into(), + bootloader: self.bootloader.unwrap_or_default().into(), minimum_image_size: self.minimum_image_size, run_command: self.run_command.unwrap_or(vec![ "qemu-system-x86_64".into(), @@ -161,21 +151,10 @@ impl Into for ConfigBuilder { impl Into for BootloaderConfigBuilder { fn into(self) -> BootloaderConfig { - let precompiled = self.precompiled.unwrap_or(false); - let default_name = if precompiled { - "bootloader_precompiled" - } else { - "bootloader" - }; BootloaderConfig { - name: self.name.unwrap_or(default_name.into()), - precompiled, + name: self.name.unwrap_or("bootloader".into()), target: self.target .unwrap_or(PathBuf::from("x86_64-bootloader.json")), - version: self.version.unwrap_or("0.2.0-alpha".into()), - git: self.git, - branch: self.branch, - path: self.path, } } } diff --git a/src/help/build_help.txt b/src/help/build_help.txt index 3009294..5477d81 100644 --- a/src/help/build_help.txt +++ b/src/help/build_help.txt @@ -6,9 +6,7 @@ USAGE: (for other forms of usage see `bootimage --help`) BUILD_OPTS: - --update-bootloader Update the bootloader dependency. - - Any additional options are directly passed to `cargo build` (see + 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. @@ -25,9 +23,4 @@ CONFIGURATION: [package.metadata.bootimage.bootloader] name = "bootloader" The bootloader crate name - version = "" The bootloader version that should be used - git = "" Use the bootloader from this git repository - branch = "" The git branch to use (defaults to master) - path = "" Use the bootloader from this local path - precompiled = false Whether the bootloader crate is precompiled target = "x86_64-bootloader.json" Target triple for compiling the bootloader diff --git a/src/help/help.txt b/src/help/help.txt index aa3bcd9..9ed07b6 100644 --- a/src/help/help.txt +++ b/src/help/help.txt @@ -13,9 +13,7 @@ OPTIONS: ---version Prints version information and exit BUILD_OPTS: - --update-bootloader Update the bootloader dependency. - - Any additional options are directly passed to `cargo build` (see + 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/main.rs b/src/main.rs index c2e61e7..1f915b7 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,20 +1,19 @@ extern crate byteorder; extern crate cargo_metadata; -extern crate tempdir; extern crate toml; -extern crate xmas_elf; extern crate wait_timeout; +extern crate xmas_elf; #[macro_use] extern crate failure; -use std::{io, process}; use args::Args; +use std::{io, process}; mod args; -mod config; mod build; -mod test; +mod config; mod help; +mod test; enum Command { NoSubcommand, diff --git a/src/test.rs b/src/test.rs index 0a24143..33a2125 100644 --- a/src/test.rs +++ b/src/test.rs @@ -1,10 +1,10 @@ -use std::{fs, io, process}; -use failure::{Error, ResultExt}; use args::Args; use build; -use wait_timeout::ChildExt; -use std::time::Duration; +use failure::{Error, ResultExt}; use std::io::Write; +use std::time::Duration; +use std::{fs, io, process}; +use wait_timeout::ChildExt; pub(crate) fn test(args: Args) -> Result<(), Error> { let (args, config, metadata, root_dir, out_dir) = build::common_setup(args)?; @@ -30,14 +30,25 @@ pub(crate) fn test(args: Args) -> Result<(), Error> { let mut tests = Vec::new(); - assert_eq!(metadata.packages.len(), 1, "Only crates with one package are supported"); + assert_eq!( + metadata.packages.len(), + 1, + "Only crates with one package are supported" + ); let target_iter = metadata.packages[0].targets.iter(); for target in target_iter.filter(|t| t.kind == ["bin"] && t.name.starts_with("test-")) { println!("{}", target.name); let mut target_args = test_args.clone(); target_args.set_bin_name(target.name.clone()); - let test_path = build::build_impl(&target_args, &test_config, &metadata, &root_dir, &out_dir, false)?; + let test_path = build::build_impl( + &target_args, + &test_config, + &metadata, + &root_dir, + &out_dir, + false, + )?; let test_result; let output_file = format!("{}-output.txt", test_path.display()); @@ -52,10 +63,14 @@ pub(crate) fn test(args: Args) -> Result<(), Error> { command.arg("-serial"); command.arg(format!("file:{}", output_file)); command.stderr(process::Stdio::null()); - let mut child = command.spawn() + let mut child = command + .spawn() .context(format_err!("Failed to launch QEMU: {:?}", command))?; let timeout = Duration::from_secs(60); - match child.wait_timeout(timeout).context("Failed to wait with timeout")? { + 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")?; @@ -63,8 +78,10 @@ pub(crate) fn test(args: Args) -> Result<(), Error> { writeln!(io::stderr(), "Timed Out")?; } Some(_) => { - let output = fs::read_to_string(&output_file) - .context(format_err!("Failed to read test output file {}", output_file))?; + let output = fs::read_to_string(&output_file).context(format_err!( + "Failed to read test output file {}", + output_file + ))?; if output.starts_with("ok\n") { test_result = TestResult::Ok; println!("Ok"); @@ -81,7 +98,7 @@ pub(crate) fn test(args: Args) -> Result<(), Error> { writeln!(io::stderr(), " {}", line)?; } } - }, + } } println!(""); From 7177777d556a6d23c7d841994b20e71ce87c4332 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Wed, 18 Jul 2018 19:06:00 +0200 Subject: [PATCH 015/271] The --update-bootloader arg is no longer needed (just do `cargo update`) --- src/args.rs | 11 ----------- src/build.rs | 8 -------- 2 files changed, 19 deletions(-) diff --git a/src/args.rs b/src/args.rs index b346885..84ccca0 100644 --- a/src/args.rs +++ b/src/args.rs @@ -37,7 +37,6 @@ where let mut bin_name: Option = None; let mut target: Option = None; let mut release: Option = None; - let mut update_bootloader: Option = None; let mut cargo_args = Vec::new(); let mut run_args = Vec::new(); let mut run_args_started = false; @@ -119,9 +118,6 @@ where set(&mut release, Some(true)); cargo_args.push(arg); } - "--update-bootloader" => { - set(&mut update_bootloader, Some(true)); - } "--" => { run_args_started = true; } @@ -139,7 +135,6 @@ where target, manifest_path, release: release.unwrap_or(false), - update_bootloader: update_bootloader.unwrap_or(false), }) } @@ -157,8 +152,6 @@ pub struct Args { target: Option, /// The release flag (also present in `cargo_args`). release: bool, - /// Whether the bootloader should be updated (not present in `cargo_args`). - update_bootloader: bool, } impl Args { @@ -178,10 +171,6 @@ impl Args { self.release } - pub fn update_bootloader(&self) -> bool { - self.update_bootloader - } - pub fn set_target(&mut self, target: String) { assert!(self.target.is_none()); self.target = Some(target.clone()); diff --git a/src/build.rs b/src/build.rs index 15aa97b..f731194 100644 --- a/src/build.rs +++ b/src/build.rs @@ -103,14 +103,6 @@ pub(crate) fn build_impl( .len(); let kernel_info_block = create_kernel_info_block(kernel_size); - if args.update_bootloader() { - let mut bootloader_cargo_lock = PathBuf::from(out_dir); - bootloader_cargo_lock.push("bootloader"); - bootloader_cargo_lock.push("Cargo.lock"); - - fs::remove_file(bootloader_cargo_lock).context("Failed to remove Cargo.lock")?; - } - let bootloader = build_bootloader(&metadata, &config).context("Failed to build bootloader")?; create_disk_image( From da982f668a8b2775f91cde3ce0c70ef6b9383047 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Wed, 18 Jul 2018 19:08:50 +0200 Subject: [PATCH 016/271] Fix `bootimage test` when cargo metadata contains deps --- src/build.rs | 2 +- src/test.rs | 13 +++++++------ 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/build.rs b/src/build.rs index f731194..6371717 100644 --- a/src/build.rs +++ b/src/build.rs @@ -3,7 +3,7 @@ use byteorder::{ByteOrder, LittleEndian}; use cargo_metadata::{self, Metadata as CargoMetadata}; use config::{self, Config}; use failure::{Error, ResultExt}; -use std::fs::{self, File}; +use std::fs::File; use std::io::Write; use std::path::{Path, PathBuf}; use std::sync::Mutex; diff --git a/src/test.rs b/src/test.rs index 33a2125..2a9a2fd 100644 --- a/src/test.rs +++ b/src/test.rs @@ -2,6 +2,7 @@ use args::Args; use build; use failure::{Error, ResultExt}; use std::io::Write; +use std::path::Path; use std::time::Duration; use std::{fs, io, process}; use wait_timeout::ChildExt; @@ -30,12 +31,12 @@ pub(crate) fn test(args: Args) -> Result<(), Error> { let mut tests = Vec::new(); - assert_eq!( - metadata.packages.len(), - 1, - "Only crates with one package are supported" - ); - let target_iter = metadata.packages[0].targets.iter(); + let crate_metadata = metadata + .packages + .iter() + .find(|p| Path::new(&p.manifest_path) == config.manifest_path) + .expect("Could not read crate name from cargo metadata"); + let target_iter = crate_metadata.targets.iter(); for target in target_iter.filter(|t| t.kind == ["bin"] && t.name.starts_with("test-")) { println!("{}", target.name); From c63e5c7d4257d967e92185ad09c0438f865fb54f Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Wed, 18 Jul 2018 19:10:53 +0200 Subject: [PATCH 017/271] Update Readme --- Readme.md | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/Readme.md b/Readme.md index 76abb69..817eb30 100644 --- a/Readme.md +++ b/Readme.md @@ -10,7 +10,16 @@ Creates a bootable disk image from a Rust OS kernel. ## Usage -To build the kernel project and create a bootable disk image from it, run: +First you need to add a dependency on the `bootloader` crate: + +```toml +# in your Cargo.toml + +[dependencies] +bootloader = "0.2.0-alpha" +``` + +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] @@ -33,20 +42,8 @@ Configuration is done through a through a `[package.metadata.bootimage]` table i [package.metadata.bootimage.bootloader] name = "bootloader" # The bootloader crate name - version = "" # The bootloader version that should be used - git = "" # Use the bootloader from this git repository - branch = "" # The git branch to use (defaults to master) - path = "" # Use the bootloader from this local path - precompiled = false # Whether the bootloader crate is precompiled target = "x86_64-bootloader.json" # Target triple for compiling the bootloader ``` -If no `[package.metadata.bootimage.bootloader]` sub-table is specified, it defaults to: - -```toml -name = "bootloader_precompiled" -precompiled = true -``` - ## License Dual-licensed under MIT or the Apache License (Version 2.0). From 2ef5ff989ca45af2d17bdcf0e69e54c5f28f6c97 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Wed, 18 Jul 2018 19:16:14 +0200 Subject: [PATCH 018/271] Disable default features of cargo_metadata to reduce build time and run cargo update --- Cargo.lock | 139 +++++++++++++++++++++++------------------------------ Cargo.toml | 5 +- 2 files changed, 63 insertions(+), 81 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 025b5f4..365f266 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,30 +1,30 @@ [[package]] name = "backtrace" -version = "0.3.5" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "backtrace-sys 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", - "cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-demangle 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "backtrace-sys 0.1.23 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-demangle 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "backtrace-sys" -version = "0.1.16" +version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cc 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "bootimage" version = "0.4.4" dependencies = [ - "byteorder 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "cargo_metadata 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cargo_metadata 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)", "failure 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "toml 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "wait-timeout 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", @@ -33,50 +33,47 @@ dependencies = [ [[package]] name = "byteorder" -version = "1.2.2" +version = "1.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "cargo_metadata" -version = "0.5.4" +version = "0.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "error-chain 0.11.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.37 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "cc" -version = "1.0.9" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "cfg-if" -version = "0.1.2" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "dtoa" -version = "0.4.2" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "error-chain" version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "backtrace 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", -] [[package]] name = "failure" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "backtrace 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", + "backtrace 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", "failure_derive 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -92,22 +89,17 @@ dependencies = [ [[package]] name = "itoa" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "libc" -version = "0.2.40" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "num-traits" -version = "0.2.2" +version = "0.2.42" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "proc-macro2" -version = "0.3.6" +version = "0.4.8" 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)", @@ -120,15 +112,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "quote" -version = "0.5.1" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro2 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "rustc-demangle" -version = "0.1.7" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -137,7 +129,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.37 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -147,38 +139,27 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "serde" -version = "1.0.37" +version = "1.0.70" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "serde_derive" -version = "1.0.37" +version = "1.0.70" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro2 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive_internals 0.23.0 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "serde_derive_internals" -version = "0.23.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "proc-macro2 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)", + "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.14.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "serde_json" -version = "1.0.13" +version = "1.0.24" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "itoa 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)", + "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.70 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -193,11 +174,11 @@ dependencies = [ [[package]] name = "syn" -version = "0.13.1" +version = "0.14.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro2 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "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)", ] @@ -223,7 +204,7 @@ name = "toml" version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "serde 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -241,12 +222,12 @@ name = "wait-timeout" version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "winapi" -version = "0.3.4" +version = "0.3.5" 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)", @@ -277,38 +258,36 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" [metadata] -"checksum backtrace 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "ebbbf59b1c43eefa8c3ede390fcc36820b4999f7914104015be25025e0d62af2" -"checksum backtrace-sys 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "44585761d6161b0f57afc49482ab6bd067e4edef48c12a152c237eb0203f7661" -"checksum byteorder 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "73b5bdfe7ee3ad0b99c9801d58807a9dbc9e09196365b0203853b99889ab3c87" -"checksum cargo_metadata 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)" = "6ebd6272a2ca4fd39dbabbd6611eb03df45c2259b3b80b39a9ff8fbdcf42a4b3" -"checksum cc 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)" = "2b4911e4bdcb4100c7680e7e854ff38e23f1b34d4d9e079efae3da2801341ffc" -"checksum cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d4c819a1287eb618df47cc647173c5c4c66ba19d888a6e50d605672aed3140de" -"checksum dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "09c3753c3db574d215cba4ea76018483895d7bff25a31b49ba45db21c48e50ab" +"checksum backtrace 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "89a47830402e9981c5c41223151efcced65a0510c13097c769cede7efb34782a" +"checksum backtrace-sys 0.1.23 (registry+https://github.com/rust-lang/crates.io-index)" = "bff67d0c06556c0b8e6b5f090f0eac52d950d9dfd1d35ba04e4ca3543eaf6a7e" +"checksum byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "74c0b906e9446b0a2e4f760cdb3fa4b2c48cdc6db8766a845c54b6ff063fd2e9" +"checksum cargo_metadata 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)" = "1efca0b863ca03ed4c109fb1c55e0bc4bbeb221d3e103d86251046b06a526bd0" +"checksum cc 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)" = "2119ea4867bd2b8ed3aecab467709720b2d55b1bcfe09f772fd68066eaf15275" +"checksum cfg-if 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "efe5c877e17a9c717a0bf3613b2709f723202c4e4675cc8f12926ded29bcb17e" +"checksum dtoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "6d301140eb411af13d3115f9a562c85cc6b541ade9dfa314132244aaee7489dd" "checksum error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ff511d5dc435d703f4971bc399647c9bc38e20cb41452e3b9feb4765419ed3f3" "checksum failure 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "934799b6c1de475a012a02dab0ace1ace43789ee4b99bcfbf1a2e3e8ced5de82" "checksum failure_derive 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c7cdda555bb90c9bb67a3b670a0f42de8e73f5981524123ad8578aafec8ddb8b" -"checksum itoa 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c069bbec61e1ca5a596166e55dfe4773ff745c3d16b700013bcaff9a6df2c682" -"checksum libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)" = "6fd41f331ac7c5b8ac259b8bf82c75c0fb2e469bbf37d2becbba9a6a2221965b" -"checksum num-traits 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dee092fcdf725aee04dd7da1d21debff559237d49ef1cb3e69bcb8ece44c7364" -"checksum proc-macro2 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "49b6a521dc81b643e9a51e0d1cf05df46d5a2f3c0280ea72bcb68276ba64a118" +"checksum itoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "5adb58558dcd1d786b5f0bd15f3226ee23486e24b7b58304b60f64dc68e62606" +"checksum libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)" = "b685088df2b950fccadf07a7187c8ef846a959c142338a48f9dc0b94517eb5f1" +"checksum proc-macro2 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "c65b1ea15bb859d922cade2d1765b4b88beac339cbfad545ef2d2ef8c8215ee6" "checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a" -"checksum quote 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7b0ff51282f28dc1b53fd154298feaa2e77c5ea0dba68e1fd8b03b72fbe13d2a" -"checksum rustc-demangle 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "11fb43a206a04116ffd7cfcf9bcb941f8eb6cc7ff667272246b0a1c74259a3cb" +"checksum quote 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "e44651a0dc4cdd99f71c83b561e221f714912d11af1a4dff0631f923d53af035" +"checksum rustc-demangle 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "76d7ba1feafada44f2d38eed812bd2489a03c0f5abb975799251518b68848649" "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.37 (registry+https://github.com/rust-lang/crates.io-index)" = "d3bcee660dcde8f52c3765dd9ca5ee36b4bf35470a738eb0bd5a8752b0389645" -"checksum serde_derive 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)" = "f1711ab8b208541fa8de00425f6a577d90f27bb60724d2bb5fd911314af9668f" -"checksum serde_derive_internals 0.23.0 (registry+https://github.com/rust-lang/crates.io-index)" = "89b340a48245bc03ddba31d0ff1709c118df90edc6adabaca4aac77aea181cce" -"checksum serde_json 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)" = "5c508584d9913df116b91505eec55610a2f5b16e9ed793c46e4d0152872b3e74" +"checksum serde 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)" = "0c3adf19c07af6d186d91dae8927b83b0553d07ca56cbf7f2f32560455c91920" +"checksum serde_derive 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)" = "3525a779832b08693031b8ecfb0de81cd71cfd3812088fafe9a7496789572124" +"checksum serde_json 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)" = "c3c6908c7b925cd6c590358a4034de93dbddb20c45e1d021931459fd419bf0e2" "checksum syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d3b891b9015c88c576343b9b3e41c2c11a51c219ef067b264bd9c8aa9b441dad" -"checksum syn 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)" = "91b52877572087400e83d24b9178488541e3d535259e04ff17a63df1e5ceff59" +"checksum syn 0.14.4 (registry+https://github.com/rust-lang/crates.io-index)" = "2beff8ebc3658f07512a413866875adddd20f4fd47b2a4e6c9da65cd281baaea" "checksum synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a393066ed9010ebaed60b9eafa373d4b1baac186dd7e008555b0f702b51945b6" "checksum synstructure 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3a761d12e6d8dcb4dcf952a7a89b475e3a9d69e4a69307e01a470977642914bd" "checksum toml 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "a0263c6c02c4db6c8f7681f9fd35e90de799ebd4cfdeab77a38f4ff6b3d8c0d9" "checksum unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f860d7d29cf02cb2f3f359fd35991af3d30bac52c57d265a3c461074cb4dc" "checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" "checksum wait-timeout 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "b9f3bf741a801531993db6478b95682117471f76916f5e690dd8d45395b09349" -"checksum winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "04e3bd221fcbe8a271359c04f21a76db7d0c6028862d1bb5512d85e1e2eb5bb3" +"checksum winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "773ef9dcc5f24b7d850d0ff101e542ff24c3b090a9768e03ff889fdef41f00fd" "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 xmas-elf 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "22678df5df766e8d1e5d609da69f0c3132d794edf6ab5e75e7abcd2270d4cf58" diff --git a/Cargo.toml b/Cargo.toml index 9463579..dd7288e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,6 +10,9 @@ repository = "https://github.com/rust-osdev/bootimage" byteorder = "1.2.1" toml = "0.4.5" xmas-elf = "0.6.1" -cargo_metadata = "0.5.3" wait-timeout = "0.1" failure = "0.1.1" + +[dependencies.cargo_metadata] +version = "0.5.3" +default-features = false From 419d76644d989554c3be14986fc14a76913d9ccf Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Wed, 18 Jul 2018 19:21:31 +0200 Subject: [PATCH 019/271] bootimage 0.5.0-alpha-00 --- Cargo.lock | 2 +- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 365f266..8352993 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -21,7 +21,7 @@ dependencies = [ [[package]] name = "bootimage" -version = "0.4.4" +version = "0.5.0-alpha-00" dependencies = [ "byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "cargo_metadata 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/Cargo.toml b/Cargo.toml index dd7288e..d907a1a 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.4.4" +version = "0.5.0-alpha-00" repository = "https://github.com/rust-osdev/bootimage" [dependencies] From 32b2d08529289a738193e5d892a983ddcaa5b160 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Thu, 19 Jul 2018 10:34:59 +0200 Subject: [PATCH 020/271] Improve error messages and link migration guide --- src/build.rs | 6 +++++- src/config.rs | 4 ++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/build.rs b/src/build.rs index 6371717..b860056 100644 --- a/src/build.rs +++ b/src/build.rs @@ -209,7 +209,11 @@ fn build_bootloader(metadata: &CargoMetadata, config: &Config) -> Result package_metadata.clone(), - None => Err(format_err!("Bootloader dependency not found"))?, + None => Err(format_err!("Bootloader dependency not found").context( + "You need to add a dependency on the `bootloader` or `bootloader_precompiled` crates \ + in your Cargo.toml.\n\nIn case you just updated bootimage from an earlier version, \ + check out the migration guide at https://github.com/rust-osdev/bootimage/pull/16", + ))?, }; let bootloader_dir = Path::new(&bootloader_metadata.manifest_path) .parent() diff --git a/src/config.rs b/src/config.rs index b312110..6c74009 100644 --- a/src/config.rs +++ b/src/config.rs @@ -73,6 +73,10 @@ pub(crate) fn read_config(manifest_path: PathBuf) -> Result { "the \ `package.metadata.bootimage.bootloader` key `{}` was deprecated", k + ).context( + "In case you just updated bootimage from an earlier version, \ + check out the migration guide at \ + https://github.com/rust-osdev/bootimage/pull/16", ))?, (key, value) => Err(format_err!( "unexpected \ From 6c520e2a7c0bc14684d77643052492f2e74ceb40 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Thu, 19 Jul 2018 10:46:04 +0200 Subject: [PATCH 021/271] Add support for precompiled bootloader again --- src/build.rs | 15 +++++++++++++-- src/config.rs | 4 ++-- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/src/build.rs b/src/build.rs index b860056..2ad87b3 100644 --- a/src/build.rs +++ b/src/build.rs @@ -207,7 +207,14 @@ fn create_kernel_info_block(kernel_size: u64) -> KernelInfoBlock { fn build_bootloader(metadata: &CargoMetadata, config: &Config) -> Result, Error> { use std::io::Read; - let bootloader_metadata = match metadata.packages.iter().find(|p| p.name == "bootloader") { + let bootloader_metadata = metadata.packages.iter().find(|p| { + if let Some(name) = config.bootloader.name.as_ref() { + p.name == name.as_str() + } else { + p.name == "bootloader" || p.name == "bootloader_precompiled" + } + }); + let bootloader_metadata = match bootloader_metadata { Some(package_metadata) => package_metadata.clone(), None => Err(format_err!("Bootloader dependency not found").context( "You need to add a dependency on the `bootloader` or `bootloader_precompiled` crates \ @@ -222,7 +229,11 @@ fn build_bootloader(metadata: &CargoMetadata, config: &Config) -> Result, pub target: PathBuf, } @@ -156,7 +156,7 @@ impl Into for ConfigBuilder { impl Into for BootloaderConfigBuilder { fn into(self) -> BootloaderConfig { BootloaderConfig { - name: self.name.unwrap_or("bootloader".into()), + name: self.name, target: self.target .unwrap_or(PathBuf::from("x86_64-bootloader.json")), } From 17ffdf3d2ff7aa876107a1a7b13d28bca22b2d2a Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Thu, 19 Jul 2018 11:31:05 +0200 Subject: [PATCH 022/271] Bump version to 0.5.0-beta --- Cargo.lock | 2 +- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8352993..9386ef4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -21,7 +21,7 @@ dependencies = [ [[package]] name = "bootimage" -version = "0.5.0-alpha-00" +version = "0.5.0-beta" dependencies = [ "byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "cargo_metadata 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/Cargo.toml b/Cargo.toml index d907a1a..95b9ff9 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.5.0-alpha-00" +version = "0.5.0-beta" repository = "https://github.com/rust-osdev/bootimage" [dependencies] From b4338dee3c82cef4698b8ce80d76292142791f25 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Thu, 19 Jul 2018 12:00:30 +0200 Subject: [PATCH 023/271] Print display formatting of errors --- src/build.rs | 11 +++++++---- src/main.rs | 2 +- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/build.rs b/src/build.rs index 2ad87b3..a236b7c 100644 --- a/src/build.rs +++ b/src/build.rs @@ -6,7 +6,6 @@ use failure::{Error, ResultExt}; use std::fs::File; use std::io::Write; use std::path::{Path, PathBuf}; -use std::sync::Mutex; use std::{io, process}; use xmas_elf; @@ -134,13 +133,17 @@ fn run_impl(args: &Args, config: &Config, output_path: &Path) -> Result<(), Erro } #[derive(Debug, Fail)] -#[fail(display = "Failed to execute `cargo metadata`")] -pub struct CargoMetadataError(Mutex); +#[fail(display = "{}", error)] +pub struct CargoMetadataError { + error: String, +} fn read_cargo_metadata(args: &Args) -> Result { let metadata = cargo_metadata::metadata_deps(args.manifest_path().as_ref().map(PathBuf::as_path), true) - .map_err(|e| CargoMetadataError(Mutex::new(e)))?; + .map_err(|e| CargoMetadataError { + error: format!("{}", e), + })?; Ok(metadata) } diff --git a/src/main.rs b/src/main.rs index 1f915b7..bd713f7 100644 --- a/src/main.rs +++ b/src/main.rs @@ -30,7 +30,7 @@ enum Command { pub fn main() { use std::io::Write; if let Err(err) = run() { - writeln!(io::stderr(), "Error: {:?}", err).unwrap(); + writeln!(io::stderr(), "Error: {}", err).unwrap(); process::exit(1); } } From fcc6c1c51bccdb699ef5eeb6223643eb804608b3 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Thu, 19 Jul 2018 12:04:39 +0200 Subject: [PATCH 024/271] Disable derive feature of failure to reduce compilation time --- Cargo.lock | 60 +++------------------------------------------------- Cargo.toml | 6 +++++- src/build.rs | 15 +++++++++---- 3 files changed, 19 insertions(+), 62 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9386ef4..e457aff 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6,7 +6,7 @@ dependencies = [ "backtrace-sys 0.1.23 (registry+https://github.com/rust-lang/crates.io-index)", "cfg-if 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-demangle 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-demangle 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -74,17 +74,6 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "backtrace 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", - "failure_derive 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "failure_derive" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)", - "synstructure 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -105,11 +94,6 @@ dependencies = [ "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "quote" -version = "0.3.15" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "quote" version = "0.6.3" @@ -120,7 +104,7 @@ dependencies = [ [[package]] name = "rustc-demangle" -version = "0.1.8" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -162,16 +146,6 @@ dependencies = [ "serde 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "syn" -version = "0.11.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", - "synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)", - "unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "syn" version = "0.14.4" @@ -182,23 +156,6 @@ dependencies = [ "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "synom" -version = "0.11.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "synstructure" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "toml" version = "0.4.6" @@ -207,11 +164,6 @@ dependencies = [ "serde 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "unicode-xid" -version = "0.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "unicode-xid" version = "0.1.0" @@ -267,24 +219,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum dtoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "6d301140eb411af13d3115f9a562c85cc6b541ade9dfa314132244aaee7489dd" "checksum error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ff511d5dc435d703f4971bc399647c9bc38e20cb41452e3b9feb4765419ed3f3" "checksum failure 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "934799b6c1de475a012a02dab0ace1ace43789ee4b99bcfbf1a2e3e8ced5de82" -"checksum failure_derive 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c7cdda555bb90c9bb67a3b670a0f42de8e73f5981524123ad8578aafec8ddb8b" "checksum itoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "5adb58558dcd1d786b5f0bd15f3226ee23486e24b7b58304b60f64dc68e62606" "checksum libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)" = "b685088df2b950fccadf07a7187c8ef846a959c142338a48f9dc0b94517eb5f1" "checksum proc-macro2 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "c65b1ea15bb859d922cade2d1765b4b88beac339cbfad545ef2d2ef8c8215ee6" -"checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a" "checksum quote 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "e44651a0dc4cdd99f71c83b561e221f714912d11af1a4dff0631f923d53af035" -"checksum rustc-demangle 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "76d7ba1feafada44f2d38eed812bd2489a03c0f5abb975799251518b68848649" +"checksum rustc-demangle 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "bcfe5b13211b4d78e5c2cadfebd7769197d95c639c35a50057eb4c05de811395" "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.70 (registry+https://github.com/rust-lang/crates.io-index)" = "0c3adf19c07af6d186d91dae8927b83b0553d07ca56cbf7f2f32560455c91920" "checksum serde_derive 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)" = "3525a779832b08693031b8ecfb0de81cd71cfd3812088fafe9a7496789572124" "checksum serde_json 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)" = "c3c6908c7b925cd6c590358a4034de93dbddb20c45e1d021931459fd419bf0e2" -"checksum syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d3b891b9015c88c576343b9b3e41c2c11a51c219ef067b264bd9c8aa9b441dad" "checksum syn 0.14.4 (registry+https://github.com/rust-lang/crates.io-index)" = "2beff8ebc3658f07512a413866875adddd20f4fd47b2a4e6c9da65cd281baaea" -"checksum synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a393066ed9010ebaed60b9eafa373d4b1baac186dd7e008555b0f702b51945b6" -"checksum synstructure 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3a761d12e6d8dcb4dcf952a7a89b475e3a9d69e4a69307e01a470977642914bd" "checksum toml 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "a0263c6c02c4db6c8f7681f9fd35e90de799ebd4cfdeab77a38f4ff6b3d8c0d9" -"checksum unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f860d7d29cf02cb2f3f359fd35991af3d30bac52c57d265a3c461074cb4dc" "checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" "checksum wait-timeout 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "b9f3bf741a801531993db6478b95682117471f76916f5e690dd8d45395b09349" "checksum winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "773ef9dcc5f24b7d850d0ff101e542ff24c3b090a9768e03ff889fdef41f00fd" diff --git a/Cargo.toml b/Cargo.toml index 95b9ff9..7145dd6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,8 +11,12 @@ byteorder = "1.2.1" toml = "0.4.5" xmas-elf = "0.6.1" wait-timeout = "0.1" -failure = "0.1.1" [dependencies.cargo_metadata] version = "0.5.3" default-features = false + +[dependencies.failure] +version = "0.1.1" +default-features = false +features = ["std"] diff --git a/src/build.rs b/src/build.rs index a236b7c..6b9628c 100644 --- a/src/build.rs +++ b/src/build.rs @@ -2,11 +2,11 @@ use args::{self, Args}; use byteorder::{ByteOrder, LittleEndian}; use cargo_metadata::{self, Metadata as CargoMetadata}; use config::{self, Config}; -use failure::{Error, ResultExt}; +use failure::{self, Error, ResultExt}; use std::fs::File; use std::io::Write; use std::path::{Path, PathBuf}; -use std::{io, process}; +use std::{fmt, io, process}; use xmas_elf; const BLOCK_SIZE: usize = 512; @@ -132,12 +132,19 @@ fn run_impl(args: &Args, config: &Config, output_path: &Path) -> Result<(), Erro Ok(()) } -#[derive(Debug, Fail)] -#[fail(display = "{}", error)] +#[derive(Debug)] pub struct CargoMetadataError { error: String, } +impl fmt::Display for CargoMetadataError { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "{}", self.error) + } +} + +impl failure::Fail for CargoMetadataError {} + fn read_cargo_metadata(args: &Args) -> Result { let metadata = cargo_metadata::metadata_deps(args.manifest_path().as_ref().map(PathBuf::as_path), true) From eb154e036d8512d852e43232ce54deff4072ccc1 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Thu, 19 Jul 2018 12:04:53 +0200 Subject: [PATCH 025/271] Bump version to 0.5.0-beta.1 --- Cargo.lock | 2 +- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e457aff..6a7a2a6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -21,7 +21,7 @@ dependencies = [ [[package]] name = "bootimage" -version = "0.5.0-beta" +version = "0.5.0-beta.1" dependencies = [ "byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "cargo_metadata 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/Cargo.toml b/Cargo.toml index 7145dd6..5580378 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.5.0-beta" +version = "0.5.0-beta.1" repository = "https://github.com/rust-osdev/bootimage" [dependencies] From 1a109b96373a56ab8ea206da7fbd222d6d8f6e69 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Fri, 20 Jul 2018 10:19:35 +0200 Subject: [PATCH 026/271] Bump version to 0.5.0 --- Cargo.lock | 2 +- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6a7a2a6..125732f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -21,7 +21,7 @@ dependencies = [ [[package]] name = "bootimage" -version = "0.5.0-beta.1" +version = "0.5.0" dependencies = [ "byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "cargo_metadata 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/Cargo.toml b/Cargo.toml index 5580378..244220d 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.5.0-beta.1" +version = "0.5.0" repository = "https://github.com/rust-osdev/bootimage" [dependencies] From 48587e1dc640d0c0eb91b06a578821d0b6f95cbe Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Fri, 20 Jul 2018 13:20:42 +0200 Subject: [PATCH 027/271] Replace all uses of `context` with `with_context` Failure doesn't display the underlying error, only the context. See https://github.com/rust-lang-nursery/failure/issues/182. --- src/build.rs | 47 ++++++++++++++++++++++++++++------------------- src/config.rs | 15 +++++++-------- src/test.rs | 19 +++++++++++-------- 3 files changed, 46 insertions(+), 35 deletions(-) diff --git a/src/build.rs b/src/build.rs index 6b9628c..43c294d 100644 --- a/src/build.rs +++ b/src/build.rs @@ -98,11 +98,12 @@ pub(crate) fn build_impl( let kernel_size = kernel .metadata() - .context("Failed to read kernel output file")? + .with_context(|e| format!("Failed to read kernel output file: {}", e))? .len(); let kernel_info_block = create_kernel_info_block(kernel_size); - let bootloader = build_bootloader(&metadata, &config).context("Failed to build bootloader")?; + let bootloader = build_bootloader(&metadata, &config) + .with_context(|e| format!("Failed to build bootloader: {}", e))?; create_disk_image( root_dir, @@ -128,7 +129,7 @@ fn run_impl(args: &Args, config: &Config, output_path: &Path) -> Result<(), Erro command.args(&args.run_args); command .status() - .context(format_err!("Failed to execute run command: {:?}", command))?; + .with_context(|e| format!("Failed to execute run `{:?}`: {}", command, e))?; Ok(()) } @@ -164,14 +165,16 @@ fn build_kernel( if verbose { println!("Building kernel"); } - let exit_status = run_xbuild(&args.cargo_args).context("Failed to run `cargo xbuild`")?; + let exit_status = run_xbuild(&args.cargo_args) + .with_context(|e| format!("Failed to run `cargo xbuild`: {}", e))?; if !exit_status.success() { process::exit(1) } let mut kernel_path = out_dir.to_owned(); kernel_path.push(bin_name); - let kernel = File::open(kernel_path).context("Failed to open kernel output file")?; + let kernel = File::open(kernel_path) + .with_context(|e| format!("Failed to open kernel output file: {}", e))?; Ok(kernel) } @@ -224,14 +227,17 @@ fn build_bootloader(metadata: &CargoMetadata, config: &Config) -> Result package_metadata.clone(), - None => Err(format_err!("Bootloader dependency not found").context( - "You need to add a dependency on the `bootloader` or `bootloader_precompiled` crates \ - in your Cargo.toml.\n\nIn case you just updated bootimage from an earlier version, \ - check out the migration guide at https://github.com/rust-osdev/bootimage/pull/16", + let bootloader_metadata = + match bootloader_metadata { + Some(package_metadata) => package_metadata.clone(), + None => Err(format_err!("Bootloader dependency not found\n\n\ + You need to add a dependency on the `bootloader` or `bootloader_precompiled` crates \ + in your Cargo.toml.\n\nIn case you just updated bootimage from an earlier version, \ + check out the migration guide at https://github.com/rust-osdev/bootimage/pull/16. \ + Alternatively, you can downgrade to bootimage 0.4 again by executing \ + `cargo install bootimage --version {} --force`.", r#"^0.4""# ))?, - }; + }; let bootloader_dir = Path::new(&bootloader_metadata.manifest_path) .parent() .unwrap(); @@ -253,7 +259,8 @@ fn build_bootloader(metadata: &CargoMetadata, config: &Config) -> Result Result Result { let cargo_toml: Value = { let mut content = String::new(); File::open(&manifest_path) - .context("Failed to open Cargo.toml")? + .with_context(|e| format!("Failed to open Cargo.toml: {}", e))? .read_to_string(&mut content) - .context("Failed to read Cargo.toml")?; + .with_context(|e| format!("Failed to read Cargo.toml: {}", e))?; content .parse::() - .context("Failed to parse Cargo.toml")? + .with_context(|e| format!("Failed to parse Cargo.toml: {}", e))? }; let metadata = cargo_toml @@ -71,12 +71,11 @@ pub(crate) fn read_config(manifest_path: PathBuf) -> Result { | (k @ "branch", _) | (k @ "path", _) => Err(format_err!( "the \ - `package.metadata.bootimage.bootloader` key `{}` was deprecated", - k - ).context( - "In case you just updated bootimage from an earlier version, \ + `package.metadata.bootimage.bootloader` key `{}` was deprecated\n\n\ + In case you just updated bootimage from an earlier version, \ check out the migration guide at \ - https://github.com/rust-osdev/bootimage/pull/16", + https://github.com/rust-osdev/bootimage/pull/16.", + k ))?, (key, value) => Err(format_err!( "unexpected \ diff --git a/src/test.rs b/src/test.rs index 2a9a2fd..c630654 100644 --- a/src/test.rs +++ b/src/test.rs @@ -66,23 +66,26 @@ pub(crate) fn test(args: Args) -> Result<(), Error> { command.stderr(process::Stdio::null()); let mut child = command .spawn() - .context(format_err!("Failed to launch QEMU: {:?}", command))?; + .with_context(|e| format_err!("Failed to launch QEMU: {:?}\n{}", command, e))?; let timeout = Duration::from_secs(60); match child .wait_timeout(timeout) - .context("Failed to wait with timeout")? + .with_context(|e| format!("Failed to wait with timeout: {}", e))? { None => { - child.kill().context("Failed to kill QEMU")?; - child.wait().context("Failed to wait for QEMU process")?; + child + .kill() + .with_context(|e| format!("Failed to kill QEMU: {}", e))?; + child + .wait() + .with_context(|e| format!("Failed to wait for QEMU process: {}", e))?; test_result = TestResult::TimedOut; writeln!(io::stderr(), "Timed Out")?; } Some(_) => { - let output = fs::read_to_string(&output_file).context(format_err!( - "Failed to read test output file {}", - output_file - ))?; + let output = fs::read_to_string(&output_file).with_context(|e| { + format_err!("Failed to read test output file {}: {}", output_file, e) + })?; if output.starts_with("ok\n") { test_result = TestResult::Ok; println!("Ok"); From dae9c8eab1c2a567bf976d7ca110bd902bea96b0 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Fri, 20 Jul 2018 13:20:59 +0200 Subject: [PATCH 028/271] bootimage 0.5.1 --- Cargo.lock | 2 +- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 125732f..241eb4d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -21,7 +21,7 @@ dependencies = [ [[package]] name = "bootimage" -version = "0.5.0" +version = "0.5.1" dependencies = [ "byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "cargo_metadata 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/Cargo.toml b/Cargo.toml index 244220d..db34d67 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.5.0" +version = "0.5.1" repository = "https://github.com/rust-osdev/bootimage" [dependencies] From 86d0f115278bb3afb9e2c7d44e1e9ee1feaf4520 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Fri, 20 Jul 2018 13:24:58 +0200 Subject: [PATCH 029/271] Add missing quote in error message --- src/build.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/build.rs b/src/build.rs index 43c294d..4251b0e 100644 --- a/src/build.rs +++ b/src/build.rs @@ -235,7 +235,7 @@ fn build_bootloader(metadata: &CargoMetadata, config: &Config) -> Result Date: Fri, 20 Jul 2018 13:25:10 +0200 Subject: [PATCH 030/271] bootimage 0.5.2 --- Cargo.lock | 2 +- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 241eb4d..117f807 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -21,7 +21,7 @@ dependencies = [ [[package]] name = "bootimage" -version = "0.5.1" +version = "0.5.2" dependencies = [ "byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "cargo_metadata 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/Cargo.toml b/Cargo.toml index db34d67..0a78ce7 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.5.1" +version = "0.5.2" repository = "https://github.com/rust-osdev/bootimage" [dependencies] From b7b665936cca9b9bfc8ce80777b05530bbda8f7f Mon Sep 17 00:00:00 2001 From: Isaac Woods Date: Tue, 24 Jul 2018 13:04:42 +0100 Subject: [PATCH 031/271] Build bootloader with the features from the dependency --- src/build.rs | 6 ++++++ src/config.rs | 56 ++++++++++++++++++++++++++++++++++++++++++++------- 2 files changed, 55 insertions(+), 7 deletions(-) diff --git a/src/build.rs b/src/build.rs index 4251b0e..8466ccd 100644 --- a/src/build.rs +++ b/src/build.rs @@ -256,6 +256,12 @@ fn build_bootloader(metadata: &CargoMetadata, config: &Config) -> Result, pub target: PathBuf, + pub features: Vec, } pub(crate) fn read_config(manifest_path: PathBuf) -> Result { @@ -48,8 +49,48 @@ pub(crate) fn read_config(manifest_path: PathBuf) -> Result { ))?, }; + /* + * The user shouldn't specify any features if they're using a precompiled bootloader, as we + * don't actually compile it. + */ + if cargo_toml + .get("dependencies") + .and_then(|table| table.get("bootloader_precompiled")) + .and_then(|table| table.get("features")) + .is_some() + { + return Err(format_err!( + "Can't change features of precompiled bootloader!" + )); + } + + let bootloader_features = match cargo_toml + .get("dependencies") + .and_then(|table| table.get("bootloader")) + .and_then(|table| table.get("features")) + { + None => None, + Some(Value::Array(array)) => { + let mut features = Vec::new(); + + for feature_string in array { + match feature_string { + Value::String(feature) => features.push(feature.clone()), + _ => return Err(format_err!("Bootloader features are malformed!")), + } + } + + Some(features) + } + Some(_) => return Err(format_err!("Bootloader features are malformed!")), + }; + let mut config = ConfigBuilder { manifest_path: Some(manifest_path), + bootloader: BootloaderConfigBuilder { + features: bootloader_features, + ..Default::default() + }, ..Default::default() }; @@ -58,12 +99,11 @@ pub(crate) fn read_config(manifest_path: PathBuf) -> Result { ("default-target", Value::String(s)) => config.default_target = From::from(s), ("output", Value::String(s)) => config.output = Some(PathBuf::from(s)), ("bootloader", Value::Table(t)) => { - let mut bootloader_config = BootloaderConfigBuilder::default(); for (key, value) in t { match (key.as_str(), value) { - ("name", Value::String(s)) => bootloader_config.name = From::from(s), + ("name", Value::String(s)) => config.bootloader.name = From::from(s), ("target", Value::String(s)) => { - bootloader_config.target = Some(PathBuf::from(s)) + config.bootloader.target = Some(PathBuf::from(s)) } (k @ "precompiled", _) | (k @ "version", _) @@ -85,7 +125,6 @@ pub(crate) fn read_config(manifest_path: PathBuf) -> Result { ))?, } } - config.bootloader = Some(bootloader_config); } ("minimum-image-size", Value::Integer(x)) => { if x >= 0 { @@ -124,7 +163,7 @@ struct ConfigBuilder { manifest_path: Option, default_target: Option, output: Option, - bootloader: Option, + bootloader: BootloaderConfigBuilder, minimum_image_size: Option, run_command: Option>, } @@ -133,6 +172,7 @@ struct ConfigBuilder { struct BootloaderConfigBuilder { name: Option, target: Option, + features: Option>, } impl Into for ConfigBuilder { @@ -141,7 +181,7 @@ impl Into for ConfigBuilder { manifest_path: self.manifest_path.expect("manifest path must be set"), default_target: self.default_target, output: self.output, - bootloader: self.bootloader.unwrap_or_default().into(), + bootloader: self.bootloader.into(), minimum_image_size: self.minimum_image_size, run_command: self.run_command.unwrap_or(vec![ "qemu-system-x86_64".into(), @@ -156,8 +196,10 @@ impl Into for BootloaderConfigBuilder { fn into(self) -> BootloaderConfig { BootloaderConfig { name: self.name, - target: self.target + target: self + .target .unwrap_or(PathBuf::from("x86_64-bootloader.json")), + features: self.features.unwrap_or(Vec::with_capacity(0)), } } } From 27853dd1458f75f6518e3bc5fe7198f7cb90e769 Mon Sep 17 00:00:00 2001 From: Isaac Woods Date: Tue, 24 Jul 2018 17:07:00 +0100 Subject: [PATCH 032/271] Handle default-features key when building the bootloader --- src/build.rs | 8 ++++++-- src/config.rs | 24 +++++++++++++++++++++++- 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/src/build.rs b/src/build.rs index 8466ccd..f4144f1 100644 --- a/src/build.rs +++ b/src/build.rs @@ -250,7 +250,7 @@ fn build_bootloader(metadata: &CargoMetadata, config: &Config) -> Result Result, pub target: PathBuf, + pub default_features: bool, pub features: Vec, } @@ -56,7 +57,11 @@ pub(crate) fn read_config(manifest_path: PathBuf) -> Result { if cargo_toml .get("dependencies") .and_then(|table| table.get("bootloader_precompiled")) - .and_then(|table| table.get("features")) + .and_then(|table| { + table + .get("features") + .or_else(|| table.get("default-features")) + }) .is_some() { return Err(format_err!( @@ -64,6 +69,20 @@ pub(crate) fn read_config(manifest_path: PathBuf) -> Result { )); } + let bootloader_dependency = cargo_toml + .get("dependencies") + .and_then(|table| table.get("bootloader")); + let bootloader_default_features = + match bootloader_dependency.and_then(|table| table.get("default-features")) { + None => None, + Some(Value::Boolean(default_features)) => Some(*default_features), + Some(_) => { + return Err(format_err!( + "Bootloader 'default-features' field should be a bool!" + )) + } + }; + let bootloader_features = match cargo_toml .get("dependencies") .and_then(|table| table.get("bootloader")) @@ -89,6 +108,7 @@ pub(crate) fn read_config(manifest_path: PathBuf) -> Result { manifest_path: Some(manifest_path), bootloader: BootloaderConfigBuilder { features: bootloader_features, + default_features: bootloader_default_features, ..Default::default() }, ..Default::default() @@ -173,6 +193,7 @@ struct BootloaderConfigBuilder { name: Option, target: Option, features: Option>, + default_features: Option, } impl Into for ConfigBuilder { @@ -200,6 +221,7 @@ impl Into for BootloaderConfigBuilder { .target .unwrap_or(PathBuf::from("x86_64-bootloader.json")), features: self.features.unwrap_or(Vec::with_capacity(0)), + default_features: self.default_features.unwrap_or(true), } } } From e7df5622d87ce1131020d74daa8c228cf1c50a66 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Wed, 25 Jul 2018 11:02:06 +0200 Subject: [PATCH 033/271] bootimage 0.5.3 --- Cargo.lock | 2 +- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 117f807..8e21f82 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -21,7 +21,7 @@ dependencies = [ [[package]] name = "bootimage" -version = "0.5.2" +version = "0.5.3" dependencies = [ "byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "cargo_metadata 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/Cargo.toml b/Cargo.toml index 0a78ce7..148f805 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.5.2" +version = "0.5.3" repository = "https://github.com/rust-osdev/bootimage" [dependencies] From 1fd5e0f00f003c2fe5327d06c89213722d205749 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Thu, 26 Jul 2018 14:26:30 +0200 Subject: [PATCH 034/271] Run `cargo fetch` before `cargo metadata` to get better output and errors MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The `cargo metadata` wrapper suppresses stdout so that the in-progress messages for long lasting operatiions such as “Updating registry” are not shown. Also the error messages (e.g. when a dependency is not found) are wrapped in a cargo metadata error and are not colorized. By running `cargo fetch` first we fix both issues. --- src/build.rs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/build.rs b/src/build.rs index f4144f1..dc87e52 100644 --- a/src/build.rs +++ b/src/build.rs @@ -147,6 +147,7 @@ impl fmt::Display for CargoMetadataError { impl failure::Fail for CargoMetadataError {} fn read_cargo_metadata(args: &Args) -> Result { + run_cargo_fetch(); let metadata = cargo_metadata::metadata_deps(args.manifest_path().as_ref().map(PathBuf::as_path), true) .map_err(|e| CargoMetadataError { @@ -204,6 +205,14 @@ fn run_xbuild(args: &[String]) -> io::Result { Ok(exit_status) } +fn run_cargo_fetch() { + let mut command = process::Command::new("cargo"); + command.arg("fetch"); + if !command.status().map(|s| s.success()).unwrap_or(false) { + process::exit(1); + } +} + fn create_kernel_info_block(kernel_size: u64) -> KernelInfoBlock { let kernel_size = if kernel_size <= u64::from(u32::max_value()) { kernel_size as u32 From b8aa5c2ae503204afac11791836037d752d3aab7 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Thu, 26 Jul 2018 14:27:30 +0200 Subject: [PATCH 035/271] bootimage 0.5.4 --- Cargo.lock | 2 +- Cargo.toml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8e21f82..4a60dfc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -21,7 +21,7 @@ dependencies = [ [[package]] name = "bootimage" -version = "0.5.3" +version = "0.5.4" dependencies = [ "byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "cargo_metadata 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/Cargo.toml b/Cargo.toml index 148f805..fac2851 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.5.3" +version = "0.5.4" repository = "https://github.com/rust-osdev/bootimage" [dependencies] @@ -13,7 +13,7 @@ xmas-elf = "0.6.1" wait-timeout = "0.1" [dependencies.cargo_metadata] -version = "0.5.3" +version = "0.5.4" default-features = false [dependencies.failure] From 87f51494b4f50007080d79c05089a3ebc2c1e795 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Thu, 26 Jul 2018 15:32:29 +0200 Subject: [PATCH 036/271] bootimage 0.5.5 --- Cargo.lock | 2 +- Cargo.toml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4a60dfc..7123d55 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -21,7 +21,7 @@ dependencies = [ [[package]] name = "bootimage" -version = "0.5.4" +version = "0.5.5" dependencies = [ "byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "cargo_metadata 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/Cargo.toml b/Cargo.toml index fac2851..0c7fd73 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.5.4" +version = "0.5.5" repository = "https://github.com/rust-osdev/bootimage" [dependencies] @@ -13,7 +13,7 @@ xmas-elf = "0.6.1" wait-timeout = "0.1" [dependencies.cargo_metadata] -version = "0.5.4" +version = "0.5.5" default-features = false [dependencies.failure] From 5d6eff407b46156fbc6a2cee0498c045b1eb97dd Mon Sep 17 00:00:00 2001 From: dekokun Date: Fri, 3 Aug 2018 23:55:16 +0900 Subject: [PATCH 037/271] fix typo in help message (#19) --- src/help/help.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/help/help.txt b/src/help/help.txt index 9ed07b6..4d594ea 100644 --- a/src/help/help.txt +++ b/src/help/help.txt @@ -10,7 +10,7 @@ For more information about a subcommand run `bootimage [subcommand] --help`. OPTIONS: -h, --help Prints help information and exit - ---version Prints version information and exit + --version Prints version information and exit BUILD_OPTS: Any options are directly passed to `cargo build` (see From 667d0f1be481710f7e6576e0c0c38afebf415660 Mon Sep 17 00:00:00 2001 From: Lachlan Sneff Date: Wed, 8 Aug 2018 16:13:39 -0400 Subject: [PATCH 038/271] Add support for packaging (#13) --- src/build.rs | 82 +++++++++++++++++++++++++++++++++++++++------------ src/config.rs | 6 ++++ 2 files changed, 69 insertions(+), 19 deletions(-) diff --git a/src/build.rs b/src/build.rs index dc87e52..b2b6931 100644 --- a/src/build.rs +++ b/src/build.rs @@ -96,11 +96,23 @@ pub(crate) fn build_impl( let kernel = build_kernel(&out_dir, &bin_name, &args, verbose)?; + let maybe_package = if let Some(ref path) = config.package_filepath { + Some(File::open(path).with_context(|e| format!("Unable to open specified package file: {}", e))?) + } else { + None + }; + + let maybe_package_size = if let Some(ref file) = maybe_package { + Some(file.metadata().with_context(|e| format!("Failed to read specified package file: {}", e))?.len()) + } else { + None + }; + let kernel_size = kernel .metadata() .with_context(|e| format!("Failed to read kernel output file: {}", e))? .len(); - let kernel_info_block = create_kernel_info_block(kernel_size); + let kernel_info_block = create_kernel_info_block(kernel_size, maybe_package_size); let bootloader = build_bootloader(&metadata, &config) .with_context(|e| format!("Failed to build bootloader: {}", e))?; @@ -111,6 +123,7 @@ pub(crate) fn build_impl( &bin_name, &config, kernel, + maybe_package, kernel_info_block, &bootloader, verbose, @@ -213,15 +226,26 @@ fn run_cargo_fetch() { } } -fn create_kernel_info_block(kernel_size: u64) -> KernelInfoBlock { +fn create_kernel_info_block(kernel_size: u64, maybe_package_size: Option) -> KernelInfoBlock { let kernel_size = if kernel_size <= u64::from(u32::max_value()) { kernel_size as u32 } else { panic!("Kernel can't be loaded by BIOS bootloader because is too big") }; + let package_size = if let Some(size) = maybe_package_size { + if size <= u64::from(u32::max_value()) { + size as u32 + } else { + panic!("Package can't be loaded by BIOS bootloader because is too big") + } + } else { + 0 + }; + let mut kernel_info_block = [0u8; BLOCK_SIZE]; LittleEndian::write_u32(&mut kernel_info_block[0..4], kernel_size); + LittleEndian::write_u32(&mut kernel_info_block[8..12], package_size); kernel_info_block } @@ -315,6 +339,7 @@ fn create_disk_image( bin_name: &str, config: &Config, mut kernel: File, + mut maybe_package: Option, kernel_info_block: KernelInfoBlock, bootloader_data: &[u8], verbose: bool, @@ -347,27 +372,46 @@ fn create_disk_image( .write_all(&kernel_info_block) .with_context(|e| format!("Could not write output bootimage file: {}", e))?; - // write out kernel elf file - let kernel_size = kernel.metadata()?.len(); - let mut buffer = [0u8; 1024]; - loop { - let (n, interrupted) = match kernel.read(&mut buffer) { - Ok(0) => break, - Ok(n) => (n, false), - Err(ref e) if e.kind() == io::ErrorKind::Interrupted => (0, true), - Err(e) => Err(e)?, - }; - if !interrupted { - output.write_all(&buffer[..n])? + fn write_file_to_file(output: &mut File, datafile: &mut File) -> Result { + let data_size = datafile.metadata()?.len(); + let mut buffer = [0u8; 1024]; + let mut acc = 0; + loop { + let (n, interrupted) = match datafile.read(&mut buffer) { + Ok(0) => break, + Ok(n) => (n, false), + Err(ref e) if e.kind() == io::ErrorKind::Interrupted => (0, true), + Err(e) => Err(e)?, + }; + if !interrupted { + acc += n; + output.write_all(&buffer[..n])? + } } + + assert!(data_size == acc as u64); + + Ok(acc) } - let padding_size = ((512 - (kernel_size % 512)) % 512) as usize; - let padding = [0u8; 512]; - output - .write_all(&padding[..padding_size]) - .with_context(|e| format!("Could not write output bootimage file: {}", e))?; + fn pad_file(output: &mut File, written_size: usize, padding: &[u8]) -> Result<(), Error> { + let padding_size = (padding.len() - (written_size % padding.len())) % padding.len(); + output.write_all(&padding[..padding_size]).with_context(|e| format!("Could not write to output file: {}", e))?; + Ok(()) + } + // write out kernel elf file + + let kernel_size = write_file_to_file(&mut output, &mut kernel)?; + + pad_file(&mut output, kernel_size, &[0; 512])?; + + if let Some(ref mut package) = maybe_package { + println!("Writing specified package to output"); + let package_size = write_file_to_file(&mut output, package)?; + pad_file(&mut output, package_size, &[0; 512])?; + } + if let Some(min_size) = config.minimum_image_size { // we already wrote to output successfully, // both metadata and set_len should succeed. diff --git a/src/config.rs b/src/config.rs index a6bab81..b91e8d0 100644 --- a/src/config.rs +++ b/src/config.rs @@ -10,6 +10,7 @@ pub struct Config { pub bootloader: BootloaderConfig, pub minimum_image_size: Option, pub run_command: Vec, + pub package_filepath: Option, } #[derive(Debug, Clone)] @@ -167,6 +168,9 @@ pub(crate) fn read_config(manifest_path: PathBuf) -> Result { } config.run_command = Some(command); } + ("package-file", Value::String(path)) => { + config.package_filepath = Some(PathBuf::from(path)); + } (key, value) => Err(format_err!( "unexpected `package.metadata.bootimage` \ key `{}` with value `{}`", @@ -186,6 +190,7 @@ struct ConfigBuilder { bootloader: BootloaderConfigBuilder, minimum_image_size: Option, run_command: Option>, + package_filepath: Option, } #[derive(Default)] @@ -209,6 +214,7 @@ impl Into for ConfigBuilder { "-drive".into(), "format=raw,file={}".into(), ]), + package_filepath: self.package_filepath, } } } From 50fd029f0cdc97f2c8666792d59ae2b1f9b32d15 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Thu, 9 Aug 2018 10:10:24 +0200 Subject: [PATCH 039/271] bootimage 0.5.6 --- Cargo.lock | 2 +- Cargo.toml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7123d55..f0b5486 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -21,7 +21,7 @@ dependencies = [ [[package]] name = "bootimage" -version = "0.5.5" +version = "0.5.6" dependencies = [ "byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "cargo_metadata 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/Cargo.toml b/Cargo.toml index 0c7fd73..626b297 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.5.5" +version = "0.5.6" repository = "https://github.com/rust-osdev/bootimage" [dependencies] @@ -13,7 +13,7 @@ xmas-elf = "0.6.1" wait-timeout = "0.1" [dependencies.cargo_metadata] -version = "0.5.5" +version = "0.5.6" default-features = false [dependencies.failure] From c02da599d7dd276864e2d3b07ced8ec6ee634bbe Mon Sep 17 00:00:00 2001 From: acheronfail Date: Fri, 23 Nov 2018 12:21:30 +1100 Subject: [PATCH 040/271] made bootimage tests run in parallel with rayon --- Cargo.lock | 106 +++++++++++++++++++++++++++++++++++++++ Cargo.toml | 3 +- src/main.rs | 1 + src/test.rs | 141 ++++++++++++++++++++++++++-------------------------- 4 files changed, 180 insertions(+), 71 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f0b5486..e6687a0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,3 +1,11 @@ +[[package]] +name = "arrayvec" +version = "0.4.7" +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 = "backtrace" version = "0.3.9" @@ -26,6 +34,7 @@ dependencies = [ "byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "cargo_metadata 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)", "failure 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rayon 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", "toml 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "wait-timeout 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "xmas-elf 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -58,11 +67,47 @@ 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.11.0" @@ -81,11 +126,34 @@ name = "itoa" version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "lazy_static" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "libc" version = "0.2.42" source = "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" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "proc-macro2" version = "0.4.8" @@ -102,11 +170,37 @@ dependencies = [ "proc-macro2 0.4.8 (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 = "rustc-demangle" version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "scopeguard" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "semver" version = "0.9.0" @@ -210,20 +304,32 @@ version = "0.1.2" source = "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 backtrace 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "89a47830402e9981c5c41223151efcced65a0510c13097c769cede7efb34782a" "checksum backtrace-sys 0.1.23 (registry+https://github.com/rust-lang/crates.io-index)" = "bff67d0c06556c0b8e6b5f090f0eac52d950d9dfd1d35ba04e4ca3543eaf6a7e" "checksum byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "74c0b906e9446b0a2e4f760cdb3fa4b2c48cdc6db8766a845c54b6ff063fd2e9" "checksum cargo_metadata 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)" = "1efca0b863ca03ed4c109fb1c55e0bc4bbeb221d3e103d86251046b06a526bd0" "checksum cc 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)" = "2119ea4867bd2b8ed3aecab467709720b2d55b1bcfe09f772fd68066eaf15275" "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.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ff511d5dc435d703f4971bc399647c9bc38e20cb41452e3b9feb4765419ed3f3" "checksum failure 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "934799b6c1de475a012a02dab0ace1ace43789ee4b99bcfbf1a2e3e8ced5de82" "checksum itoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "5adb58558dcd1d786b5f0bd15f3226ee23486e24b7b58304b60f64dc68e62606" +"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 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 rustc-demangle 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "bcfe5b13211b4d78e5c2cadfebd7769197d95c639c35a50057eb4c05de811395" +"checksum scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27" "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.70 (registry+https://github.com/rust-lang/crates.io-index)" = "0c3adf19c07af6d186d91dae8927b83b0553d07ca56cbf7f2f32560455c91920" diff --git a/Cargo.toml b/Cargo.toml index 626b297..0ac46c1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,9 +8,10 @@ repository = "https://github.com/rust-osdev/bootimage" [dependencies] byteorder = "1.2.1" +rayon = "1.0" toml = "0.4.5" -xmas-elf = "0.6.1" wait-timeout = "0.1" +xmas-elf = "0.6.1" [dependencies.cargo_metadata] version = "0.5.6" diff --git a/src/main.rs b/src/main.rs index bd713f7..4064403 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,5 +1,6 @@ extern crate byteorder; extern crate cargo_metadata; +extern crate rayon; extern crate toml; extern crate wait_timeout; extern crate xmas_elf; diff --git a/src/test.rs b/src/test.rs index c630654..afd58a8 100644 --- a/src/test.rs +++ b/src/test.rs @@ -1,6 +1,7 @@ use args::Args; use build; use failure::{Error, ResultExt}; +use rayon::prelude::*; use std::io::Write; use std::path::Path; use std::time::Duration; @@ -29,88 +30,88 @@ pub(crate) fn test(args: Args) -> Result<(), Error> { test_config }; - let mut tests = Vec::new(); - - let crate_metadata = metadata + let tests = metadata .packages .iter() .find(|p| Path::new(&p.manifest_path) == config.manifest_path) - .expect("Could not read crate name from cargo metadata"); - let target_iter = crate_metadata.targets.iter(); - for target in target_iter.filter(|t| t.kind == ["bin"] && t.name.starts_with("test-")) { - println!("{}", target.name); + .expect("Could not read crate name from cargo metadata") + .targets + .par_iter() + .filter(|t| t.kind == ["bin"] && t.name.starts_with("test-")) + .map(|target| { + println!("RUN: {}", target.name); - let mut target_args = test_args.clone(); - target_args.set_bin_name(target.name.clone()); - let test_path = build::build_impl( - &target_args, - &test_config, - &metadata, - &root_dir, - &out_dir, - false, - )?; + let mut target_args = test_args.clone(); + target_args.set_bin_name(target.name.clone()); + let test_path = build::build_impl( + &target_args, + &test_config, + &metadata, + &root_dir, + &out_dir, + false, + )?; - let test_result; - let output_file = format!("{}-output.txt", test_path.display()); + 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() - .with_context(|e| format_err!("Failed to launch QEMU: {:?}\n{}", command, e))?; - let timeout = Duration::from_secs(60); - match child - .wait_timeout(timeout) - .with_context(|e| format!("Failed to wait with timeout: {}", e))? - { - None => { - child - .kill() - .with_context(|e| format!("Failed to kill QEMU: {}", e))?; - child - .wait() - .with_context(|e| format!("Failed to wait for QEMU process: {}", e))?; - test_result = TestResult::TimedOut; - writeln!(io::stderr(), "Timed Out")?; - } - Some(_) => { - let output = fs::read_to_string(&output_file).with_context(|e| { - format_err!("Failed to read test output file {}: {}", output_file, e) - })?; - if output.starts_with("ok\n") { - test_result = TestResult::Ok; - println!("Ok"); - } else if output.starts_with("failed\n") { - test_result = TestResult::Failed; - writeln!(io::stderr(), "Failed:")?; - for line in output[7..].lines() { - writeln!(io::stderr(), " {}", line)?; - } - } else { - test_result = TestResult::Invalid; - writeln!(io::stderr(), "Failed: Invalid Output:")?; - for line in output.lines() { - writeln!(io::stderr(), " {}", line)?; + 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() + .with_context(|e| format_err!("Failed to launch QEMU: {:?}\n{}", command, e))?; + let timeout = Duration::from_secs(60); + match child + .wait_timeout(timeout) + .with_context(|e| format!("Failed to wait with timeout: {}", e))? + { + None => { + child + .kill() + .with_context(|e| format!("Failed to kill QEMU: {}", e))?; + child + .wait() + .with_context(|e| format!("Failed to wait for QEMU process: {}", e))?; + test_result = TestResult::TimedOut; + writeln!(io::stderr(), "Timed Out")?; + } + Some(_) => { + let output = fs::read_to_string(&output_file).with_context(|e| { + format_err!("Failed to read test output file {}: {}", output_file, e) + })?; + if output.starts_with("ok\n") { + test_result = TestResult::Ok; + println!("OK: {}", target.name); + } else if output.starts_with("failed\n") { + test_result = TestResult::Failed; + writeln!(io::stderr(), "Failed:")?; + for line in output[7..].lines() { + writeln!(io::stderr(), " {}", line)?; + } + } else { + test_result = TestResult::Invalid; + writeln!(io::stderr(), "Failed: Invalid Output:")?; + for line in output.lines() { + writeln!(io::stderr(), " {}", line)?; + } } } } - } - println!(""); - tests.push((target.name.clone(), test_result)) - } + Ok((target.name.clone(), test_result)) + }) + .collect::, Error>>()?; if tests.iter().all(|t| t.1 == TestResult::Ok) { - println!("All tests succeeded."); + println!("\nAll tests succeeded."); Ok(()) } else { writeln!(io::stderr(), "The following tests failed:")?; From c113fd411df65599e7e1c7902a60201b7f97978f Mon Sep 17 00:00:00 2001 From: acheronfail Date: Fri, 23 Nov 2018 12:36:53 +1100 Subject: [PATCH 041/271] add newline to failure case --- src/test.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test.rs b/src/test.rs index afd58a8..4249f35 100644 --- a/src/test.rs +++ b/src/test.rs @@ -114,7 +114,7 @@ pub(crate) fn test(args: Args) -> Result<(), Error> { println!("\nAll tests succeeded."); Ok(()) } else { - writeln!(io::stderr(), "The following tests failed:")?; + writeln!(io::stderr(), "\nThe following tests failed:")?; for test in tests.iter().filter(|t| t.1 != TestResult::Ok) { writeln!(io::stderr(), " {}: {:?}", test.0, test.1)?; } From d5fad44d42c01f74c7782a3bb803c7d52976c904 Mon Sep 17 00:00:00 2001 From: acheronfail Date: Fri, 23 Nov 2018 21:59:49 +1100 Subject: [PATCH 042/271] iter first to build, par_iter to run --- src/test.rs | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/src/test.rs b/src/test.rs index 4249f35..d0bbf53 100644 --- a/src/test.rs +++ b/src/test.rs @@ -3,7 +3,7 @@ use build; use failure::{Error, ResultExt}; use rayon::prelude::*; use std::io::Write; -use std::path::Path; +use std::path::{Path, PathBuf}; use std::time::Duration; use std::{fs, io, process}; use wait_timeout::ChildExt; @@ -30,16 +30,16 @@ pub(crate) fn test(args: Args) -> Result<(), Error> { test_config }; - let tests = metadata + let test_targets = metadata .packages .iter() .find(|p| Path::new(&p.manifest_path) == config.manifest_path) .expect("Could not read crate name from cargo metadata") .targets - .par_iter() + .iter() .filter(|t| t.kind == ["bin"] && t.name.starts_with("test-")) .map(|target| { - println!("RUN: {}", target.name); + println!("BUILD: {}", target.name); let mut target_args = test_args.clone(); target_args.set_bin_name(target.name.clone()); @@ -50,7 +50,17 @@ pub(crate) fn test(args: Args) -> Result<(), Error> { &root_dir, &out_dir, false, - )?; + ).expect(&format!("Failed to build test: {}", target.name)); + println!(""); + + (target, test_path) + }) + .collect::>(); + + 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()); @@ -92,13 +102,13 @@ pub(crate) fn test(args: Args) -> Result<(), Error> { println!("OK: {}", target.name); } else if output.starts_with("failed\n") { test_result = TestResult::Failed; - writeln!(io::stderr(), "Failed:")?; + writeln!(io::stderr(), "FAIL:")?; for line in output[7..].lines() { writeln!(io::stderr(), " {}", line)?; } } else { test_result = TestResult::Invalid; - writeln!(io::stderr(), "Failed: Invalid Output:")?; + writeln!(io::stderr(), "FAIL: Invalid Output:")?; for line in output.lines() { writeln!(io::stderr(), " {}", line)?; } @@ -110,11 +120,12 @@ pub(crate) fn test(args: Args) -> Result<(), Error> { }) .collect::, Error>>()?; + println!(""); if tests.iter().all(|t| t.1 == TestResult::Ok) { - println!("\nAll tests succeeded."); + println!("All tests succeeded."); Ok(()) } else { - writeln!(io::stderr(), "\nThe following tests failed:")?; + 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)?; } From e08a6293f8bc1273bff9fe42a7b2c42310894228 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Sun, 25 Nov 2018 13:16:34 +0100 Subject: [PATCH 043/271] bootimage 0.5.7 --- Cargo.lock | 2 +- Cargo.toml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e6687a0..0c85c1f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -29,7 +29,7 @@ dependencies = [ [[package]] name = "bootimage" -version = "0.5.6" +version = "0.5.7" dependencies = [ "byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "cargo_metadata 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/Cargo.toml b/Cargo.toml index 0ac46c1..a899dc0 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.5.6" +version = "0.5.7" repository = "https://github.com/rust-osdev/bootimage" [dependencies] @@ -14,7 +14,7 @@ wait-timeout = "0.1" xmas-elf = "0.6.1" [dependencies.cargo_metadata] -version = "0.5.6" +version = "0.5.7" default-features = false [dependencies.failure] From d89a6c51b82aa1e110e7d7716e791b76f1a74291 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Wed, 9 Jan 2019 14:55:07 +0100 Subject: [PATCH 044/271] Use target_directory field of cargo metadata instead of hardcoding `target` (#26) The target directory can be overridden, e.g. through the CARGO_TARGET_DIR environment variable. --- src/build.rs | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/build.rs b/src/build.rs index b2b6931..2ba5234 100644 --- a/src/build.rs +++ b/src/build.rs @@ -271,9 +271,9 @@ fn build_bootloader(metadata: &CargoMetadata, config: &Config) -> Result Result Date: Wed, 9 Jan 2019 14:56:47 +0100 Subject: [PATCH 045/271] bootimage 0.5.8 --- Cargo.lock | 2 +- Cargo.toml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0c85c1f..ce746d9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -29,7 +29,7 @@ dependencies = [ [[package]] name = "bootimage" -version = "0.5.7" +version = "0.5.8" dependencies = [ "byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "cargo_metadata 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/Cargo.toml b/Cargo.toml index a899dc0..98170e7 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.5.7" +version = "0.5.8" repository = "https://github.com/rust-osdev/bootimage" [dependencies] @@ -14,7 +14,7 @@ wait-timeout = "0.1" xmas-elf = "0.6.1" [dependencies.cargo_metadata] -version = "0.5.7" +version = "0.5.8" default-features = false [dependencies.failure] From 86f52bf97a40c8fb66474faaaf3cea70992f0b39 Mon Sep 17 00:00:00 2001 From: Josh Mcguigan Date: Sun, 20 Jan 2019 10:13:48 -0700 Subject: [PATCH 046/271] remove run command duplication (#27) --- src/test.rs | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/src/test.rs b/src/test.rs index d0bbf53..f463763 100644 --- a/src/test.rs +++ b/src/test.rs @@ -12,21 +12,10 @@ pub(crate) fn test(args: Args) -> Result<(), Error> { let (args, config, metadata, root_dir, out_dir) = build::common_setup(args)?; let test_args = args.clone(); - let test_run_command = vec![ - "qemu-system-x86_64".into(), - "-drive".into(), - "format=raw,file={}".into(), - "-device".into(), - "isa-debug-exit,iobase=0xf4,iosize=0x04".into(), - "-display".into(), - "none".into(), - "-serial".into(), - "file:{}-output.txt".into(), - ]; + let test_config = { let mut test_config = config.clone(); test_config.output = None; - test_config.run_command = test_run_command; test_config }; From a8987b3fd28e9f89766bdf6af66dab74b2a176d3 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Sun, 20 Jan 2019 18:50:59 +0100 Subject: [PATCH 047/271] Use current directory instead of workspace root as default manifest path Fixes #28 Fixes phil-opp/blog_os#522 --- Changelog.md | 3 +++ src/build.rs | 9 +++------ 2 files changed, 6 insertions(+), 6 deletions(-) create mode 100644 Changelog.md diff --git a/Changelog.md b/Changelog.md new file mode 100644 index 0000000..621e835 --- /dev/null +++ b/Changelog.md @@ -0,0 +1,3 @@ + +- \[Breaking\] When no `--manifest-path` argument is passed, `bootimage` defaults to the `Cargo.toml` in the current directory instead of the workspace root. + - This fixes compilation of projects that are part of a workspace diff --git a/src/build.rs b/src/build.rs index 2ba5234..2a13474 100644 --- a/src/build.rs +++ b/src/build.rs @@ -44,12 +44,9 @@ pub(crate) fn common_setup( } let metadata = read_cargo_metadata(&args)?; - let crate_root = PathBuf::from(&metadata.workspace_root); - let manifest_path = args.manifest_path().as_ref().map(Clone::clone).unwrap_or({ - let mut path = crate_root.clone(); - path.push("Cargo.toml"); - path - }); + let manifest_path = args.manifest_path().as_ref().map(Clone::clone) + .unwrap_or(Path::new("./Cargo.toml").canonicalize().unwrap()); + let crate_root = manifest_path.parent().unwrap().to_path_buf(); let config = config::read_config(manifest_path)?; if args.target().is_none() { From 02f9a7f0f1e760fe3b55a44856574f4839275378 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Sun, 20 Jan 2019 19:18:01 +0100 Subject: [PATCH 048/271] bootimage 0.6.0 --- Cargo.lock | 14 +++++++------- Cargo.toml | 4 ++-- Changelog.md | 2 ++ 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ce746d9..8765be9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -29,10 +29,10 @@ dependencies = [ [[package]] name = "bootimage" -version = "0.5.8" +version = "0.6.0" dependencies = [ "byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "cargo_metadata 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)", + "cargo_metadata 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", "failure 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "rayon 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", "toml 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -47,10 +47,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "cargo_metadata" -version = "0.5.8" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", + "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.70 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)", @@ -110,7 +110,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "error-chain" -version = "0.11.0" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -308,7 +308,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum backtrace 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "89a47830402e9981c5c41223151efcced65a0510c13097c769cede7efb34782a" "checksum backtrace-sys 0.1.23 (registry+https://github.com/rust-lang/crates.io-index)" = "bff67d0c06556c0b8e6b5f090f0eac52d950d9dfd1d35ba04e4ca3543eaf6a7e" "checksum byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "74c0b906e9446b0a2e4f760cdb3fa4b2c48cdc6db8766a845c54b6ff063fd2e9" -"checksum cargo_metadata 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)" = "1efca0b863ca03ed4c109fb1c55e0bc4bbeb221d3e103d86251046b06a526bd0" +"checksum cargo_metadata 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "e5d1b4d380e1bab994591a24c2bdd1b054f64b60bef483a8c598c7c345bc3bbe" "checksum cc 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)" = "2119ea4867bd2b8ed3aecab467709720b2d55b1bcfe09f772fd68066eaf15275" "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" @@ -316,7 +316,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "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.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ff511d5dc435d703f4971bc399647c9bc38e20cb41452e3b9feb4765419ed3f3" +"checksum error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "07e791d3be96241c77c43846b665ef1384606da2cd2a48730abe606a12906e02" "checksum failure 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "934799b6c1de475a012a02dab0ace1ace43789ee4b99bcfbf1a2e3e8ced5de82" "checksum itoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "5adb58558dcd1d786b5f0bd15f3226ee23486e24b7b58304b60f64dc68e62606" "checksum lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a374c89b9db55895453a74c1e38861d9deec0b01b405a82516e9d5de4820dea1" diff --git a/Cargo.toml b/Cargo.toml index 98170e7..c94e7bb 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.5.8" +version = "0.6.0" repository = "https://github.com/rust-osdev/bootimage" [dependencies] @@ -14,7 +14,7 @@ wait-timeout = "0.1" xmas-elf = "0.6.1" [dependencies.cargo_metadata] -version = "0.5.8" +version = "0.6.0" default-features = false [dependencies.failure] diff --git a/Changelog.md b/Changelog.md index 621e835..82e38c8 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,3 +1,5 @@ +0.6.0 + - \[Breaking\] When no `--manifest-path` argument is passed, `bootimage` defaults to the `Cargo.toml` in the current directory instead of the workspace root. - This fixes compilation of projects that are part of a workspace From 920ad32a954faa2eb746ab32b869eff13e7179e4 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Sun, 20 Jan 2019 19:20:06 +0100 Subject: [PATCH 049/271] Improve changelog formatting --- Changelog.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Changelog.md b/Changelog.md index 82e38c8..9deec0c 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,5 +1,6 @@ -0.6.0 +# 0.6.0 +**Breaking**: -- \[Breaking\] When no `--manifest-path` argument is passed, `bootimage` defaults to the `Cargo.toml` in the current directory instead of the workspace root. +- When no `--manifest-path` argument is passed, `bootimage` defaults to the `Cargo.toml` in the current directory instead of the workspace root. - This fixes compilation of projects that are part of a workspace From 4e6affc678402f95f16a1a7056a381385a8a26eb Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Sun, 20 Jan 2019 19:41:49 +0100 Subject: [PATCH 050/271] Pass manifest-path to `cargo fetch` if present --- Changelog.md | 4 ++++ src/build.rs | 8 ++++++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/Changelog.md b/Changelog.md index 9deec0c..0521a7c 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,5 +1,9 @@ +- Fix: bootimage should now work correctly with `--manifest-path` + # 0.6.0 +(Yanked from crates.io because of a bug fixed in 0.6.1.) + **Breaking**: - When no `--manifest-path` argument is passed, `bootimage` defaults to the `Cargo.toml` in the current directory instead of the workspace root. diff --git a/src/build.rs b/src/build.rs index 2a13474..372b36a 100644 --- a/src/build.rs +++ b/src/build.rs @@ -157,7 +157,7 @@ impl fmt::Display for CargoMetadataError { impl failure::Fail for CargoMetadataError {} fn read_cargo_metadata(args: &Args) -> Result { - run_cargo_fetch(); + run_cargo_fetch(args); let metadata = cargo_metadata::metadata_deps(args.manifest_path().as_ref().map(PathBuf::as_path), true) .map_err(|e| CargoMetadataError { @@ -215,9 +215,13 @@ fn run_xbuild(args: &[String]) -> io::Result { Ok(exit_status) } -fn run_cargo_fetch() { +fn run_cargo_fetch(args: &Args) { let mut command = process::Command::new("cargo"); command.arg("fetch"); + if let Some(manifest_path) = args.manifest_path() { + command.arg("--manifest-path"); + command.arg(manifest_path); + } if !command.status().map(|s| s.success()).unwrap_or(false) { process::exit(1); } From 254e6797024c37d3af37b142eed0924835152954 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Sun, 20 Jan 2019 19:47:48 +0100 Subject: [PATCH 051/271] bootimage 0.6.1 --- Cargo.lock | 2 +- Cargo.toml | 4 ++-- Changelog.md | 2 ++ 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8765be9..7bdbbfc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -29,7 +29,7 @@ dependencies = [ [[package]] name = "bootimage" -version = "0.6.0" +version = "0.6.1" dependencies = [ "byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "cargo_metadata 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/Cargo.toml b/Cargo.toml index c94e7bb..b63b989 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.6.0" +version = "0.6.1" repository = "https://github.com/rust-osdev/bootimage" [dependencies] @@ -14,7 +14,7 @@ wait-timeout = "0.1" xmas-elf = "0.6.1" [dependencies.cargo_metadata] -version = "0.6.0" +version = "0.6.1" default-features = false [dependencies.failure] diff --git a/Changelog.md b/Changelog.md index 0521a7c..d9676af 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,3 +1,5 @@ +# 0.6.1 + - Fix: bootimage should now work correctly with `--manifest-path` # 0.6.0 From abe86918a437159517f0d8ecb860fb6eae27e368 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Sun, 20 Jan 2019 20:44:26 +0100 Subject: [PATCH 052/271] Fix build on Windows The `.` directory doesn't work on Windows. --- Changelog.md | 2 ++ src/build.rs | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/Changelog.md b/Changelog.md index d9676af..4f6bb30 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,3 +1,5 @@ +- Fix build on Windows + # 0.6.1 - Fix: bootimage should now work correctly with `--manifest-path` diff --git a/src/build.rs b/src/build.rs index 372b36a..f05ff6a 100644 --- a/src/build.rs +++ b/src/build.rs @@ -45,7 +45,7 @@ pub(crate) fn common_setup( let metadata = read_cargo_metadata(&args)?; let manifest_path = args.manifest_path().as_ref().map(Clone::clone) - .unwrap_or(Path::new("./Cargo.toml").canonicalize().unwrap()); + .unwrap_or(Path::new("Cargo.toml").canonicalize().unwrap()); let crate_root = manifest_path.parent().unwrap().to_path_buf(); let config = config::read_config(manifest_path)?; From af3d5b54af22538892683400892f58037ecccd39 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Sun, 20 Jan 2019 20:44:51 +0100 Subject: [PATCH 053/271] bootimage 0.6.2 --- Cargo.lock | 2 +- Cargo.toml | 4 ++-- Changelog.md | 2 ++ 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7bdbbfc..3bd8449 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -29,7 +29,7 @@ dependencies = [ [[package]] name = "bootimage" -version = "0.6.1" +version = "0.6.2" dependencies = [ "byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "cargo_metadata 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/Cargo.toml b/Cargo.toml index b63b989..bcd7c3b 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.6.1" +version = "0.6.2" repository = "https://github.com/rust-osdev/bootimage" [dependencies] @@ -14,7 +14,7 @@ wait-timeout = "0.1" xmas-elf = "0.6.1" [dependencies.cargo_metadata] -version = "0.6.1" +version = "0.6.2" default-features = false [dependencies.failure] diff --git a/Changelog.md b/Changelog.md index 4f6bb30..3f93f93 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,3 +1,5 @@ +# 0.6.2 + - Fix build on Windows # 0.6.1 From 8d1dd58b830d38245de0d6fa84997894d016af56 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Sun, 20 Jan 2019 21:42:31 +0100 Subject: [PATCH 054/271] Run rustfmt --- src/build.rs | 27 ++++++++++++++++++++------- src/config.rs | 5 +++-- src/test.rs | 3 ++- 3 files changed, 25 insertions(+), 10 deletions(-) diff --git a/src/build.rs b/src/build.rs index f05ff6a..4ab195a 100644 --- a/src/build.rs +++ b/src/build.rs @@ -44,7 +44,10 @@ pub(crate) fn common_setup( } let metadata = read_cargo_metadata(&args)?; - let manifest_path = args.manifest_path().as_ref().map(Clone::clone) + let manifest_path = args + .manifest_path() + .as_ref() + .map(Clone::clone) .unwrap_or(Path::new("Cargo.toml").canonicalize().unwrap()); let crate_root = manifest_path.parent().unwrap().to_path_buf(); let config = config::read_config(manifest_path)?; @@ -66,7 +69,8 @@ pub(crate) fn common_setup( io::stderr(), "Please pass a path to `--target` (with `.json` extension`): `--target {}.json`", target - ).unwrap(); + ) + .unwrap(); process::exit(1); } } @@ -94,17 +98,24 @@ pub(crate) fn build_impl( let kernel = build_kernel(&out_dir, &bin_name, &args, verbose)?; let maybe_package = if let Some(ref path) = config.package_filepath { - Some(File::open(path).with_context(|e| format!("Unable to open specified package file: {}", e))?) + Some( + File::open(path) + .with_context(|e| format!("Unable to open specified package file: {}", e))?, + ) } else { None }; let maybe_package_size = if let Some(ref file) = maybe_package { - Some(file.metadata().with_context(|e| format!("Failed to read specified package file: {}", e))?.len()) + Some( + file.metadata() + .with_context(|e| format!("Failed to read specified package file: {}", e))? + .len(), + ) } else { None }; - + let kernel_size = kernel .metadata() .with_context(|e| format!("Failed to read kernel output file: {}", e))? @@ -400,7 +411,9 @@ fn create_disk_image( fn pad_file(output: &mut File, written_size: usize, padding: &[u8]) -> Result<(), Error> { let padding_size = (padding.len() - (written_size % padding.len())) % padding.len(); - output.write_all(&padding[..padding_size]).with_context(|e| format!("Could not write to output file: {}", e))?; + output + .write_all(&padding[..padding_size]) + .with_context(|e| format!("Could not write to output file: {}", e))?; Ok(()) } @@ -415,7 +428,7 @@ fn create_disk_image( let package_size = write_file_to_file(&mut output, package)?; pad_file(&mut output, package_size, &[0; 512])?; } - + if let Some(min_size) = config.minimum_image_size { // we already wrote to output successfully, // both metadata and set_len should succeed. diff --git a/src/config.rs b/src/config.rs index b91e8d0..fad966a 100644 --- a/src/config.rs +++ b/src/config.rs @@ -43,7 +43,8 @@ pub(crate) fn read_config(manifest_path: PathBuf) -> Result { return Ok(ConfigBuilder { manifest_path: Some(manifest_path), ..Default::default() - }.into()) + } + .into()); } Some(metadata) => metadata.as_table().ok_or(format_err!( "Bootimage configuration invalid: {:?}", @@ -80,7 +81,7 @@ pub(crate) fn read_config(manifest_path: PathBuf) -> Result { Some(_) => { return Err(format_err!( "Bootloader 'default-features' field should be a bool!" - )) + )); } }; diff --git a/src/test.rs b/src/test.rs index f463763..9b06155 100644 --- a/src/test.rs +++ b/src/test.rs @@ -39,7 +39,8 @@ pub(crate) fn test(args: Args) -> Result<(), Error> { &root_dir, &out_dir, false, - ).expect(&format!("Failed to build test: {}", target.name)); + ) + .expect(&format!("Failed to build test: {}", target.name)); println!(""); (target, test_path) From 1fd1d15919e91fc9bfded84fa5c3b362af7dad81 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Sun, 20 Jan 2019 21:46:13 +0100 Subject: [PATCH 055/271] Canonicalize paths before comparing them This caused an error on Windows where the path in the cargo metadata is not fully canonicalized. --- Changelog.md | 5 ++++- src/build.rs | 7 ++++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/Changelog.md b/Changelog.md index 3f93f93..a4dc344 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,6 +1,9 @@ +- Canonicalize paths before comparing them + - This caused an error on Windows where the path in the cargo metadata is not fully canonicalized + # 0.6.2 -- Fix build on Windows +- Fix build on Windows (don't use the `.` directory) # 0.6.1 diff --git a/src/build.rs b/src/build.rs index 4ab195a..a77946c 100644 --- a/src/build.rs +++ b/src/build.rs @@ -91,7 +91,12 @@ pub(crate) fn build_impl( let crate_ = metadata .packages .iter() - .find(|p| Path::new(&p.manifest_path) == config.manifest_path) + .find(|p| { + Path::new(&p.manifest_path) + .canonicalize() + .map(|path| path == config.manifest_path) + .unwrap_or(false) + }) .expect("Could not read crate name from cargo metadata"); let bin_name: String = args.bin_name().as_ref().unwrap_or(&crate_.name).clone(); From e14f4e709d56092e0071e8c5f8ddcef9c68ec8d2 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Sun, 20 Jan 2019 21:46:33 +0100 Subject: [PATCH 056/271] bootimage 0.6.3 --- Cargo.lock | 2 +- Cargo.toml | 4 ++-- Changelog.md | 2 ++ 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3bd8449..3cce78d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -29,7 +29,7 @@ dependencies = [ [[package]] name = "bootimage" -version = "0.6.2" +version = "0.6.3" dependencies = [ "byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "cargo_metadata 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/Cargo.toml b/Cargo.toml index bcd7c3b..1eddd38 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.6.2" +version = "0.6.3" repository = "https://github.com/rust-osdev/bootimage" [dependencies] @@ -14,7 +14,7 @@ wait-timeout = "0.1" xmas-elf = "0.6.1" [dependencies.cargo_metadata] -version = "0.6.2" +version = "0.6.3" default-features = false [dependencies.failure] diff --git a/Changelog.md b/Changelog.md index a4dc344..7f452cb 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,3 +1,5 @@ +# 0.6.3 + - Canonicalize paths before comparing them - This caused an error on Windows where the path in the cargo metadata is not fully canonicalized From 0eeb135e863a2c77cecc76566e82276463ed2534 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Sun, 20 Jan 2019 22:07:25 +0100 Subject: [PATCH 057/271] Try `bootimage test` on blog_os on CI --- .travis.yml | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index dff6ebf..a42d8c9 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,8 +9,38 @@ notifications: rust: - nightly + - stable + - beta -cache: cargo +os: + - linux + - osx + - windows + +cache: + cargo: true + directories: + - $HOME/Library/Caches/Homebrew + +addons: + apt: + packages: + - qemu-system-x86 + homebrew: + packages: + - qemu + +install: + - if [ $TRAVIS_OS_NAME = windows ]; then choco install qemu; export PATH="/c/Program Files/qemu:$PATH"; fi + +before_script: + - rustup component add rust-src + - (test -x $HOME/.cargo/bin/cargo-update-installed || cargo install cargo-update-installed) + - (test -x $HOME/.cargo/bin/cargo-xbuild || cargo install cargo-xbuild) + - cargo update-installed script: - cargo test +- cargo install --debug --force +- git clone https://github.com/phil-opp/blog_os.git +- if [ $TRAVIS_RUST_VERSION = nightly ]; then bootimage test --manifest-path blog_os/Cargo.toml; fi From a5474b03f880697db7498eb13d01dbc580750206 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Sun, 20 Jan 2019 23:05:43 +0100 Subject: [PATCH 058/271] Add bors.toml --- bors.toml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 bors.toml diff --git a/bors.toml b/bors.toml new file mode 100644 index 0000000..574c563 --- /dev/null +++ b/bors.toml @@ -0,0 +1,4 @@ +status = [ + "continuous-integration/travis-ci/push", +] +delete_merged_branches = true From e11e4dcdec9d2aa226c830f1ed792abfc5d47928 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Sun, 20 Jan 2019 22:01:25 +0100 Subject: [PATCH 059/271] Canonicalize paths before comparing them in `bootimage test` --- Changelog.md | 5 ++++- src/test.rs | 7 ++++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/Changelog.md b/Changelog.md index 7f452cb..7cf1e8b 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,6 +1,9 @@ +- Canonicalize paths before comparing them when invoking `bootimage test` + - This caused an error on Windows where the path in the cargo metadata is not fully canonicalized + # 0.6.3 -- Canonicalize paths before comparing them +- Canonicalize paths before comparing them when invoking `bootimage build` - This caused an error on Windows where the path in the cargo metadata is not fully canonicalized # 0.6.2 diff --git a/src/test.rs b/src/test.rs index 9b06155..6d31af4 100644 --- a/src/test.rs +++ b/src/test.rs @@ -22,7 +22,12 @@ pub(crate) fn test(args: Args) -> Result<(), Error> { let test_targets = metadata .packages .iter() - .find(|p| Path::new(&p.manifest_path) == config.manifest_path) + .find(|p| { + Path::new(&p.manifest_path) + .canonicalize() + .map(|path| path == config.manifest_path) + .unwrap_or(false) + }) .expect("Could not read crate name from cargo metadata") .targets .iter() From e159e4095ca03826a5b366b1cf528804a06bf6bc Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Mon, 21 Jan 2019 09:06:45 +0100 Subject: [PATCH 060/271] bootimage 0.6.4 --- Cargo.lock | 2 +- Cargo.toml | 4 ++-- Changelog.md | 3 +++ 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3cce78d..c6c11d8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -29,7 +29,7 @@ dependencies = [ [[package]] name = "bootimage" -version = "0.6.3" +version = "0.6.4" dependencies = [ "byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "cargo_metadata 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/Cargo.toml b/Cargo.toml index 1eddd38..0d82ff9 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.6.3" +version = "0.6.4" repository = "https://github.com/rust-osdev/bootimage" [dependencies] @@ -14,7 +14,7 @@ wait-timeout = "0.1" xmas-elf = "0.6.1" [dependencies.cargo_metadata] -version = "0.6.3" +version = "0.6.4" default-features = false [dependencies.failure] diff --git a/Changelog.md b/Changelog.md index 7cf1e8b..dbca1bb 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,5 +1,8 @@ +# 0.6.4 + - Canonicalize paths before comparing them when invoking `bootimage test` - This caused an error on Windows where the path in the cargo metadata is not fully canonicalized +- Improve CI infrastructure # 0.6.3 From 287ff8834bc97c1aea811a45c25ee3faeb40349d Mon Sep 17 00:00:00 2001 From: Phoebe Bell Date: Tue, 12 Feb 2019 22:04:02 -0800 Subject: [PATCH 061/271] bootimage test now considers qemu's exit code --- src/test.rs | 66 +++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 52 insertions(+), 14 deletions(-) diff --git a/src/test.rs b/src/test.rs index 6d31af4..a9d2d06 100644 --- a/src/test.rs +++ b/src/test.rs @@ -88,24 +88,62 @@ pub(crate) fn test(args: Args) -> Result<(), Error> { test_result = TestResult::TimedOut; writeln!(io::stderr(), "Timed Out")?; } - Some(_) => { + Some(exit_status) => { let output = fs::read_to_string(&output_file).with_context(|e| { format_err!("Failed to read test output file {}: {}", output_file, e) })?; - if output.starts_with("ok\n") { - test_result = TestResult::Ok; - println!("OK: {}", target.name); - } else if output.starts_with("failed\n") { - test_result = TestResult::Failed; - writeln!(io::stderr(), "FAIL:")?; - for line in output[7..].lines() { - writeln!(io::stderr(), " {}", line)?; + + match exit_status.code() { + None => { + test_result = TestResult::Invalid; + writeln!(io::stderr(), "FAIL: No Exit Code.")?; + for line in output.lines() { + writeln!(io::stderr(), " {}", line)?; + } } - } else { - test_result = TestResult::Invalid; - writeln!(io::stderr(), "FAIL: Invalid Output:")?; - for line in output.lines() { - writeln!(io::stderr(), " {}", line)?; + Some(code) => { + if code == 1 { + // 0 << 1 | 1 + if output.starts_with("ok\n") { + test_result = TestResult::Ok; + println!("OK: {}", target.name); + } else if output.starts_with("failed\n") { + test_result = TestResult::Failed; + writeln!(io::stderr(), "FAIL:")?; + for line in output[7..].lines() { + writeln!(io::stderr(), " {}", line)?; + } + } else { + test_result = TestResult::Invalid; + writeln!(io::stderr(), "FAIL: Invalid Output:")?; + for line in output.lines() { + writeln!(io::stderr(), " {}", line)?; + } + } + } else if code == 5 { + // 2 << 1 | 1 + test_result = TestResult::Ok; + println!("OK: {}", target.name); + } else if code == 7 { + // 3 << 1 | 1 + test_result = TestResult::Failed; + 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)?; + } + } else { + test_result = TestResult::Invalid; + writeln!(io::stderr(), "FAIL: Invalid Exit Code {}:", code)?; + for line in output.lines() { + writeln!(io::stderr(), " {}", line)?; + } + } } } } From c252e1c98fbea55de2b7340eca1fafd85bdb18ed Mon Sep 17 00:00:00 2001 From: Phoebe Bell Date: Tue, 12 Feb 2019 22:23:56 -0800 Subject: [PATCH 062/271] refactored code into handle_exit_status() --- src/test.rs | 125 +++++++++++++++++++++++++++++----------------------- 1 file changed, 70 insertions(+), 55 deletions(-) diff --git a/src/test.rs b/src/test.rs index a9d2d06..1e83813 100644 --- a/src/test.rs +++ b/src/test.rs @@ -6,7 +6,7 @@ use std::io::Write; use std::path::{Path, PathBuf}; use std::time::Duration; use std::{fs, io, process}; -use wait_timeout::ChildExt; +use wait_timeout::{ChildExt, ExitStatus}; pub(crate) fn test(args: Args) -> Result<(), Error> { let (args, config, metadata, root_dir, out_dir) = build::common_setup(args)?; @@ -92,60 +92,7 @@ pub(crate) fn test(args: Args) -> Result<(), Error> { let output = fs::read_to_string(&output_file).with_context(|e| { format_err!("Failed to read test output file {}: {}", output_file, e) })?; - - match exit_status.code() { - None => { - test_result = TestResult::Invalid; - writeln!(io::stderr(), "FAIL: No Exit Code.")?; - for line in output.lines() { - writeln!(io::stderr(), " {}", line)?; - } - } - Some(code) => { - if code == 1 { - // 0 << 1 | 1 - if output.starts_with("ok\n") { - test_result = TestResult::Ok; - println!("OK: {}", target.name); - } else if output.starts_with("failed\n") { - test_result = TestResult::Failed; - writeln!(io::stderr(), "FAIL:")?; - for line in output[7..].lines() { - writeln!(io::stderr(), " {}", line)?; - } - } else { - test_result = TestResult::Invalid; - writeln!(io::stderr(), "FAIL: Invalid Output:")?; - for line in output.lines() { - writeln!(io::stderr(), " {}", line)?; - } - } - } else if code == 5 { - // 2 << 1 | 1 - test_result = TestResult::Ok; - println!("OK: {}", target.name); - } else if code == 7 { - // 3 << 1 | 1 - test_result = TestResult::Failed; - 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)?; - } - } else { - test_result = TestResult::Invalid; - writeln!(io::stderr(), "FAIL: Invalid Exit Code {}:", code)?; - for line in output.lines() { - writeln!(io::stderr(), " {}", line)?; - } - } - } - } + test_result = handle_exit_status(exit_status, &output, &target.name)?; } } @@ -166,6 +113,74 @@ pub(crate) fn test(args: Args) -> Result<(), Error> { } } +fn handle_exit_status( + exit_status: 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, From 9a2df16246c0bc617778c83908ed9753a5bc43f1 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Wed, 13 Feb 2019 11:11:13 +0100 Subject: [PATCH 063/271] [Fix CI] The blog_os code now lives in the post-10 branch --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index a42d8c9..9ed6fec 100644 --- a/.travis.yml +++ b/.travis.yml @@ -42,5 +42,5 @@ before_script: script: - cargo test - cargo install --debug --force -- git clone https://github.com/phil-opp/blog_os.git +- git clone https://github.com/phil-opp/blog_os.git --branch post-10 - if [ $TRAVIS_RUST_VERSION = nightly ]; then bootimage test --manifest-path blog_os/Cargo.toml; fi From b777e213dc74b893afcd7ca2329d2cf0d6b21280 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Wed, 13 Feb 2019 11:29:56 +0100 Subject: [PATCH 064/271] Update changelog --- Changelog.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Changelog.md b/Changelog.md index dbca1bb..4356ecd 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,3 +1,5 @@ +- You can now mark integration tests as success/failure by setting the exit code in the QEMU `isa-debug-exit` device. See [#32](https://github.com/rust-osdev/bootimage/issues/32) for more information. + # 0.6.4 - Canonicalize paths before comparing them when invoking `bootimage test` From 87ed26cf6f711fe4cbf695b19364cd67aad407ec Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Wed, 13 Feb 2019 11:41:07 +0100 Subject: [PATCH 065/271] bootimage 0.6.5 --- 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 c6c11d8..f4f6449 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -29,7 +29,7 @@ dependencies = [ [[package]] name = "bootimage" -version = "0.6.4" +version = "0.6.5" dependencies = [ "byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "cargo_metadata 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/Cargo.toml b/Cargo.toml index 0d82ff9..93d15aa 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.6.4" +version = "0.6.5" repository = "https://github.com/rust-osdev/bootimage" [dependencies] diff --git a/Changelog.md b/Changelog.md index 4356ecd..103d50e 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,3 +1,5 @@ +# 0.6.5 + - You can now mark integration tests as success/failure by setting the exit code in the QEMU `isa-debug-exit` device. See [#32](https://github.com/rust-osdev/bootimage/issues/32) for more information. # 0.6.4 From 34783d0dd6c6d0fbed20858f8ca2baddc803f587 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Tue, 26 Mar 2019 14:10:14 +0100 Subject: [PATCH 066/271] Replace deprecated trim_left_matches --- src/args.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/args.rs b/src/args.rs index 84ccca0..7fcc5b9 100644 --- a/src/args.rs +++ b/src/args.rs @@ -73,7 +73,7 @@ where _ if arg.starts_with("--bin=") => { set( &mut bin_name, - Some(String::from(arg.trim_left_matches("--bin="))), + Some(String::from(arg.trim_start_matches("--bin="))), ); cargo_args.push(arg); } @@ -88,7 +88,7 @@ where _ if arg.starts_with("--target=") => { set( &mut target, - Some(String::from(arg.trim_left_matches("--target="))), + Some(String::from(arg.trim_start_matches("--target="))), ); cargo_args.push(arg); } @@ -108,7 +108,7 @@ where } } _ if arg.starts_with("--manifest-path=") => { - let path = Path::new(arg.trim_left_matches("--manifest-path=")) + let path = Path::new(arg.trim_start_matches("--manifest-path=")) .canonicalize() .expect("--manifest-path invalid"); set(&mut manifest_path, Some(path)); From ece17842a1c6b910532b5cb87167c3e900528c70 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Tue, 26 Mar 2019 14:09:52 +0100 Subject: [PATCH 067/271] Update dependencies --- Cargo.lock | 56 +++++++++++++++++++++++++++------------------------- Cargo.toml | 12 +++++------ Changelog.md | 2 ++ src/build.rs | 31 ++++++++++++++++++++--------- src/test.rs | 4 ++-- 5 files changed, 61 insertions(+), 44 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f4f6449..54a4b09 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,3 +1,5 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. [[package]] name = "arrayvec" version = "0.4.7" @@ -31,29 +33,29 @@ dependencies = [ name = "bootimage" version = "0.6.5" dependencies = [ - "byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "cargo_metadata 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", - "failure 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "cargo_metadata 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)", + "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "rayon 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", - "toml 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "wait-timeout 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "toml 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "wait-timeout 0.2.0 (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 = "byteorder" -version = "1.2.3" +version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "cargo_metadata" -version = "0.6.4" +version = "0.7.4" 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.70 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.70 (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)", ] @@ -115,7 +117,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "failure" -version = "0.1.1" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "backtrace 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", @@ -207,7 +209,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.70 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -217,17 +219,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "serde" -version = "1.0.70" +version = "1.0.89" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "serde_derive" -version = "1.0.70" +version = "1.0.89" 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.14.4 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.15.29 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -237,12 +239,12 @@ 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.70 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "syn" -version = "0.14.4" +version = "0.15.29" 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)", @@ -252,10 +254,10 @@ dependencies = [ [[package]] name = "toml" -version = "0.4.6" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "serde 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -265,7 +267,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "wait-timeout" -version = "0.1.5" +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)", @@ -307,8 +309,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)" = "a1e964f9e24d588183fcb43503abda40d288c8657dfc27311516ce2f05675aef" "checksum backtrace 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "89a47830402e9981c5c41223151efcced65a0510c13097c769cede7efb34782a" "checksum backtrace-sys 0.1.23 (registry+https://github.com/rust-lang/crates.io-index)" = "bff67d0c06556c0b8e6b5f090f0eac52d950d9dfd1d35ba04e4ca3543eaf6a7e" -"checksum byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "74c0b906e9446b0a2e4f760cdb3fa4b2c48cdc6db8766a845c54b6ff063fd2e9" -"checksum cargo_metadata 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "e5d1b4d380e1bab994591a24c2bdd1b054f64b60bef483a8c598c7c345bc3bbe" +"checksum byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a019b10a2a7cdeb292db131fc8113e57ea2a908f6e7894b0c3c671893b65dbeb" +"checksum cargo_metadata 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)" = "178d62b240c34223f265a4c1e275e37d62da163d421fc8d7f7e3ee340f803c57" "checksum cc 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)" = "2119ea4867bd2b8ed3aecab467709720b2d55b1bcfe09f772fd68066eaf15275" "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" @@ -317,7 +319,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "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 failure 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "934799b6c1de475a012a02dab0ace1ace43789ee4b99bcfbf1a2e3e8ced5de82" +"checksum failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "795bd83d3abeb9220f257e597aa0080a508b27533824adf336529648f6abf7e2" "checksum itoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "5adb58558dcd1d786b5f0bd15f3226ee23486e24b7b58304b60f64dc68e62606" "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" @@ -332,13 +334,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27" "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.70 (registry+https://github.com/rust-lang/crates.io-index)" = "0c3adf19c07af6d186d91dae8927b83b0553d07ca56cbf7f2f32560455c91920" -"checksum serde_derive 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)" = "3525a779832b08693031b8ecfb0de81cd71cfd3812088fafe9a7496789572124" +"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.14.4 (registry+https://github.com/rust-lang/crates.io-index)" = "2beff8ebc3658f07512a413866875adddd20f4fd47b2a4e6c9da65cd281baaea" -"checksum toml 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "a0263c6c02c4db6c8f7681f9fd35e90de799ebd4cfdeab77a38f4ff6b3d8c0d9" +"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 wait-timeout 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "b9f3bf741a801531993db6478b95682117471f76916f5e690dd8d45395b09349" +"checksum wait-timeout 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9f200f5b12eb75f8c1ed65abd4b2db8a6e1b138a20de009dacee265a2498f3f6" "checksum winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "773ef9dcc5f24b7d850d0ff101e542ff24c3b090a9768e03ff889fdef41f00fd" "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" diff --git a/Cargo.toml b/Cargo.toml index 93d15aa..f9af847 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,17 +7,17 @@ version = "0.6.5" repository = "https://github.com/rust-osdev/bootimage" [dependencies] -byteorder = "1.2.1" +byteorder = "1.3.1" rayon = "1.0" -toml = "0.4.5" -wait-timeout = "0.1" -xmas-elf = "0.6.1" +toml = "0.5.0" +wait-timeout = "0.2" +xmas-elf = "0.6.2" [dependencies.cargo_metadata] -version = "0.6.4" +version = "0.7.4" default-features = false [dependencies.failure] -version = "0.1.1" +version = "0.1.5" default-features = false features = ["std"] diff --git a/Changelog.md b/Changelog.md index 103d50e..331aa42 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,3 +1,5 @@ +- Update dependencies + # 0.6.5 - You can now mark integration tests as success/failure by setting the exit code in the QEMU `isa-debug-exit` device. See [#32](https://github.com/rust-osdev/bootimage/issues/32) for more information. diff --git a/src/build.rs b/src/build.rs index a77946c..f1bc258 100644 --- a/src/build.rs +++ b/src/build.rs @@ -174,11 +174,15 @@ impl failure::Fail for CargoMetadataError {} fn read_cargo_metadata(args: &Args) -> Result { run_cargo_fetch(args); - let metadata = - cargo_metadata::metadata_deps(args.manifest_path().as_ref().map(PathBuf::as_path), true) - .map_err(|e| CargoMetadataError { - error: format!("{}", e), - })?; + let metadata = { + let mut cmd = cargo_metadata::MetadataCommand::new(); + if let Some(ref path) = args.manifest_path() { + cmd.manifest_path(path.as_path()); + } + cmd.exec().map_err(|e| CargoMetadataError { + error: format!("{}", e), + })? + }; Ok(metadata) } @@ -302,7 +306,12 @@ fn build_bootloader(metadata: &CargoMetadata, config: &Config) -> Result Result Result<(), Error> { let (args, config, metadata, root_dir, out_dir) = build::common_setup(args)?; @@ -114,7 +114,7 @@ pub(crate) fn test(args: Args) -> Result<(), Error> { } fn handle_exit_status( - exit_status: ExitStatus, + exit_status: process::ExitStatus, output: &str, target_name: &str, ) -> Result { From beb954106411ea35b42b198c0f3fc39146f1ad7d Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Tue, 26 Mar 2019 14:24:50 +0100 Subject: [PATCH 068/271] bootimage 0.6.6 --- 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 54a4b09..5d402a4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -31,7 +31,7 @@ dependencies = [ [[package]] name = "bootimage" -version = "0.6.5" +version = "0.6.6" dependencies = [ "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "cargo_metadata 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/Cargo.toml b/Cargo.toml index f9af847..ff9eb3f 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.6.5" +version = "0.6.6" repository = "https://github.com/rust-osdev/bootimage" [dependencies] diff --git a/Changelog.md b/Changelog.md index 331aa42..f0fa753 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,3 +1,5 @@ +# 0.6.6 + - Update dependencies # 0.6.5 From b18204458b5fb7fcf55e817a646188cc0891e93e Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Tue, 26 Mar 2019 19:23:50 +0100 Subject: [PATCH 069/271] Update to 2018 edition --- Cargo.toml | 1 + src/args.rs | 2 +- src/build.rs | 4 ++-- src/main.rs | 6 ------ src/test.rs | 4 ++-- 5 files changed, 6 insertions(+), 11 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index ff9eb3f..2f9d9bc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,6 +5,7 @@ license = "MIT/Apache-2.0" name = "bootimage" version = "0.6.6" repository = "https://github.com/rust-osdev/bootimage" +edition = "2018" [dependencies] byteorder = "1.3.1" diff --git a/src/args.rs b/src/args.rs index 7fcc5b9..c9e8314 100644 --- a/src/args.rs +++ b/src/args.rs @@ -1,6 +1,6 @@ use std::path::{Path, PathBuf}; use std::{env, mem}; -use Command; +use crate::Command; pub(crate) fn parse_args() -> Command { let mut args = env::args().skip(1); diff --git a/src/build.rs b/src/build.rs index f1bc258..68560aa 100644 --- a/src/build.rs +++ b/src/build.rs @@ -1,7 +1,7 @@ -use args::{self, Args}; +use crate::args::{self, Args}; use byteorder::{ByteOrder, LittleEndian}; use cargo_metadata::{self, Metadata as CargoMetadata}; -use config::{self, Config}; +use crate::config::{self, Config}; use failure::{self, Error, ResultExt}; use std::fs::File; use std::io::Write; diff --git a/src/main.rs b/src/main.rs index 4064403..2f3c49c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,9 +1,3 @@ -extern crate byteorder; -extern crate cargo_metadata; -extern crate rayon; -extern crate toml; -extern crate wait_timeout; -extern crate xmas_elf; #[macro_use] extern crate failure; diff --git a/src/test.rs b/src/test.rs index b173e4a..8ff8dac 100644 --- a/src/test.rs +++ b/src/test.rs @@ -1,5 +1,5 @@ -use args::Args; -use build; +use crate::args::Args; +use crate::build; use failure::{Error, ResultExt}; use rayon::prelude::*; use std::io::Write; From 3d508ca922a5ca61d17df5a3b00fe0e9b6c58652 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Tue, 26 Mar 2019 23:27:17 +0100 Subject: [PATCH 070/271] Rewrite for new bootloader build system --- Cargo.lock | 23 ++ Cargo.toml | 2 + src/args.rs | 11 +- src/build.rs | 459 ----------------------------------- src/config.rs | 17 +- src/lib.rs | 434 +++++++++++++++++++++++++++++++++ src/main.rs | 40 ++- src/subcommand.rs | 3 + src/subcommand/build.rs | 67 +++++ src/subcommand/run.rs | 33 +++ src/{ => subcommand}/test.rs | 44 ++-- 11 files changed, 629 insertions(+), 504 deletions(-) delete mode 100644 src/build.rs create mode 100644 src/lib.rs create mode 100644 src/subcommand.rs create mode 100644 src/subcommand/build.rs create mode 100644 src/subcommand/run.rs rename src/{ => subcommand}/test.rs (85%) diff --git a/Cargo.lock b/Cargo.lock index 5d402a4..6b27efa 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -36,6 +36,8 @@ dependencies = [ "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "cargo_metadata 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)", "failure 0.1.5 (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)", "wait-timeout 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -128,6 +130,11 @@ name = "itoa" version = "0.4.2" 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" @@ -138,6 +145,19 @@ name = "libc" version = "0.2.42" 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 = "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" @@ -321,8 +341,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "07e791d3be96241c77c43846b665ef1384606da2cd2a48730abe606a12906e02" "checksum failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "795bd83d3abeb9220f257e597aa0080a508b27533824adf336529648f6abf7e2" "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 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" diff --git a/Cargo.toml b/Cargo.toml index 2f9d9bc..ded8653 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,6 +13,8 @@ rayon = "1.0" toml = "0.5.0" wait-timeout = "0.2" xmas-elf = "0.6.2" +llvm-tools = "0.1.1" +locate-cargo-manifest = "0.1.0" [dependencies.cargo_metadata] version = "0.7.4" diff --git a/src/args.rs b/src/args.rs index c9e8314..e4c0041 100644 --- a/src/args.rs +++ b/src/args.rs @@ -1,6 +1,6 @@ +use crate::{config::Config, Command}; use std::path::{Path, PathBuf}; use std::{env, mem}; -use crate::Command; pub(crate) fn parse_args() -> Command { let mut args = env::args().skip(1); @@ -184,4 +184,13 @@ 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()); + } + } + } } diff --git a/src/build.rs b/src/build.rs deleted file mode 100644 index 68560aa..0000000 --- a/src/build.rs +++ /dev/null @@ -1,459 +0,0 @@ -use crate::args::{self, Args}; -use byteorder::{ByteOrder, LittleEndian}; -use cargo_metadata::{self, Metadata as CargoMetadata}; -use crate::config::{self, Config}; -use failure::{self, Error, ResultExt}; -use std::fs::File; -use std::io::Write; -use std::path::{Path, PathBuf}; -use std::{fmt, io, process}; -use xmas_elf; - -const BLOCK_SIZE: usize = 512; -type KernelInfoBlock = [u8; BLOCK_SIZE]; - -pub(crate) fn build(args: Args) -> Result<(), Error> { - let (args, config, metadata, root_dir, out_dir) = common_setup(args)?; - - build_impl(&args, &config, &metadata, &root_dir, &out_dir, true)?; - Ok(()) -} - -pub(crate) fn run(args: Args) -> Result<(), Error> { - let (args, config, metadata, root_dir, out_dir) = common_setup(args)?; - - let output_path = build_impl(&args, &config, &metadata, &root_dir, &out_dir, true)?; - run_impl(&args, &config, &output_path) -} - -pub(crate) fn common_setup( - mut args: Args, -) -> Result<(Args, Config, CargoMetadata, PathBuf, PathBuf), Error> { - fn out_dir(args: &Args, metadata: &CargoMetadata) -> PathBuf { - let target_dir = PathBuf::from(&metadata.target_directory); - let mut out_dir = target_dir; - if let &Some(ref target) = args.target() { - out_dir.push(Path::new(target).file_stem().unwrap().to_str().unwrap()); - } - if args.release() { - out_dir.push("release"); - } else { - out_dir.push("debug"); - } - out_dir - } - - let metadata = read_cargo_metadata(&args)?; - let manifest_path = args - .manifest_path() - .as_ref() - .map(Clone::clone) - .unwrap_or(Path::new("Cargo.toml").canonicalize().unwrap()); - let crate_root = manifest_path.parent().unwrap().to_path_buf(); - let config = config::read_config(manifest_path)?; - - if args.target().is_none() { - if let Some(ref target) = config.default_target { - let mut canonicalized_target = crate_root.clone(); - canonicalized_target.push(target); - args.set_target(canonicalized_target.to_string_lossy().into_owned()); - } - } - - if let &Some(ref target) = args.target() { - if !target.ends_with(".json") { - use std::io::{self, Write}; - use std::process; - - writeln!( - io::stderr(), - "Please pass a path to `--target` (with `.json` extension`): `--target {}.json`", - target - ) - .unwrap(); - process::exit(1); - } - } - - let out_dir = out_dir(&args, &metadata); - - Ok((args, config, metadata, crate_root, out_dir)) -} - -pub(crate) fn build_impl( - args: &Args, - config: &Config, - metadata: &CargoMetadata, - root_dir: &Path, - out_dir: &Path, - verbose: bool, -) -> Result { - let crate_ = metadata - .packages - .iter() - .find(|p| { - Path::new(&p.manifest_path) - .canonicalize() - .map(|path| path == config.manifest_path) - .unwrap_or(false) - }) - .expect("Could not read crate name from cargo metadata"); - let bin_name: String = args.bin_name().as_ref().unwrap_or(&crate_.name).clone(); - - let kernel = build_kernel(&out_dir, &bin_name, &args, verbose)?; - - let maybe_package = if let Some(ref path) = config.package_filepath { - Some( - File::open(path) - .with_context(|e| format!("Unable to open specified package file: {}", e))?, - ) - } else { - None - }; - - let maybe_package_size = if let Some(ref file) = maybe_package { - Some( - file.metadata() - .with_context(|e| format!("Failed to read specified package file: {}", e))? - .len(), - ) - } else { - None - }; - - let kernel_size = kernel - .metadata() - .with_context(|e| format!("Failed to read kernel output file: {}", e))? - .len(); - let kernel_info_block = create_kernel_info_block(kernel_size, maybe_package_size); - - let bootloader = build_bootloader(&metadata, &config) - .with_context(|e| format!("Failed to build bootloader: {}", e))?; - - create_disk_image( - root_dir, - out_dir, - &bin_name, - &config, - kernel, - maybe_package, - kernel_info_block, - &bootloader, - verbose, - ) -} - -fn run_impl(args: &Args, config: &Config, output_path: &Path) -> Result<(), Error> { - let command = &config.run_command[0]; - let mut command = process::Command::new(command); - for arg in &config.run_command[1..] { - command.arg(arg.replace( - "{}", - output_path.to_str().expect("output must be valid unicode"), - )); - } - command.args(&args.run_args); - command - .status() - .with_context(|e| format!("Failed to execute run `{:?}`: {}", command, e))?; - Ok(()) -} - -#[derive(Debug)] -pub struct CargoMetadataError { - error: String, -} - -impl fmt::Display for CargoMetadataError { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{}", self.error) - } -} - -impl failure::Fail for CargoMetadataError {} - -fn read_cargo_metadata(args: &Args) -> Result { - run_cargo_fetch(args); - let metadata = { - let mut cmd = cargo_metadata::MetadataCommand::new(); - if let Some(ref path) = args.manifest_path() { - cmd.manifest_path(path.as_path()); - } - cmd.exec().map_err(|e| CargoMetadataError { - error: format!("{}", e), - })? - }; - Ok(metadata) -} - -fn build_kernel( - out_dir: &Path, - bin_name: &str, - args: &args::Args, - verbose: bool, -) -> Result { - // compile kernel - if verbose { - println!("Building kernel"); - } - let exit_status = run_xbuild(&args.cargo_args) - .with_context(|e| format!("Failed to run `cargo xbuild`: {}", e))?; - if !exit_status.success() { - process::exit(1) - } - - let mut kernel_path = out_dir.to_owned(); - kernel_path.push(bin_name); - let kernel = File::open(kernel_path) - .with_context(|e| format!("Failed to open kernel output file: {}", e))?; - Ok(kernel) -} - -fn run_xbuild(args: &[String]) -> io::Result { - let mut command = process::Command::new("cargo"); - command.arg("xbuild"); - command.args(args); - let exit_status = command.status()?; - - if !exit_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() { - let mut stderr = io::stderr(); - writeln!( - stderr, - "Failed to run `cargo xbuild`. Perhaps it is not installed?" - )?; - writeln!(stderr, "Run `cargo install cargo-xbuild` to install it.")?; - } - } - } - - Ok(exit_status) -} - -fn run_cargo_fetch(args: &Args) { - let mut command = process::Command::new("cargo"); - command.arg("fetch"); - if let Some(manifest_path) = args.manifest_path() { - command.arg("--manifest-path"); - command.arg(manifest_path); - } - if !command.status().map(|s| s.success()).unwrap_or(false) { - process::exit(1); - } -} - -fn create_kernel_info_block(kernel_size: u64, maybe_package_size: Option) -> KernelInfoBlock { - let kernel_size = if kernel_size <= u64::from(u32::max_value()) { - kernel_size as u32 - } else { - panic!("Kernel can't be loaded by BIOS bootloader because is too big") - }; - - let package_size = if let Some(size) = maybe_package_size { - if size <= u64::from(u32::max_value()) { - size as u32 - } else { - panic!("Package can't be loaded by BIOS bootloader because is too big") - } - } else { - 0 - }; - - let mut kernel_info_block = [0u8; BLOCK_SIZE]; - LittleEndian::write_u32(&mut kernel_info_block[0..4], kernel_size); - LittleEndian::write_u32(&mut kernel_info_block[8..12], package_size); - - kernel_info_block -} - -fn build_bootloader(metadata: &CargoMetadata, config: &Config) -> Result, Error> { - use std::io::Read; - - let bootloader_metadata = metadata.packages.iter().find(|p| { - if let Some(name) = config.bootloader.name.as_ref() { - p.name == name.as_str() - } else { - p.name == "bootloader" || p.name == "bootloader_precompiled" - } - }); - let bootloader_metadata = - match bootloader_metadata { - Some(package_metadata) => package_metadata.clone(), - None => Err(format_err!("Bootloader dependency not found\n\n\ - You need to add a dependency on the `bootloader` or `bootloader_precompiled` crates \ - in your Cargo.toml.\n\nIn case you just updated bootimage from an earlier version, \ - check out the migration guide at https://github.com/rust-osdev/bootimage/pull/16. \ - Alternatively, you can downgrade to bootimage 0.4 again by executing \ - `cargo install bootimage --version {} --force`.", r#""^0.4""# - ))?, - }; - - let bootloader_manifest_path = Path::new(&bootloader_metadata.manifest_path); - let bootloader_dir = bootloader_manifest_path.parent().unwrap(); - - let mut bootloader_target_path = PathBuf::from(bootloader_dir); - bootloader_target_path.push(&config.bootloader.target); - - let bootloader_elf_path = if bootloader_metadata.name == "bootloader_precompiled" { - let mut bootloader_elf_path = bootloader_dir.to_path_buf(); - bootloader_elf_path.push("bootloader"); - bootloader_elf_path - } else { - let mut args = vec![ - String::from("--manifest-path"), - bootloader_metadata - .manifest_path - .as_os_str() - .to_os_string() - .into_string() - .expect("manifest path not valid unicode"), - String::from("--target"), - bootloader_target_path.display().to_string(), - String::from("--release"), - String::from("--features"), - config - .bootloader - .features - .iter() - .fold(String::new(), |i, j| i + " " + j), - ]; - - if !config.bootloader.default_features { - args.push(String::from("--no-default-features")); - } - - println!("Building bootloader v{}", bootloader_metadata.version); - let exit_status = - run_xbuild(&args).with_context(|e| format!("Failed to run `cargo xbuild`: {}", e))?; - if !exit_status.success() { - process::exit(1) - } - - let bootloader_metadata = { - let mut cmd = cargo_metadata::MetadataCommand::new(); - cmd.manifest_path(&bootloader_manifest_path); - cmd.no_deps(); - cmd.exec().map_err(|e| CargoMetadataError { - error: format!("{}", e), - })? - }; - let mut bootloader_elf_path = PathBuf::from(bootloader_metadata.target_directory); - bootloader_elf_path.push(config.bootloader.target.file_stem().unwrap()); - bootloader_elf_path.push("release"); - bootloader_elf_path.push("bootloader"); - bootloader_elf_path - }; - - let mut bootloader_elf_bytes = Vec::new(); - let mut bootloader = File::open(&bootloader_elf_path) - .with_context(|e| format!("Could not open bootloader: {}", e))?; - bootloader - .read_to_end(&mut bootloader_elf_bytes) - .with_context(|e| format!("Could not read bootloader: {}", e))?; - - // copy bootloader section of ELF file to bootloader_path - let elf_file = xmas_elf::ElfFile::new(&bootloader_elf_bytes).unwrap(); - xmas_elf::header::sanity_check(&elf_file).unwrap(); - let bootloader_section = elf_file - .find_section_by_name(".bootloader") - .expect("bootloader must have a .bootloader section"); - - Ok(Vec::from(bootloader_section.raw_data(&elf_file)).into_boxed_slice()) -} - -fn create_disk_image( - root_dir: &Path, - out_dir: &Path, - bin_name: &str, - config: &Config, - mut kernel: File, - mut maybe_package: Option, - kernel_info_block: KernelInfoBlock, - bootloader_data: &[u8], - verbose: bool, -) -> Result { - use std::io::{Read, Write}; - - let mut output_path = PathBuf::from(out_dir); - let file_name = format!("bootimage-{}.bin", bin_name); - output_path.push(file_name); - - if let Some(ref output) = config.output { - output_path = output.clone(); - } - - if verbose { - println!( - "Creating disk image at {}", - output_path - .strip_prefix(root_dir) - .unwrap_or(output_path.as_path()) - .display() - ); - } - let mut output = File::create(&output_path) - .with_context(|e| format!("Could not create output bootimage file: {}", e))?; - output - .write_all(&bootloader_data) - .with_context(|e| format!("Could not write output bootimage file: {}", e))?; - output - .write_all(&kernel_info_block) - .with_context(|e| format!("Could not write output bootimage file: {}", e))?; - - fn write_file_to_file(output: &mut File, datafile: &mut File) -> Result { - let data_size = datafile.metadata()?.len(); - let mut buffer = [0u8; 1024]; - let mut acc = 0; - loop { - let (n, interrupted) = match datafile.read(&mut buffer) { - Ok(0) => break, - Ok(n) => (n, false), - Err(ref e) if e.kind() == io::ErrorKind::Interrupted => (0, true), - Err(e) => Err(e)?, - }; - if !interrupted { - acc += n; - output.write_all(&buffer[..n])? - } - } - - assert!(data_size == acc as u64); - - Ok(acc) - } - - fn pad_file(output: &mut File, written_size: usize, padding: &[u8]) -> Result<(), Error> { - let padding_size = (padding.len() - (written_size % padding.len())) % padding.len(); - output - .write_all(&padding[..padding_size]) - .with_context(|e| format!("Could not write to output file: {}", e))?; - Ok(()) - } - - // write out kernel elf file - - let kernel_size = write_file_to_file(&mut output, &mut kernel)?; - - pad_file(&mut output, kernel_size, &[0; 512])?; - - if let Some(ref mut package) = maybe_package { - println!("Writing specified package to output"); - let package_size = write_file_to_file(&mut output, package)?; - pad_file(&mut output, package_size, &[0; 512])?; - } - - if let Some(min_size) = config.minimum_image_size { - // we already wrote to output successfully, - // both metadata and set_len should succeed. - if output.metadata()?.len() < min_size { - output.set_len(min_size)?; - } - } - - Ok(output_path) -} diff --git a/src/config.rs b/src/config.rs index fad966a..24ca282 100644 --- a/src/config.rs +++ b/src/config.rs @@ -1,3 +1,4 @@ +use crate::ErrorString; use failure::{Error, ResultExt}; use std::path::PathBuf; use toml::Value; @@ -6,11 +7,11 @@ use toml::Value; pub struct Config { pub manifest_path: PathBuf, pub default_target: Option, - pub output: Option, - pub bootloader: BootloaderConfig, - pub minimum_image_size: Option, + pub output: Option, // remove + pub bootloader: BootloaderConfig, // remove + pub minimum_image_size: Option, // remove pub run_command: Vec, - pub package_filepath: Option, + pub package_filepath: Option, // remove } #[derive(Debug, Clone)] @@ -21,7 +22,13 @@ pub struct BootloaderConfig { pub features: Vec, } -pub(crate) fn read_config(manifest_path: PathBuf) -> Result { +pub(crate) fn read_config(manifest_path: PathBuf) -> Result { + let config = read_config_inner(manifest_path) + .map_err(|err| format!("Failed to read bootimage configuration: {:?}", err))?; + Ok(config) +} + +pub(crate) fn read_config_inner(manifest_path: PathBuf) -> Result { use std::{fs::File, io::Read}; let cargo_toml: Value = { let mut content = String::new(); diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..73876cd --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,434 @@ +use std::{ + fmt, fs, io, + path::{Path, PathBuf}, + process::{self, Command}, +}; + +pub struct Builder { + kernel_manifest_path: PathBuf, + kernel_metadata: cargo_metadata::Metadata, +} + +impl Builder { + 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, + }) + } + + pub fn kernel_manifest_path(&self) -> &Path { + &self.kernel_manifest_path + } + + pub fn kernel_root(&self) -> &Path { + self.kernel_manifest_path + .parent() + .expect("kernel manifest has no parent directory") + } + + pub fn kernel_metadata(&self) -> &cargo_metadata::Metadata { + &self.kernel_metadata + } + + 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() + )) + } + + 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, + }); + } + + Ok(()) + } + + 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_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), + })?; + bootloader_resolve.features.clone() + }; + let bootloader_target_triple = + default_target_triple_from_cargo_config(&bootloader_root, false) + .map_err(CreateBootimageError::BootloaderInvalid)? + .ok_or(CreateBootimageError::BootloaderInvalid(format!( + "bootloader must have a default target" + )))?; + + // build bootloader + if !quiet { + println!("Building bootloader"); + } + + let cargo = std::env::var("CARGO").unwrap_or("cargo".to_owned()); + let mut cmd = process::Command::new(cargo); + cmd.arg("xbuild"); + cmd.arg("--manifest-path"); + cmd.arg(&bootloader_pkg.manifest_path); + cmd.arg("--target-dir").arg(&target_dir); + cmd.arg("--features") + .arg(bootloader_features.as_slice().join(" ")); + cmd.arg("--release"); + cmd.current_dir(bootloader_root); + cmd.env("KERNEL", kernel_bin_path); + cmd.env_remove("RUSTFLAGS"); + 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, + }); + } + + let bootloader_elf_path = target_dir + .join(&bootloader_target_triple) + .join("release") + .join(&bootloader_name); + + 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, + }); + } + + Ok(()) + } +} + +pub fn default_target_triple_from_cargo_config( + crate_root: &Path, + walk_up: bool, +) -> Result, String> { + let default_triple = default_target_from_cargo_config(crate_root, walk_up)?; + default_triple + .map(|(target, crate_root)| { + if target.ends_with(".json") { + crate_root + .join(target) + .file_stem() + .ok_or(String::from( + "The target path specfied in `build.target` has no file stem", + ))? + .to_os_string() + .into_string() + .map_err(|err| format!("Default target triple not valid UTF-8: {:?}", err)) + } else { + Ok(target) + } + }) + .transpose() +} + +fn default_target_from_cargo_config( + crate_root: &Path, + walk_up: bool, +) -> Result, String> { + let mut parent_dir = crate_root; + + loop { + let config_path = parent_dir.join(".cargo/config"); + if config_path.exists() { + let config_content = fs::read_to_string(config_path).map_err(|err| { + format!("Failed to read `.cargo/config` file of crate: {:?}", err) + })?; + let config = config_content.parse::().map_err(|err| { + format!( + "Failed to parse `.cargo/config` of crate as toml: {:?}", + err + ) + })?; + let target = config + .get("build") + .and_then(|v| v.get("target")) + .and_then(|v| v.as_str()) + .map(String::from); + if let Some(target) = target { + return Ok(Some((target, parent_dir.to_owned()))); + } + } + if walk_up { + parent_dir = match parent_dir.parent() { + Some(parent) => parent, + None => break, + } + } else { + break; + } + } + Ok(None) +} + +#[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 + ), + } + } +} + +#[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, + }, + XbuildNotFound, + XbuildFailed { + stderr: Vec, + }, + CargoConfigInvalid { + path: PathBuf, + error: String, + }, +} + +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: {}: {}", 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: {}", String::from_utf8_lossy(stderr)) + } + BuildKernelError::CargoConfigInvalid{path,error} => { + writeln!(f, "Failed to read cargo config at {}: {}", path.display(), error) + }, + } + } +} + +#[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), + BootloaderBuildFailed { + 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 { + stderr: Vec, + }, +} + +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:\n\n{}", + String::from_utf8_lossy(stderr) + ), + 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) + ), + } + } +} + +// 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/main.rs b/src/main.rs index 2f3c49c..70dd72f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,13 +2,13 @@ extern crate failure; use args::Args; -use std::{io, process}; +use std::{fmt, process}; mod args; -mod build; mod config; mod help; -mod test; + +mod subcommand; enum Command { NoSubcommand, @@ -23,20 +23,19 @@ enum Command { } pub fn main() { - use std::io::Write; if let Err(err) = run() { - writeln!(io::stderr(), "Error: {}", err).unwrap(); + eprintln!("Error: {}", err.display()); process::exit(1); } } -fn run() -> Result<(), failure::Error> { +fn run() -> Result<(), ErrorString> { let command = args::parse_args(); match command { + Command::Build(args) => subcommand::build::build(args), + Command::Run(args) => subcommand::run::run(args), + Command::Test(args) => subcommand::test::test(args), Command::NoSubcommand => help::no_subcommand(), - Command::Build(args) => build::build(args), - Command::Run(args) => build::run(args), - Command::Test(args) => test::test(args), Command::Help => Ok(help::help()), Command::BuildHelp => Ok(help::build_help()), Command::RunHelp => Ok(help::run_help()), @@ -44,3 +43,26 @@ fn run() -> Result<(), failure::Error> { Command::Version => Ok(println!("bootimage {}", env!("CARGO_PKG_VERSION"))), } } + +struct ErrorString(Box); + +impl ErrorString { + fn display(&self) -> &dyn fmt::Display { + &self.0 + } +} + +impl fmt::Debug for ErrorString { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + self.display().fmt(f) + } +} + +impl From for ErrorString +where + T: fmt::Display + 'static, +{ + fn from(err: T) -> Self { + ErrorString(Box::new(err)) + } +} diff --git a/src/subcommand.rs b/src/subcommand.rs new file mode 100644 index 0000000..34bfd46 --- /dev/null +++ b/src/subcommand.rs @@ -0,0 +1,3 @@ +pub mod build; +pub mod run; +pub mod test; diff --git a/src/subcommand/build.rs b/src/subcommand/build.rs new file mode 100644 index 0000000..014e069 --- /dev/null +++ b/src/subcommand/build.rs @@ -0,0 +1,67 @@ +use crate::{args::Args, config, ErrorString}; +use bootimage::Builder; +use std::{ + path::{Path, PathBuf}, + process, +}; + +pub(crate) fn build(mut args: Args) -> Result<(), ErrorString> { + let builder = bootimage::Builder::new(args.manifest_path().clone())?; + let config = config::read_config(builder.kernel_manifest_path().to_owned())?; + args.apply_default_target(&config, builder.kernel_root()); + + build_impl(&builder, &mut args, false).map(|_| ()) +} + +pub(crate) fn build_impl( + builder: &Builder, + args: &Args, + quiet: bool, +) -> Result { + run_cargo_fetch(&args); + + builder.build_kernel(&args.cargo_args, quiet)?; + + let out_dir = out_dir(&args, &builder)?; + let kernel_package = builder + .kernel_package() + .map_err(|key| format!("Kernel package not found in cargo metadata (`{}`)", key))?; + let kernel_bin_name = args.bin_name().as_ref().unwrap_or(&kernel_package.name); + let kernel_path = out_dir.join(kernel_bin_name); + + let bootimage_path = out_dir.join(format!("bootimage-{}.bin", kernel_bin_name)); + builder.create_bootimage(&kernel_path, &bootimage_path, quiet)?; + Ok(bootimage_path) +} + +fn out_dir(args: &Args, builder: &bootimage::Builder) -> Result { + let target_dir = PathBuf::from(&builder.kernel_metadata().target_directory); + let mut out_dir = target_dir; + if let &Some(ref target) = args.target() { + out_dir.push(Path::new(target).file_stem().unwrap().to_str().unwrap()); + } else { + let default_triple = + bootimage::default_target_triple_from_cargo_config(builder.kernel_root(), true)?; + if let Some(triple) = default_triple { + out_dir.push(triple); + } + } + if args.release() { + out_dir.push("release"); + } else { + out_dir.push("debug"); + } + Ok(out_dir) +} + +fn run_cargo_fetch(args: &Args) { + let mut command = process::Command::new("cargo"); + command.arg("fetch"); + if let Some(manifest_path) = args.manifest_path() { + command.arg("--manifest-path"); + command.arg(manifest_path); + } + if !command.status().map(|s| s.success()).unwrap_or(false) { + process::exit(1); + } +} diff --git a/src/subcommand/run.rs b/src/subcommand/run.rs new file mode 100644 index 0000000..0804275 --- /dev/null +++ b/src/subcommand/run.rs @@ -0,0 +1,33 @@ +use crate::{args::Args, config, ErrorString}; +use std::process; + +pub(crate) fn run(mut args: Args) -> Result<(), ErrorString> { + use crate::subcommand::build; + + let builder = bootimage::Builder::new(args.manifest_path().clone())?; + let config = config::read_config(builder.kernel_manifest_path().to_owned())?; + args.apply_default_target(&config, builder.kernel_root()); + + let bootimage_path = build::build_impl(&builder, &mut args, false)?; + + 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(ErrorString::from("bootimage path is not valid unicode"))?, + ), + ); + } + command.args(&args.run_args); + command.status().map_err(|err| { + ErrorString::from(format!( + "Failed to execute run command `{:?}`: {}", + command, err + )) + })?; + Ok(()) +} diff --git a/src/test.rs b/src/subcommand/test.rs similarity index 85% rename from src/test.rs rename to src/subcommand/test.rs index 8ff8dac..bd51062 100644 --- a/src/test.rs +++ b/src/subcommand/test.rs @@ -1,34 +1,25 @@ use crate::args::Args; -use crate::build; +use crate::config; +use crate::subcommand::build; use failure::{Error, ResultExt}; use rayon::prelude::*; use std::io::Write; -use std::path::{Path, PathBuf}; +use std::path::PathBuf; use std::time::Duration; use std::{fs, io, process}; use wait_timeout::ChildExt; -pub(crate) fn test(args: Args) -> Result<(), Error> { - let (args, config, metadata, root_dir, out_dir) = build::common_setup(args)?; +pub(crate) fn test(mut args: Args) -> Result<(), crate::ErrorString> { + let builder = bootimage::Builder::new(args.manifest_path().clone())?; + let config = config::read_config(builder.kernel_manifest_path().to_owned())?; + args.apply_default_target(&config, builder.kernel_root()); let test_args = args.clone(); - let test_config = { - let mut test_config = config.clone(); - test_config.output = None; - test_config - }; - - let test_targets = metadata - .packages - .iter() - .find(|p| { - Path::new(&p.manifest_path) - .canonicalize() - .map(|path| path == config.manifest_path) - .unwrap_or(false) - }) - .expect("Could not read crate name from cargo metadata") + let kernel_package = builder + .kernel_package() + .map_err(|key| format!("Kernel package not found it cargo metadata (`{}`)", key))?; + let test_targets = kernel_package .targets .iter() .filter(|t| t.kind == ["bin"] && t.name.starts_with("test-")) @@ -37,18 +28,11 @@ pub(crate) fn test(args: Args) -> Result<(), Error> { let mut target_args = test_args.clone(); target_args.set_bin_name(target.name.clone()); - let test_path = build::build_impl( - &target_args, - &test_config, - &metadata, - &root_dir, - &out_dir, - false, - ) - .expect(&format!("Failed to build test: {}", target.name)); + let test_bin_path = build::build_impl(&builder, &mut target_args, true) + .expect(&format!("Failed to build test: {}", target.name)); println!(""); - (target, test_path) + (target, test_bin_path) }) .collect::>(); From 89e9c50384a331da2f9f47bc3958c5a3d317bdfd Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Wed, 27 Mar 2019 09:49:44 +0100 Subject: [PATCH 071/271] Remove various config options --- src/config.rs | 124 -------------------------------------------------- 1 file changed, 124 deletions(-) diff --git a/src/config.rs b/src/config.rs index 24ca282..2c77154 100644 --- a/src/config.rs +++ b/src/config.rs @@ -7,19 +7,7 @@ use toml::Value; pub struct Config { pub manifest_path: PathBuf, pub default_target: Option, - pub output: Option, // remove - pub bootloader: BootloaderConfig, // remove - pub minimum_image_size: Option, // remove pub run_command: Vec, - pub package_filepath: Option, // remove -} - -#[derive(Debug, Clone)] -pub struct BootloaderConfig { - pub name: Option, - pub target: PathBuf, - pub default_features: bool, - pub features: Vec, } pub(crate) fn read_config(manifest_path: PathBuf) -> Result { @@ -78,94 +66,14 @@ pub(crate) fn read_config_inner(manifest_path: PathBuf) -> Result )); } - let bootloader_dependency = cargo_toml - .get("dependencies") - .and_then(|table| table.get("bootloader")); - let bootloader_default_features = - match bootloader_dependency.and_then(|table| table.get("default-features")) { - None => None, - Some(Value::Boolean(default_features)) => Some(*default_features), - Some(_) => { - return Err(format_err!( - "Bootloader 'default-features' field should be a bool!" - )); - } - }; - - let bootloader_features = match cargo_toml - .get("dependencies") - .and_then(|table| table.get("bootloader")) - .and_then(|table| table.get("features")) - { - None => None, - Some(Value::Array(array)) => { - let mut features = Vec::new(); - - for feature_string in array { - match feature_string { - Value::String(feature) => features.push(feature.clone()), - _ => return Err(format_err!("Bootloader features are malformed!")), - } - } - - Some(features) - } - Some(_) => return Err(format_err!("Bootloader features are malformed!")), - }; - let mut config = ConfigBuilder { manifest_path: Some(manifest_path), - bootloader: BootloaderConfigBuilder { - features: bootloader_features, - default_features: bootloader_default_features, - ..Default::default() - }, ..Default::default() }; for (key, value) in metadata { match (key.as_str(), value.clone()) { ("default-target", Value::String(s)) => config.default_target = From::from(s), - ("output", Value::String(s)) => config.output = Some(PathBuf::from(s)), - ("bootloader", Value::Table(t)) => { - for (key, value) in t { - match (key.as_str(), value) { - ("name", Value::String(s)) => config.bootloader.name = From::from(s), - ("target", Value::String(s)) => { - config.bootloader.target = Some(PathBuf::from(s)) - } - (k @ "precompiled", _) - | (k @ "version", _) - | (k @ "git", _) - | (k @ "branch", _) - | (k @ "path", _) => Err(format_err!( - "the \ - `package.metadata.bootimage.bootloader` key `{}` was deprecated\n\n\ - In case you just updated bootimage from an earlier version, \ - check out the migration guide at \ - https://github.com/rust-osdev/bootimage/pull/16.", - k - ))?, - (key, value) => Err(format_err!( - "unexpected \ - `package.metadata.bootimage.bootloader` key `{}` with value `{}`", - key, - value - ))?, - } - } - } - ("minimum-image-size", Value::Integer(x)) => { - if x >= 0 { - config.minimum_image_size = Some((x * 1024 * 1024) as u64); // MiB -> Byte - } else { - Err(format_err!( - "unexpected `package.metadata.bootimage` \ - key `minimum-image-size` with negative value `{}`", - value - ))? - } - } ("run-command", Value::Array(array)) => { let mut command = Vec::new(); for value in array { @@ -176,9 +84,6 @@ pub(crate) fn read_config_inner(manifest_path: PathBuf) -> Result } config.run_command = Some(command); } - ("package-file", Value::String(path)) => { - config.package_filepath = Some(PathBuf::from(path)); - } (key, value) => Err(format_err!( "unexpected `package.metadata.bootimage` \ key `{}` with value `{}`", @@ -194,19 +99,7 @@ pub(crate) fn read_config_inner(manifest_path: PathBuf) -> Result struct ConfigBuilder { manifest_path: Option, default_target: Option, - output: Option, - bootloader: BootloaderConfigBuilder, - minimum_image_size: Option, run_command: Option>, - package_filepath: Option, -} - -#[derive(Default)] -struct BootloaderConfigBuilder { - name: Option, - target: Option, - features: Option>, - default_features: Option, } impl Into for ConfigBuilder { @@ -214,28 +107,11 @@ impl Into for ConfigBuilder { Config { manifest_path: self.manifest_path.expect("manifest path must be set"), default_target: self.default_target, - output: self.output, - bootloader: self.bootloader.into(), - minimum_image_size: self.minimum_image_size, run_command: self.run_command.unwrap_or(vec![ "qemu-system-x86_64".into(), "-drive".into(), "format=raw,file={}".into(), ]), - package_filepath: self.package_filepath, - } - } -} - -impl Into for BootloaderConfigBuilder { - fn into(self) -> BootloaderConfig { - BootloaderConfig { - name: self.name, - target: self - .target - .unwrap_or(PathBuf::from("x86_64-bootloader.json")), - features: self.features.unwrap_or(Vec::with_capacity(0)), - default_features: self.default_features.unwrap_or(true), } } } From a1745f84838a6772d4beea3539a75e7529bf0cd1 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Wed, 27 Mar 2019 10:01:43 +0100 Subject: [PATCH 072/271] Remove the dependency on failure --- Cargo.lock | 67 ------------------------------------------ Cargo.toml | 5 ---- src/config.rs | 34 +++++---------------- src/main.rs | 7 ++--- src/subcommand/test.rs | 28 +++++++----------- 5 files changed, 20 insertions(+), 121 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6b27efa..94a0846 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8,34 +8,12 @@ dependencies = [ "nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "backtrace" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "backtrace-sys 0.1.23 (registry+https://github.com/rust-lang/crates.io-index)", - "cfg-if 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-demangle 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "backtrace-sys" -version = "0.1.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "cc 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "bootimage" version = "0.6.6" dependencies = [ "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "cargo_metadata 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)", - "failure 0.1.5 (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)", @@ -61,11 +39,6 @@ dependencies = [ "serde_json 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "cc" -version = "1.0.18" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "cfg-if" version = "0.1.4" @@ -117,14 +90,6 @@ name = "error-chain" version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "failure" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "backtrace 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "itoa" version = "0.4.2" @@ -213,11 +178,6 @@ dependencies = [ "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "rustc-demangle" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "scopeguard" version = "0.3.3" @@ -293,25 +253,6 @@ dependencies = [ "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "winapi" -version = "0.3.5" -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 = "xmas-elf" version = "0.6.2" @@ -327,11 +268,8 @@ source = "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 backtrace 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "89a47830402e9981c5c41223151efcced65a0510c13097c769cede7efb34782a" -"checksum backtrace-sys 0.1.23 (registry+https://github.com/rust-lang/crates.io-index)" = "bff67d0c06556c0b8e6b5f090f0eac52d950d9dfd1d35ba04e4ca3543eaf6a7e" "checksum byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a019b10a2a7cdeb292db131fc8113e57ea2a908f6e7894b0c3c671893b65dbeb" "checksum cargo_metadata 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)" = "178d62b240c34223f265a4c1e275e37d62da163d421fc8d7f7e3ee340f803c57" -"checksum cc 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)" = "2119ea4867bd2b8ed3aecab467709720b2d55b1bcfe09f772fd68066eaf15275" "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" @@ -339,7 +277,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "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 failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "795bd83d3abeb9220f257e597aa0080a508b27533824adf336529648f6abf7e2" "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" @@ -353,7 +290,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "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 rustc-demangle 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "bcfe5b13211b4d78e5c2cadfebd7769197d95c639c35a50057eb4c05de811395" "checksum scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27" "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" @@ -364,8 +300,5 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "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 wait-timeout 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9f200f5b12eb75f8c1ed65abd4b2db8a6e1b138a20de009dacee265a2498f3f6" -"checksum winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "773ef9dcc5f24b7d850d0ff101e542ff24c3b090a9768e03ff889fdef41f00fd" -"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 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/Cargo.toml b/Cargo.toml index ded8653..4bd9804 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,8 +19,3 @@ locate-cargo-manifest = "0.1.0" [dependencies.cargo_metadata] version = "0.7.4" default-features = false - -[dependencies.failure] -version = "0.1.5" -default-features = false -features = ["std"] diff --git a/src/config.rs b/src/config.rs index 2c77154..5acd6e0 100644 --- a/src/config.rs +++ b/src/config.rs @@ -1,5 +1,4 @@ use crate::ErrorString; -use failure::{Error, ResultExt}; use std::path::PathBuf; use toml::Value; @@ -16,17 +15,17 @@ pub(crate) fn read_config(manifest_path: PathBuf) -> Result Ok(config) } -pub(crate) fn read_config_inner(manifest_path: PathBuf) -> Result { +pub(crate) fn read_config_inner(manifest_path: PathBuf) -> Result { use std::{fs::File, io::Read}; let cargo_toml: Value = { let mut content = String::new(); File::open(&manifest_path) - .with_context(|e| format!("Failed to open Cargo.toml: {}", e))? + .map_err(|e| format!("Failed to open Cargo.toml: {}", e))? .read_to_string(&mut content) - .with_context(|e| format!("Failed to read Cargo.toml: {}", e))?; + .map_err(|e| format!("Failed to read Cargo.toml: {}", e))?; content .parse::() - .with_context(|e| format!("Failed to parse Cargo.toml: {}", e))? + .map_err(|e| format!("Failed to parse Cargo.toml: {}", e))? }; let metadata = cargo_toml @@ -41,31 +40,12 @@ pub(crate) fn read_config_inner(manifest_path: PathBuf) -> Result } .into()); } - Some(metadata) => metadata.as_table().ok_or(format_err!( + Some(metadata) => metadata.as_table().ok_or(format!( "Bootimage configuration invalid: {:?}", metadata ))?, }; - /* - * The user shouldn't specify any features if they're using a precompiled bootloader, as we - * don't actually compile it. - */ - if cargo_toml - .get("dependencies") - .and_then(|table| table.get("bootloader_precompiled")) - .and_then(|table| { - table - .get("features") - .or_else(|| table.get("default-features")) - }) - .is_some() - { - return Err(format_err!( - "Can't change features of precompiled bootloader!" - )); - } - let mut config = ConfigBuilder { manifest_path: Some(manifest_path), ..Default::default() @@ -79,12 +59,12 @@ pub(crate) fn read_config_inner(manifest_path: PathBuf) -> Result for value in array { match value { Value::String(s) => command.push(s), - _ => Err(format_err!("run-command must be a list of strings"))?, + _ => Err(format!("run-command must be a list of strings"))?, } } config.run_command = Some(command); } - (key, value) => Err(format_err!( + (key, value) => Err(format!( "unexpected `package.metadata.bootimage` \ key `{}` with value `{}`", key, diff --git a/src/main.rs b/src/main.rs index 70dd72f..2ec34de 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,6 +1,3 @@ -#[macro_use] -extern crate failure; - use args::Args; use std::{fmt, process}; @@ -44,7 +41,7 @@ fn run() -> Result<(), ErrorString> { } } -struct ErrorString(Box); +struct ErrorString(Box); impl ErrorString { fn display(&self) -> &dyn fmt::Display { @@ -60,7 +57,7 @@ impl fmt::Debug for ErrorString { impl From for ErrorString where - T: fmt::Display + 'static, + T: fmt::Display + Send + 'static, { fn from(err: T) -> Self { ErrorString(Box::new(err)) diff --git a/src/subcommand/test.rs b/src/subcommand/test.rs index bd51062..6dee868 100644 --- a/src/subcommand/test.rs +++ b/src/subcommand/test.rs @@ -1,15 +1,9 @@ -use crate::args::Args; -use crate::config; -use crate::subcommand::build; -use failure::{Error, ResultExt}; +use crate::{args::Args, config, subcommand::build, ErrorString}; +use std::{io::Write, path::PathBuf, time::Duration, fs, io, process}; use rayon::prelude::*; -use std::io::Write; -use std::path::PathBuf; -use std::time::Duration; -use std::{fs, io, process}; use wait_timeout::ChildExt; -pub(crate) fn test(mut args: Args) -> Result<(), crate::ErrorString> { +pub(crate) fn test(mut args: Args) -> Result<(), ErrorString> { let builder = bootimage::Builder::new(args.manifest_path().clone())?; let config = config::read_config(builder.kernel_manifest_path().to_owned())?; args.apply_default_target(&config, builder.kernel_root()); @@ -56,25 +50,25 @@ pub(crate) fn test(mut args: Args) -> Result<(), crate::ErrorString> { command.stderr(process::Stdio::null()); let mut child = command .spawn() - .with_context(|e| format_err!("Failed to launch QEMU: {:?}\n{}", command, e))?; + .map_err(|e| format!("Failed to launch QEMU: {:?}\n{}", command, e))?; let timeout = Duration::from_secs(60); match child .wait_timeout(timeout) - .with_context(|e| format!("Failed to wait with timeout: {}", e))? + .map_err(|e| format!("Failed to wait with timeout: {}", e))? { None => { child .kill() - .with_context(|e| format!("Failed to kill QEMU: {}", e))?; + .map_err(|e| format!("Failed to kill QEMU: {}", e))?; child .wait() - .with_context(|e| format!("Failed to wait for QEMU process: {}", e))?; + .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).with_context(|e| { - format_err!("Failed to read test output file {}: {}", output_file, e) + 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)?; } @@ -82,7 +76,7 @@ pub(crate) fn test(mut args: Args) -> Result<(), crate::ErrorString> { Ok((target.name.clone(), test_result)) }) - .collect::, Error>>()?; + .collect::, ErrorString>>()?; println!(""); if tests.iter().all(|t| t.1 == TestResult::Ok) { @@ -101,7 +95,7 @@ fn handle_exit_status( exit_status: process::ExitStatus, output: &str, target_name: &str, -) -> Result { +) -> Result { match exit_status.code() { None => { writeln!(io::stderr(), "FAIL: No Exit Code.")?; From 2e98cbeced380c293df6415d7067a0624080160c Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Wed, 27 Mar 2019 10:05:53 +0100 Subject: [PATCH 073/271] Update help and Readme --- Readme.md | 12 ++++-------- src/help/build_help.txt | 6 ------ 2 files changed, 4 insertions(+), 14 deletions(-) diff --git a/Readme.md b/Readme.md index 817eb30..0def8db 100644 --- a/Readme.md +++ b/Readme.md @@ -16,16 +16,18 @@ First you need to add a dependency on the `bootloader` crate: # in your Cargo.toml [dependencies] -bootloader = "0.2.0-alpha" +bootloader = "0.5.0" ``` +**Note**: At least bootloader version `0.5.0` is required. + 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] ``` -The command will invoke [`cargo xbuild`](https://github.com/rust-osdev/cargo-xbuild), forwarding all passed options. Then it will download and build a bootloader, by default the [rust-osdev/bootloader](https://github.com/rust-osdev/bootloader). Finally, it combines the kernel and the bootloader into a bootable disk image. +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. ## Configuration @@ -34,15 +36,9 @@ Configuration is done through a through a `[package.metadata.bootimage]` table i ```toml [package.metadata.bootimage] default-target = "" # This target is used if no `--target` is passed - output = "bootimage.bin" # The output file name - minimum-image-size = 0 # The minimum output file size (in MiB) # The command invoked on `bootimage run` # (the "{}" will be replaced with the path to the bootable disk image) run-command = ["qemu-system-x86_64", "-drive", "format=raw,file={}"] - - [package.metadata.bootimage.bootloader] - name = "bootloader" # The bootloader crate name - target = "x86_64-bootloader.json" # Target triple for compiling the bootloader ``` ## License diff --git a/src/help/build_help.txt b/src/help/build_help.txt index 5477d81..e92d588 100644 --- a/src/help/build_help.txt +++ b/src/help/build_help.txt @@ -18,9 +18,3 @@ CONFIGURATION: [package.metadata.bootimage] default-target = "" This target is used if no `--target` is passed - output = "bootimage.bin" The output file name - minimum-image-size = 0 The minimum output file size (in MiB) - - [package.metadata.bootimage.bootloader] - name = "bootloader" The bootloader crate name - target = "x86_64-bootloader.json" Target triple for compiling the bootloader From 935dacc2ee69934c66e8f1fe2c32a20e4c9230f1 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Wed, 27 Mar 2019 10:32:38 +0100 Subject: [PATCH 074/271] Add example kernels and azure pipelines CI script --- azure-pipelines.yml | 127 +++++++ example-kernels/basic/.gitignore | 2 + example-kernels/basic/Cargo.lock | 297 ++++++++++++++++ example-kernels/basic/Cargo.toml | 9 + example-kernels/basic/src/main.rs | 28 ++ example-kernels/basic/x86_64-basic.json | 15 + .../default-target-bootimage/.gitignore | 2 + .../default-target-bootimage/Cargo.lock | 328 ++++++++++++++++++ .../default-target-bootimage/Cargo.toml | 14 + .../default-target-bootimage/src/main.rs | 28 ++ .../x86_64-default-target.json | 15 + .../default-target-cargo/.cargo/config | 2 + .../default-target-cargo/.gitignore | 2 + .../default-target-cargo/Cargo.lock | 328 ++++++++++++++++++ .../default-target-cargo/Cargo.toml | 11 + .../default-target-cargo/src/main.rs | 28 ++ .../x86_64-default-target.json | 15 + example-kernels/rust-toolchain | 1 + example-kernels/testing/.gitignore | 2 + example-kernels/testing/Cargo.lock | 328 ++++++++++++++++++ example-kernels/testing/Cargo.toml | 14 + .../testing/src/bin/test-basic-boot.rs | 33 ++ example-kernels/testing/src/bin/test-panic.rs | 23 ++ example-kernels/testing/src/lib.rs | 58 ++++ example-kernels/testing/src/main.rs | 28 ++ example-kernels/testing/x86_64-testing.json | 15 + 26 files changed, 1753 insertions(+) create mode 100644 azure-pipelines.yml create mode 100644 example-kernels/basic/.gitignore create mode 100644 example-kernels/basic/Cargo.lock create mode 100644 example-kernels/basic/Cargo.toml create mode 100644 example-kernels/basic/src/main.rs create mode 100644 example-kernels/basic/x86_64-basic.json create mode 100644 example-kernels/default-target-bootimage/.gitignore create mode 100644 example-kernels/default-target-bootimage/Cargo.lock create mode 100644 example-kernels/default-target-bootimage/Cargo.toml create mode 100644 example-kernels/default-target-bootimage/src/main.rs create mode 100644 example-kernels/default-target-bootimage/x86_64-default-target.json create mode 100644 example-kernels/default-target-cargo/.cargo/config create mode 100644 example-kernels/default-target-cargo/.gitignore create mode 100644 example-kernels/default-target-cargo/Cargo.lock create mode 100644 example-kernels/default-target-cargo/Cargo.toml create mode 100644 example-kernels/default-target-cargo/src/main.rs create mode 100644 example-kernels/default-target-cargo/x86_64-default-target.json create mode 100644 example-kernels/rust-toolchain create mode 100644 example-kernels/testing/.gitignore create mode 100644 example-kernels/testing/Cargo.lock create mode 100644 example-kernels/testing/Cargo.toml create mode 100644 example-kernels/testing/src/bin/test-basic-boot.rs create mode 100644 example-kernels/testing/src/bin/test-panic.rs create mode 100644 example-kernels/testing/src/lib.rs create mode 100644 example-kernels/testing/src/main.rs create mode 100644 example-kernels/testing/x86_64-testing.json diff --git a/azure-pipelines.yml b/azure-pipelines.yml new file mode 100644 index 0000000..d1cab8e --- /dev/null +++ b/azure-pipelines.yml @@ -0,0 +1,127 @@ +# Documentation: https://aka.ms/yaml + +trigger: + batch: true + branches: + include: + # This is where pull requests from "bors r+" are built. + - staging + # This is where pull requests from "bors try" are built. + - trying + # Build pull requests. + - master + +strategy: + matrix: + linux: + image_name: 'ubuntu-16.04' + rustup_toolchain: stable + mac: + image_name: 'macos-10.13' + 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)' + +- script: curl -sSf -o rustup-init.exe https://win.rustup.rs && rustup-init.exe -y --default-toolchain %RUSTUP_TOOLCHAIN% + condition: eq( variables['Agent.OS'], 'Windows_NT' ) + displayName: 'Install Rust (Windows)' + +- script: | + echo ##vso[task.setvariable variable=PATH;]%PATH%;%USERPROFILE%\.cargo\bin + condition: eq( variables['Agent.OS'], 'Windows_NT' ) + displayName: 'Add ~/.cargo/bin to PATH (Windows)' + +- script: | + rustc -Vv + cargo -V + displayName: 'Print Rust Version' + continueOnError: true + +- script: cargo build + displayName: 'Build' + +- script: cargo test + displayName: 'Test' + +- 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: rustup toolchain add nightly + displayName: 'Install Rust Nightly' + +- script: bootimage build --target x86_64-basic.json && file target/x86_64-basic/debug/bootimage-basic.bin + workingDirectory: example-kernels/basic + displayName: 'Build Example Kernel "Basic"' + +- script: bootimage run --target x86_64-basic.json + workingDirectory: example-kernels/basic + displayName: 'Run Example Kernel "basic"' + +- script: bootimage build && file target/x86_64-default-target/debug/bootimage-default-target-bootimage.bin + workingDirectory: example-kernels/default-target-bootimage + displayName: 'Build Example Kernel "default-target-bootimage"' + +- script: bootimage run + workingDirectory: example-kernels/default-target-bootimage + displayName: 'Run Example Kernel "default-target-bootimage"' + +- script: bootimage build && file target/x86_64-default-target/debug/bootimage-default-target-cargo.bin + workingDirectory: example-kernels/default-target-cargo + displayName: 'Build Example Kernel "default-target-cargo"' + +- script: bootimage run + workingDirectory: example-kernels/default-target-cargo + displayName: 'Run Example Kernel "default-target-cargo"' diff --git a/example-kernels/basic/.gitignore b/example-kernels/basic/.gitignore new file mode 100644 index 0000000..eccd7b4 --- /dev/null +++ b/example-kernels/basic/.gitignore @@ -0,0 +1,2 @@ +/target/ +**/*.rs.bk diff --git a/example-kernels/basic/Cargo.lock b/example-kernels/basic/Cargo.lock new file mode 100644 index 0000000..dd4ef6b --- /dev/null +++ b/example-kernels/basic/Cargo.lock @@ -0,0 +1,297 @@ +# 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.4.0", + "x86_64 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "bit_field" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "bitflags" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "bootloader" +version = "0.4.0" +dependencies = [ + "fixedvec 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "font8x8 0.2.4 (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)", + "xmas-elf 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "cc" +version = "1.0.32" +source = "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 = "font8x8" +version = "0.2.4" +source = "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.18" +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 = "libc" +version = "0.2.50" +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.18 (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.50 (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.6 (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.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.32 (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.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi 0.3.6 (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 = "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.1 (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.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "winapi" +version = "0.3.6" +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.3.6" +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.0.4 (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.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "x86_64" +version = "0.5.3" +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.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "raw-cpuid 6.1.0 (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.2 (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.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "228047a76f468627ca71776ecdebd732a3423081fcf5125585bcd7c49886ce12" +"checksum cc 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)" = "ad0daef304fa0b4238f5f7ed7178774b43b06f6a9b6509f6642bef4ff1f7b9b2" +"checksum fixedvec 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7c6c16d316ccdac21a4dd648e314e76facbbaf316e83ca137d0857a9c07419d0" +"checksum font8x8 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b81d84c3c978af7d05d31a2198af4b9ba956d819d15d8f6d58fc150e33f8dc1f" +"checksum fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" +"checksum getopts 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)" = "0a7292d30132fb5424b354f5dc02512a86e4c516fe544bb7a25e7f266951b797" +"checksum libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)" = "aab692d7759f5cd8c859e169db98ae5b52c924add2af5fbbca11d12fefb567c1" +"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.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3488ba1b9a2084d38645c4c08276a1752dcbf2c7130d74f1569681ad5d2799c5" +"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 tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "15f2b5fb00ccdf689e0149d1b1b3c03fead81c2b37735d812fa8bddbbf41b6d8" +"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.2 (registry+https://github.com/rust-lang/crates.io-index)" = "53d8df5dd8d07fedccd202de1887d94481fadaea3db70479f459e8163a1fab41" +"checksum winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "92c1eb33641e276cfa214a0522acad57be5c56b10cb348b3c5117db75f3ac4b0" +"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.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "f9258d7e2dd25008d69e8c9e9ee37865887a5e1e3d06a62f1cb3f6c209e6f177" +"checksum x86_64 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8f7e92e985f4052118fd69f2b366c67e91288c0f01f4ae52610dce236425dfa0" +"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/basic/Cargo.toml b/example-kernels/basic/Cargo.toml new file mode 100644 index 0000000..331b235 --- /dev/null +++ b/example-kernels/basic/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "basic" +version = "0.1.0" +authors = ["Philipp Oppermann "] +edition = "2018" + +[dependencies] +bootloader = "0.5.0" +x86_64 = "0.5.3" diff --git a/example-kernels/basic/src/main.rs b/example-kernels/basic/src/main.rs new file mode 100644 index 0000000..f0352e2 --- /dev/null +++ b/example-kernels/basic/src/main.rs @@ -0,0 +1,28 @@ +#![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 +} diff --git a/example-kernels/basic/x86_64-basic.json b/example-kernels/basic/x86_64-basic.json new file mode 100644 index 0000000..9afe809 --- /dev/null +++ b/example-kernels/basic/x86_64-basic.json @@ -0,0 +1,15 @@ +{ + "llvm-target": "x86_64-unknown-none", + "data-layout": "e-m:e-i64:64-f80:128-n8:16:32:64-S128", + "arch": "x86_64", + "target-endian": "little", + "target-pointer-width": "64", + "target-c-int-width": "32", + "os": "none", + "executables": true, + "linker-flavor": "ld.lld", + "linker": "rust-lld", + "panic-strategy": "abort", + "disable-redzone": true, + "features": "-mmx,-sse,+soft-float" + } diff --git a/example-kernels/default-target-bootimage/.gitignore b/example-kernels/default-target-bootimage/.gitignore new file mode 100644 index 0000000..eccd7b4 --- /dev/null +++ b/example-kernels/default-target-bootimage/.gitignore @@ -0,0 +1,2 @@ +/target/ +**/*.rs.bk diff --git a/example-kernels/default-target-bootimage/Cargo.lock b/example-kernels/default-target-bootimage/Cargo.lock new file mode 100644 index 0000000..06cfb07 --- /dev/null +++ b/example-kernels/default-target-bootimage/Cargo.lock @@ -0,0 +1,328 @@ +# 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.4.0", + "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.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "bit_field" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "bitflags" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "bootloader" +version = "0.4.0" +dependencies = [ + "fixedvec 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "font8x8 0.2.4 (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)", + "xmas-elf 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "cc" +version = "1.0.32" +source = "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 = "font8x8" +version = "0.2.4" +source = "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.18" +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 = "libc" +version = "0.2.50" +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.18 (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.50 (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.6 (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.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.32 (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.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi 0.3.6 (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 = "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.1 (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.0.4 (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.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "winapi" +version = "0.3.6" +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.0.4 (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.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "x86_64" +version = "0.3.6" +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.0.4 (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.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "x86_64" +version = "0.5.3" +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.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "raw-cpuid 6.1.0 (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.2 (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.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "228047a76f468627ca71776ecdebd732a3423081fcf5125585bcd7c49886ce12" +"checksum cc 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)" = "ad0daef304fa0b4238f5f7ed7178774b43b06f6a9b6509f6642bef4ff1f7b9b2" +"checksum fixedvec 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7c6c16d316ccdac21a4dd648e314e76facbbaf316e83ca137d0857a9c07419d0" +"checksum font8x8 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b81d84c3c978af7d05d31a2198af4b9ba956d819d15d8f6d58fc150e33f8dc1f" +"checksum fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" +"checksum getopts 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)" = "0a7292d30132fb5424b354f5dc02512a86e4c516fe544bb7a25e7f266951b797" +"checksum libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)" = "aab692d7759f5cd8c859e169db98ae5b52c924add2af5fbbca11d12fefb567c1" +"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.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3488ba1b9a2084d38645c4c08276a1752dcbf2c7130d74f1569681ad5d2799c5" +"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 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.2 (registry+https://github.com/rust-lang/crates.io-index)" = "53d8df5dd8d07fedccd202de1887d94481fadaea3db70479f459e8163a1fab41" +"checksum winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "92c1eb33641e276cfa214a0522acad57be5c56b10cb348b3c5117db75f3ac4b0" +"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.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8f7e92e985f4052118fd69f2b366c67e91288c0f01f4ae52610dce236425dfa0" +"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/default-target-bootimage/Cargo.toml b/example-kernels/default-target-bootimage/Cargo.toml new file mode 100644 index 0000000..f62b2ac --- /dev/null +++ b/example-kernels/default-target-bootimage/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "default-target-bootimage" +version = "0.1.0" +authors = ["Philipp Oppermann "] +edition = "2018" + +[dependencies] +bootloader = "0.5.0" +x86_64 = "0.5.3" +spin = "0.4.9" +uart_16550 = "0.1.0" + +[package.metadata.bootimage] +default-target = "x86_64-default-target.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 new file mode 100644 index 0000000..f0352e2 --- /dev/null +++ b/example-kernels/default-target-bootimage/src/main.rs @@ -0,0 +1,28 @@ +#![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 +} diff --git a/example-kernels/default-target-bootimage/x86_64-default-target.json b/example-kernels/default-target-bootimage/x86_64-default-target.json new file mode 100644 index 0000000..9afe809 --- /dev/null +++ b/example-kernels/default-target-bootimage/x86_64-default-target.json @@ -0,0 +1,15 @@ +{ + "llvm-target": "x86_64-unknown-none", + "data-layout": "e-m:e-i64:64-f80:128-n8:16:32:64-S128", + "arch": "x86_64", + "target-endian": "little", + "target-pointer-width": "64", + "target-c-int-width": "32", + "os": "none", + "executables": true, + "linker-flavor": "ld.lld", + "linker": "rust-lld", + "panic-strategy": "abort", + "disable-redzone": true, + "features": "-mmx,-sse,+soft-float" + } diff --git a/example-kernels/default-target-cargo/.cargo/config b/example-kernels/default-target-cargo/.cargo/config new file mode 100644 index 0000000..35c3b41 --- /dev/null +++ b/example-kernels/default-target-cargo/.cargo/config @@ -0,0 +1,2 @@ +[build] +target = "x86_64-default-target.json" \ No newline at end of file diff --git a/example-kernels/default-target-cargo/.gitignore b/example-kernels/default-target-cargo/.gitignore new file mode 100644 index 0000000..eccd7b4 --- /dev/null +++ b/example-kernels/default-target-cargo/.gitignore @@ -0,0 +1,2 @@ +/target/ +**/*.rs.bk diff --git a/example-kernels/default-target-cargo/Cargo.lock b/example-kernels/default-target-cargo/Cargo.lock new file mode 100644 index 0000000..06cfb07 --- /dev/null +++ b/example-kernels/default-target-cargo/Cargo.lock @@ -0,0 +1,328 @@ +# 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.4.0", + "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.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "bit_field" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "bitflags" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "bootloader" +version = "0.4.0" +dependencies = [ + "fixedvec 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "font8x8 0.2.4 (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)", + "xmas-elf 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "cc" +version = "1.0.32" +source = "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 = "font8x8" +version = "0.2.4" +source = "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.18" +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 = "libc" +version = "0.2.50" +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.18 (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.50 (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.6 (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.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.32 (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.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi 0.3.6 (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 = "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.1 (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.0.4 (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.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "winapi" +version = "0.3.6" +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.0.4 (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.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "x86_64" +version = "0.3.6" +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.0.4 (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.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "x86_64" +version = "0.5.3" +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.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "raw-cpuid 6.1.0 (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.2 (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.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "228047a76f468627ca71776ecdebd732a3423081fcf5125585bcd7c49886ce12" +"checksum cc 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)" = "ad0daef304fa0b4238f5f7ed7178774b43b06f6a9b6509f6642bef4ff1f7b9b2" +"checksum fixedvec 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7c6c16d316ccdac21a4dd648e314e76facbbaf316e83ca137d0857a9c07419d0" +"checksum font8x8 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b81d84c3c978af7d05d31a2198af4b9ba956d819d15d8f6d58fc150e33f8dc1f" +"checksum fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" +"checksum getopts 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)" = "0a7292d30132fb5424b354f5dc02512a86e4c516fe544bb7a25e7f266951b797" +"checksum libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)" = "aab692d7759f5cd8c859e169db98ae5b52c924add2af5fbbca11d12fefb567c1" +"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.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3488ba1b9a2084d38645c4c08276a1752dcbf2c7130d74f1569681ad5d2799c5" +"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 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.2 (registry+https://github.com/rust-lang/crates.io-index)" = "53d8df5dd8d07fedccd202de1887d94481fadaea3db70479f459e8163a1fab41" +"checksum winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "92c1eb33641e276cfa214a0522acad57be5c56b10cb348b3c5117db75f3ac4b0" +"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.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8f7e92e985f4052118fd69f2b366c67e91288c0f01f4ae52610dce236425dfa0" +"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/default-target-cargo/Cargo.toml b/example-kernels/default-target-cargo/Cargo.toml new file mode 100644 index 0000000..8c1a298 --- /dev/null +++ b/example-kernels/default-target-cargo/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "default-target-cargo" +version = "0.1.0" +authors = ["Philipp Oppermann "] +edition = "2018" + +[dependencies] +bootloader = "0.5.0" +x86_64 = "0.5.3" +spin = "0.4.9" +uart_16550 = "0.1.0" diff --git a/example-kernels/default-target-cargo/src/main.rs b/example-kernels/default-target-cargo/src/main.rs new file mode 100644 index 0000000..f0352e2 --- /dev/null +++ b/example-kernels/default-target-cargo/src/main.rs @@ -0,0 +1,28 @@ +#![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 +} diff --git a/example-kernels/default-target-cargo/x86_64-default-target.json b/example-kernels/default-target-cargo/x86_64-default-target.json new file mode 100644 index 0000000..9afe809 --- /dev/null +++ b/example-kernels/default-target-cargo/x86_64-default-target.json @@ -0,0 +1,15 @@ +{ + "llvm-target": "x86_64-unknown-none", + "data-layout": "e-m:e-i64:64-f80:128-n8:16:32:64-S128", + "arch": "x86_64", + "target-endian": "little", + "target-pointer-width": "64", + "target-c-int-width": "32", + "os": "none", + "executables": true, + "linker-flavor": "ld.lld", + "linker": "rust-lld", + "panic-strategy": "abort", + "disable-redzone": true, + "features": "-mmx,-sse,+soft-float" + } diff --git a/example-kernels/rust-toolchain b/example-kernels/rust-toolchain new file mode 100644 index 0000000..07ade69 --- /dev/null +++ b/example-kernels/rust-toolchain @@ -0,0 +1 @@ +nightly \ No newline at end of file diff --git a/example-kernels/testing/.gitignore b/example-kernels/testing/.gitignore new file mode 100644 index 0000000..eccd7b4 --- /dev/null +++ b/example-kernels/testing/.gitignore @@ -0,0 +1,2 @@ +/target/ +**/*.rs.bk diff --git a/example-kernels/testing/Cargo.lock b/example-kernels/testing/Cargo.lock new file mode 100644 index 0000000..06cfb07 --- /dev/null +++ b/example-kernels/testing/Cargo.lock @@ -0,0 +1,328 @@ +# 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.4.0", + "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.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "bit_field" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "bitflags" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "bootloader" +version = "0.4.0" +dependencies = [ + "fixedvec 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "font8x8 0.2.4 (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)", + "xmas-elf 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "cc" +version = "1.0.32" +source = "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 = "font8x8" +version = "0.2.4" +source = "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.18" +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 = "libc" +version = "0.2.50" +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.18 (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.50 (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.6 (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.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.32 (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.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi 0.3.6 (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 = "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.1 (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.0.4 (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.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "winapi" +version = "0.3.6" +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.0.4 (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.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "x86_64" +version = "0.3.6" +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.0.4 (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.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "x86_64" +version = "0.5.3" +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.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "raw-cpuid 6.1.0 (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.2 (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.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "228047a76f468627ca71776ecdebd732a3423081fcf5125585bcd7c49886ce12" +"checksum cc 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)" = "ad0daef304fa0b4238f5f7ed7178774b43b06f6a9b6509f6642bef4ff1f7b9b2" +"checksum fixedvec 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7c6c16d316ccdac21a4dd648e314e76facbbaf316e83ca137d0857a9c07419d0" +"checksum font8x8 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b81d84c3c978af7d05d31a2198af4b9ba956d819d15d8f6d58fc150e33f8dc1f" +"checksum fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" +"checksum getopts 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)" = "0a7292d30132fb5424b354f5dc02512a86e4c516fe544bb7a25e7f266951b797" +"checksum libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)" = "aab692d7759f5cd8c859e169db98ae5b52c924add2af5fbbca11d12fefb567c1" +"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.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3488ba1b9a2084d38645c4c08276a1752dcbf2c7130d74f1569681ad5d2799c5" +"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 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.2 (registry+https://github.com/rust-lang/crates.io-index)" = "53d8df5dd8d07fedccd202de1887d94481fadaea3db70479f459e8163a1fab41" +"checksum winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "92c1eb33641e276cfa214a0522acad57be5c56b10cb348b3c5117db75f3ac4b0" +"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.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8f7e92e985f4052118fd69f2b366c67e91288c0f01f4ae52610dce236425dfa0" +"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/testing/Cargo.toml b/example-kernels/testing/Cargo.toml new file mode 100644 index 0000000..9b5541f --- /dev/null +++ b/example-kernels/testing/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "testing" +version = "0.1.0" +authors = ["Philipp Oppermann "] +edition = "2018" + +[dependencies] +bootloader = "0.5.0" +x86_64 = "0.5.3" +spin = "0.4.9" +uart_16550 = "0.1.0" + +[package.metadata.bootimage] +default-target = "x86_64-testing.json" \ No newline at end of file diff --git a/example-kernels/testing/src/bin/test-basic-boot.rs b/example-kernels/testing/src/bin/test-basic-boot.rs new file mode 100644 index 0000000..f77d4a0 --- /dev/null +++ b/example-kernels/testing/src/bin/test-basic-boot.rs @@ -0,0 +1,33 @@ +#![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 blog_os::{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/src/bin/test-panic.rs b/example-kernels/testing/src/bin/test-panic.rs new file mode 100644 index 0000000..c68ac51 --- /dev/null +++ b/example-kernels/testing/src/bin/test-panic.rs @@ -0,0 +1,23 @@ +#![cfg_attr(not(test), no_std)] +#![cfg_attr(not(test), no_main)] +#![cfg_attr(test, allow(unused_imports))] + +use blog_os::{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/src/lib.rs b/example-kernels/testing/src/lib.rs new file mode 100644 index 0000000..6bd2578 --- /dev/null +++ b/example-kernels/testing/src/lib.rs @@ -0,0 +1,58 @@ +#![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/src/main.rs b/example-kernels/testing/src/main.rs new file mode 100644 index 0000000..f0352e2 --- /dev/null +++ b/example-kernels/testing/src/main.rs @@ -0,0 +1,28 @@ +#![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 +} diff --git a/example-kernels/testing/x86_64-testing.json b/example-kernels/testing/x86_64-testing.json new file mode 100644 index 0000000..9afe809 --- /dev/null +++ b/example-kernels/testing/x86_64-testing.json @@ -0,0 +1,15 @@ +{ + "llvm-target": "x86_64-unknown-none", + "data-layout": "e-m:e-i64:64-f80:128-n8:16:32:64-S128", + "arch": "x86_64", + "target-endian": "little", + "target-pointer-width": "64", + "target-c-int-width": "32", + "os": "none", + "executables": true, + "linker-flavor": "ld.lld", + "linker": "rust-lld", + "panic-strategy": "abort", + "disable-redzone": true, + "features": "-mmx,-sse,+soft-float" + } From 7515dee2a8b7d5638d19c81c75703ef0a384823d Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Wed, 27 Mar 2019 11:28:04 +0100 Subject: [PATCH 075/271] Add a new `bootimage runner` subcommand for use as `target.runner` --- Cargo.lock | 85 ++++++++++++++++++++++++++++++++++++++++ Cargo.toml | 1 + src/args.rs | 39 ++++++++++++++++++ src/main.rs | 26 ++++++------ src/subcommand.rs | 1 + src/subcommand/runner.rs | 42 ++++++++++++++++++++ 6 files changed, 183 insertions(+), 11 deletions(-) create mode 100644 src/subcommand/runner.rs diff --git a/Cargo.lock b/Cargo.lock index 94a0846..d94e047 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -17,6 +17,7 @@ dependencies = [ "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)", + "tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", "toml 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", "wait-timeout 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "xmas-elf 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -90,6 +91,11 @@ name = "error-chain" version = "0.12.0" source = "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 = "itoa" version = "0.4.2" @@ -157,6 +163,31 @@ dependencies = [ "proc-macro2 0.4.8 (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.42 (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.6 (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 = "rayon" version = "1.0.3" @@ -178,6 +209,22 @@ dependencies = [ "num_cpus 1.8.0 (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.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "scopeguard" version = "0.3.3" @@ -232,6 +279,15 @@ dependencies = [ "unicode-xid 0.1.0 (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.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "toml" version = "0.5.0" @@ -253,6 +309,25 @@ dependencies = [ "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "winapi" +version = "0.3.6" +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 = "xmas-elf" version = "0.6.2" @@ -277,6 +352,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "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 fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" "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" @@ -288,8 +364,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "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 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 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 rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" +"checksum remove_dir_all 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3488ba1b9a2084d38645c4c08276a1752dcbf2c7130d74f1569681ad5d2799c5" "checksum scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27" "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" @@ -297,8 +378,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "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 tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "15f2b5fb00ccdf689e0149d1b1b3c03fead81c2b37735d812fa8bddbbf41b6d8" "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 wait-timeout 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9f200f5b12eb75f8c1ed65abd4b2db8a6e1b138a20de009dacee265a2498f3f6" +"checksum winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "92c1eb33641e276cfa214a0522acad57be5c56b10cb348b3c5117db75f3ac4b0" +"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 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/Cargo.toml b/Cargo.toml index 4bd9804..28bf2fc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,6 +15,7 @@ wait-timeout = "0.2" xmas-elf = "0.6.2" llvm-tools = "0.1.1" locate-cargo-manifest = "0.1.0" +tempdir = "0.3.7" [dependencies.cargo_metadata] version = "0.7.4" diff --git a/src/args.rs b/src/args.rs index e4c0041..494ad1a 100644 --- a/src/args.rs +++ b/src/args.rs @@ -23,6 +23,7 @@ pub(crate) fn parse_args() -> Command { Command::BuildHelp => Command::TestHelp, cmd => cmd, }, + Some("runner") => parse_runner_args(args), Some("--help") | Some("-h") => Command::Help, Some("--version") => Command::Version, _ => Command::NoSubcommand, @@ -194,3 +195,41 @@ impl Args { } } } + +fn parse_runner_args(args: A) -> Command +where + A: Iterator, +{ + let mut arg_iter = args.into_iter().fuse(); + let executable = PathBuf::from(arg_iter.next().expect("excepted path to kernel executable as first argument")).canonicalize().expect("Failed to canonicalize executable path"); + let mut run_command = None; + + loop { + match arg_iter.next().as_ref().map(|s| s.as_str()) { + Some("--command") => { + let old = mem::replace(&mut run_command, Some(arg_iter.collect())); + assert!(old.is_none(), "multiple `--command` arguments"); + break; + } + Some("--help") | Some("-h") => { + return Command::RunnerHelp; + } + Some("--version") => { + return Command::Version; + } + None => break, + Some(arg) => panic!("unexpected argument `{}`", arg), + } + } + + Command::Runner(RunnerArgs { + executable, + run_command, + }) +} + +#[derive(Debug, Clone)] +pub struct RunnerArgs { + pub executable: PathBuf, + pub run_command: Option>, +} diff --git a/src/main.rs b/src/main.rs index 2ec34de..8a9e2d4 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,4 +1,4 @@ -use args::Args; +use args::{Args, RunnerArgs}; use std::{fmt, process}; mod args; @@ -12,17 +12,19 @@ enum Command { Build(Args), Run(Args), Test(Args), + Runner(RunnerArgs), Help, BuildHelp, RunHelp, TestHelp, + RunnerHelp, Version, } pub fn main() { if let Err(err) = run() { - eprintln!("Error: {}", err.display()); - process::exit(1); + eprintln!("Error: {}", err.message); + process::exit(err.exit_code); } } @@ -32,26 +34,25 @@ fn run() -> Result<(), ErrorString> { Command::Build(args) => subcommand::build::build(args), Command::Run(args) => subcommand::run::run(args), Command::Test(args) => subcommand::test::test(args), + Command::Runner(args) => subcommand::runner::runner(args), Command::NoSubcommand => help::no_subcommand(), Command::Help => Ok(help::help()), Command::BuildHelp => Ok(help::build_help()), Command::RunHelp => Ok(help::run_help()), Command::TestHelp => Ok(help::test_help()), + Command::RunnerHelp => unimplemented!(), Command::Version => Ok(println!("bootimage {}", env!("CARGO_PKG_VERSION"))), } } -struct ErrorString(Box); - -impl ErrorString { - fn display(&self) -> &dyn fmt::Display { - &self.0 - } +struct ErrorString { + pub message: Box, + pub exit_code: i32, } impl fmt::Debug for ErrorString { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - self.display().fmt(f) + self.message.fmt(f) } } @@ -60,6 +61,9 @@ where T: fmt::Display + Send + 'static, { fn from(err: T) -> Self { - ErrorString(Box::new(err)) + ErrorString { + message: Box::new(err), + exit_code: 1, + } } } diff --git a/src/subcommand.rs b/src/subcommand.rs index 34bfd46..f848c46 100644 --- a/src/subcommand.rs +++ b/src/subcommand.rs @@ -1,3 +1,4 @@ pub mod build; pub mod run; +pub mod runner; pub mod test; diff --git a/src/subcommand/runner.rs b/src/subcommand/runner.rs new file mode 100644 index 0000000..7e3a386 --- /dev/null +++ b/src/subcommand/runner.rs @@ -0,0 +1,42 @@ +use crate::{args::RunnerArgs, ErrorString}; +use std::process; + +pub(crate) fn runner(args: RunnerArgs) -> Result<(), ErrorString> { + let out_dir = tempdir::TempDir::new("bootimage-runner")?; + let bootimage_bin = out_dir.path().join("bootimage.bin"); + + let builder = bootimage::Builder::new(None)?; + builder.create_bootimage(&args.executable, &bootimage_bin, false)?; + + let run_cmd = args.run_command.unwrap_or(vec![ + "qemu-system-x86_64".into(), + "-drive".into(), + "format=raw,file={bootimage}".into(), + ]); + + println!("Running {:?}", run_cmd); + + let mut command = process::Command::new(&run_cmd[0]); + for arg in &run_cmd[1..] { + command.arg(arg.replace("{bootimage}", &format!("{}", bootimage_bin.display()))); + } + let output = command + .output() + .map_err(|e| format!("Failed to execute `{:?}`: {}", command, e))?; + + if !output.status.success() { + return Err(ErrorString { + exit_code: output.status.code().unwrap_or(1), + message: Box::new(format!( + "Command `{:?}` failed:\n{}", + command, + String::from_utf8_lossy(&output.stderr) + )), + }); + } + + drop(bootimage_bin); + out_dir.close()?; + + Ok(()) +} From 83282120fb7e85923ef8dd1b0c78b11234d87e26 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Wed, 27 Mar 2019 11:28:20 +0100 Subject: [PATCH 076/271] Run cargo fmt --- src/args.rs | 8 +++++++- src/config.rs | 10 ++++------ src/subcommand/test.rs | 2 +- 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/src/args.rs b/src/args.rs index 494ad1a..3d97978 100644 --- a/src/args.rs +++ b/src/args.rs @@ -201,7 +201,13 @@ where A: Iterator, { let mut arg_iter = args.into_iter().fuse(); - let executable = PathBuf::from(arg_iter.next().expect("excepted path to kernel executable as first argument")).canonicalize().expect("Failed to canonicalize executable path"); + let executable = PathBuf::from( + arg_iter + .next() + .expect("excepted path to kernel executable as first argument"), + ) + .canonicalize() + .expect("Failed to canonicalize executable path"); let mut run_command = None; loop { diff --git a/src/config.rs b/src/config.rs index 5acd6e0..73a3de7 100644 --- a/src/config.rs +++ b/src/config.rs @@ -40,10 +40,9 @@ pub(crate) fn read_config_inner(manifest_path: PathBuf) -> Result metadata.as_table().ok_or(format!( - "Bootimage configuration invalid: {:?}", - metadata - ))?, + Some(metadata) => metadata + .as_table() + .ok_or(format!("Bootimage configuration invalid: {:?}", metadata))?, }; let mut config = ConfigBuilder { @@ -67,8 +66,7 @@ pub(crate) fn read_config_inner(manifest_path: PathBuf) -> Result Err(format!( "unexpected `package.metadata.bootimage` \ key `{}` with value `{}`", - key, - value + key, value ))?, } } diff --git a/src/subcommand/test.rs b/src/subcommand/test.rs index 6dee868..b381356 100644 --- a/src/subcommand/test.rs +++ b/src/subcommand/test.rs @@ -1,6 +1,6 @@ use crate::{args::Args, config, subcommand::build, ErrorString}; -use std::{io::Write, path::PathBuf, time::Duration, fs, io, process}; use rayon::prelude::*; +use std::{fs, io, io::Write, path::PathBuf, process, time::Duration}; use wait_timeout::ChildExt; pub(crate) fn test(mut args: Args) -> Result<(), ErrorString> { From acfc0b2708db12e8d2465bc7746aed154a0c4a82 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Wed, 27 Mar 2019 12:11:00 +0100 Subject: [PATCH 077/271] Refactor: Move everything to library --- src/builder.rs | 371 ++++++++++++++++++++++++++++++ src/cargo_config.rs | 61 +++++ src/lib.rs | 470 +++++---------------------------------- src/main.rs | 65 +----- src/subcommand/build.rs | 10 +- src/subcommand/run.rs | 4 +- src/subcommand/runner.rs | 4 +- src/subcommand/test.rs | 4 +- 8 files changed, 494 insertions(+), 495 deletions(-) create mode 100644 src/builder.rs create mode 100644 src/cargo_config.rs diff --git a/src/builder.rs b/src/builder.rs new file mode 100644 index 0000000..546d3af --- /dev/null +++ b/src/builder.rs @@ -0,0 +1,371 @@ +use std::{ + fmt, io, + path::{Path, PathBuf}, + process::{self, Command}, +}; + +pub struct Builder { + kernel_manifest_path: PathBuf, + kernel_metadata: cargo_metadata::Metadata, +} + +impl Builder { + 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, + }) + } + + pub fn kernel_manifest_path(&self) -> &Path { + &self.kernel_manifest_path + } + + pub fn kernel_root(&self) -> &Path { + self.kernel_manifest_path + .parent() + .expect("kernel manifest has no parent directory") + } + + pub fn kernel_metadata(&self) -> &cargo_metadata::Metadata { + &self.kernel_metadata + } + + 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() + )) + } + + 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, + }); + } + + Ok(()) + } + + 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_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), + })?; + bootloader_resolve.features.clone() + }; + let bootloader_target_triple = + crate::cargo_config::default_target_triple(&bootloader_root, false) + .map_err(CreateBootimageError::BootloaderInvalid)? + .ok_or(CreateBootimageError::BootloaderInvalid(format!( + "bootloader must have a default target" + )))?; + + // build bootloader + if !quiet { + println!("Building bootloader"); + } + + let cargo = std::env::var("CARGO").unwrap_or("cargo".to_owned()); + let mut cmd = process::Command::new(cargo); + cmd.arg("xbuild"); + cmd.arg("--manifest-path"); + cmd.arg(&bootloader_pkg.manifest_path); + cmd.arg("--target-dir").arg(&target_dir); + cmd.arg("--features") + .arg(bootloader_features.as_slice().join(" ")); + cmd.arg("--release"); + cmd.current_dir(bootloader_root); + cmd.env("KERNEL", kernel_bin_path); + cmd.env_remove("RUSTFLAGS"); + 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, + }); + } + + let bootloader_elf_path = target_dir + .join(&bootloader_target_triple) + .join("release") + .join(&bootloader_name); + + 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, + }); + } + + Ok(()) + } +} + +#[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 + ), + } + } +} + +#[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, + }, + XbuildNotFound, + XbuildFailed { + stderr: Vec, + }, + CargoConfigInvalid { + path: PathBuf, + error: String, + }, +} + +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: {}: {}", 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: {}", String::from_utf8_lossy(stderr)) + } + BuildKernelError::CargoConfigInvalid{path,error} => { + writeln!(f, "Failed to read cargo config at {}: {}", path.display(), error) + }, + } + } +} + +#[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), + BootloaderBuildFailed { + 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 { + stderr: Vec, + }, +} + +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:\n\n{}", + String::from_utf8_lossy(stderr) + ), + 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) + ), + } + } +} + +// 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/cargo_config.rs b/src/cargo_config.rs new file mode 100644 index 0000000..4e57ad7 --- /dev/null +++ b/src/cargo_config.rs @@ -0,0 +1,61 @@ +use std::{ + fs, + path::{Path, PathBuf}, +}; + +pub fn default_target_triple(crate_root: &Path, walk_up: bool) -> Result, String> { + let default_triple = default_target(crate_root, walk_up)?; + default_triple + .map(|(target, crate_root)| { + if target.ends_with(".json") { + crate_root + .join(target) + .file_stem() + .ok_or(String::from( + "The target path specfied in `build.target` has no file stem", + ))? + .to_os_string() + .into_string() + .map_err(|err| format!("Default target triple not valid UTF-8: {:?}", err)) + } else { + Ok(target) + } + }) + .transpose() +} + +fn default_target(crate_root: &Path, walk_up: bool) -> Result, String> { + let mut parent_dir = crate_root; + + loop { + let config_path = parent_dir.join(".cargo/config"); + if config_path.exists() { + let config_content = fs::read_to_string(config_path).map_err(|err| { + format!("Failed to read `.cargo/config` file of crate: {:?}", err) + })?; + let config = config_content.parse::().map_err(|err| { + format!( + "Failed to parse `.cargo/config` of crate as toml: {:?}", + err + ) + })?; + let target = config + .get("build") + .and_then(|v| v.get("target")) + .and_then(|v| v.as_str()) + .map(String::from); + if let Some(target) = target { + return Ok(Some((target, parent_dir.to_owned()))); + } + } + if walk_up { + parent_dir = match parent_dir.parent() { + Some(parent) => parent, + None => break, + } + } else { + break; + } + } + Ok(None) +} diff --git a/src/lib.rs b/src/lib.rs index 73876cd..9fa9559 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,434 +1,64 @@ -use std::{ - fmt, fs, io, - path::{Path, PathBuf}, - process::{self, Command}, -}; - -pub struct Builder { - kernel_manifest_path: PathBuf, - kernel_metadata: cargo_metadata::Metadata, +use args::{Args, RunnerArgs}; +use std::fmt; + +pub mod args; +pub mod builder; +pub mod cargo_config; +pub mod config; +pub mod help; + +mod subcommand; + +enum Command { + NoSubcommand, + Build(Args), + Run(Args), + Test(Args), + Runner(RunnerArgs), + Help, + BuildHelp, + RunHelp, + TestHelp, + RunnerHelp, + Version, } -impl Builder { - 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, - }) - } - - pub fn kernel_manifest_path(&self) -> &Path { - &self.kernel_manifest_path - } - - pub fn kernel_root(&self) -> &Path { - self.kernel_manifest_path - .parent() - .expect("kernel manifest has no parent directory") - } - - pub fn kernel_metadata(&self) -> &cargo_metadata::Metadata { - &self.kernel_metadata - } - - 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() - )) - } - - 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, - }); - } - - Ok(()) - } - - 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_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), - })?; - bootloader_resolve.features.clone() - }; - let bootloader_target_triple = - default_target_triple_from_cargo_config(&bootloader_root, false) - .map_err(CreateBootimageError::BootloaderInvalid)? - .ok_or(CreateBootimageError::BootloaderInvalid(format!( - "bootloader must have a default target" - )))?; - - // build bootloader - if !quiet { - println!("Building bootloader"); - } - - let cargo = std::env::var("CARGO").unwrap_or("cargo".to_owned()); - let mut cmd = process::Command::new(cargo); - cmd.arg("xbuild"); - cmd.arg("--manifest-path"); - cmd.arg(&bootloader_pkg.manifest_path); - cmd.arg("--target-dir").arg(&target_dir); - cmd.arg("--features") - .arg(bootloader_features.as_slice().join(" ")); - cmd.arg("--release"); - cmd.current_dir(bootloader_root); - cmd.env("KERNEL", kernel_bin_path); - cmd.env_remove("RUSTFLAGS"); - 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, - }); - } - - let bootloader_elf_path = target_dir - .join(&bootloader_target_triple) - .join("release") - .join(&bootloader_name); - - 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, - }); - } - - Ok(()) +pub fn run() -> Result<(), ErrorString> { + let command = args::parse_args(); + match command { + Command::Build(args) => subcommand::build::build(args), + Command::Run(args) => subcommand::run::run(args), + Command::Test(args) => subcommand::test::test(args), + Command::Runner(args) => subcommand::runner::runner(args), + Command::NoSubcommand => help::no_subcommand(), + Command::Help => Ok(help::help()), + Command::BuildHelp => Ok(help::build_help()), + Command::RunHelp => Ok(help::run_help()), + Command::TestHelp => Ok(help::test_help()), + Command::RunnerHelp => unimplemented!(), + Command::Version => Ok(println!("bootimage {}", env!("CARGO_PKG_VERSION"))), } } -pub fn default_target_triple_from_cargo_config( - crate_root: &Path, - walk_up: bool, -) -> Result, String> { - let default_triple = default_target_from_cargo_config(crate_root, walk_up)?; - default_triple - .map(|(target, crate_root)| { - if target.ends_with(".json") { - crate_root - .join(target) - .file_stem() - .ok_or(String::from( - "The target path specfied in `build.target` has no file stem", - ))? - .to_os_string() - .into_string() - .map_err(|err| format!("Default target triple not valid UTF-8: {:?}", err)) - } else { - Ok(target) - } - }) - .transpose() +pub struct ErrorString { + pub message: Box, + pub exit_code: i32, } -fn default_target_from_cargo_config( - crate_root: &Path, - walk_up: bool, -) -> Result, String> { - let mut parent_dir = crate_root; - - loop { - let config_path = parent_dir.join(".cargo/config"); - if config_path.exists() { - let config_content = fs::read_to_string(config_path).map_err(|err| { - format!("Failed to read `.cargo/config` file of crate: {:?}", err) - })?; - let config = config_content.parse::().map_err(|err| { - format!( - "Failed to parse `.cargo/config` of crate as toml: {:?}", - err - ) - })?; - let target = config - .get("build") - .and_then(|v| v.get("target")) - .and_then(|v| v.as_str()) - .map(String::from); - if let Some(target) = target { - return Ok(Some((target, parent_dir.to_owned()))); - } - } - if walk_up { - parent_dir = match parent_dir.parent() { - Some(parent) => parent, - None => break, - } - } else { - break; - } - } - Ok(None) -} - -#[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 { +impl fmt::Debug for ErrorString { 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 - ), - } + self.message.fmt(f) } } -#[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, - }, - XbuildNotFound, - XbuildFailed { - stderr: Vec, - }, - CargoConfigInvalid { - path: PathBuf, - error: String, - }, -} - -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: {}: {}", 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: {}", String::from_utf8_lossy(stderr)) - } - BuildKernelError::CargoConfigInvalid{path,error} => { - writeln!(f, "Failed to read cargo config at {}: {}", path.display(), error) - }, +impl From for ErrorString +where + T: fmt::Display + Send + 'static, +{ + fn from(err: T) -> Self { + ErrorString { + message: Box::new(err), + exit_code: 1, } } } - -#[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), - BootloaderBuildFailed { - 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 { - stderr: Vec, - }, -} - -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:\n\n{}", - String::from_utf8_lossy(stderr) - ), - 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) - ), - } - } -} - -// 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/main.rs b/src/main.rs index 8a9e2d4..d6e09a5 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,69 +1,8 @@ -use args::{Args, RunnerArgs}; -use std::{fmt, process}; - -mod args; -mod config; -mod help; - -mod subcommand; - -enum Command { - NoSubcommand, - Build(Args), - Run(Args), - Test(Args), - Runner(RunnerArgs), - Help, - BuildHelp, - RunHelp, - TestHelp, - RunnerHelp, - Version, -} +use std::process; pub fn main() { - if let Err(err) = run() { + if let Err(err) = bootimage::run() { eprintln!("Error: {}", err.message); process::exit(err.exit_code); } } - -fn run() -> Result<(), ErrorString> { - let command = args::parse_args(); - match command { - Command::Build(args) => subcommand::build::build(args), - Command::Run(args) => subcommand::run::run(args), - Command::Test(args) => subcommand::test::test(args), - Command::Runner(args) => subcommand::runner::runner(args), - Command::NoSubcommand => help::no_subcommand(), - Command::Help => Ok(help::help()), - Command::BuildHelp => Ok(help::build_help()), - Command::RunHelp => Ok(help::run_help()), - Command::TestHelp => Ok(help::test_help()), - Command::RunnerHelp => unimplemented!(), - Command::Version => Ok(println!("bootimage {}", env!("CARGO_PKG_VERSION"))), - } -} - -struct ErrorString { - pub message: Box, - pub exit_code: i32, -} - -impl fmt::Debug for ErrorString { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - self.message.fmt(f) - } -} - -impl From for ErrorString -where - T: fmt::Display + Send + 'static, -{ - fn from(err: T) -> Self { - ErrorString { - message: Box::new(err), - exit_code: 1, - } - } -} diff --git a/src/subcommand/build.rs b/src/subcommand/build.rs index 014e069..6db5f3c 100644 --- a/src/subcommand/build.rs +++ b/src/subcommand/build.rs @@ -1,12 +1,11 @@ -use crate::{args::Args, config, ErrorString}; -use bootimage::Builder; +use crate::{args::Args, builder::Builder, cargo_config, config, ErrorString}; use std::{ path::{Path, PathBuf}, process, }; pub(crate) fn build(mut args: Args) -> Result<(), ErrorString> { - let builder = bootimage::Builder::new(args.manifest_path().clone())?; + let builder = Builder::new(args.manifest_path().clone())?; let config = config::read_config(builder.kernel_manifest_path().to_owned())?; args.apply_default_target(&config, builder.kernel_root()); @@ -34,14 +33,13 @@ pub(crate) fn build_impl( Ok(bootimage_path) } -fn out_dir(args: &Args, builder: &bootimage::Builder) -> Result { +fn out_dir(args: &Args, builder: &Builder) -> Result { let target_dir = PathBuf::from(&builder.kernel_metadata().target_directory); let mut out_dir = target_dir; if let &Some(ref target) = args.target() { out_dir.push(Path::new(target).file_stem().unwrap().to_str().unwrap()); } else { - let default_triple = - bootimage::default_target_triple_from_cargo_config(builder.kernel_root(), true)?; + let default_triple = cargo_config::default_target_triple(builder.kernel_root(), true)?; if let Some(triple) = default_triple { out_dir.push(triple); } diff --git a/src/subcommand/run.rs b/src/subcommand/run.rs index 0804275..92eddd5 100644 --- a/src/subcommand/run.rs +++ b/src/subcommand/run.rs @@ -1,10 +1,10 @@ -use crate::{args::Args, config, ErrorString}; +use crate::{args::Args, builder::Builder, config, ErrorString}; use std::process; pub(crate) fn run(mut args: Args) -> Result<(), ErrorString> { use crate::subcommand::build; - let builder = bootimage::Builder::new(args.manifest_path().clone())?; + let builder = Builder::new(args.manifest_path().clone())?; let config = config::read_config(builder.kernel_manifest_path().to_owned())?; args.apply_default_target(&config, builder.kernel_root()); diff --git a/src/subcommand/runner.rs b/src/subcommand/runner.rs index 7e3a386..bbb6a16 100644 --- a/src/subcommand/runner.rs +++ b/src/subcommand/runner.rs @@ -1,11 +1,11 @@ -use crate::{args::RunnerArgs, ErrorString}; +use crate::{args::RunnerArgs, builder::Builder, ErrorString}; use std::process; pub(crate) fn runner(args: RunnerArgs) -> Result<(), ErrorString> { let out_dir = tempdir::TempDir::new("bootimage-runner")?; let bootimage_bin = out_dir.path().join("bootimage.bin"); - let builder = bootimage::Builder::new(None)?; + let builder = Builder::new(None)?; builder.create_bootimage(&args.executable, &bootimage_bin, false)?; let run_cmd = args.run_command.unwrap_or(vec![ diff --git a/src/subcommand/test.rs b/src/subcommand/test.rs index b381356..0f82acc 100644 --- a/src/subcommand/test.rs +++ b/src/subcommand/test.rs @@ -1,10 +1,10 @@ -use crate::{args::Args, config, subcommand::build, ErrorString}; +use crate::{args::Args, builder::Builder, config, subcommand::build, ErrorString}; use rayon::prelude::*; use std::{fs, io, io::Write, path::PathBuf, process, time::Duration}; use wait_timeout::ChildExt; pub(crate) fn test(mut args: Args) -> Result<(), ErrorString> { - let builder = bootimage::Builder::new(args.manifest_path().clone())?; + let builder = Builder::new(args.manifest_path().clone())?; let config = config::read_config(builder.kernel_manifest_path().to_owned())?; args.apply_default_target(&config, builder.kernel_root()); From e3b7f7556c1037a8bd24d4b06f1026eb8f09cf1f Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Wed, 27 Mar 2019 12:32:40 +0100 Subject: [PATCH 078/271] Add a `cargo-bootimage` executable (equivalent to `bootimage build`) --- src/args.rs | 80 +++++++++++++++++++++----------------- src/bin/cargo-bootimage.rs | 8 ++++ src/lib.rs | 5 ++- 3 files changed, 55 insertions(+), 38 deletions(-) create mode 100644 src/bin/cargo-bootimage.rs diff --git a/src/args.rs b/src/args.rs index 3d97978..e68a753 100644 --- a/src/args.rs +++ b/src/args.rs @@ -1,18 +1,24 @@ -use crate::{config::Config, Command}; +use crate::{config::Config, Command, ErrorString}; use std::path::{Path, PathBuf}; use std::{env, mem}; -pub(crate) fn parse_args() -> Command { - let mut args = env::args().skip(1); +pub(crate) fn parse_args() -> Result { + let mut args = env::args(); + let executable_name = args.next().ok_or("no first argument (executable name)")?; let first = args.next(); match first.as_ref().map(|s| s.as_str()) { Some("build") => parse_build_args(args), - Some("run") => match parse_build_args(args) { + Some("bootimage") if executable_name.ends_with("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") => match parse_build_args(args) { + }), + Some("test") => parse_build_args(args).map(|cmd| match cmd { Command::Build(args) => { assert_eq!( args.bin_name, None, @@ -22,15 +28,15 @@ pub(crate) fn parse_args() -> Command { } Command::BuildHelp => Command::TestHelp, cmd => cmd, - }, + }), Some("runner") => parse_runner_args(args), - Some("--help") | Some("-h") => Command::Help, - Some("--version") => Command::Version, - _ => Command::NoSubcommand, + Some("--help") | Some("-h") => Ok(Command::Help), + Some("--version") => Ok(Command::Version), + _ => Ok(Command::NoSubcommand), } } -fn parse_build_args(args: A) -> Command +fn parse_build_args(args: A) -> Result where A: Iterator, { @@ -42,12 +48,12 @@ where let mut run_args = Vec::new(); let mut run_args_started = false; { - fn set(arg: &mut Option, value: Option) { + fn set(arg: &mut Option, value: Option) -> Result<(), ErrorString> { let previous = mem::replace(arg, value); - assert!( - previous.is_none(), - "multiple arguments of same type provided" - ) + if previous.is_some() { + Err("multiple arguments of same type provided")? + } + Ok(()) }; let mut arg_iter = args.into_iter(); @@ -58,14 +64,14 @@ where } match arg.as_ref() { "--help" | "-h" => { - return Command::BuildHelp; + return Ok(Command::BuildHelp); } "--version" => { - return Command::Version; + return Ok(Command::Version); } "--bin" => { let next = arg_iter.next(); - set(&mut bin_name, next.clone()); + set(&mut bin_name, next.clone())?; cargo_args.push(arg); if let Some(next) = next { cargo_args.push(next); @@ -75,12 +81,12 @@ where 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()); + set(&mut target, next.clone())?; cargo_args.push(arg); if let Some(next) = next { cargo_args.push(next); @@ -90,7 +96,7 @@ where set( &mut target, Some(String::from(arg.trim_start_matches("--target="))), - ); + )?; cargo_args.push(arg); } "--manifest-path" => { @@ -102,7 +108,7 @@ where .canonicalize() .expect("--manifest-path invalid") }), - ); + )?; cargo_args.push(arg); if let Some(next) = next { cargo_args.push(next); @@ -112,11 +118,11 @@ where let path = Path::new(arg.trim_start_matches("--manifest-path=")) .canonicalize() .expect("--manifest-path invalid"); - set(&mut manifest_path, Some(path)); + set(&mut manifest_path, Some(path))?; cargo_args.push(arg); } "--release" => { - set(&mut release, Some(true)); + set(&mut release, Some(true))?; cargo_args.push(arg); } "--" => { @@ -129,14 +135,14 @@ where } } - Command::Build(Args { + Ok(Command::Build(Args { cargo_args, run_args, bin_name, target, manifest_path, release: release.unwrap_or(false), - }) + })) } #[derive(Debug, Clone)] @@ -196,7 +202,7 @@ impl Args { } } -fn parse_runner_args(args: A) -> Command +fn parse_runner_args(args: A) -> Result where A: Iterator, { @@ -204,34 +210,36 @@ where let executable = PathBuf::from( arg_iter .next() - .expect("excepted path to kernel executable as first argument"), + .ok_or("excepted path to kernel executable as first argument")?, ) .canonicalize() - .expect("Failed to canonicalize executable path"); + .map_err(|err| format!("Failed to canonicalize executable path: {}", err))?; let mut run_command = None; loop { match arg_iter.next().as_ref().map(|s| s.as_str()) { Some("--command") => { let old = mem::replace(&mut run_command, Some(arg_iter.collect())); - assert!(old.is_none(), "multiple `--command` arguments"); + if !old.is_none() { + Err("multiple `--command` arguments")?; + } break; } Some("--help") | Some("-h") => { - return Command::RunnerHelp; + return Ok(Command::RunnerHelp); } Some("--version") => { - return Command::Version; + return Ok(Command::Version); } None => break, - Some(arg) => panic!("unexpected argument `{}`", arg), + Some(arg) => Err(format!("unexpected argument `{}`", arg))?, } } - Command::Runner(RunnerArgs { + Ok(Command::Runner(RunnerArgs { executable, run_command, - }) + })) } #[derive(Debug, Clone)] diff --git a/src/bin/cargo-bootimage.rs b/src/bin/cargo-bootimage.rs new file mode 100644 index 0000000..d6e09a5 --- /dev/null +++ b/src/bin/cargo-bootimage.rs @@ -0,0 +1,8 @@ +use std::process; + +pub fn main() { + if let Err(err) = bootimage::run() { + eprintln!("Error: {}", err.message); + process::exit(err.exit_code); + } +} diff --git a/src/lib.rs b/src/lib.rs index 9fa9559..0a1a976 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -19,12 +19,13 @@ enum Command { BuildHelp, RunHelp, TestHelp, + CargoBootimageHelp, RunnerHelp, Version, } pub fn run() -> Result<(), ErrorString> { - let command = args::parse_args(); + let command = args::parse_args()?; match command { Command::Build(args) => subcommand::build::build(args), Command::Run(args) => subcommand::run::run(args), @@ -35,8 +36,8 @@ pub fn run() -> Result<(), ErrorString> { Command::BuildHelp => Ok(help::build_help()), Command::RunHelp => Ok(help::run_help()), Command::TestHelp => Ok(help::test_help()), - Command::RunnerHelp => unimplemented!(), Command::Version => Ok(println!("bootimage {}", env!("CARGO_PKG_VERSION"))), + Command::RunnerHelp | Command::CargoBootimageHelp => unimplemented!(), } } From 1fc4abdba63fa4ce11de5dc9a6e8b25d17ac9fe9 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Wed, 27 Mar 2019 12:37:58 +0100 Subject: [PATCH 079/271] Avoid newlines between `BUILD` lines in output of `bootimage test` --- src/subcommand/test.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/subcommand/test.rs b/src/subcommand/test.rs index 0f82acc..f60b1b2 100644 --- a/src/subcommand/test.rs +++ b/src/subcommand/test.rs @@ -24,7 +24,6 @@ pub(crate) fn test(mut args: Args) -> Result<(), ErrorString> { target_args.set_bin_name(target.name.clone()); let test_bin_path = build::build_impl(&builder, &mut target_args, true) .expect(&format!("Failed to build test: {}", target.name)); - println!(""); (target, test_bin_path) }) From 9287964c157f8a0638be6dea8e64450796fd82cf Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Wed, 27 Mar 2019 12:39:31 +0100 Subject: [PATCH 080/271] Increase test timeout to 5 minutes to allow for longer tests --- src/subcommand/test.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/subcommand/test.rs b/src/subcommand/test.rs index f60b1b2..866f8a8 100644 --- a/src/subcommand/test.rs +++ b/src/subcommand/test.rs @@ -50,7 +50,7 @@ pub(crate) fn test(mut args: Args) -> Result<(), ErrorString> { let mut child = command .spawn() .map_err(|e| format!("Failed to launch QEMU: {:?}\n{}", command, e))?; - let timeout = Duration::from_secs(60); + let timeout = Duration::from_secs(60 * 5); match child .wait_timeout(timeout) .map_err(|e| format!("Failed to wait with timeout: {}", e))? From 4c3bca0137fdc5fffb62caacc714dae6494c6cc0 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Wed, 27 Mar 2019 12:46:10 +0100 Subject: [PATCH 081/271] Make `test_timeout` configurable --- Readme.md | 7 ++++++- src/config.rs | 10 +++++++++- src/help/test_help.txt | 9 +++++++++ src/subcommand/test.rs | 2 +- 4 files changed, 25 insertions(+), 3 deletions(-) diff --git a/Readme.md b/Readme.md index 0def8db..ba964f7 100644 --- a/Readme.md +++ b/Readme.md @@ -35,10 +35,15 @@ Configuration is done through a through a `[package.metadata.bootimage]` table i ```toml [package.metadata.bootimage] - default-target = "" # This target is used if no `--target` is passed + # This target is used if no `--target` is passed + default-target = "" + # The command invoked on `bootimage run` # (the "{}" will be replaced with the path to the bootable disk image) run-command = ["qemu-system-x86_64", "-drive", "format=raw,file={}"] + + # The timeout for running an integration test in seconds + test-timeout = 300 ``` ## License diff --git a/src/config.rs b/src/config.rs index 73a3de7..93a4833 100644 --- a/src/config.rs +++ b/src/config.rs @@ -7,6 +7,7 @@ pub struct Config { pub manifest_path: PathBuf, pub default_target: Option, pub run_command: Vec, + pub test_timeout: u64, } pub(crate) fn read_config(manifest_path: PathBuf) -> Result { @@ -16,7 +17,7 @@ pub(crate) fn read_config(manifest_path: PathBuf) -> Result } pub(crate) fn read_config_inner(manifest_path: PathBuf) -> Result { - use std::{fs::File, io::Read}; + use std::{convert::TryFrom, fs::File, io::Read}; let cargo_toml: Value = { let mut content = String::new(); File::open(&manifest_path) @@ -53,6 +54,11 @@ pub(crate) fn read_config_inner(manifest_path: PathBuf) -> Result config.default_target = From::from(s), + ("test-timeout", Value::Integer(s)) => { + config.test_timeout = u64::try_from(s) + .map_err(|err| format!("test-timeout is not valid: {}", err))? + .into() + } ("run-command", Value::Array(array)) => { let mut command = Vec::new(); for value in array { @@ -78,6 +84,7 @@ struct ConfigBuilder { manifest_path: Option, default_target: Option, run_command: Option>, + test_timeout: Option, } impl Into for ConfigBuilder { @@ -90,6 +97,7 @@ impl Into for ConfigBuilder { "-drive".into(), "format=raw,file={}".into(), ]), + test_timeout: self.test_timeout.unwrap_or(60 * 5), } } } diff --git a/src/help/test_help.txt b/src/help/test_help.txt index 18c5b91..a9fa8e1 100644 --- a/src/help/test_help.txt +++ b/src/help/test_help.txt @@ -15,3 +15,12 @@ USAGE: (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/test.rs b/src/subcommand/test.rs index 866f8a8..dbb8845 100644 --- a/src/subcommand/test.rs +++ b/src/subcommand/test.rs @@ -50,7 +50,7 @@ pub(crate) fn test(mut args: Args) -> Result<(), ErrorString> { let mut child = command .spawn() .map_err(|e| format!("Failed to launch QEMU: {:?}\n{}", command, e))?; - let timeout = Duration::from_secs(60 * 5); + let timeout = Duration::from_secs(config.test_timeout); match child .wait_timeout(timeout) .map_err(|e| format!("Failed to wait with timeout: {}", e))? From 60f050665698f01243cbb3a52522e3ac443410c3 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Wed, 27 Mar 2019 10:06:05 +0100 Subject: [PATCH 082/271] Update changelog --- Changelog.md | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/Changelog.md b/Changelog.md index f0fa753..160b0c4 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,3 +1,26 @@ + +## Breaking + +- Rewrite for new bootloader build system + - Compatible with bootloader 0.5.0+ +- Remove the following config options: `output`, `bootloader.*`, `minimum_image_size`, and `package_filepath` + - The bootloader is now fully controlled through cargo dependencies. + - For using a bootloader crate with name different than `bootloader` use [cargo's rename feature](https://doc.rust-lang.org/cargo/reference/specifying-dependencies.html#renaming-dependencies-in-cargotoml). +- Remove support for `bootloader_precompiled` + - The `bootloader` crate compiles fine on all architectures for some time and should be prefered +- Require the `llvm-tools-preview` rustup component + +## Other + +- Add support for default targets declared in `.cargo/config` files +- Add a `cargo-bootimage` executable that is equivalent to `bootimage build` and can be used as cargo subcommand (`cargo bootimage`) +- Add a new `bootimage runner` subcommand that can be used as `target.[…].runner` in `.cargo/config` files +- Make test timeout configurable and increase default to 5 minutes +- Move crate to 2018 edition +- Refactor and cleanup the code +- Remove the dependency on `failure` + - Use a custom `ErrorString` type instead + # 0.6.6 - Update dependencies From 3d1bbcb5af6969a58fe4c957e4df6e3a3a376443 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Wed, 27 Mar 2019 14:11:23 +0100 Subject: [PATCH 083/271] Add a tester subcommand that can be used to run integration tests --- src/args.rs | 20 ++++ src/lib.rs | 7 +- src/subcommand.rs | 1 + src/subcommand/tester.rs | 201 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 227 insertions(+), 2 deletions(-) create mode 100644 src/subcommand/tester.rs diff --git a/src/args.rs b/src/args.rs index e68a753..ea98206 100644 --- a/src/args.rs +++ b/src/args.rs @@ -30,6 +30,11 @@ pub(crate) fn parse_args() -> Result { cmd => cmd, }), Some("runner") => parse_runner_args(args), + Some("tester") => parse_runner_args(args).map(|cmd| match cmd { + Command::Runner(args) => Command::Tester(TesterArgs::from(args)), + Command::RunnerHelp => Command::TesterHelp, + other => other, + }), Some("--help") | Some("-h") => Ok(Command::Help), Some("--version") => Ok(Command::Version), _ => Ok(Command::NoSubcommand), @@ -247,3 +252,18 @@ pub struct RunnerArgs { pub executable: PathBuf, pub run_command: Option>, } + +#[derive(Debug, Clone)] +pub struct TesterArgs { + pub test_path: PathBuf, + pub run_command: Option>, +} + +impl From for TesterArgs { + fn from(args: RunnerArgs) -> Self { + Self { + test_path: args.executable, + run_command: args.run_command, + } + } +} diff --git a/src/lib.rs b/src/lib.rs index 0a1a976..8ec0ef8 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,4 +1,4 @@ -use args::{Args, RunnerArgs}; +use args::{Args, RunnerArgs, TesterArgs}; use std::fmt; pub mod args; @@ -15,12 +15,14 @@ enum Command { Run(Args), Test(Args), Runner(RunnerArgs), + Tester(TesterArgs), Help, BuildHelp, RunHelp, TestHelp, CargoBootimageHelp, RunnerHelp, + TesterHelp, Version, } @@ -31,13 +33,14 @@ pub fn run() -> Result<(), ErrorString> { Command::Run(args) => subcommand::run::run(args), Command::Test(args) => subcommand::test::test(args), Command::Runner(args) => subcommand::runner::runner(args), + Command::Tester(args) => subcommand::tester::tester(args), Command::NoSubcommand => help::no_subcommand(), Command::Help => Ok(help::help()), Command::BuildHelp => Ok(help::build_help()), Command::RunHelp => Ok(help::run_help()), Command::TestHelp => Ok(help::test_help()), Command::Version => Ok(println!("bootimage {}", env!("CARGO_PKG_VERSION"))), - Command::RunnerHelp | Command::CargoBootimageHelp => unimplemented!(), + Command::RunnerHelp | Command::TesterHelp | Command::CargoBootimageHelp => unimplemented!(), } } diff --git a/src/subcommand.rs b/src/subcommand.rs index f848c46..0e49f4f 100644 --- a/src/subcommand.rs +++ b/src/subcommand.rs @@ -2,3 +2,4 @@ pub mod build; pub mod run; pub mod runner; pub mod test; +pub mod tester; diff --git a/src/subcommand/tester.rs b/src/subcommand/tester.rs new file mode 100644 index 0000000..4b246d5 --- /dev/null +++ b/src/subcommand/tester.rs @@ -0,0 +1,201 @@ +use crate::{args::TesterArgs, builder::Builder, config, ErrorString}; +use std::{ + fs, + io::{self, Write}, + path::Path, + process, + process::Command, + time::Duration, +}; +use wait_timeout::ChildExt; + +pub(crate) fn tester(args: TesterArgs) -> Result<(), ErrorString> { + let builder = Builder::new(None)?; + let config = config::read_config(builder.kernel_manifest_path().to_owned())?; + + let test_name = args + .test_path + .file_stem() + .expect("no file stem") + .to_os_string() + .into_string() + .expect("test name invalid utf8"); + + let kernel_manifest_path = locate_cargo_manifest::locate_manifest().unwrap_or( + Path::new("Cargo.toml") + .canonicalize() + .expect("failed to canonicalize manifest path"), + ); + let kernel_root_path = kernel_manifest_path + .parent() + .expect("kernel manifest path has no parent"); + let kernel_manifest_content = + fs::read_to_string(&kernel_manifest_path).expect("failed to read kernel manifest"); + let kernel_manifest: toml::Value = kernel_manifest_content + .parse() + .expect("failed to parse Cargo.toml"); + + let kernel_name = kernel_manifest + .get("package") + .and_then(|p| p.get("name")) + .expect("no package.name found in Cargo.toml") + .as_str() + .expect("package name must be a string"); + let dependency_table = { + let mut table = toml::value::Table::new(); + let mut dependencies = kernel_manifest + .get("dependencies") + .map(|v| { + v.as_table() + .expect("`dependencies` must be a table in Cargo.toml") + .clone() + }) + .unwrap_or(toml::value::Table::new()); + dependencies.insert( + kernel_name.to_owned(), + toml::from_str(&format!(r#"path = "{}""#, kernel_root_path.display())).unwrap(), + ); + for (key, entry) in kernel_manifest + .get("dev-dependencies") + .map(|v| { + v.as_table() + .expect("`dev-dependencies` must be a table in Cargo.toml") + .clone() + }) + .unwrap_or(toml::value::Table::new()) + { + dependencies.insert(key, entry); + } + table.insert("dependencies".to_owned(), toml::Value::Table(dependencies)); + toml::Value::Table(table) + }; + let kernel_target_dir = Path::new("target") + .canonicalize() + .expect("failed to canonicalize target dir"); // TODO + let kernel_target_json = Path::new("x86_64-blog_os.json") + .canonicalize() + .expect("failed to canonicalize target.json"); // TODO + let kernel_target_json_triple = kernel_target_json + .file_stem() + .expect("kernel target json has no valid file stem"); + + let out_dir = kernel_target_dir.join("integration-tests").join(&test_name); + fs::create_dir_all(&out_dir).expect("failed to create out dir"); + + let manifest_path = out_dir.join("Cargo.toml"); + let manifest_content = format!( + r#" +[package] +authors = ["Bootimage Tester "] +name = "{test_name}" +version = "0.0.0" +edition = "2018" + +[[bin]] +name = "{test_name}" +path = "{test_path}" + +{dependency_table} +"#, + test_name = test_name, + test_path = args.test_path.display(), + dependency_table = dependency_table + ); + + fs::write(&manifest_path, manifest_content)?; + + let cargo = std::env::var("CARGO").unwrap_or("cargo".to_owned()); + let mut cmd = Command::new(cargo); + cmd.arg("xbuild"); + cmd.arg("--manifest-path").arg(&manifest_path); + cmd.arg("--target-dir").arg(&kernel_target_dir); + cmd.env("SYSROOT_DIR", &kernel_target_dir.join("sysroot")); // for cargo-xbuild + cmd.arg("--target").arg(&kernel_target_json); // TODO remove when default targets are canonicalized properly + let output = cmd.output().expect("failed to run cargo xbuild"); + if !output.status.success() { + io::stderr() + .write_all(&output.stderr) + .expect("failed to write to stderr"); + process::exit(1); + } + + let executable = kernel_target_dir + .join(&kernel_target_json_triple) + .join("debug") + .join(&test_name); + let bootimage_bin_path = out_dir.join(format!("bootimage-{}.bin", test_name)); + + builder.create_bootimage(&executable, &bootimage_bin_path, true)?; + + let run_cmd = args.run_command.clone().unwrap_or( + [ + "qemu-system-x86_64", + "-drive", + "format=raw,file={bootimage}", + "-device", + "isa-debug-exit,iobase=0xf4,iosize=0x04", + "-display", + "none", + "-serial", + "file:{output_file}", + ] + .into_iter() + .map(|&s| String::from(s)) + .collect(), + ); + + let output_file = out_dir.join(format!("output-{}.txt", test_name)); + + let mut command = process::Command::new(&run_cmd[0]); + for arg in &run_cmd[1..] { + command.arg( + arg.replace("{bootimage}", &format!("{}", bootimage_bin_path.display())) + .replace("{output_file}", &format!("{}", output_file.display())), + ); + } + 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); + let (exit_status, output) = 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))?; + Err("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.display(), + e + ) + })?; + Ok((exit_status, output)) + } + }?; + + match exit_status.code() { + None => Err("No QEMU Exit Code")?, + Some(5) => {} // 2 << 1 | 1 + Some(7) => { + // 3 << 1 | 1 + let fail_index = output.rfind("bootimage:stderr\n"); + if let Some(index) = fail_index { + Err(format!("Test Failed:\n{}", &output[index..]))? + } else { + Err("Test Failed")? + } + } + Some(c) => Err(format!("Test returned with unexpected exit code {}", c))?, + } + Ok(()) +} From 6b53e04890ac217d4178afe689b1d8e08e798d18 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Mon, 1 Apr 2019 16:07:48 +0200 Subject: [PATCH 084/271] Avoid TryFrom, since it is not in stable yet --- src/config.rs | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/config.rs b/src/config.rs index 93a4833..301e630 100644 --- a/src/config.rs +++ b/src/config.rs @@ -17,7 +17,7 @@ pub(crate) fn read_config(manifest_path: PathBuf) -> Result } pub(crate) fn read_config_inner(manifest_path: PathBuf) -> Result { - use std::{convert::TryFrom, fs::File, io::Read}; + use std::{fs::File, io::Read}; let cargo_toml: Value = { let mut content = String::new(); File::open(&manifest_path) @@ -54,10 +54,11 @@ pub(crate) fn read_config_inner(manifest_path: PathBuf) -> Result config.default_target = From::from(s), - ("test-timeout", Value::Integer(s)) => { - config.test_timeout = u64::try_from(s) - .map_err(|err| format!("test-timeout is not valid: {}", err))? - .into() + ("test-timeout", Value::Integer(timeout)) if timeout.is_negative() => { + Err(format!("test-timeout must not be negative"))? + } + ("test-timeout", Value::Integer(timeout)) => { + config.test_timeout = Some(timeout as u64); } ("run-command", Value::Array(array)) => { let mut command = Vec::new(); From bf405e3dd34f3592d4993d8a0e214e3d275b7abc Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Mon, 1 Apr 2019 16:10:48 +0200 Subject: [PATCH 085/271] We don't need u64 for the test timeout A timeout greater than 2^32 seconds (~136 years) does not make much sense, so we can use u32 instead of u64. --- src/config.rs | 6 +++--- src/subcommand/test.rs | 2 +- src/subcommand/tester.rs | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/config.rs b/src/config.rs index 301e630..5ccf1d4 100644 --- a/src/config.rs +++ b/src/config.rs @@ -7,7 +7,7 @@ pub struct Config { pub manifest_path: PathBuf, pub default_target: Option, pub run_command: Vec, - pub test_timeout: u64, + pub test_timeout: u32, } pub(crate) fn read_config(manifest_path: PathBuf) -> Result { @@ -58,7 +58,7 @@ pub(crate) fn read_config_inner(manifest_path: PathBuf) -> Result { - config.test_timeout = Some(timeout as u64); + config.test_timeout = Some(timeout as u32); } ("run-command", Value::Array(array)) => { let mut command = Vec::new(); @@ -85,7 +85,7 @@ struct ConfigBuilder { manifest_path: Option, default_target: Option, run_command: Option>, - test_timeout: Option, + test_timeout: Option, } impl Into for ConfigBuilder { diff --git a/src/subcommand/test.rs b/src/subcommand/test.rs index dbb8845..418a28f 100644 --- a/src/subcommand/test.rs +++ b/src/subcommand/test.rs @@ -50,7 +50,7 @@ pub(crate) fn test(mut args: Args) -> Result<(), ErrorString> { let mut child = command .spawn() .map_err(|e| format!("Failed to launch QEMU: {:?}\n{}", command, e))?; - let timeout = Duration::from_secs(config.test_timeout); + let timeout = Duration::from_secs(config.test_timeout.into()); match child .wait_timeout(timeout) .map_err(|e| format!("Failed to wait with timeout: {}", e))? diff --git a/src/subcommand/tester.rs b/src/subcommand/tester.rs index 4b246d5..2f1beb4 100644 --- a/src/subcommand/tester.rs +++ b/src/subcommand/tester.rs @@ -157,7 +157,7 @@ path = "{test_path}" let mut child = command .spawn() .map_err(|e| format!("Failed to launch QEMU: {:?}\n{}", command, e))?; - let timeout = Duration::from_secs(config.test_timeout); + let timeout = Duration::from_secs(config.test_timeout.into()); let (exit_status, output) = match child .wait_timeout(timeout) .map_err(|e| format!("Failed to wait with timeout: {}", e))? From c8e7bf745df47aecd0a085e919e73aae1e059c34 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Mon, 1 Apr 2019 17:50:24 +0200 Subject: [PATCH 086/271] Add a `--run-args` argument --- src/args.rs | 10 ++++++++++ src/subcommand/runner.rs | 3 +++ 2 files changed, 13 insertions(+) diff --git a/src/args.rs b/src/args.rs index ea98206..9f512cc 100644 --- a/src/args.rs +++ b/src/args.rs @@ -220,6 +220,7 @@ where .canonicalize() .map_err(|err| format!("Failed to canonicalize executable path: {}", err))?; let mut run_command = None; + let mut run_args = None; loop { match arg_iter.next().as_ref().map(|s| s.as_str()) { @@ -230,6 +231,13 @@ where } break; } + Some("--args") => { + let old = mem::replace(&mut run_args, Some(arg_iter.collect())); + if !old.is_none() { + Err("multiple `--args` arguments")?; + } + break; + } Some("--help") | Some("-h") => { return Ok(Command::RunnerHelp); } @@ -244,6 +252,7 @@ where Ok(Command::Runner(RunnerArgs { executable, run_command, + run_args: run_args, })) } @@ -251,6 +260,7 @@ where pub struct RunnerArgs { pub executable: PathBuf, pub run_command: Option>, + pub run_args: Option>, } #[derive(Debug, Clone)] diff --git a/src/subcommand/runner.rs b/src/subcommand/runner.rs index bbb6a16..1a38c41 100644 --- a/src/subcommand/runner.rs +++ b/src/subcommand/runner.rs @@ -20,6 +20,9 @@ pub(crate) fn runner(args: RunnerArgs) -> Result<(), ErrorString> { for arg in &run_cmd[1..] { command.arg(arg.replace("{bootimage}", &format!("{}", bootimage_bin.display()))); } + if let Some(run_args) = args.run_args { + command.args(run_args); + } let output = command .output() .map_err(|e| format!("Failed to execute `{:?}`: {}", command, e))?; From e1d59cd7c6104cb9ca4d0e82f6eae54bb98986c2 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Mon, 1 Apr 2019 18:41:51 +0200 Subject: [PATCH 087/271] Add a separate `parse_tester_args` function and add add a `--target` argument --- src/args.rs | 66 +++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 52 insertions(+), 14 deletions(-) diff --git a/src/args.rs b/src/args.rs index 9f512cc..c7e462e 100644 --- a/src/args.rs +++ b/src/args.rs @@ -30,11 +30,7 @@ pub(crate) fn parse_args() -> Result { cmd => cmd, }), Some("runner") => parse_runner_args(args), - Some("tester") => parse_runner_args(args).map(|cmd| match cmd { - Command::Runner(args) => Command::Tester(TesterArgs::from(args)), - Command::RunnerHelp => Command::TesterHelp, - other => other, - }), + Some("tester") => parse_tester_args(args), Some("--help") | Some("-h") => Ok(Command::Help), Some("--version") => Ok(Command::Version), _ => Ok(Command::NoSubcommand), @@ -252,7 +248,7 @@ where Ok(Command::Runner(RunnerArgs { executable, run_command, - run_args: run_args, + run_args, })) } @@ -263,17 +259,59 @@ pub struct RunnerArgs { pub run_args: Option>, } +fn parse_tester_args(args: A) -> Result +where + A: Iterator, +{ + let mut arg_iter = args.into_iter().fuse(); + let test_path = PathBuf::from( + arg_iter + .next() + .ok_or("excepted path to test source file as first argument")?, + ) + .canonicalize() + .map_err(|err| format!("Failed to canonicalize test path: {}", err))?; + let mut run_command = None; + let mut target = None; + + loop { + match arg_iter.next().as_ref().map(|s| s.as_str()) { + Some("--command") => { + let old = mem::replace(&mut run_command, Some(arg_iter.collect())); + if !old.is_none() { + Err("multiple `--command` arguments")?; + } + break; + } + Some("--target") => { + let old = mem::replace(&mut target, arg_iter.next()); + if !old.is_none() { + Err("multiple `--target` arguments")?; + } + break; + } + Some("--help") | Some("-h") => { + return Ok(Command::TesterHelp); + } + Some("--version") => { + return Ok(Command::Version); + } + None => break, + Some(arg) => Err(format!("unexpected argument `{}`", arg))?, + } + } + + Ok(Command::Tester(TesterArgs { + test_path, + run_command, + target, + })) +} + #[derive(Debug, Clone)] pub struct TesterArgs { pub test_path: PathBuf, pub run_command: Option>, + pub target: Option, } -impl From for TesterArgs { - fn from(args: RunnerArgs) -> Self { - Self { - test_path: args.executable, - run_command: args.run_command, - } - } -} From 9ccaf9f15526df09e6da9569e37eda953a4b5348 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Mon, 1 Apr 2019 18:42:46 +0200 Subject: [PATCH 088/271] Use correct target for tester and respect default targets --- src/subcommand/tester.rs | 37 ++++++++++++++++++++++++------------- 1 file changed, 24 insertions(+), 13 deletions(-) diff --git a/src/subcommand/tester.rs b/src/subcommand/tester.rs index 2f1beb4..49b9200 100644 --- a/src/subcommand/tester.rs +++ b/src/subcommand/tester.rs @@ -1,4 +1,4 @@ -use crate::{args::TesterArgs, builder::Builder, config, ErrorString}; +use crate::{cargo_config, args::TesterArgs, builder::Builder, config, ErrorString}; use std::{ fs, io::{self, Write}, @@ -72,14 +72,8 @@ pub(crate) fn tester(args: TesterArgs) -> Result<(), ErrorString> { let kernel_target_dir = Path::new("target") .canonicalize() .expect("failed to canonicalize target dir"); // TODO - let kernel_target_json = Path::new("x86_64-blog_os.json") - .canonicalize() - .expect("failed to canonicalize target.json"); // TODO - let kernel_target_json_triple = kernel_target_json - .file_stem() - .expect("kernel target json has no valid file stem"); - let out_dir = kernel_target_dir.join("integration-tests").join(&test_name); + let out_dir = kernel_target_dir.join("bootimage").join("integration-tests").join(&test_name); fs::create_dir_all(&out_dir).expect("failed to create out dir"); let manifest_path = out_dir.join("Cargo.toml"); @@ -110,7 +104,9 @@ path = "{test_path}" cmd.arg("--manifest-path").arg(&manifest_path); cmd.arg("--target-dir").arg(&kernel_target_dir); cmd.env("SYSROOT_DIR", &kernel_target_dir.join("sysroot")); // for cargo-xbuild - cmd.arg("--target").arg(&kernel_target_json); // TODO remove when default targets are canonicalized properly + if let Some(target) = args.target.as_ref().or(config.default_target.as_ref()) { + cmd.arg("--target").arg(target); + } let output = cmd.output().expect("failed to run cargo xbuild"); if !output.status.success() { io::stderr() @@ -119,10 +115,25 @@ path = "{test_path}" process::exit(1); } - let executable = kernel_target_dir - .join(&kernel_target_json_triple) - .join("debug") - .join(&test_name); + let kernel_target_triple = { + match args.target.or(config.default_target) { + None => cargo_config::default_target_triple(kernel_root_path, true)?, + Some(ref target) if target.ends_with(".json") => { + Some(Path::new(target).file_stem().expect("kernel target json has no valid file stem").to_str().expect("invalid unicode").to_owned()) + } + Some(triple) => Some(triple), + } + }; + + let executable = { + let mut path = kernel_target_dir.clone(); + if let Some(triple) = kernel_target_triple { + path.push(triple); + } + path.push("debug"); + path.push(&test_name); + path + }; let bootimage_bin_path = out_dir.join(format!("bootimage-{}.bin", test_name)); builder.create_bootimage(&executable, &bootimage_bin_path, true)?; From 5aad6cd1c17c53b83b2dc5aa76a67eec1daf03c2 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Tue, 2 Apr 2019 13:20:10 +0200 Subject: [PATCH 089/271] Run build command with --message-format=json to find out binary paths This frees us from walking the `.cargo/config` files manually since cargo just tells us where it placed the executables. We run the command a second time to provide the user with human readable output in case the compilation fails. This commit also improves a few other things: - Don't change current_dir when building bootloader so that rustup overrides are respected. Instead read the bootloader target manually from the bootloader's `.cargo/config` file. - Place bootimage.bin for running inside target/bootimage instead of a temp dir - Print the replaced command on `bootimage runner` (no {bootimage} placeholders) - Remove unneeded dependencies --- Cargo.lock | 109 +-------------------------------- Cargo.toml | 4 +- src/args.rs | 1 - src/builder.rs | 128 +++++++++++++++++++++++++++++++-------- src/cargo_config.rs | 61 ------------------- src/lib.rs | 1 - src/subcommand/build.rs | 53 ++++++---------- src/subcommand/run.rs | 6 +- src/subcommand/runner.rs | 46 +++++++++++--- src/subcommand/test.rs | 32 ++++++---- src/subcommand/tester.rs | 86 +++++++++++++++----------- 11 files changed, 235 insertions(+), 292 deletions(-) delete mode 100644 src/cargo_config.rs diff --git a/Cargo.lock b/Cargo.lock index d94e047..56481c0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -12,22 +12,15 @@ dependencies = [ name = "bootimage" version = "0.6.6" dependencies = [ - "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "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)", "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)", - "tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", "toml 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", "wait-timeout 0.2.0 (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 = "byteorder" -version = "1.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "cargo_metadata" version = "0.7.4" @@ -91,11 +84,6 @@ name = "error-chain" version = "0.12.0" source = "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 = "itoa" version = "0.4.2" @@ -163,31 +151,6 @@ dependencies = [ "proc-macro2 0.4.8 (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.42 (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.6 (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 = "rayon" version = "1.0.3" @@ -209,22 +172,6 @@ dependencies = [ "num_cpus 1.8.0 (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.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "scopeguard" version = "0.3.3" @@ -279,15 +226,6 @@ dependencies = [ "unicode-xid 0.1.0 (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.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "toml" version = "0.5.0" @@ -309,41 +247,8 @@ dependencies = [ "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "winapi" -version = "0.3.6" -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 = "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 arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)" = "a1e964f9e24d588183fcb43503abda40d288c8657dfc27311516ce2f05675aef" -"checksum byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a019b10a2a7cdeb292db131fc8113e57ea2a908f6e7894b0c3c671893b65dbeb" "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" @@ -352,7 +257,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "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 fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" "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" @@ -364,13 +268,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "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 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 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 rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" -"checksum remove_dir_all 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3488ba1b9a2084d38645c4c08276a1752dcbf2c7130d74f1569681ad5d2799c5" "checksum scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27" "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" @@ -378,12 +277,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "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 tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "15f2b5fb00ccdf689e0149d1b1b3c03fead81c2b37735d812fa8bddbbf41b6d8" "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 wait-timeout 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9f200f5b12eb75f8c1ed65abd4b2db8a6e1b138a20de009dacee265a2498f3f6" -"checksum winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "92c1eb33641e276cfa214a0522acad57be5c56b10cb348b3c5117db75f3ac4b0" -"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 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/Cargo.toml b/Cargo.toml index 28bf2fc..efc90fe 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,14 +8,12 @@ repository = "https://github.com/rust-osdev/bootimage" edition = "2018" [dependencies] -byteorder = "1.3.1" rayon = "1.0" toml = "0.5.0" wait-timeout = "0.2" -xmas-elf = "0.6.2" llvm-tools = "0.1.1" locate-cargo-manifest = "0.1.0" -tempdir = "0.3.7" +json = "0.11.13" [dependencies.cargo_metadata] version = "0.7.4" diff --git a/src/args.rs b/src/args.rs index c7e462e..ac33bc9 100644 --- a/src/args.rs +++ b/src/args.rs @@ -314,4 +314,3 @@ pub struct TesterArgs { pub run_command: Option>, pub target: Option, } - diff --git a/src/builder.rs b/src/builder.rs index 546d3af..fe19b21 100644 --- a/src/builder.rs +++ b/src/builder.rs @@ -1,5 +1,5 @@ use std::{ - fmt, io, + fmt, fs, io, path::{Path, PathBuf}, process::{self, Command}, }; @@ -45,13 +45,17 @@ impl Builder { )) } - pub fn build_kernel(&self, args: &[String], quiet: bool) -> Result<(), BuildKernelError> { + 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); + let mut cmd = process::Command::new(&cargo); cmd.arg("xbuild"); cmd.args(args); if !quiet { @@ -61,7 +65,7 @@ impl Builder { 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"); @@ -77,7 +81,29 @@ impl Builder { }); } - Ok(()) + // 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).unwrap().lines() { + let mut artifact = json::parse(line).unwrap(); + if let Some(executable) = artifact["executable"].take_string() { + executables.push(PathBuf::from(executable)); + } + } + + Ok(executables) } pub fn create_bootimage( @@ -115,6 +141,31 @@ impl Builder { "bootloader manifest has no target directory".into(), ), )?; + let bootloader_target = { + let cargo_config_content = match fs::read_to_string( + bootloader_root.join(".cargo").join("config"), + ) { + Err(ref err) if err.kind() == io::ErrorKind::NotFound => { + return Err(CreateBootimageError::BootloaderInvalid("No `.cargo/config` file found in bootloader crate\n\n\ + (If you're using the official bootloader crate, you need at least version 0.5.0.)".into())); + } + Err(err) => { + return Err(CreateBootimageError::Io { + message: "Failed to read `cargo/config` file of bootloader crate", + error: err, + }); + } + Ok(content) => content, + }; + let cargo_config: toml::Value = cargo_config_content.parse().map_err(|err| { + CreateBootimageError::BootloaderInvalid(format!( + "The `.cargo/config` file of the bootloader crate is not valid TOML: {}", + err + )) + })?; + let target = cargo_config.get("build").and_then(|v| v.get("target")).and_then(|v| v.as_str()).ok_or(CreateBootimageError::BootloaderInvalid("The `.cargo/config` file of the bootloader crate contains no build.target key or it is not valid".into()))?; + bootloader_root.join(target) + }; let bootloader_features = { let resolve = metadata.resolve.as_ref().ok_or( @@ -131,12 +182,6 @@ impl Builder { })?; bootloader_resolve.features.clone() }; - let bootloader_target_triple = - crate::cargo_config::default_target_triple(&bootloader_root, false) - .map_err(CreateBootimageError::BootloaderInvalid)? - .ok_or(CreateBootimageError::BootloaderInvalid(format!( - "bootloader must have a default target" - )))?; // build bootloader if !quiet { @@ -144,17 +189,23 @@ impl Builder { } let cargo = std::env::var("CARGO").unwrap_or("cargo".to_owned()); - let mut cmd = process::Command::new(cargo); - cmd.arg("xbuild"); - cmd.arg("--manifest-path"); - cmd.arg(&bootloader_pkg.manifest_path); - cmd.arg("--target-dir").arg(&target_dir); - cmd.arg("--features") - .arg(bootloader_features.as_slice().join(" ")); - cmd.arg("--release"); - cmd.current_dir(bootloader_root); - cmd.env("KERNEL", kernel_bin_path); - cmd.env_remove("RUSTFLAGS"); + 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("--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_remove("RUSTFLAGS"); + cmd.env("SYSROOT_DIR", target_dir.join("sysroot")); // for cargo-xbuild + cmd + }; + + let mut cmd = build_command(); if !quiet { cmd.stdout(process::Stdio::inherit()); cmd.stderr(process::Stdio::inherit()); @@ -169,10 +220,35 @@ impl Builder { }); } - let bootloader_elf_path = target_dir - .join(&bootloader_target_triple) - .join("release") - .join(&bootloader_name); + // 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).unwrap().lines() { + let mut artifact = json::parse(line).unwrap(); + 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 diff --git a/src/cargo_config.rs b/src/cargo_config.rs deleted file mode 100644 index 4e57ad7..0000000 --- a/src/cargo_config.rs +++ /dev/null @@ -1,61 +0,0 @@ -use std::{ - fs, - path::{Path, PathBuf}, -}; - -pub fn default_target_triple(crate_root: &Path, walk_up: bool) -> Result, String> { - let default_triple = default_target(crate_root, walk_up)?; - default_triple - .map(|(target, crate_root)| { - if target.ends_with(".json") { - crate_root - .join(target) - .file_stem() - .ok_or(String::from( - "The target path specfied in `build.target` has no file stem", - ))? - .to_os_string() - .into_string() - .map_err(|err| format!("Default target triple not valid UTF-8: {:?}", err)) - } else { - Ok(target) - } - }) - .transpose() -} - -fn default_target(crate_root: &Path, walk_up: bool) -> Result, String> { - let mut parent_dir = crate_root; - - loop { - let config_path = parent_dir.join(".cargo/config"); - if config_path.exists() { - let config_content = fs::read_to_string(config_path).map_err(|err| { - format!("Failed to read `.cargo/config` file of crate: {:?}", err) - })?; - let config = config_content.parse::().map_err(|err| { - format!( - "Failed to parse `.cargo/config` of crate as toml: {:?}", - err - ) - })?; - let target = config - .get("build") - .and_then(|v| v.get("target")) - .and_then(|v| v.as_str()) - .map(String::from); - if let Some(target) = target { - return Ok(Some((target, parent_dir.to_owned()))); - } - } - if walk_up { - parent_dir = match parent_dir.parent() { - Some(parent) => parent, - None => break, - } - } else { - break; - } - } - Ok(None) -} diff --git a/src/lib.rs b/src/lib.rs index 8ec0ef8..054087f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -3,7 +3,6 @@ use std::fmt; pub mod args; pub mod builder; -pub mod cargo_config; pub mod config; pub mod help; diff --git a/src/subcommand/build.rs b/src/subcommand/build.rs index 6db5f3c..4b496b8 100644 --- a/src/subcommand/build.rs +++ b/src/subcommand/build.rs @@ -1,8 +1,5 @@ -use crate::{args::Args, builder::Builder, cargo_config, config, ErrorString}; -use std::{ - path::{Path, PathBuf}, - process, -}; +use crate::{args::Args, builder::Builder, config, ErrorString}; +use std::{path::PathBuf, process}; pub(crate) fn build(mut args: Args) -> Result<(), ErrorString> { let builder = Builder::new(args.manifest_path().clone())?; @@ -16,40 +13,30 @@ pub(crate) fn build_impl( builder: &Builder, args: &Args, quiet: bool, -) -> Result { +) -> Result, ErrorString> { run_cargo_fetch(&args); - builder.build_kernel(&args.cargo_args, quiet)?; + let executables = builder.build_kernel(&args.cargo_args, quiet)?; + if executables.len() == 0 { + Err("no executables built")?; + } - let out_dir = out_dir(&args, &builder)?; - let kernel_package = builder - .kernel_package() - .map_err(|key| format!("Kernel package not found in cargo metadata (`{}`)", key))?; - let kernel_bin_name = args.bin_name().as_ref().unwrap_or(&kernel_package.name); - let kernel_path = out_dir.join(kernel_bin_name); + let mut bootimages = Vec::new(); - let bootimage_path = out_dir.join(format!("bootimage-{}.bin", kernel_bin_name)); - builder.create_bootimage(&kernel_path, &bootimage_path, quiet)?; - Ok(bootimage_path) -} + 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")?; -fn out_dir(args: &Args, builder: &Builder) -> Result { - let target_dir = PathBuf::from(&builder.kernel_metadata().target_directory); - let mut out_dir = target_dir; - if let &Some(ref target) = args.target() { - out_dir.push(Path::new(target).file_stem().unwrap().to_str().unwrap()); - } else { - let default_triple = cargo_config::default_target_triple(builder.kernel_root(), true)?; - if let Some(triple) = default_triple { - out_dir.push(triple); - } + let bootimage_path = out_dir.join(format!("bootimage-{}.bin", file_stem)); + builder.create_bootimage(&executable, &bootimage_path, quiet)?; + bootimages.push(bootimage_path); } - if args.release() { - out_dir.push("release"); - } else { - out_dir.push("debug"); - } - Ok(out_dir) + + Ok(bootimages) } fn run_cargo_fetch(args: &Args) { diff --git a/src/subcommand/run.rs b/src/subcommand/run.rs index 92eddd5..d62e8f3 100644 --- a/src/subcommand/run.rs +++ b/src/subcommand/run.rs @@ -8,7 +8,11 @@ pub(crate) fn run(mut args: Args) -> Result<(), ErrorString> { let config = config::read_config(builder.kernel_manifest_path().to_owned())?; args.apply_default_target(&config, builder.kernel_root()); - let bootimage_path = build::build_impl(&builder, &mut args, false)?; + let bootimages = build::build_impl(&builder, &mut args, false)?; + 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); diff --git a/src/subcommand/runner.rs b/src/subcommand/runner.rs index 1a38c41..668a37c 100644 --- a/src/subcommand/runner.rs +++ b/src/subcommand/runner.rs @@ -1,11 +1,41 @@ use crate::{args::RunnerArgs, builder::Builder, ErrorString}; -use std::process; +use std::{fs, process}; pub(crate) fn runner(args: RunnerArgs) -> Result<(), ErrorString> { - let out_dir = tempdir::TempDir::new("bootimage-runner")?; - let bootimage_bin = out_dir.path().join("bootimage.bin"); - let builder = Builder::new(None)?; + + let bootimage_bin = { + let kernel_target_dir = &builder.kernel_metadata().target_directory; + let bootimage_target_dir = kernel_target_dir.join("bootimage").join("runner"); + + let parent = args + .executable + .parent() + .ok_or("kernel executable has no parent")?; + 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")?; + let sub_path = parent.strip_prefix(kernel_target_dir).map_err(|err| { + format!( + "kernel executable does not live in kernel target directory: {}", + err + ) + })?; + + let out_dir = bootimage_target_dir.join(sub_path); + fs::create_dir_all(&out_dir).map_err(|err| { + format!( + "failed to create output directory {}: {}", + out_dir.display(), + err + ) + })?; + out_dir.join(format!("bootimage-{}.bin", file_stem)) + }; + builder.create_bootimage(&args.executable, &bootimage_bin, false)?; let run_cmd = args.run_command.unwrap_or(vec![ @@ -14,8 +44,6 @@ pub(crate) fn runner(args: RunnerArgs) -> Result<(), ErrorString> { "format=raw,file={bootimage}".into(), ]); - println!("Running {:?}", run_cmd); - let mut command = process::Command::new(&run_cmd[0]); for arg in &run_cmd[1..] { command.arg(arg.replace("{bootimage}", &format!("{}", bootimage_bin.display()))); @@ -23,6 +51,9 @@ pub(crate) fn runner(args: RunnerArgs) -> Result<(), ErrorString> { if let Some(run_args) = args.run_args { command.args(run_args); } + + println!("Running: {:?}", command); + let output = command .output() .map_err(|e| format!("Failed to execute `{:?}`: {}", command, e))?; @@ -38,8 +69,5 @@ pub(crate) fn runner(args: RunnerArgs) -> Result<(), ErrorString> { }); } - drop(bootimage_bin); - out_dir.close()?; - Ok(()) } diff --git a/src/subcommand/test.rs b/src/subcommand/test.rs index 418a28f..b93f1e0 100644 --- a/src/subcommand/test.rs +++ b/src/subcommand/test.rs @@ -1,6 +1,6 @@ use crate::{args::Args, builder::Builder, config, subcommand::build, ErrorString}; use rayon::prelude::*; -use std::{fs, io, io::Write, path::PathBuf, process, time::Duration}; +use std::{fs, io, io::Write, process, time::Duration}; use wait_timeout::ChildExt; pub(crate) fn test(mut args: Args) -> Result<(), ErrorString> { @@ -13,21 +13,29 @@ pub(crate) fn test(mut args: Args) -> Result<(), ErrorString> { let kernel_package = builder .kernel_package() .map_err(|key| format!("Kernel package not found it cargo metadata (`{}`)", key))?; - let test_targets = kernel_package + let test_target_iter = kernel_package .targets .iter() - .filter(|t| t.kind == ["bin"] && t.name.starts_with("test-")) - .map(|target| { - println!("BUILD: {}", target.name); + .filter(|t| t.kind == ["bin"] && t.name.starts_with("test-")); - let mut target_args = test_args.clone(); - target_args.set_bin_name(target.name.clone()); - let test_bin_path = build::build_impl(&builder, &mut target_args, true) - .expect(&format!("Failed to build test: {}", target.name)); + let mut test_targets = Vec::new(); + for target in test_target_iter { + println!("BUILD: {}", target.name); - (target, test_bin_path) - }) - .collect::>(); + 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() diff --git a/src/subcommand/tester.rs b/src/subcommand/tester.rs index 49b9200..a48e6cc 100644 --- a/src/subcommand/tester.rs +++ b/src/subcommand/tester.rs @@ -1,8 +1,7 @@ -use crate::{cargo_config, args::TesterArgs, builder::Builder, config, ErrorString}; +use crate::{args::TesterArgs, builder::Builder, config, ErrorString}; use std::{ fs, - io::{self, Write}, - path::Path, + path::{Path, PathBuf}, process, process::Command, time::Duration, @@ -69,11 +68,10 @@ pub(crate) fn tester(args: TesterArgs) -> Result<(), ErrorString> { table.insert("dependencies".to_owned(), toml::Value::Table(dependencies)); toml::Value::Table(table) }; - let kernel_target_dir = Path::new("target") - .canonicalize() - .expect("failed to canonicalize target dir"); // TODO - let out_dir = kernel_target_dir.join("bootimage").join("integration-tests").join(&test_name); + let kernel_target_dir = &builder.kernel_metadata().target_directory; + let integration_test_dir = kernel_target_dir.join("bootimage").join("tester"); + let out_dir = integration_test_dir.join(&test_name); fs::create_dir_all(&out_dir).expect("failed to create out dir"); let manifest_path = out_dir.join("Cargo.toml"); @@ -99,43 +97,57 @@ path = "{test_path}" fs::write(&manifest_path, manifest_content)?; let cargo = std::env::var("CARGO").unwrap_or("cargo".to_owned()); - let mut cmd = Command::new(cargo); - cmd.arg("xbuild"); - cmd.arg("--manifest-path").arg(&manifest_path); - cmd.arg("--target-dir").arg(&kernel_target_dir); - cmd.env("SYSROOT_DIR", &kernel_target_dir.join("sysroot")); // for cargo-xbuild - if let Some(target) = args.target.as_ref().or(config.default_target.as_ref()) { - cmd.arg("--target").arg(target); - } - let output = cmd.output().expect("failed to run cargo xbuild"); + let build_command = || { + let mut cmd = Command::new(&cargo); + cmd.arg("xbuild"); + cmd.arg("--manifest-path").arg(&manifest_path); + cmd.arg("--target-dir") + .arg(&integration_test_dir.join("target")); + cmd.env("SYSROOT_DIR", &integration_test_dir.join("sysroot")); // for cargo-xbuild + + if let Some(target) = args.target.as_ref().or(config.default_target.as_ref()) { + cmd.arg("--target").arg(target); + } + cmd + }; + + let mut cmd = build_command(); + let output = cmd + .output() + .map_err(|err| format!("failed to run cargo xbuild: {}", err))?; if !output.status.success() { - io::stderr() - .write_all(&output.stderr) - .expect("failed to write to stderr"); - process::exit(1); + Err(format!( + "Test build failed:\n{}", + String::from_utf8_lossy(&output.stderr) + ))?; } - let kernel_target_triple = { - match args.target.or(config.default_target) { - None => cargo_config::default_target_triple(kernel_root_path, true)?, - Some(ref target) if target.ends_with(".json") => { - Some(Path::new(target).file_stem().expect("kernel target json has no valid file stem").to_str().expect("invalid unicode").to_owned()) + let mut cmd_json = build_command(); + cmd_json.arg("--message-format").arg("json"); + let output = cmd_json.output().map_err(|err| { + format!( + "failed to execute bootloader build command with json output: {}", + err + ) + })?; + if !output.status.success() { + Err(format!( + "Test build (with json output) failed:\n{}", + String::from_utf8_lossy(&output.stderr) + ))?; + } + let mut test_executable = None; + for line in String::from_utf8(output.stdout).unwrap().lines() { + let mut artifact = json::parse(line).unwrap(); + if let Some(executable) = artifact["executable"].take_string() { + if test_executable.replace(PathBuf::from(executable)).is_some() { + Err("integration test has multiple executables")?; } - Some(triple) => Some(triple), } - }; + } - let executable = { - let mut path = kernel_target_dir.clone(); - if let Some(triple) = kernel_target_triple { - path.push(triple); - } - path.push("debug"); - path.push(&test_name); - path - }; + let executable = test_executable.ok_or("no test executable")?; let bootimage_bin_path = out_dir.join(format!("bootimage-{}.bin", test_name)); - builder.create_bootimage(&executable, &bootimage_bin_path, true)?; let run_cmd = args.run_command.clone().unwrap_or( From 675c8acc015129b4f000304fd9c1db6137c4d537 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Tue, 2 Apr 2019 14:27:23 +0200 Subject: [PATCH 090/271] Pass through exit code of run commands --- src/bin/cargo-bootimage.rs | 7 +------ src/lib.rs | 38 ++++++++++++++++++++++++++------------ src/main.rs | 7 +------ src/subcommand/run.rs | 6 +++--- src/subcommand/runner.rs | 15 ++------------- 5 files changed, 33 insertions(+), 40 deletions(-) diff --git a/src/bin/cargo-bootimage.rs b/src/bin/cargo-bootimage.rs index d6e09a5..5349675 100644 --- a/src/bin/cargo-bootimage.rs +++ b/src/bin/cargo-bootimage.rs @@ -1,8 +1,3 @@ -use std::process; - pub fn main() { - if let Err(err) = bootimage::run() { - eprintln!("Error: {}", err.message); - process::exit(err.exit_code); - } + bootimage::lib_main(); } diff --git a/src/lib.rs b/src/lib.rs index 054087f..c166502 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,5 +1,5 @@ use args::{Args, RunnerArgs, TesterArgs}; -use std::fmt; +use std::{fmt, process}; pub mod args; pub mod builder; @@ -25,20 +25,34 @@ enum Command { Version, } -pub fn run() -> Result<(), ErrorString> { +pub fn lib_main() { + match run() { + Err(err) => { + eprintln!("Error: {}", err.message); + process::exit(err.exit_code); + } + Ok(Some(exit_code)) => { + process::exit(exit_code); + } + Ok(None) => {} + } +} + +pub fn run() -> Result, ErrorString> { let command = args::parse_args()?; + let none = |()| None; match command { - Command::Build(args) => subcommand::build::build(args), - Command::Run(args) => subcommand::run::run(args), - Command::Test(args) => subcommand::test::test(args), - Command::Runner(args) => subcommand::runner::runner(args), - Command::Tester(args) => subcommand::tester::tester(args), + 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::Tester(args) => subcommand::tester::tester(args).map(none), Command::NoSubcommand => help::no_subcommand(), - Command::Help => Ok(help::help()), - Command::BuildHelp => Ok(help::build_help()), - Command::RunHelp => Ok(help::run_help()), - Command::TestHelp => Ok(help::test_help()), - Command::Version => Ok(println!("bootimage {}", env!("CARGO_PKG_VERSION"))), + Command::Help => Ok(help::help()).map(none), + Command::BuildHelp => Ok(help::build_help()).map(none), + Command::RunHelp => Ok(help::run_help()).map(none), + Command::TestHelp => Ok(help::test_help()).map(none), + Command::Version => Ok(println!("bootimage {}", env!("CARGO_PKG_VERSION"))).map(none), Command::RunnerHelp | Command::TesterHelp | Command::CargoBootimageHelp => unimplemented!(), } } diff --git a/src/main.rs b/src/main.rs index d6e09a5..5349675 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,8 +1,3 @@ -use std::process; - pub fn main() { - if let Err(err) = bootimage::run() { - eprintln!("Error: {}", err.message); - process::exit(err.exit_code); - } + bootimage::lib_main(); } diff --git a/src/subcommand/run.rs b/src/subcommand/run.rs index d62e8f3..287b195 100644 --- a/src/subcommand/run.rs +++ b/src/subcommand/run.rs @@ -1,7 +1,7 @@ use crate::{args::Args, builder::Builder, config, ErrorString}; use std::process; -pub(crate) fn run(mut args: Args) -> Result<(), ErrorString> { +pub(crate) fn run(mut args: Args) -> Result { use crate::subcommand::build; let builder = Builder::new(args.manifest_path().clone())?; @@ -27,11 +27,11 @@ pub(crate) fn run(mut args: Args) -> Result<(), ErrorString> { ); } command.args(&args.run_args); - command.status().map_err(|err| { + let exit_status = command.status().map_err(|err| { ErrorString::from(format!( "Failed to execute run command `{:?}`: {}", command, err )) })?; - Ok(()) + Ok(exit_status.code().unwrap_or(1)) } diff --git a/src/subcommand/runner.rs b/src/subcommand/runner.rs index 668a37c..4bbbe74 100644 --- a/src/subcommand/runner.rs +++ b/src/subcommand/runner.rs @@ -1,7 +1,7 @@ use crate::{args::RunnerArgs, builder::Builder, ErrorString}; use std::{fs, process}; -pub(crate) fn runner(args: RunnerArgs) -> Result<(), ErrorString> { +pub(crate) fn runner(args: RunnerArgs) -> Result { let builder = Builder::new(None)?; let bootimage_bin = { @@ -58,16 +58,5 @@ pub(crate) fn runner(args: RunnerArgs) -> Result<(), ErrorString> { .output() .map_err(|e| format!("Failed to execute `{:?}`: {}", command, e))?; - if !output.status.success() { - return Err(ErrorString { - exit_code: output.status.code().unwrap_or(1), - message: Box::new(format!( - "Command `{:?}` failed:\n{}", - command, - String::from_utf8_lossy(&output.stderr) - )), - }); - } - - Ok(()) + Ok(output.status.code().unwrap_or(1)) } From 2e6c48f1974614f33ba3a76c4f6d8c9fb7622349 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Tue, 2 Apr 2019 15:00:02 +0200 Subject: [PATCH 091/271] Print newlines before errors --- src/builder.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/builder.rs b/src/builder.rs index fe19b21..7ae70af 100644 --- a/src/builder.rs +++ b/src/builder.rs @@ -329,17 +329,17 @@ impl fmt::Display for BuildKernelError { 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: {}: {}", 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: {}", String::from_utf8_lossy(stderr)) + writeln!(f, "Kernel build failed:\n{}", String::from_utf8_lossy(stderr)) } BuildKernelError::CargoConfigInvalid{path,error} => { - writeln!(f, "Failed to read cargo config at {}: {}", path.display(), error) + writeln!(f, "Failed to read cargo config at {}:\n{}", path.display(), error) }, } } From 3739e4e90671d80dcf5e4f4e14af54729b31726c Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Mon, 1 Apr 2019 18:43:27 +0200 Subject: [PATCH 092/271] Update test suite --- azure-pipelines.yml | 303 ++++++++++------ example-kernels/{testing => }/.gitignore | 0 .../{default-target-bootimage => }/Cargo.lock | 90 ++++- example-kernels/Cargo.toml | 10 + example-kernels/basic/Cargo.lock | 297 ---------------- example-kernels/basic/src/main.rs | 2 +- .../default-target-bootimage/Cargo.toml | 4 +- .../default-target-bootimage/src/main.rs | 2 +- .../x86_64-default-target.json | 15 - .../default-target-cargo/.cargo/config | 2 +- .../default-target-cargo/Cargo.lock | 328 ------------------ .../default-target-cargo/Cargo.toml | 2 - .../default-target-cargo/src/main.rs | 2 +- .../x86_64-default-target.json | 15 - example-kernels/runner/.cargo/config | 5 + example-kernels/runner/.gitignore | 2 + example-kernels/runner/Cargo.toml | 9 + example-kernels/runner/src/main.rs | 28 ++ example-kernels/tester/.gitignore | 2 + example-kernels/tester/Cargo.toml | 9 + example-kernels/tester/build.rs | 27 ++ example-kernels/tester/src/lib.rs | 21 ++ .../tester/tests/integration_tests.rs | 14 + .../integration_tests/test-basic-boot.rs | 27 ++ .../tests/integration_tests/test-panic.rs | 21 ++ .../testing-qemu-exit-code/.gitignore | 2 + .../Cargo.toml | 6 +- .../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} | 2 +- .../src/bin/test-panic-serial.rs} | 2 +- .../src/lib.rs | 0 .../src/main.rs | 0 example-kernels/testing/Cargo.lock | 328 ------------------ example-kernels/testing/x86_64-testing.json | 15 - ... => x86_64-bootimage-example-kernels.json} | 0 39 files changed, 542 insertions(+), 1139 deletions(-) rename example-kernels/{testing => }/.gitignore (100%) rename example-kernels/{default-target-bootimage => }/Cargo.lock (82%) create mode 100644 example-kernels/Cargo.toml delete mode 100644 example-kernels/basic/Cargo.lock delete mode 100644 example-kernels/default-target-bootimage/x86_64-default-target.json delete mode 100644 example-kernels/default-target-cargo/Cargo.lock delete mode 100644 example-kernels/default-target-cargo/x86_64-default-target.json create mode 100644 example-kernels/runner/.cargo/config create mode 100644 example-kernels/runner/.gitignore create mode 100644 example-kernels/runner/Cargo.toml create mode 100644 example-kernels/runner/src/main.rs create mode 100644 example-kernels/tester/.gitignore create mode 100644 example-kernels/tester/Cargo.toml create mode 100644 example-kernels/tester/build.rs create mode 100644 example-kernels/tester/src/lib.rs create mode 100644 example-kernels/tester/tests/integration_tests.rs create mode 100644 example-kernels/tester/tests/integration_tests/test-basic-boot.rs create mode 100644 example-kernels/tester/tests/integration_tests/test-panic.rs create mode 100644 example-kernels/testing-qemu-exit-code/.gitignore rename example-kernels/{testing => testing-qemu-exit-code}/Cargo.toml (66%) create mode 100644 example-kernels/testing-qemu-exit-code/src/bin/test-basic-boot.rs create mode 100644 example-kernels/testing-qemu-exit-code/src/bin/test-panic.rs create mode 100644 example-kernels/testing-qemu-exit-code/src/lib.rs create mode 100644 example-kernels/testing-serial-result/.gitignore create mode 100644 example-kernels/testing-serial-result/Cargo.toml rename example-kernels/{testing/src/bin/test-basic-boot.rs => testing-serial-result/src/bin/test-basic-boot-serial.rs} (92%) rename example-kernels/{testing/src/bin/test-panic.rs => testing-serial-result/src/bin/test-panic-serial.rs} (86%) rename example-kernels/{testing => testing-serial-result}/src/lib.rs (100%) rename example-kernels/{testing => testing-serial-result}/src/main.rs (100%) delete mode 100644 example-kernels/testing/Cargo.lock delete mode 100644 example-kernels/testing/x86_64-testing.json rename example-kernels/{basic/x86_64-basic.json => x86_64-bootimage-example-kernels.json} (100%) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index d1cab8e..5c85131 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -11,117 +11,192 @@ trigger: # Build pull requests. - master -strategy: - matrix: - linux: - image_name: 'ubuntu-16.04' - rustup_toolchain: stable - mac: - image_name: 'macos-10.13' - 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)' - -- script: curl -sSf -o rustup-init.exe https://win.rustup.rs && rustup-init.exe -y --default-toolchain %RUSTUP_TOOLCHAIN% - condition: eq( variables['Agent.OS'], 'Windows_NT' ) - displayName: 'Install Rust (Windows)' - -- script: | - echo ##vso[task.setvariable variable=PATH;]%PATH%;%USERPROFILE%\.cargo\bin - condition: eq( variables['Agent.OS'], 'Windows_NT' ) - displayName: 'Add ~/.cargo/bin to PATH (Windows)' - -- script: | - rustc -Vv - cargo -V - displayName: 'Print Rust Version' - continueOnError: true - -- script: cargo build - displayName: 'Build' - -- script: cargo test - displayName: 'Test' - -- 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: rustup toolchain add nightly - displayName: 'Install Rust Nightly' - -- script: bootimage build --target x86_64-basic.json && file target/x86_64-basic/debug/bootimage-basic.bin - workingDirectory: example-kernels/basic - displayName: 'Build Example Kernel "Basic"' - -- script: bootimage run --target x86_64-basic.json - workingDirectory: example-kernels/basic - displayName: 'Run Example Kernel "basic"' - -- script: bootimage build && file target/x86_64-default-target/debug/bootimage-default-target-bootimage.bin - workingDirectory: example-kernels/default-target-bootimage - displayName: 'Build Example Kernel "default-target-bootimage"' - -- script: bootimage run - workingDirectory: example-kernels/default-target-bootimage - displayName: 'Run Example Kernel "default-target-bootimage"' - -- script: bootimage build && file target/x86_64-default-target/debug/bootimage-default-target-cargo.bin - workingDirectory: example-kernels/default-target-cargo - displayName: 'Build Example Kernel "default-target-cargo"' - -- script: bootimage run - workingDirectory: example-kernels/default-target-cargo - displayName: 'Run Example Kernel "default-target-cargo"' +jobs: +- job: build + displayName: Build + strategy: + matrix: + linux: + image_name: 'ubuntu-16.04' + rustup_toolchain: stable + mac: + image_name: 'macos-10.13' + 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)' + + - script: curl -sSf -o rustup-init.exe https://win.rustup.rs && rustup-init.exe -y --default-toolchain %RUSTUP_TOOLCHAIN% + condition: eq( variables['Agent.OS'], 'Windows_NT' ) + displayName: 'Install Rust (Windows)' + + - script: | + echo ##vso[task.setvariable variable=PATH;]%PATH%;%USERPROFILE%\.cargo\bin + condition: eq( variables['Agent.OS'], 'Windows_NT' ) + displayName: 'Add ~/.cargo/bin to PATH (Windows)' + + - 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.13' + 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)' + + - script: curl -sSf -o rustup-init.exe https://win.rustup.rs && rustup-init.exe -y --default-toolchain %RUSTUP_TOOLCHAIN% + condition: eq( variables['Agent.OS'], 'Windows_NT' ) + displayName: 'Install Rust (Windows)' + + - script: | + echo ##vso[task.setvariable variable=PATH;]%PATH%;%USERPROFILE%\.cargo\bin + condition: eq( variables['Agent.OS'], 'Windows_NT' ) + displayName: 'Add ~/.cargo/bin to PATH (Windows)' + + - 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' + + - script: cargo xrun + workingDirectory: example-kernels/runner + displayName: 'Run `cargo xrun` for "runner" kernel' + + - script: cargo test + workingDirectory: example-kernels/tester + displayName: 'Run `cargo test` for "tester" kernel' diff --git a/example-kernels/testing/.gitignore b/example-kernels/.gitignore similarity index 100% rename from example-kernels/testing/.gitignore rename to example-kernels/.gitignore diff --git a/example-kernels/default-target-bootimage/Cargo.lock b/example-kernels/Cargo.lock similarity index 82% rename from example-kernels/default-target-bootimage/Cargo.lock rename to example-kernels/Cargo.lock index 06cfb07..cd749b3 100644 --- a/example-kernels/default-target-bootimage/Cargo.lock +++ b/example-kernels/Cargo.lock @@ -12,9 +12,7 @@ dependencies = [ name = "basic" version = "0.1.0" dependencies = [ - "bootloader 0.4.0", - "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)", + "bootloader 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", "x86_64 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -30,7 +28,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "bootloader" -version = "0.4.0" +version = "0.5.0" +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.4 (registry+https://github.com/rust-lang/crates.io-index)", @@ -45,6 +44,22 @@ name = "cc" version = "1.0.32" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "default-target-bootimage" +version = "0.1.0" +dependencies = [ + "bootloader 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "x86_64 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "default-target-cargo" +version = "0.1.0" +dependencies = [ + "bootloader 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "x86_64 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "fixedvec" version = "0.2.3" @@ -71,9 +86,17 @@ 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.50" +version = "0.2.51" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -105,7 +128,7 @@ 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.50 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.51 (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.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -150,6 +173,14 @@ dependencies = [ "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "runner" +version = "0.1.0" +dependencies = [ + "bootloader 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "x86_64 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "rustc_version" version = "0.2.3" @@ -185,6 +216,11 @@ 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" @@ -194,6 +230,33 @@ dependencies = [ "remove_dir_all 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "tester" +version = "0.1.0" +dependencies = [ + "bootloader 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "x86_64 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "testing-qemu-exit-code" +version = "0.1.0" +dependencies = [ + "bootloader 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "x86_64 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "testing-serial-result" +version = "0.1.0" +dependencies = [ + "bootloader 0.5.0 (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.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "uart_16550" version = "0.1.0" @@ -215,7 +278,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "ux" -version = "0.1.2" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -246,7 +309,7 @@ dependencies = [ "bitflags 1.0.4 (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.2 (registry+https://github.com/rust-lang/crates.io-index)", + "ux 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -259,7 +322,7 @@ dependencies = [ "bitflags 1.0.4 (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.2 (registry+https://github.com/rust-lang/crates.io-index)", + "ux 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -272,7 +335,7 @@ dependencies = [ "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "raw-cpuid 6.1.0 (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.2 (registry+https://github.com/rust-lang/crates.io-index)", + "ux 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -292,12 +355,14 @@ 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.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "228047a76f468627ca71776ecdebd732a3423081fcf5125585bcd7c49886ce12" +"checksum bootloader 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8668a7d724534aba1c3f2509eea122fcf611c31101662ecb947d502cc3cb96ae" "checksum cc 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)" = "ad0daef304fa0b4238f5f7ed7178774b43b06f6a9b6509f6642bef4ff1f7b9b2" "checksum fixedvec 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7c6c16d316ccdac21a4dd648e314e76facbbaf316e83ca137d0857a9c07419d0" "checksum font8x8 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b81d84c3c978af7d05d31a2198af4b9ba956d819d15d8f6d58fc150e33f8dc1f" "checksum fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" "checksum getopts 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)" = "0a7292d30132fb5424b354f5dc02512a86e4c516fe544bb7a25e7f266951b797" -"checksum libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)" = "aab692d7759f5cd8c859e169db98ae5b52c924add2af5fbbca11d12fefb567c1" +"checksum lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bc5729f27f159ddd61f4df6228e827e86643d4d3e7c32183cb30a1c08f604a14" +"checksum libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)" = "bedcc7a809076656486ffe045abeeac163da1b558e963a31e29fbfbeba916917" "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" @@ -313,11 +378,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "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.2 (registry+https://github.com/rust-lang/crates.io-index)" = "53d8df5dd8d07fedccd202de1887d94481fadaea3db70479f459e8163a1fab41" +"checksum ux 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "88dfeb711b61ce620c0cb6fd9f8e3e678622f0c971da2a63c4b3e25e88ed012f" "checksum winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "92c1eb33641e276cfa214a0522acad57be5c56b10cb348b3c5117db75f3ac4b0" "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" diff --git a/example-kernels/Cargo.toml b/example-kernels/Cargo.toml new file mode 100644 index 0000000..03cc7ed --- /dev/null +++ b/example-kernels/Cargo.toml @@ -0,0 +1,10 @@ +[workspace] +members = [ + "basic", + "default-target-bootimage", + "default-target-cargo", + "runner", + "tester", + "testing-qemu-exit-code", + "testing-serial-result", +] \ No newline at end of file diff --git a/example-kernels/basic/Cargo.lock b/example-kernels/basic/Cargo.lock deleted file mode 100644 index dd4ef6b..0000000 --- a/example-kernels/basic/Cargo.lock +++ /dev/null @@ -1,297 +0,0 @@ -# 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.4.0", - "x86_64 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "bit_field" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "bitflags" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "bootloader" -version = "0.4.0" -dependencies = [ - "fixedvec 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "font8x8 0.2.4 (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)", - "xmas-elf 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "cc" -version = "1.0.32" -source = "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 = "font8x8" -version = "0.2.4" -source = "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.18" -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 = "libc" -version = "0.2.50" -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.18 (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.50 (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.6 (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.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "cc 1.0.32 (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.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "winapi 0.3.6 (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 = "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.1 (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.2" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "winapi" -version = "0.3.6" -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.3.6" -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.0.4 (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.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "x86_64" -version = "0.5.3" -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.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "raw-cpuid 6.1.0 (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.2 (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.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "228047a76f468627ca71776ecdebd732a3423081fcf5125585bcd7c49886ce12" -"checksum cc 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)" = "ad0daef304fa0b4238f5f7ed7178774b43b06f6a9b6509f6642bef4ff1f7b9b2" -"checksum fixedvec 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7c6c16d316ccdac21a4dd648e314e76facbbaf316e83ca137d0857a9c07419d0" -"checksum font8x8 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b81d84c3c978af7d05d31a2198af4b9ba956d819d15d8f6d58fc150e33f8dc1f" -"checksum fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" -"checksum getopts 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)" = "0a7292d30132fb5424b354f5dc02512a86e4c516fe544bb7a25e7f266951b797" -"checksum libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)" = "aab692d7759f5cd8c859e169db98ae5b52c924add2af5fbbca11d12fefb567c1" -"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.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3488ba1b9a2084d38645c4c08276a1752dcbf2c7130d74f1569681ad5d2799c5" -"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 tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "15f2b5fb00ccdf689e0149d1b1b3c03fead81c2b37735d812fa8bddbbf41b6d8" -"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.2 (registry+https://github.com/rust-lang/crates.io-index)" = "53d8df5dd8d07fedccd202de1887d94481fadaea3db70479f459e8163a1fab41" -"checksum winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "92c1eb33641e276cfa214a0522acad57be5c56b10cb348b3c5117db75f3ac4b0" -"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.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "f9258d7e2dd25008d69e8c9e9ee37865887a5e1e3d06a62f1cb3f6c209e6f177" -"checksum x86_64 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8f7e92e985f4052118fd69f2b366c67e91288c0f01f4ae52610dce236425dfa0" -"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/basic/src/main.rs b/example-kernels/basic/src/main.rs index f0352e2..0acc995 100644 --- a/example-kernels/basic/src/main.rs +++ b/example-kernels/basic/src/main.rs @@ -24,5 +24,5 @@ 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 + port.write(51); // exit code is (51 << 1) | 1 = 103 } diff --git a/example-kernels/default-target-bootimage/Cargo.toml b/example-kernels/default-target-bootimage/Cargo.toml index f62b2ac..5825f0a 100644 --- a/example-kernels/default-target-bootimage/Cargo.toml +++ b/example-kernels/default-target-bootimage/Cargo.toml @@ -7,8 +7,6 @@ edition = "2018" [dependencies] bootloader = "0.5.0" x86_64 = "0.5.3" -spin = "0.4.9" -uart_16550 = "0.1.0" [package.metadata.bootimage] -default-target = "x86_64-default-target.json" \ No newline at end of file +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 index f0352e2..44b77a9 100644 --- a/example-kernels/default-target-bootimage/src/main.rs +++ b/example-kernels/default-target-bootimage/src/main.rs @@ -24,5 +24,5 @@ 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 + port.write(52); // exit code is (52 << 1) | 1 = 105 } diff --git a/example-kernels/default-target-bootimage/x86_64-default-target.json b/example-kernels/default-target-bootimage/x86_64-default-target.json deleted file mode 100644 index 9afe809..0000000 --- a/example-kernels/default-target-bootimage/x86_64-default-target.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "llvm-target": "x86_64-unknown-none", - "data-layout": "e-m:e-i64:64-f80:128-n8:16:32:64-S128", - "arch": "x86_64", - "target-endian": "little", - "target-pointer-width": "64", - "target-c-int-width": "32", - "os": "none", - "executables": true, - "linker-flavor": "ld.lld", - "linker": "rust-lld", - "panic-strategy": "abort", - "disable-redzone": true, - "features": "-mmx,-sse,+soft-float" - } diff --git a/example-kernels/default-target-cargo/.cargo/config b/example-kernels/default-target-cargo/.cargo/config index 35c3b41..79fdf34 100644 --- a/example-kernels/default-target-cargo/.cargo/config +++ b/example-kernels/default-target-cargo/.cargo/config @@ -1,2 +1,2 @@ [build] -target = "x86_64-default-target.json" \ No newline at end of file +target = "../x86_64-bootimage-example-kernels.json" \ No newline at end of file diff --git a/example-kernels/default-target-cargo/Cargo.lock b/example-kernels/default-target-cargo/Cargo.lock deleted file mode 100644 index 06cfb07..0000000 --- a/example-kernels/default-target-cargo/Cargo.lock +++ /dev/null @@ -1,328 +0,0 @@ -# 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.4.0", - "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.3 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "bit_field" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "bitflags" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "bootloader" -version = "0.4.0" -dependencies = [ - "fixedvec 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "font8x8 0.2.4 (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)", - "xmas-elf 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "cc" -version = "1.0.32" -source = "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 = "font8x8" -version = "0.2.4" -source = "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.18" -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 = "libc" -version = "0.2.50" -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.18 (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.50 (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.6 (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.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "cc 1.0.32 (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.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "winapi 0.3.6 (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 = "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.1 (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.0.4 (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.2" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "winapi" -version = "0.3.6" -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.0.4 (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.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "x86_64" -version = "0.3.6" -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.0.4 (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.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "x86_64" -version = "0.5.3" -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.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "raw-cpuid 6.1.0 (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.2 (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.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "228047a76f468627ca71776ecdebd732a3423081fcf5125585bcd7c49886ce12" -"checksum cc 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)" = "ad0daef304fa0b4238f5f7ed7178774b43b06f6a9b6509f6642bef4ff1f7b9b2" -"checksum fixedvec 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7c6c16d316ccdac21a4dd648e314e76facbbaf316e83ca137d0857a9c07419d0" -"checksum font8x8 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b81d84c3c978af7d05d31a2198af4b9ba956d819d15d8f6d58fc150e33f8dc1f" -"checksum fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" -"checksum getopts 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)" = "0a7292d30132fb5424b354f5dc02512a86e4c516fe544bb7a25e7f266951b797" -"checksum libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)" = "aab692d7759f5cd8c859e169db98ae5b52c924add2af5fbbca11d12fefb567c1" -"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.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3488ba1b9a2084d38645c4c08276a1752dcbf2c7130d74f1569681ad5d2799c5" -"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 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.2 (registry+https://github.com/rust-lang/crates.io-index)" = "53d8df5dd8d07fedccd202de1887d94481fadaea3db70479f459e8163a1fab41" -"checksum winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "92c1eb33641e276cfa214a0522acad57be5c56b10cb348b3c5117db75f3ac4b0" -"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.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8f7e92e985f4052118fd69f2b366c67e91288c0f01f4ae52610dce236425dfa0" -"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/default-target-cargo/Cargo.toml b/example-kernels/default-target-cargo/Cargo.toml index 8c1a298..737b944 100644 --- a/example-kernels/default-target-cargo/Cargo.toml +++ b/example-kernels/default-target-cargo/Cargo.toml @@ -7,5 +7,3 @@ edition = "2018" [dependencies] bootloader = "0.5.0" x86_64 = "0.5.3" -spin = "0.4.9" -uart_16550 = "0.1.0" diff --git a/example-kernels/default-target-cargo/src/main.rs b/example-kernels/default-target-cargo/src/main.rs index f0352e2..14aead9 100644 --- a/example-kernels/default-target-cargo/src/main.rs +++ b/example-kernels/default-target-cargo/src/main.rs @@ -24,5 +24,5 @@ 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 + port.write(53); // exit code is (53 << 1) | 1 = 107 } diff --git a/example-kernels/default-target-cargo/x86_64-default-target.json b/example-kernels/default-target-cargo/x86_64-default-target.json deleted file mode 100644 index 9afe809..0000000 --- a/example-kernels/default-target-cargo/x86_64-default-target.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "llvm-target": "x86_64-unknown-none", - "data-layout": "e-m:e-i64:64-f80:128-n8:16:32:64-S128", - "arch": "x86_64", - "target-endian": "little", - "target-pointer-width": "64", - "target-c-int-width": "32", - "os": "none", - "executables": true, - "linker-flavor": "ld.lld", - "linker": "rust-lld", - "panic-strategy": "abort", - "disable-redzone": true, - "features": "-mmx,-sse,+soft-float" - } diff --git a/example-kernels/runner/.cargo/config b/example-kernels/runner/.cargo/config new file mode 100644 index 0000000..ece5e24 --- /dev/null +++ b/example-kernels/runner/.cargo/config @@ -0,0 +1,5 @@ +[build] +target = "../x86_64-bootimage-example-kernels.json" + +[target.'cfg(target_os = "none")'] +runner = "bootimage runner --args -device isa-debug-exit,iobase=0xf4,iosize=0x04 -display none" diff --git a/example-kernels/runner/.gitignore b/example-kernels/runner/.gitignore new file mode 100644 index 0000000..eccd7b4 --- /dev/null +++ b/example-kernels/runner/.gitignore @@ -0,0 +1,2 @@ +/target/ +**/*.rs.bk diff --git a/example-kernels/runner/Cargo.toml b/example-kernels/runner/Cargo.toml new file mode 100644 index 0000000..d095399 --- /dev/null +++ b/example-kernels/runner/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "runner" +version = "0.1.0" +authors = ["Philipp Oppermann "] +edition = "2018" + +[dependencies] +bootloader = "0.5.0" +x86_64 = "0.5.3" diff --git a/example-kernels/runner/src/main.rs b/example-kernels/runner/src/main.rs new file mode 100644 index 0000000..033f446 --- /dev/null +++ b/example-kernels/runner/src/main.rs @@ -0,0 +1,28 @@ +#![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(54); // exit code is (54 << 1) | 1 = 109 +} diff --git a/example-kernels/tester/.gitignore b/example-kernels/tester/.gitignore new file mode 100644 index 0000000..eccd7b4 --- /dev/null +++ b/example-kernels/tester/.gitignore @@ -0,0 +1,2 @@ +/target/ +**/*.rs.bk diff --git a/example-kernels/tester/Cargo.toml b/example-kernels/tester/Cargo.toml new file mode 100644 index 0000000..73c86fc --- /dev/null +++ b/example-kernels/tester/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "tester" +version = "0.1.0" +authors = ["Philipp Oppermann "] +edition = "2018" + +[dependencies] +bootloader = "0.5.0" +x86_64 = "0.5.3" diff --git a/example-kernels/tester/build.rs b/example-kernels/tester/build.rs new file mode 100644 index 0000000..ee98612 --- /dev/null +++ b/example-kernels/tester/build.rs @@ -0,0 +1,27 @@ +use std::{env, fs::File, io::Write, path::Path}; + +fn main() { + let out_dir = env::var("OUT_DIR").unwrap(); + let dest_path = Path::new(&out_dir).join("generated_tests.rs"); + let mut tests = File::create(&dest_path).unwrap(); + for entry in Path::new("tests/integration_tests").read_dir().expect("failed to read tests/integration tests") { + let entry = entry.expect("failed to read dir entry"); + assert!(entry.file_type().unwrap().is_file()); + let test_path = entry.path(); + let test_name = test_path.file_stem().expect("no file stem").to_os_string().into_string().expect("file name not valid utf8"); + + let content = format!(r#" +#[test] +fn {test_name}() {{ + run_test("{test_path}"); +}} +"#, test_name = test_name.replace("-", "_"), test_path = test_path.display()); + + tests.write_all(content.as_bytes()).expect("failed to write test"); + + println!("cargo:rerun-if-changed={}", entry.path().display()); + } + + println!("cargo:rustc-env=GENERATED_TESTS={}", dest_path.display()); + println!("cargo:rerun-if-changed=build.rs"); +} diff --git a/example-kernels/tester/src/lib.rs b/example-kernels/tester/src/lib.rs new file mode 100644 index 0000000..cdc0ba8 --- /dev/null +++ b/example-kernels/tester/src/lib.rs @@ -0,0 +1,21 @@ +#![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/tester/tests/integration_tests.rs b/example-kernels/tester/tests/integration_tests.rs new file mode 100644 index 0000000..4db5e2d --- /dev/null +++ b/example-kernels/tester/tests/integration_tests.rs @@ -0,0 +1,14 @@ +include!(env!("GENERATED_TESTS")); + +fn run_test(test_path: &str) { + let mut cmd = std::process::Command::new("bootimage"); + cmd.arg("tester"); + cmd.arg(test_path); + cmd.arg("--target"); + cmd.arg("../x86_64-bootimage-example-kernels.json"); + let output = cmd.output().expect("failed to run bootimage"); + if !output.status.success() { + eprintln!("{}", String::from_utf8_lossy(&output.stderr)); + panic!("test failed"); + } +} \ No newline at end of file diff --git a/example-kernels/tester/tests/integration_tests/test-basic-boot.rs b/example-kernels/tester/tests/integration_tests/test-basic-boot.rs new file mode 100644 index 0000000..e870449 --- /dev/null +++ b/example-kernels/tester/tests/integration_tests/test-basic-boot.rs @@ -0,0 +1,27 @@ +#![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::{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/tester/tests/integration_tests/test-panic.rs b/example-kernels/tester/tests/integration_tests/test-panic.rs new file mode 100644 index 0000000..ef8e768 --- /dev/null +++ b/example-kernels/tester/tests/integration_tests/test-panic.rs @@ -0,0 +1,21 @@ +#![cfg_attr(not(test), no_std)] +#![cfg_attr(not(test), no_main)] +#![cfg_attr(test, allow(unused_imports))] + +use testing::{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/.gitignore b/example-kernels/testing-qemu-exit-code/.gitignore new file mode 100644 index 0000000..eccd7b4 --- /dev/null +++ b/example-kernels/testing-qemu-exit-code/.gitignore @@ -0,0 +1,2 @@ +/target/ +**/*.rs.bk diff --git a/example-kernels/testing/Cargo.toml b/example-kernels/testing-qemu-exit-code/Cargo.toml similarity index 66% rename from example-kernels/testing/Cargo.toml rename to example-kernels/testing-qemu-exit-code/Cargo.toml index 9b5541f..6efb450 100644 --- a/example-kernels/testing/Cargo.toml +++ b/example-kernels/testing-qemu-exit-code/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "testing" +name = "testing-qemu-exit-code" version = "0.1.0" authors = ["Philipp Oppermann "] edition = "2018" @@ -7,8 +7,6 @@ edition = "2018" [dependencies] bootloader = "0.5.0" x86_64 = "0.5.3" -spin = "0.4.9" -uart_16550 = "0.1.0" [package.metadata.bootimage] -default-target = "x86_64-testing.json" \ No newline at end of file +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 new file mode 100644 index 0000000..1a506f1 --- /dev/null +++ b/example-kernels/testing-qemu-exit-code/src/bin/test-basic-boot.rs @@ -0,0 +1,27 @@ +#![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 new file mode 100644 index 0000000..a1c05f8 --- /dev/null +++ b/example-kernels/testing-qemu-exit-code/src/bin/test-panic.rs @@ -0,0 +1,21 @@ +#![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 new file mode 100644 index 0000000..cdc0ba8 --- /dev/null +++ b/example-kernels/testing-qemu-exit-code/src/lib.rs @@ -0,0 +1,21 @@ +#![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 new file mode 100644 index 0000000..eccd7b4 --- /dev/null +++ b/example-kernels/testing-serial-result/.gitignore @@ -0,0 +1,2 @@ +/target/ +**/*.rs.bk diff --git a/example-kernels/testing-serial-result/Cargo.toml b/example-kernels/testing-serial-result/Cargo.toml new file mode 100644 index 0000000..bbe84a2 --- /dev/null +++ b/example-kernels/testing-serial-result/Cargo.toml @@ -0,0 +1,18 @@ +[package] +name = "testing-serial-result" +version = "0.1.0" +authors = ["Philipp Oppermann "] +edition = "2018" + +[dependencies] +bootloader = "0.5.0" +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/src/bin/test-basic-boot.rs b/example-kernels/testing-serial-result/src/bin/test-basic-boot-serial.rs similarity index 92% rename from example-kernels/testing/src/bin/test-basic-boot.rs rename to example-kernels/testing-serial-result/src/bin/test-basic-boot-serial.rs index f77d4a0..d6982d0 100644 --- a/example-kernels/testing/src/bin/test-basic-boot.rs +++ b/example-kernels/testing-serial-result/src/bin/test-basic-boot-serial.rs @@ -2,7 +2,7 @@ #![cfg_attr(not(test), no_main)] // disable all Rust-level entry points #![cfg_attr(test, allow(unused_imports))] -use blog_os::{exit_qemu, serial_println}; +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 diff --git a/example-kernels/testing/src/bin/test-panic.rs b/example-kernels/testing-serial-result/src/bin/test-panic-serial.rs similarity index 86% rename from example-kernels/testing/src/bin/test-panic.rs rename to example-kernels/testing-serial-result/src/bin/test-panic-serial.rs index c68ac51..324a28f 100644 --- a/example-kernels/testing/src/bin/test-panic.rs +++ b/example-kernels/testing-serial-result/src/bin/test-panic-serial.rs @@ -2,7 +2,7 @@ #![cfg_attr(not(test), no_main)] #![cfg_attr(test, allow(unused_imports))] -use blog_os::{exit_qemu, serial_println}; +use testing_serial_result::{exit_qemu, serial_println}; use core::panic::PanicInfo; #[cfg(not(test))] diff --git a/example-kernels/testing/src/lib.rs b/example-kernels/testing-serial-result/src/lib.rs similarity index 100% rename from example-kernels/testing/src/lib.rs rename to example-kernels/testing-serial-result/src/lib.rs diff --git a/example-kernels/testing/src/main.rs b/example-kernels/testing-serial-result/src/main.rs similarity index 100% rename from example-kernels/testing/src/main.rs rename to example-kernels/testing-serial-result/src/main.rs diff --git a/example-kernels/testing/Cargo.lock b/example-kernels/testing/Cargo.lock deleted file mode 100644 index 06cfb07..0000000 --- a/example-kernels/testing/Cargo.lock +++ /dev/null @@ -1,328 +0,0 @@ -# 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.4.0", - "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.3 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "bit_field" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "bitflags" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "bootloader" -version = "0.4.0" -dependencies = [ - "fixedvec 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "font8x8 0.2.4 (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)", - "xmas-elf 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "cc" -version = "1.0.32" -source = "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 = "font8x8" -version = "0.2.4" -source = "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.18" -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 = "libc" -version = "0.2.50" -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.18 (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.50 (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.6 (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.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "cc 1.0.32 (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.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "winapi 0.3.6 (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 = "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.1 (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.0.4 (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.2" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "winapi" -version = "0.3.6" -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.0.4 (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.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "x86_64" -version = "0.3.6" -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.0.4 (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.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "x86_64" -version = "0.5.3" -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.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "raw-cpuid 6.1.0 (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.2 (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.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "228047a76f468627ca71776ecdebd732a3423081fcf5125585bcd7c49886ce12" -"checksum cc 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)" = "ad0daef304fa0b4238f5f7ed7178774b43b06f6a9b6509f6642bef4ff1f7b9b2" -"checksum fixedvec 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7c6c16d316ccdac21a4dd648e314e76facbbaf316e83ca137d0857a9c07419d0" -"checksum font8x8 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b81d84c3c978af7d05d31a2198af4b9ba956d819d15d8f6d58fc150e33f8dc1f" -"checksum fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" -"checksum getopts 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)" = "0a7292d30132fb5424b354f5dc02512a86e4c516fe544bb7a25e7f266951b797" -"checksum libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)" = "aab692d7759f5cd8c859e169db98ae5b52c924add2af5fbbca11d12fefb567c1" -"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.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3488ba1b9a2084d38645c4c08276a1752dcbf2c7130d74f1569681ad5d2799c5" -"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 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.2 (registry+https://github.com/rust-lang/crates.io-index)" = "53d8df5dd8d07fedccd202de1887d94481fadaea3db70479f459e8163a1fab41" -"checksum winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "92c1eb33641e276cfa214a0522acad57be5c56b10cb348b3c5117db75f3ac4b0" -"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.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8f7e92e985f4052118fd69f2b366c67e91288c0f01f4ae52610dce236425dfa0" -"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/testing/x86_64-testing.json b/example-kernels/testing/x86_64-testing.json deleted file mode 100644 index 9afe809..0000000 --- a/example-kernels/testing/x86_64-testing.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "llvm-target": "x86_64-unknown-none", - "data-layout": "e-m:e-i64:64-f80:128-n8:16:32:64-S128", - "arch": "x86_64", - "target-endian": "little", - "target-pointer-width": "64", - "target-c-int-width": "32", - "os": "none", - "executables": true, - "linker-flavor": "ld.lld", - "linker": "rust-lld", - "panic-strategy": "abort", - "disable-redzone": true, - "features": "-mmx,-sse,+soft-float" - } diff --git a/example-kernels/basic/x86_64-basic.json b/example-kernels/x86_64-bootimage-example-kernels.json similarity index 100% rename from example-kernels/basic/x86_64-basic.json rename to example-kernels/x86_64-bootimage-example-kernels.json From 13b3998a44d3cb7655e644531a658dea22eb85f1 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Tue, 2 Apr 2019 15:38:45 +0200 Subject: [PATCH 093/271] Convert runner args to config keys Variable length args are not possible since the executable name is appended at the end --- example-kernels/runner/.cargo/config | 2 +- example-kernels/runner/Cargo.toml | 3 ++ src/args.rs | 43 +++++++++------------------- src/config.rs | 13 +++++++++ src/subcommand/runner.rs | 17 ++++------- 5 files changed, 37 insertions(+), 41 deletions(-) diff --git a/example-kernels/runner/.cargo/config b/example-kernels/runner/.cargo/config index ece5e24..3b4d89e 100644 --- a/example-kernels/runner/.cargo/config +++ b/example-kernels/runner/.cargo/config @@ -2,4 +2,4 @@ target = "../x86_64-bootimage-example-kernels.json" [target.'cfg(target_os = "none")'] -runner = "bootimage runner --args -device isa-debug-exit,iobase=0xf4,iosize=0x04 -display none" +runner = "bootimage runner" diff --git a/example-kernels/runner/Cargo.toml b/example-kernels/runner/Cargo.toml index d095399..966cce4 100644 --- a/example-kernels/runner/Cargo.toml +++ b/example-kernels/runner/Cargo.toml @@ -7,3 +7,6 @@ edition = "2018" [dependencies] bootloader = "0.5.0" x86_64 = "0.5.3" + +[package.metadata.bootimage] +run-args = ["-device", "isa-debug-exit,iobase=0xf4,iosize=0x04", "-display", "none"] diff --git a/src/args.rs b/src/args.rs index ac33bc9..c8823bf 100644 --- a/src/args.rs +++ b/src/args.rs @@ -207,56 +207,41 @@ fn parse_runner_args(args: A) -> Result where A: Iterator, { + let mut executable = None; let mut arg_iter = args.into_iter().fuse(); - let executable = PathBuf::from( - arg_iter - .next() - .ok_or("excepted path to kernel executable as first argument")?, - ) - .canonicalize() - .map_err(|err| format!("Failed to canonicalize executable path: {}", err))?; - let mut run_command = None; - let mut run_args = None; loop { match arg_iter.next().as_ref().map(|s| s.as_str()) { - Some("--command") => { - let old = mem::replace(&mut run_command, Some(arg_iter.collect())); - if !old.is_none() { - Err("multiple `--command` arguments")?; - } - break; - } - Some("--args") => { - let old = mem::replace(&mut run_args, Some(arg_iter.collect())); - if !old.is_none() { - Err("multiple `--args` arguments")?; - } - break; - } Some("--help") | Some("-h") => { return Ok(Command::RunnerHelp); } Some("--version") => { return Ok(Command::Version); } - None => break, + Some(exe) if executable.is_none() => { + let path = Path::new(exe); + let path_canonicalized = path.canonicalize().map_err(|err| { + format!( + "Failed to canonicalize executable path `{}`: {}", + path.display(), + err + ) + })?; + executable = Some(path_canonicalized); + } Some(arg) => Err(format!("unexpected argument `{}`", arg))?, + None => break, } } Ok(Command::Runner(RunnerArgs { - executable, - run_command, - run_args, + executable: executable.ok_or("excepted path to kernel executable as first argument")?, })) } #[derive(Debug, Clone)] pub struct RunnerArgs { pub executable: PathBuf, - pub run_command: Option>, - pub run_args: Option>, } fn parse_tester_args(args: A) -> Result diff --git a/src/config.rs b/src/config.rs index 5ccf1d4..6f10e20 100644 --- a/src/config.rs +++ b/src/config.rs @@ -7,6 +7,7 @@ pub struct Config { pub manifest_path: PathBuf, pub default_target: Option, pub run_command: Vec, + pub run_args: Option>, pub test_timeout: u32, } @@ -70,6 +71,16 @@ pub(crate) fn read_config_inner(manifest_path: PathBuf) -> Result { + let mut args = Vec::new(); + for value in array { + match value { + Value::String(s) => args.push(s), + _ => Err(format!("run-args must be a list of strings"))?, + } + } + config.run_args = Some(args); + } (key, value) => Err(format!( "unexpected `package.metadata.bootimage` \ key `{}` with value `{}`", @@ -85,6 +96,7 @@ struct ConfigBuilder { manifest_path: Option, default_target: Option, run_command: Option>, + run_args: Option>, test_timeout: Option, } @@ -98,6 +110,7 @@ impl Into for ConfigBuilder { "-drive".into(), "format=raw,file={}".into(), ]), + run_args: self.run_args, test_timeout: self.test_timeout.unwrap_or(60 * 5), } } diff --git a/src/subcommand/runner.rs b/src/subcommand/runner.rs index 4bbbe74..326b911 100644 --- a/src/subcommand/runner.rs +++ b/src/subcommand/runner.rs @@ -1,8 +1,9 @@ -use crate::{args::RunnerArgs, builder::Builder, ErrorString}; +use crate::{args::RunnerArgs, builder::Builder, config, ErrorString}; use std::{fs, process}; pub(crate) fn runner(args: RunnerArgs) -> Result { let builder = Builder::new(None)?; + let config = config::read_config(builder.kernel_manifest_path().to_owned())?; let bootimage_bin = { let kernel_target_dir = &builder.kernel_metadata().target_directory; @@ -38,17 +39,11 @@ pub(crate) fn runner(args: RunnerArgs) -> Result { builder.create_bootimage(&args.executable, &bootimage_bin, false)?; - let run_cmd = args.run_command.unwrap_or(vec![ - "qemu-system-x86_64".into(), - "-drive".into(), - "format=raw,file={bootimage}".into(), - ]); - - let mut command = process::Command::new(&run_cmd[0]); - for arg in &run_cmd[1..] { - command.arg(arg.replace("{bootimage}", &format!("{}", bootimage_bin.display()))); + let mut command = process::Command::new(&config.run_command[0]); + for arg in &config.run_command[1..] { + command.arg(arg.replace("{}", &format!("{}", bootimage_bin.display()))); } - if let Some(run_args) = args.run_args { + if let Some(run_args) = config.run_args { command.args(run_args); } From c73be6fafe48e494b1f0b601b10f8874c713c3e3 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Tue, 2 Apr 2019 15:50:13 +0200 Subject: [PATCH 094/271] Check for correct exit code of `cargo xrun` in CI script --- azure-pipelines.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 5c85131..18c0e0e 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -193,7 +193,9 @@ jobs: workingDirectory: example-kernels/testing-qemu-exit-code displayName: 'Run `bootimage test` for "testing-qemu-exit-code" kernel' - - script: cargo xrun + - bash: | + cargo xrun + if [ $? -eq 109 ]; then (exit 0); else (exit 1); fi workingDirectory: example-kernels/runner displayName: 'Run `cargo xrun` for "runner" kernel' From 81860b3c4563e0268d2890832d8e69a647f1c449 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Tue, 2 Apr 2019 16:05:07 +0200 Subject: [PATCH 095/271] Exclude generated test crates from parent workspace --- src/subcommand/tester.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/subcommand/tester.rs b/src/subcommand/tester.rs index a48e6cc..401ebb4 100644 --- a/src/subcommand/tester.rs +++ b/src/subcommand/tester.rs @@ -83,6 +83,8 @@ name = "{test_name}" version = "0.0.0" edition = "2018" +[workspace] # exclude this crate from parent workspaces + [[bin]] name = "{test_name}" path = "{test_path}" From 03528dd3790a807cba1bf6644fd0249fabf888c4 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Tue, 2 Apr 2019 16:06:51 +0200 Subject: [PATCH 096/271] Fix imports in tester tests --- .../tester/tests/integration_tests/test-basic-boot.rs | 2 +- example-kernels/tester/tests/integration_tests/test-panic.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/example-kernels/tester/tests/integration_tests/test-basic-boot.rs b/example-kernels/tester/tests/integration_tests/test-basic-boot.rs index e870449..02de359 100644 --- a/example-kernels/tester/tests/integration_tests/test-basic-boot.rs +++ b/example-kernels/tester/tests/integration_tests/test-basic-boot.rs @@ -2,7 +2,7 @@ #![cfg_attr(not(test), no_main)] // disable all Rust-level entry points #![cfg_attr(test, allow(unused_imports))] -use testing::{exit_qemu, ExitCode}; +use tester::{exit_qemu, ExitCode}; use core::panic::PanicInfo; /// This function is the entry point, since the linker looks for a function diff --git a/example-kernels/tester/tests/integration_tests/test-panic.rs b/example-kernels/tester/tests/integration_tests/test-panic.rs index ef8e768..5a7d176 100644 --- a/example-kernels/tester/tests/integration_tests/test-panic.rs +++ b/example-kernels/tester/tests/integration_tests/test-panic.rs @@ -2,7 +2,7 @@ #![cfg_attr(not(test), no_main)] #![cfg_attr(test, allow(unused_imports))] -use testing::{exit_qemu, ExitCode}; +use tester::{exit_qemu, ExitCode}; use core::panic::PanicInfo; #[cfg(not(test))] From 80aeb7cf835ecc3f9deb60f9f74406101c1a3e80 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Tue, 2 Apr 2019 16:54:32 +0200 Subject: [PATCH 097/271] Place bootimage-*.bin in default target directory for `runner` This is the same behavior as `bootimage run`. --- src/subcommand/runner.rs | 22 ++-------------------- 1 file changed, 2 insertions(+), 20 deletions(-) diff --git a/src/subcommand/runner.rs b/src/subcommand/runner.rs index 326b911..6c0dc6b 100644 --- a/src/subcommand/runner.rs +++ b/src/subcommand/runner.rs @@ -1,14 +1,11 @@ use crate::{args::RunnerArgs, builder::Builder, config, ErrorString}; -use std::{fs, process}; +use std::process; pub(crate) fn runner(args: RunnerArgs) -> Result { let builder = Builder::new(None)?; let config = config::read_config(builder.kernel_manifest_path().to_owned())?; let bootimage_bin = { - let kernel_target_dir = &builder.kernel_metadata().target_directory; - let bootimage_target_dir = kernel_target_dir.join("bootimage").join("runner"); - let parent = args .executable .parent() @@ -19,22 +16,7 @@ pub(crate) fn runner(args: RunnerArgs) -> Result { .ok_or("kernel executable has no file stem")? .to_str() .ok_or("kernel executable file stem is not valid UTF-8")?; - let sub_path = parent.strip_prefix(kernel_target_dir).map_err(|err| { - format!( - "kernel executable does not live in kernel target directory: {}", - err - ) - })?; - - let out_dir = bootimage_target_dir.join(sub_path); - fs::create_dir_all(&out_dir).map_err(|err| { - format!( - "failed to create output directory {}: {}", - out_dir.display(), - err - ) - })?; - out_dir.join(format!("bootimage-{}.bin", file_stem)) + parent.join(format!("bootimage-{}.bin", file_stem)) }; builder.create_bootimage(&args.executable, &bootimage_bin, false)?; From 976289a685da0c73d42bf1d4ccd19143e9ca8b99 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Tue, 2 Apr 2019 17:06:02 +0200 Subject: [PATCH 098/271] Use kernel target dir for tester to improve performance --- src/subcommand/tester.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/subcommand/tester.rs b/src/subcommand/tester.rs index 401ebb4..7fbd0ad 100644 --- a/src/subcommand/tester.rs +++ b/src/subcommand/tester.rs @@ -86,7 +86,7 @@ edition = "2018" [workspace] # exclude this crate from parent workspaces [[bin]] -name = "{test_name}" +name = "bootimage-tester-{test_name}" path = "{test_path}" {dependency_table} @@ -103,8 +103,7 @@ path = "{test_path}" let mut cmd = Command::new(&cargo); cmd.arg("xbuild"); cmd.arg("--manifest-path").arg(&manifest_path); - cmd.arg("--target-dir") - .arg(&integration_test_dir.join("target")); + cmd.arg("--target-dir").arg(&kernel_target_dir); cmd.env("SYSROOT_DIR", &integration_test_dir.join("sysroot")); // for cargo-xbuild if let Some(target) = args.target.as_ref().or(config.default_target.as_ref()) { From 841d2ec54b9c1d51bc722e95ec58078c7c59676b Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Tue, 2 Apr 2019 17:25:23 +0200 Subject: [PATCH 099/271] Print path in error message when canonicalization fails --- src/args.rs | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/args.rs b/src/args.rs index c8823bf..23950c3 100644 --- a/src/args.rs +++ b/src/args.rs @@ -249,13 +249,18 @@ where A: Iterator, { let mut arg_iter = args.into_iter().fuse(); - let test_path = PathBuf::from( + let test_path_arg = PathBuf::from( arg_iter .next() .ok_or("excepted path to test source file as first argument")?, - ) - .canonicalize() - .map_err(|err| format!("Failed to canonicalize test path: {}", err))?; + ); + let test_path = test_path_arg.canonicalize().map_err(|err| { + format!( + "Failed to canonicalize test path `{}`: {}", + test_path_arg.display(), + err + ) + })?; let mut run_command = None; let mut target = None; From a01c22cbf2bdfc02044020b1885197b8627f3d8b Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Tue, 2 Apr 2019 17:43:13 +0200 Subject: [PATCH 100/271] Try to fix test error on Windows --- example-kernels/tester/build.rs | 2 +- example-kernels/tester/tests/integration_tests.rs | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/example-kernels/tester/build.rs b/example-kernels/tester/build.rs index ee98612..fd1c011 100644 --- a/example-kernels/tester/build.rs +++ b/example-kernels/tester/build.rs @@ -4,7 +4,7 @@ fn main() { let out_dir = env::var("OUT_DIR").unwrap(); let dest_path = Path::new(&out_dir).join("generated_tests.rs"); let mut tests = File::create(&dest_path).unwrap(); - for entry in Path::new("tests/integration_tests").read_dir().expect("failed to read tests/integration tests") { + for entry in Path::new("tests").join("integration_tests").read_dir().expect("failed to read tests/integration tests") { let entry = entry.expect("failed to read dir entry"); assert!(entry.file_type().unwrap().is_file()); let test_path = entry.path(); diff --git a/example-kernels/tester/tests/integration_tests.rs b/example-kernels/tester/tests/integration_tests.rs index 4db5e2d..352e413 100644 --- a/example-kernels/tester/tests/integration_tests.rs +++ b/example-kernels/tester/tests/integration_tests.rs @@ -1,9 +1,11 @@ +use std::path::Path; + include!(env!("GENERATED_TESTS")); fn run_test(test_path: &str) { let mut cmd = std::process::Command::new("bootimage"); cmd.arg("tester"); - cmd.arg(test_path); + cmd.arg(Path::new(test_path)); cmd.arg("--target"); cmd.arg("../x86_64-bootimage-example-kernels.json"); let output = cmd.output().expect("failed to run bootimage"); From ee987a1333104afb474bba906027ce6d71dafd9f Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Tue, 2 Apr 2019 18:41:43 +0200 Subject: [PATCH 101/271] Remove `tester` subcommand again This functionality is better implemented manually on top of `bootimage run`. Such a manual implementation can be a proper workspace member and correctly share the sysroot and the target artifacts (with the `bootimage tester` we don't achieve sharing because the dependency fingerprints differ). --- azure-pipelines.yml | 4 - src/args.rs | 61 ----------- src/lib.rs | 7 +- src/subcommand.rs | 1 - src/subcommand/tester.rs | 225 --------------------------------------- 5 files changed, 2 insertions(+), 296 deletions(-) delete mode 100644 src/subcommand/tester.rs diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 18c0e0e..f750360 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -198,7 +198,3 @@ jobs: if [ $? -eq 109 ]; then (exit 0); else (exit 1); fi workingDirectory: example-kernels/runner displayName: 'Run `cargo xrun` for "runner" kernel' - - - script: cargo test - workingDirectory: example-kernels/tester - displayName: 'Run `cargo test` for "tester" kernel' diff --git a/src/args.rs b/src/args.rs index 23950c3..4c9ffd4 100644 --- a/src/args.rs +++ b/src/args.rs @@ -30,7 +30,6 @@ pub(crate) fn parse_args() -> Result { cmd => cmd, }), Some("runner") => parse_runner_args(args), - Some("tester") => parse_tester_args(args), Some("--help") | Some("-h") => Ok(Command::Help), Some("--version") => Ok(Command::Version), _ => Ok(Command::NoSubcommand), @@ -244,63 +243,3 @@ pub struct RunnerArgs { pub executable: PathBuf, } -fn parse_tester_args(args: A) -> Result -where - A: Iterator, -{ - let mut arg_iter = args.into_iter().fuse(); - let test_path_arg = PathBuf::from( - arg_iter - .next() - .ok_or("excepted path to test source file as first argument")?, - ); - let test_path = test_path_arg.canonicalize().map_err(|err| { - format!( - "Failed to canonicalize test path `{}`: {}", - test_path_arg.display(), - err - ) - })?; - let mut run_command = None; - let mut target = None; - - loop { - match arg_iter.next().as_ref().map(|s| s.as_str()) { - Some("--command") => { - let old = mem::replace(&mut run_command, Some(arg_iter.collect())); - if !old.is_none() { - Err("multiple `--command` arguments")?; - } - break; - } - Some("--target") => { - let old = mem::replace(&mut target, arg_iter.next()); - if !old.is_none() { - Err("multiple `--target` arguments")?; - } - break; - } - Some("--help") | Some("-h") => { - return Ok(Command::TesterHelp); - } - Some("--version") => { - return Ok(Command::Version); - } - None => break, - Some(arg) => Err(format!("unexpected argument `{}`", arg))?, - } - } - - Ok(Command::Tester(TesterArgs { - test_path, - run_command, - target, - })) -} - -#[derive(Debug, Clone)] -pub struct TesterArgs { - pub test_path: PathBuf, - pub run_command: Option>, - pub target: Option, -} diff --git a/src/lib.rs b/src/lib.rs index c166502..1e00d15 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,4 +1,4 @@ -use args::{Args, RunnerArgs, TesterArgs}; +use args::{Args, RunnerArgs}; use std::{fmt, process}; pub mod args; @@ -14,14 +14,12 @@ enum Command { Run(Args), Test(Args), Runner(RunnerArgs), - Tester(TesterArgs), Help, BuildHelp, RunHelp, TestHelp, CargoBootimageHelp, RunnerHelp, - TesterHelp, Version, } @@ -46,14 +44,13 @@ pub fn run() -> Result, ErrorString> { 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::Tester(args) => subcommand::tester::tester(args).map(none), Command::NoSubcommand => help::no_subcommand(), Command::Help => Ok(help::help()).map(none), Command::BuildHelp => Ok(help::build_help()).map(none), Command::RunHelp => Ok(help::run_help()).map(none), Command::TestHelp => Ok(help::test_help()).map(none), Command::Version => Ok(println!("bootimage {}", env!("CARGO_PKG_VERSION"))).map(none), - Command::RunnerHelp | Command::TesterHelp | Command::CargoBootimageHelp => unimplemented!(), + Command::RunnerHelp | Command::CargoBootimageHelp => unimplemented!(), } } diff --git a/src/subcommand.rs b/src/subcommand.rs index 0e49f4f..f848c46 100644 --- a/src/subcommand.rs +++ b/src/subcommand.rs @@ -2,4 +2,3 @@ pub mod build; pub mod run; pub mod runner; pub mod test; -pub mod tester; diff --git a/src/subcommand/tester.rs b/src/subcommand/tester.rs deleted file mode 100644 index 7fbd0ad..0000000 --- a/src/subcommand/tester.rs +++ /dev/null @@ -1,225 +0,0 @@ -use crate::{args::TesterArgs, builder::Builder, config, ErrorString}; -use std::{ - fs, - path::{Path, PathBuf}, - process, - process::Command, - time::Duration, -}; -use wait_timeout::ChildExt; - -pub(crate) fn tester(args: TesterArgs) -> Result<(), ErrorString> { - let builder = Builder::new(None)?; - let config = config::read_config(builder.kernel_manifest_path().to_owned())?; - - let test_name = args - .test_path - .file_stem() - .expect("no file stem") - .to_os_string() - .into_string() - .expect("test name invalid utf8"); - - let kernel_manifest_path = locate_cargo_manifest::locate_manifest().unwrap_or( - Path::new("Cargo.toml") - .canonicalize() - .expect("failed to canonicalize manifest path"), - ); - let kernel_root_path = kernel_manifest_path - .parent() - .expect("kernel manifest path has no parent"); - let kernel_manifest_content = - fs::read_to_string(&kernel_manifest_path).expect("failed to read kernel manifest"); - let kernel_manifest: toml::Value = kernel_manifest_content - .parse() - .expect("failed to parse Cargo.toml"); - - let kernel_name = kernel_manifest - .get("package") - .and_then(|p| p.get("name")) - .expect("no package.name found in Cargo.toml") - .as_str() - .expect("package name must be a string"); - let dependency_table = { - let mut table = toml::value::Table::new(); - let mut dependencies = kernel_manifest - .get("dependencies") - .map(|v| { - v.as_table() - .expect("`dependencies` must be a table in Cargo.toml") - .clone() - }) - .unwrap_or(toml::value::Table::new()); - dependencies.insert( - kernel_name.to_owned(), - toml::from_str(&format!(r#"path = "{}""#, kernel_root_path.display())).unwrap(), - ); - for (key, entry) in kernel_manifest - .get("dev-dependencies") - .map(|v| { - v.as_table() - .expect("`dev-dependencies` must be a table in Cargo.toml") - .clone() - }) - .unwrap_or(toml::value::Table::new()) - { - dependencies.insert(key, entry); - } - table.insert("dependencies".to_owned(), toml::Value::Table(dependencies)); - toml::Value::Table(table) - }; - - let kernel_target_dir = &builder.kernel_metadata().target_directory; - let integration_test_dir = kernel_target_dir.join("bootimage").join("tester"); - let out_dir = integration_test_dir.join(&test_name); - fs::create_dir_all(&out_dir).expect("failed to create out dir"); - - let manifest_path = out_dir.join("Cargo.toml"); - let manifest_content = format!( - r#" -[package] -authors = ["Bootimage Tester "] -name = "{test_name}" -version = "0.0.0" -edition = "2018" - -[workspace] # exclude this crate from parent workspaces - -[[bin]] -name = "bootimage-tester-{test_name}" -path = "{test_path}" - -{dependency_table} -"#, - test_name = test_name, - test_path = args.test_path.display(), - dependency_table = dependency_table - ); - - fs::write(&manifest_path, manifest_content)?; - - let cargo = std::env::var("CARGO").unwrap_or("cargo".to_owned()); - let build_command = || { - let mut cmd = Command::new(&cargo); - cmd.arg("xbuild"); - cmd.arg("--manifest-path").arg(&manifest_path); - cmd.arg("--target-dir").arg(&kernel_target_dir); - cmd.env("SYSROOT_DIR", &integration_test_dir.join("sysroot")); // for cargo-xbuild - - if let Some(target) = args.target.as_ref().or(config.default_target.as_ref()) { - cmd.arg("--target").arg(target); - } - cmd - }; - - let mut cmd = build_command(); - let output = cmd - .output() - .map_err(|err| format!("failed to run cargo xbuild: {}", err))?; - if !output.status.success() { - Err(format!( - "Test build failed:\n{}", - String::from_utf8_lossy(&output.stderr) - ))?; - } - - let mut cmd_json = build_command(); - cmd_json.arg("--message-format").arg("json"); - let output = cmd_json.output().map_err(|err| { - format!( - "failed to execute bootloader build command with json output: {}", - err - ) - })?; - if !output.status.success() { - Err(format!( - "Test build (with json output) failed:\n{}", - String::from_utf8_lossy(&output.stderr) - ))?; - } - let mut test_executable = None; - for line in String::from_utf8(output.stdout).unwrap().lines() { - let mut artifact = json::parse(line).unwrap(); - if let Some(executable) = artifact["executable"].take_string() { - if test_executable.replace(PathBuf::from(executable)).is_some() { - Err("integration test has multiple executables")?; - } - } - } - - let executable = test_executable.ok_or("no test executable")?; - let bootimage_bin_path = out_dir.join(format!("bootimage-{}.bin", test_name)); - builder.create_bootimage(&executable, &bootimage_bin_path, true)?; - - let run_cmd = args.run_command.clone().unwrap_or( - [ - "qemu-system-x86_64", - "-drive", - "format=raw,file={bootimage}", - "-device", - "isa-debug-exit,iobase=0xf4,iosize=0x04", - "-display", - "none", - "-serial", - "file:{output_file}", - ] - .into_iter() - .map(|&s| String::from(s)) - .collect(), - ); - - let output_file = out_dir.join(format!("output-{}.txt", test_name)); - - let mut command = process::Command::new(&run_cmd[0]); - for arg in &run_cmd[1..] { - command.arg( - arg.replace("{bootimage}", &format!("{}", bootimage_bin_path.display())) - .replace("{output_file}", &format!("{}", output_file.display())), - ); - } - 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()); - let (exit_status, output) = 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))?; - Err("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.display(), - e - ) - })?; - Ok((exit_status, output)) - } - }?; - - match exit_status.code() { - None => Err("No QEMU Exit Code")?, - Some(5) => {} // 2 << 1 | 1 - Some(7) => { - // 3 << 1 | 1 - let fail_index = output.rfind("bootimage:stderr\n"); - if let Some(index) = fail_index { - Err(format!("Test Failed:\n{}", &output[index..]))? - } else { - Err("Test Failed")? - } - } - Some(c) => Err(format!("Test returned with unexpected exit code {}", c))?, - } - Ok(()) -} From 9598497a3404889405bce676babba19b314df31f Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Tue, 2 Apr 2019 18:42:00 +0200 Subject: [PATCH 102/271] Apply config.run_args for `bootimage run` too --- src/subcommand/run.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/subcommand/run.rs b/src/subcommand/run.rs index 287b195..fee5247 100644 --- a/src/subcommand/run.rs +++ b/src/subcommand/run.rs @@ -26,6 +26,9 @@ pub(crate) fn run(mut args: Args) -> Result { ), ); } + 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| { ErrorString::from(format!( From 683b3ee84ca67e009f3da3492b1a56aed4392890 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Tue, 2 Apr 2019 21:17:45 +0200 Subject: [PATCH 103/271] Add a `--quiet` argument --- src/args.rs | 15 +++++++++++++++ src/subcommand/build.rs | 3 ++- src/subcommand/run.rs | 3 ++- src/subcommand/runner.rs | 2 +- 4 files changed, 20 insertions(+), 3 deletions(-) diff --git a/src/args.rs b/src/args.rs index 4c9ffd4..f40104e 100644 --- a/src/args.rs +++ b/src/args.rs @@ -47,6 +47,7 @@ where 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<(), ErrorString> { let previous = mem::replace(arg, value); @@ -69,6 +70,9 @@ where "--version" => { return Ok(Command::Version); } + "--quiet" => { + quiet = true; + } "--bin" => { let next = arg_iter.next(); set(&mut bin_name, next.clone())?; @@ -142,6 +146,7 @@ where target, manifest_path, release: release.unwrap_or(false), + quiet, })) } @@ -151,6 +156,8 @@ pub struct Args { 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`). @@ -207,6 +214,8 @@ where A: Iterator, { let mut executable = None; + let mut quiet = false; + let mut arg_iter = args.into_iter().fuse(); loop { @@ -217,6 +226,9 @@ where Some("--version") => { return Ok(Command::Version); } + Some("--quiet") => { + quiet = true; + } Some(exe) if executable.is_none() => { let path = Path::new(exe); let path_canonicalized = path.canonicalize().map_err(|err| { @@ -235,11 +247,14 @@ where Ok(Command::Runner(RunnerArgs { executable: executable.ok_or("excepted path to kernel executable as first argument")?, + quiet, })) } #[derive(Debug, Clone)] pub struct RunnerArgs { pub executable: PathBuf, + /// Suppress any output to stdout. + pub quiet: bool, } diff --git a/src/subcommand/build.rs b/src/subcommand/build.rs index 4b496b8..ea6bc54 100644 --- a/src/subcommand/build.rs +++ b/src/subcommand/build.rs @@ -6,7 +6,8 @@ pub(crate) fn build(mut args: Args) -> Result<(), ErrorString> { let config = config::read_config(builder.kernel_manifest_path().to_owned())?; args.apply_default_target(&config, builder.kernel_root()); - build_impl(&builder, &mut args, false).map(|_| ()) + let quiet = args.quiet; + build_impl(&builder, &mut args, quiet).map(|_| ()) } pub(crate) fn build_impl( diff --git a/src/subcommand/run.rs b/src/subcommand/run.rs index fee5247..b505b80 100644 --- a/src/subcommand/run.rs +++ b/src/subcommand/run.rs @@ -8,7 +8,8 @@ pub(crate) fn run(mut args: Args) -> Result { let config = config::read_config(builder.kernel_manifest_path().to_owned())?; args.apply_default_target(&config, builder.kernel_root()); - let bootimages = build::build_impl(&builder, &mut args, false)?; + 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")?; diff --git a/src/subcommand/runner.rs b/src/subcommand/runner.rs index 6c0dc6b..1815b52 100644 --- a/src/subcommand/runner.rs +++ b/src/subcommand/runner.rs @@ -19,7 +19,7 @@ pub(crate) fn runner(args: RunnerArgs) -> Result { parent.join(format!("bootimage-{}.bin", file_stem)) }; - builder.create_bootimage(&args.executable, &bootimage_bin, false)?; + builder.create_bootimage(&args.executable, &bootimage_bin, args.quiet)?; let mut command = process::Command::new(&config.run_command[0]); for arg in &config.run_command[1..] { From cd7d510dd8a728f481724928e469684689e51508 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Tue, 2 Apr 2019 21:18:17 +0200 Subject: [PATCH 104/271] Update changelog --- Changelog.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Changelog.md b/Changelog.md index 160b0c4..34684ed 100644 --- a/Changelog.md +++ b/Changelog.md @@ -9,6 +9,7 @@ - Remove support for `bootloader_precompiled` - The `bootloader` crate compiles fine on all architectures for some time and should be prefered - Require the `llvm-tools-preview` rustup component +- Pass the QEMU exit code in `bootimage run` ## Other @@ -20,6 +21,8 @@ - Refactor and cleanup the code - Remove the dependency on `failure` - Use a custom `ErrorString` type instead +- Add a new `run-args` config key +- Add a new `--quiet` argument to suppress output # 0.6.6 From a703656e584f56c6a264f849086fbae5505d30a8 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Tue, 2 Apr 2019 21:19:25 +0200 Subject: [PATCH 105/271] Remove travis CI script --- .travis.yml | 46 ---------------------------------------------- bors.toml | 2 +- 2 files changed, 1 insertion(+), 47 deletions(-) delete mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 9ed6fec..0000000 --- a/.travis.yml +++ /dev/null @@ -1,46 +0,0 @@ -language: rust - -sudo: false - -notifications: - email: - on_success: never - on_failure: change - -rust: - - nightly - - stable - - beta - -os: - - linux - - osx - - windows - -cache: - cargo: true - directories: - - $HOME/Library/Caches/Homebrew - -addons: - apt: - packages: - - qemu-system-x86 - homebrew: - packages: - - qemu - -install: - - if [ $TRAVIS_OS_NAME = windows ]; then choco install qemu; export PATH="/c/Program Files/qemu:$PATH"; fi - -before_script: - - rustup component add rust-src - - (test -x $HOME/.cargo/bin/cargo-update-installed || cargo install cargo-update-installed) - - (test -x $HOME/.cargo/bin/cargo-xbuild || cargo install cargo-xbuild) - - cargo update-installed - -script: -- cargo test -- cargo install --debug --force -- git clone https://github.com/phil-opp/blog_os.git --branch post-10 -- if [ $TRAVIS_RUST_VERSION = nightly ]; then bootimage test --manifest-path blog_os/Cargo.toml; fi diff --git a/bors.toml b/bors.toml index 574c563..9c47331 100644 --- a/bors.toml +++ b/bors.toml @@ -1,4 +1,4 @@ status = [ - "continuous-integration/travis-ci/push", + "rust-osdev.bootimage", ] delete_merged_branches = true From 2517b94bc686e52f57a04216ead68883625ffac2 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Tue, 2 Apr 2019 21:31:18 +0200 Subject: [PATCH 106/271] Update Readme --- Readme.md | 54 ++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 48 insertions(+), 6 deletions(-) diff --git a/Readme.md b/Readme.md index ba964f7..03fa576 100644 --- a/Readme.md +++ b/Readme.md @@ -10,7 +10,7 @@ Creates a bootable disk image from a Rust OS kernel. ## Usage -First you need to add a dependency on the `bootloader` crate: +First you need to add a dependency on the [`bootloader`](https://github.com/rust-osdev/bootloader) crate: ```toml # in your Cargo.toml @@ -21,30 +21,72 @@ bootloader = "0.5.0" **Note**: At least bootloader version `0.5.0` is required. +If you want to use a custom bootloader with a different name, you can use Cargo's [rename functionality](https://doc.rust-lang.org/cargo/reference/specifying-dependencies.html#renaming-dependencies-in-cargotoml). + +### Building + 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] +bootimage build --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: + +``` +cargo bootimage --target your_custom_target.json [other_args] +``` + +### Running + +To run your kernel in QEMU, you can use `bootimage run`: + +``` +bootimage run --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" +``` + +Now you can run your kernel through `cargo xrun --target […]`. + ## Configuration -Configuration is done through a through a `[package.metadata.bootimage]` table in the `Cargo.toml`. The following options are available: +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] # This target is used if no `--target` is passed default-target = "" - # The command invoked on `bootimage run` + # The command invoked on `bootimage run` or `bootimage runner` # (the "{}" will be replaced with the path to the bootable disk image) run-command = ["qemu-system-x86_64", "-drive", "format=raw,file={}"] - # The timeout for running an integration test in seconds + # Additional arguments passed to the runner on `bootimage run` or `bootimage runner` + # (this is useful when you want to add some arguments to the default QEMU command) + run-args = [] + + # The timeout for running an integration test through `bootimage test` in seconds test-timeout = 300 ``` ## License -Dual-licensed under MIT or the Apache License (Version 2.0). + +Licensed under either of + +- Apache License, Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE) or + http://www.apache.org/licenses/LICENSE-2.0) +- MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT) + +at your option. + +Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions. From 2e892808a5b0736c66db3d5df6d4f4e626183d55 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Tue, 2 Apr 2019 21:39:32 +0200 Subject: [PATCH 107/271] Remove unused `ExitCode` field of `ErrorString` --- src/lib.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 1e00d15..681f181 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -27,7 +27,7 @@ pub fn lib_main() { match run() { Err(err) => { eprintln!("Error: {}", err.message); - process::exit(err.exit_code); + process::exit(1); } Ok(Some(exit_code)) => { process::exit(exit_code); @@ -56,7 +56,6 @@ pub fn run() -> Result, ErrorString> { pub struct ErrorString { pub message: Box, - pub exit_code: i32, } impl fmt::Debug for ErrorString { @@ -72,7 +71,6 @@ where fn from(err: T) -> Self { ErrorString { message: Box::new(err), - exit_code: 1, } } } From 667bb265da6ac8db00f09295be642d7348ae4f00 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Tue, 2 Apr 2019 21:41:11 +0200 Subject: [PATCH 108/271] Rename `ErrorString` to `ErrorMessage` --- Changelog.md | 2 +- src/args.rs | 11 +++++------ src/config.rs | 6 +++--- src/lib.rs | 10 +++++----- src/subcommand/build.rs | 6 +++--- src/subcommand/run.rs | 8 ++++---- src/subcommand/runner.rs | 4 ++-- src/subcommand/test.rs | 8 ++++---- 8 files changed, 27 insertions(+), 28 deletions(-) diff --git a/Changelog.md b/Changelog.md index 34684ed..2b3c486 100644 --- a/Changelog.md +++ b/Changelog.md @@ -20,7 +20,7 @@ - Move crate to 2018 edition - Refactor and cleanup the code - Remove the dependency on `failure` - - Use a custom `ErrorString` type instead + - Use a custom `ErrorMessage` type instead - Add a new `run-args` config key - Add a new `--quiet` argument to suppress output diff --git a/src/args.rs b/src/args.rs index f40104e..b65aa3b 100644 --- a/src/args.rs +++ b/src/args.rs @@ -1,8 +1,8 @@ -use crate::{config::Config, Command, ErrorString}; +use crate::{config::Config, Command, ErrorMessage}; use std::path::{Path, PathBuf}; use std::{env, mem}; -pub(crate) fn parse_args() -> Result { +pub(crate) fn parse_args() -> Result { let mut args = env::args(); let executable_name = args.next().ok_or("no first argument (executable name)")?; let first = args.next(); @@ -36,7 +36,7 @@ pub(crate) fn parse_args() -> Result { } } -fn parse_build_args(args: A) -> Result +fn parse_build_args(args: A) -> Result where A: Iterator, { @@ -49,7 +49,7 @@ where let mut run_args_started = false; let mut quiet = false; { - fn set(arg: &mut Option, value: Option) -> Result<(), ErrorString> { + 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")? @@ -209,7 +209,7 @@ impl Args { } } -fn parse_runner_args(args: A) -> Result +fn parse_runner_args(args: A) -> Result where A: Iterator, { @@ -257,4 +257,3 @@ pub struct RunnerArgs { /// Suppress any output to stdout. pub quiet: bool, } - diff --git a/src/config.rs b/src/config.rs index 6f10e20..2b3f4fc 100644 --- a/src/config.rs +++ b/src/config.rs @@ -1,4 +1,4 @@ -use crate::ErrorString; +use crate::ErrorMessage; use std::path::PathBuf; use toml::Value; @@ -11,13 +11,13 @@ pub struct Config { pub test_timeout: u32, } -pub(crate) fn read_config(manifest_path: PathBuf) -> Result { +pub(crate) fn read_config(manifest_path: PathBuf) -> Result { let config = read_config_inner(manifest_path) .map_err(|err| format!("Failed to read bootimage configuration: {:?}", err))?; Ok(config) } -pub(crate) fn read_config_inner(manifest_path: PathBuf) -> Result { +pub(crate) fn read_config_inner(manifest_path: PathBuf) -> Result { use std::{fs::File, io::Read}; let cargo_toml: Value = { let mut content = String::new(); diff --git a/src/lib.rs b/src/lib.rs index 681f181..e66f392 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -36,7 +36,7 @@ pub fn lib_main() { } } -pub fn run() -> Result, ErrorString> { +pub fn run() -> Result, ErrorMessage> { let command = args::parse_args()?; let none = |()| None; match command { @@ -54,22 +54,22 @@ pub fn run() -> Result, ErrorString> { } } -pub struct ErrorString { +pub struct ErrorMessage { pub message: Box, } -impl fmt::Debug for ErrorString { +impl fmt::Debug for ErrorMessage { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { self.message.fmt(f) } } -impl From for ErrorString +impl From for ErrorMessage where T: fmt::Display + Send + 'static, { fn from(err: T) -> Self { - ErrorString { + ErrorMessage { message: Box::new(err), } } diff --git a/src/subcommand/build.rs b/src/subcommand/build.rs index ea6bc54..c96b0d3 100644 --- a/src/subcommand/build.rs +++ b/src/subcommand/build.rs @@ -1,7 +1,7 @@ -use crate::{args::Args, builder::Builder, config, ErrorString}; +use crate::{args::Args, builder::Builder, config, ErrorMessage}; use std::{path::PathBuf, process}; -pub(crate) fn build(mut args: Args) -> Result<(), ErrorString> { +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().to_owned())?; args.apply_default_target(&config, builder.kernel_root()); @@ -14,7 +14,7 @@ pub(crate) fn build_impl( builder: &Builder, args: &Args, quiet: bool, -) -> Result, ErrorString> { +) -> Result, ErrorMessage> { run_cargo_fetch(&args); let executables = builder.build_kernel(&args.cargo_args, quiet)?; diff --git a/src/subcommand/run.rs b/src/subcommand/run.rs index b505b80..df42e51 100644 --- a/src/subcommand/run.rs +++ b/src/subcommand/run.rs @@ -1,7 +1,7 @@ -use crate::{args::Args, builder::Builder, config, ErrorString}; +use crate::{args::Args, builder::Builder, config, ErrorMessage}; use std::process; -pub(crate) fn run(mut args: Args) -> Result { +pub(crate) fn run(mut args: Args) -> Result { use crate::subcommand::build; let builder = Builder::new(args.manifest_path().clone())?; @@ -23,7 +23,7 @@ pub(crate) fn run(mut args: Args) -> Result { "{}", bootimage_path .to_str() - .ok_or(ErrorString::from("bootimage path is not valid unicode"))?, + .ok_or(ErrorMessage::from("bootimage path is not valid unicode"))?, ), ); } @@ -32,7 +32,7 @@ pub(crate) fn run(mut args: Args) -> Result { } command.args(&args.run_args); let exit_status = command.status().map_err(|err| { - ErrorString::from(format!( + ErrorMessage::from(format!( "Failed to execute run command `{:?}`: {}", command, err )) diff --git a/src/subcommand/runner.rs b/src/subcommand/runner.rs index 1815b52..4cb72db 100644 --- a/src/subcommand/runner.rs +++ b/src/subcommand/runner.rs @@ -1,7 +1,7 @@ -use crate::{args::RunnerArgs, builder::Builder, config, ErrorString}; +use crate::{args::RunnerArgs, builder::Builder, config, ErrorMessage}; use std::process; -pub(crate) fn runner(args: RunnerArgs) -> Result { +pub(crate) fn runner(args: RunnerArgs) -> Result { let builder = Builder::new(None)?; let config = config::read_config(builder.kernel_manifest_path().to_owned())?; diff --git a/src/subcommand/test.rs b/src/subcommand/test.rs index b93f1e0..858ecc2 100644 --- a/src/subcommand/test.rs +++ b/src/subcommand/test.rs @@ -1,9 +1,9 @@ -use crate::{args::Args, builder::Builder, config, subcommand::build, ErrorString}; +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<(), ErrorString> { +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().to_owned())?; args.apply_default_target(&config, builder.kernel_root()); @@ -83,7 +83,7 @@ pub(crate) fn test(mut args: Args) -> Result<(), ErrorString> { Ok((target.name.clone(), test_result)) }) - .collect::, ErrorString>>()?; + .collect::, ErrorMessage>>()?; println!(""); if tests.iter().all(|t| t.1 == TestResult::Ok) { @@ -102,7 +102,7 @@ fn handle_exit_status( exit_status: process::ExitStatus, output: &str, target_name: &str, -) -> Result { +) -> Result { match exit_status.code() { None => { writeln!(io::stderr(), "FAIL: No Exit Code.")?; From c6f5afdd22b25d38d34b0784910f6d088e226875 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Tue, 2 Apr 2019 23:04:15 +0200 Subject: [PATCH 109/271] Make args module private and remove unused methods --- src/args.rs | 8 -------- src/lib.rs | 2 +- 2 files changed, 1 insertion(+), 9 deletions(-) diff --git a/src/args.rs b/src/args.rs index b65aa3b..80ea78e 100644 --- a/src/args.rs +++ b/src/args.rs @@ -173,18 +173,10 @@ impl Args { &self.manifest_path } - pub fn bin_name(&self) -> &Option { - &self.bin_name - } - pub fn target(&self) -> &Option { &self.target } - pub fn release(&self) -> bool { - self.release - } - pub fn set_target(&mut self, target: String) { assert!(self.target.is_none()); self.target = Some(target.clone()); diff --git a/src/lib.rs b/src/lib.rs index e66f392..86f2a3a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,8 +1,8 @@ use args::{Args, RunnerArgs}; use std::{fmt, process}; -pub mod args; pub mod builder; +mod args; pub mod config; pub mod help; From 211415dfae0c98d66a670b597d88a48dfe3ccac9 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Tue, 2 Apr 2019 23:05:12 +0200 Subject: [PATCH 110/271] Remove remaining unwraps in builder module --- src/builder.rs | 43 ++++++++++++++++++++++++++++++++----------- 1 file changed, 32 insertions(+), 11 deletions(-) diff --git a/src/builder.rs b/src/builder.rs index 7ae70af..6a4ee3a 100644 --- a/src/builder.rs +++ b/src/builder.rs @@ -96,8 +96,12 @@ impl Builder { }); } let mut executables = Vec::new(); - for line in String::from_utf8(output.stdout).unwrap().lines() { - let mut artifact = json::parse(line).unwrap(); + 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)); } @@ -233,8 +237,12 @@ impl Builder { }); } let mut bootloader_elf_path = None; - for line in String::from_utf8(output.stdout).unwrap().lines() { - let mut artifact = json::parse(line).unwrap(); + 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)) @@ -316,10 +324,8 @@ pub enum BuildKernelError { XbuildFailed { stderr: Vec, }, - CargoConfigInvalid { - path: PathBuf, - error: String, - }, + XbuildJsonOutputInvalidUtf8(std::string::FromUtf8Error), + XbuildJsonOutputInvalidJson(json::Error), } impl fmt::Display for BuildKernelError { @@ -338,9 +344,12 @@ impl fmt::Display for BuildKernelError { BuildKernelError::XbuildFailed{stderr} => { writeln!(f, "Kernel build failed:\n{}", String::from_utf8_lossy(stderr)) } - BuildKernelError::CargoConfigInvalid{path,error} => { - writeln!(f, "Failed to read cargo config at {}:\n{}", path.display(), error) - }, + 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) + } } } } @@ -374,6 +383,8 @@ pub enum CreateBootimageError { ObjcopyFailed { stderr: Vec, }, + XbuildJsonOutputInvalidUtf8(std::string::FromUtf8Error), + XbuildJsonOutputInvalidJson(json::Error), } impl fmt::Display for CreateBootimageError { @@ -422,6 +433,16 @@ impl fmt::Display for CreateBootimageError { "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 + ), } } } From 48d7b803f2c229a8083b5b158a7d37f50d48f38a Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Tue, 2 Apr 2019 23:13:23 +0200 Subject: [PATCH 111/271] Make BuildKernelError and CreateBootimageError non-exhaustive --- src/builder.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/builder.rs b/src/builder.rs index 6a4ee3a..f23f8e2 100644 --- a/src/builder.rs +++ b/src/builder.rs @@ -326,6 +326,8 @@ pub enum BuildKernelError { }, XbuildJsonOutputInvalidUtf8(std::string::FromUtf8Error), XbuildJsonOutputInvalidJson(json::Error), + #[doc(hidden)] + __NonExhaustive, } impl fmt::Display for BuildKernelError { @@ -350,6 +352,7 @@ impl fmt::Display for BuildKernelError { 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"), } } } @@ -385,6 +388,8 @@ pub enum CreateBootimageError { }, XbuildJsonOutputInvalidUtf8(std::string::FromUtf8Error), XbuildJsonOutputInvalidJson(json::Error), + #[doc(hidden)] + __NonExhaustive, } impl fmt::Display for CreateBootimageError { @@ -443,6 +448,7 @@ impl fmt::Display for CreateBootimageError { "Output of bootloader build with --message-format=json is not valid JSON:\n{}", err ), + CreateBootimageError::__NonExhaustive => panic!("__NonExhaustive variant constructed"), } } } From 1e8306bddb4a09fa59e426aaa756c862610b1ced Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Tue, 2 Apr 2019 23:22:54 +0200 Subject: [PATCH 112/271] Remove unused config.manifest_path field --- src/config.rs | 22 ++++++---------------- src/subcommand/build.rs | 2 +- src/subcommand/run.rs | 2 +- src/subcommand/runner.rs | 2 +- src/subcommand/test.rs | 2 +- 5 files changed, 10 insertions(+), 20 deletions(-) diff --git a/src/config.rs b/src/config.rs index 2b3f4fc..3c3b3be 100644 --- a/src/config.rs +++ b/src/config.rs @@ -1,27 +1,26 @@ use crate::ErrorMessage; -use std::path::PathBuf; +use std::path::Path; use toml::Value; #[derive(Debug, Clone)] pub struct Config { - pub manifest_path: PathBuf, pub default_target: Option, pub run_command: Vec, pub run_args: Option>, pub test_timeout: u32, } -pub(crate) fn read_config(manifest_path: PathBuf) -> Result { +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) } -pub(crate) fn read_config_inner(manifest_path: PathBuf) -> Result { +pub(crate) 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) + File::open(manifest_path) .map_err(|e| format!("Failed to open Cargo.toml: {}", e))? .read_to_string(&mut content) .map_err(|e| format!("Failed to read Cargo.toml: {}", e))?; @@ -36,21 +35,14 @@ pub(crate) fn read_config_inner(manifest_path: PathBuf) -> Result { - return Ok(ConfigBuilder { - manifest_path: Some(manifest_path), - ..Default::default() - } - .into()); + return Ok(ConfigBuilder::default().into()); } Some(metadata) => metadata .as_table() .ok_or(format!("Bootimage configuration invalid: {:?}", metadata))?, }; - let mut config = ConfigBuilder { - manifest_path: Some(manifest_path), - ..Default::default() - }; + let mut config = ConfigBuilder::default(); for (key, value) in metadata { match (key.as_str(), value.clone()) { @@ -93,7 +85,6 @@ pub(crate) fn read_config_inner(manifest_path: PathBuf) -> Result, default_target: Option, run_command: Option>, run_args: Option>, @@ -103,7 +94,6 @@ struct ConfigBuilder { impl Into for ConfigBuilder { fn into(self) -> Config { Config { - manifest_path: self.manifest_path.expect("manifest path must be set"), default_target: self.default_target, run_command: self.run_command.unwrap_or(vec![ "qemu-system-x86_64".into(), diff --git a/src/subcommand/build.rs b/src/subcommand/build.rs index c96b0d3..0a86d2d 100644 --- a/src/subcommand/build.rs +++ b/src/subcommand/build.rs @@ -3,7 +3,7 @@ use std::{path::PathBuf, process}; 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().to_owned())?; + let config = config::read_config(builder.kernel_manifest_path())?; args.apply_default_target(&config, builder.kernel_root()); let quiet = args.quiet; diff --git a/src/subcommand/run.rs b/src/subcommand/run.rs index df42e51..e83b8dd 100644 --- a/src/subcommand/run.rs +++ b/src/subcommand/run.rs @@ -5,7 +5,7 @@ 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().to_owned())?; + let config = config::read_config(builder.kernel_manifest_path())?; args.apply_default_target(&config, builder.kernel_root()); let quiet = args.quiet; diff --git a/src/subcommand/runner.rs b/src/subcommand/runner.rs index 4cb72db..f00e4de 100644 --- a/src/subcommand/runner.rs +++ b/src/subcommand/runner.rs @@ -3,7 +3,7 @@ use std::process; pub(crate) fn runner(args: RunnerArgs) -> Result { let builder = Builder::new(None)?; - let config = config::read_config(builder.kernel_manifest_path().to_owned())?; + let config = config::read_config(builder.kernel_manifest_path())?; let bootimage_bin = { let parent = args diff --git a/src/subcommand/test.rs b/src/subcommand/test.rs index 858ecc2..6373959 100644 --- a/src/subcommand/test.rs +++ b/src/subcommand/test.rs @@ -5,7 +5,7 @@ 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().to_owned())?; + let config = config::read_config(builder.kernel_manifest_path())?; args.apply_default_target(&config, builder.kernel_root()); let test_args = args.clone(); From 3d9e95c98484471b30e94a6e691b38875e944d6e Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Tue, 2 Apr 2019 23:23:52 +0200 Subject: [PATCH 113/271] Make config::Config struct non-exhaustive --- src/config.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/config.rs b/src/config.rs index 3c3b3be..6b80a55 100644 --- a/src/config.rs +++ b/src/config.rs @@ -8,6 +8,7 @@ pub struct Config { pub run_command: Vec, pub run_args: Option>, pub test_timeout: u32, + non_exhaustive: (), } pub(crate) fn read_config(manifest_path: &Path) -> Result { @@ -102,6 +103,7 @@ impl Into for ConfigBuilder { ]), run_args: self.run_args, test_timeout: self.test_timeout.unwrap_or(60 * 5), + non_exhaustive: (), } } } From df26d3e48bbbec8424b090e88e059bcac467cdc4 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Tue, 2 Apr 2019 23:29:05 +0200 Subject: [PATCH 114/271] Remove now unused `tester` example crate --- example-kernels/Cargo.lock | 8 ------ example-kernels/Cargo.toml | 1 - example-kernels/tester/.gitignore | 2 -- example-kernels/tester/Cargo.toml | 9 ------- example-kernels/tester/build.rs | 27 ------------------- example-kernels/tester/src/lib.rs | 21 --------------- .../tester/tests/integration_tests.rs | 16 ----------- .../integration_tests/test-basic-boot.rs | 27 ------------------- .../tests/integration_tests/test-panic.rs | 21 --------------- 9 files changed, 132 deletions(-) delete mode 100644 example-kernels/tester/.gitignore delete mode 100644 example-kernels/tester/Cargo.toml delete mode 100644 example-kernels/tester/build.rs delete mode 100644 example-kernels/tester/src/lib.rs delete mode 100644 example-kernels/tester/tests/integration_tests.rs delete mode 100644 example-kernels/tester/tests/integration_tests/test-basic-boot.rs delete mode 100644 example-kernels/tester/tests/integration_tests/test-panic.rs diff --git a/example-kernels/Cargo.lock b/example-kernels/Cargo.lock index cd749b3..01c75f4 100644 --- a/example-kernels/Cargo.lock +++ b/example-kernels/Cargo.lock @@ -230,14 +230,6 @@ dependencies = [ "remove_dir_all 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "tester" -version = "0.1.0" -dependencies = [ - "bootloader 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", - "x86_64 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "testing-qemu-exit-code" version = "0.1.0" diff --git a/example-kernels/Cargo.toml b/example-kernels/Cargo.toml index 03cc7ed..ede58ed 100644 --- a/example-kernels/Cargo.toml +++ b/example-kernels/Cargo.toml @@ -4,7 +4,6 @@ members = [ "default-target-bootimage", "default-target-cargo", "runner", - "tester", "testing-qemu-exit-code", "testing-serial-result", ] \ No newline at end of file diff --git a/example-kernels/tester/.gitignore b/example-kernels/tester/.gitignore deleted file mode 100644 index eccd7b4..0000000 --- a/example-kernels/tester/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -/target/ -**/*.rs.bk diff --git a/example-kernels/tester/Cargo.toml b/example-kernels/tester/Cargo.toml deleted file mode 100644 index 73c86fc..0000000 --- a/example-kernels/tester/Cargo.toml +++ /dev/null @@ -1,9 +0,0 @@ -[package] -name = "tester" -version = "0.1.0" -authors = ["Philipp Oppermann "] -edition = "2018" - -[dependencies] -bootloader = "0.5.0" -x86_64 = "0.5.3" diff --git a/example-kernels/tester/build.rs b/example-kernels/tester/build.rs deleted file mode 100644 index fd1c011..0000000 --- a/example-kernels/tester/build.rs +++ /dev/null @@ -1,27 +0,0 @@ -use std::{env, fs::File, io::Write, path::Path}; - -fn main() { - let out_dir = env::var("OUT_DIR").unwrap(); - let dest_path = Path::new(&out_dir).join("generated_tests.rs"); - let mut tests = File::create(&dest_path).unwrap(); - for entry in Path::new("tests").join("integration_tests").read_dir().expect("failed to read tests/integration tests") { - let entry = entry.expect("failed to read dir entry"); - assert!(entry.file_type().unwrap().is_file()); - let test_path = entry.path(); - let test_name = test_path.file_stem().expect("no file stem").to_os_string().into_string().expect("file name not valid utf8"); - - let content = format!(r#" -#[test] -fn {test_name}() {{ - run_test("{test_path}"); -}} -"#, test_name = test_name.replace("-", "_"), test_path = test_path.display()); - - tests.write_all(content.as_bytes()).expect("failed to write test"); - - println!("cargo:rerun-if-changed={}", entry.path().display()); - } - - println!("cargo:rustc-env=GENERATED_TESTS={}", dest_path.display()); - println!("cargo:rerun-if-changed=build.rs"); -} diff --git a/example-kernels/tester/src/lib.rs b/example-kernels/tester/src/lib.rs deleted file mode 100644 index cdc0ba8..0000000 --- a/example-kernels/tester/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/tester/tests/integration_tests.rs b/example-kernels/tester/tests/integration_tests.rs deleted file mode 100644 index 352e413..0000000 --- a/example-kernels/tester/tests/integration_tests.rs +++ /dev/null @@ -1,16 +0,0 @@ -use std::path::Path; - -include!(env!("GENERATED_TESTS")); - -fn run_test(test_path: &str) { - let mut cmd = std::process::Command::new("bootimage"); - cmd.arg("tester"); - cmd.arg(Path::new(test_path)); - cmd.arg("--target"); - cmd.arg("../x86_64-bootimage-example-kernels.json"); - let output = cmd.output().expect("failed to run bootimage"); - if !output.status.success() { - eprintln!("{}", String::from_utf8_lossy(&output.stderr)); - panic!("test failed"); - } -} \ No newline at end of file diff --git a/example-kernels/tester/tests/integration_tests/test-basic-boot.rs b/example-kernels/tester/tests/integration_tests/test-basic-boot.rs deleted file mode 100644 index 02de359..0000000 --- a/example-kernels/tester/tests/integration_tests/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 tester::{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/tester/tests/integration_tests/test-panic.rs b/example-kernels/tester/tests/integration_tests/test-panic.rs deleted file mode 100644 index 5a7d176..0000000 --- a/example-kernels/tester/tests/integration_tests/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 tester::{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 {} -} From 2e73c32908f0c8d6db8f882d08627ef7a0eb3478 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Tue, 2 Apr 2019 23:30:11 +0200 Subject: [PATCH 115/271] Document all library types --- src/args.rs | 2 ++ src/builder.rs | 34 ++++++++++++++++++++++++++++++++++ src/config.rs | 13 +++++++++++++ src/lib.rs | 27 ++++++++++++++++++++++++++- 4 files changed, 75 insertions(+), 1 deletion(-) diff --git a/src/args.rs b/src/args.rs index 80ea78e..05ea511 100644 --- a/src/args.rs +++ b/src/args.rs @@ -1,3 +1,5 @@ +//! Parses command line arguments. + use crate::{config::Config, Command, ErrorMessage}; use std::path::{Path, PathBuf}; use std::{env, mem}; diff --git a/src/builder.rs b/src/builder.rs index f23f8e2..f0e78ad 100644 --- a/src/builder.rs +++ b/src/builder.rs @@ -1,15 +1,21 @@ +//! 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()?); @@ -22,20 +28,24 @@ impl Builder { }) } + /// 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); @@ -45,6 +55,12 @@ impl Builder { )) } + /// 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], @@ -110,6 +126,11 @@ impl Builder { 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, @@ -284,6 +305,7 @@ impl Builder { } } +/// Represents an error that occurred while creating a new `Builder`. #[derive(Debug)] pub enum BuilderError { /// Failed to locate cargo manifest @@ -309,6 +331,7 @@ impl fmt::Display for BuilderError { } } +/// 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 @@ -320,11 +343,16 @@ pub enum BuildKernelError { /// 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, @@ -357,6 +385,7 @@ impl fmt::Display for BuildKernelError { } } +/// 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 @@ -368,7 +397,9 @@ pub enum CreateBootimageError { 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 @@ -384,9 +415,12 @@ pub enum CreateBootimageError { 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, diff --git a/src/config.rs b/src/config.rs index 6b80a55..6c80bfd 100644 --- a/src/config.rs +++ b/src/config.rs @@ -1,12 +1,25 @@ +//! Parses the `package.metadata.bootimage` configuration table + use crate::ErrorMessage; use std::path::Path; use toml::Value; +/// Represents the `package.metadata.bootimage` configuration table +/// +/// The bootimage crate can be configured through a `package.metadata.bootimage` table +/// in the `Cargo.toml` file of the kernel. This struct represents the parsed configuration +/// 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. pub run_command: Vec, + /// Additional arguments passed to the runner on `bootimage run` or `bootimage runner` pub run_args: Option>, + /// The timeout for running an integration test through `bootimage test` in seconds pub test_timeout: u32, non_exhaustive: (), } diff --git a/src/lib.rs b/src/lib.rs index 86f2a3a..29f2163 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,8 +1,14 @@ +//! Provides functions to create a bootable OS image from a kernel binary. +//! +//! This crate is mainly built as a binary tool. Run `cargo install bootimage` to install it. + +#![warn(missing_docs)] + use args::{Args, RunnerArgs}; use std::{fmt, process}; -pub mod builder; mod args; +pub mod builder; pub mod config; pub mod help; @@ -23,6 +29,13 @@ enum Command { 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) => { @@ -36,6 +49,13 @@ pub fn lib_main() { } } +/// 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; @@ -54,7 +74,12 @@ pub fn run() -> Result, ErrorMessage> { } } +/// 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, } From 04cdce283eea9acd2bc7866d02240c29a18abed6 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Tue, 2 Apr 2019 23:30:30 +0200 Subject: [PATCH 116/271] Make help module private --- src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index 29f2163..f99af11 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -10,7 +10,7 @@ use std::{fmt, process}; mod args; pub mod builder; pub mod config; -pub mod help; +mod help; mod subcommand; From a94c1c32245736cc227747ede05b56f111d5961e Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Tue, 2 Apr 2019 23:46:12 +0200 Subject: [PATCH 117/271] Update --help output --- src/help/build_help.txt | 6 +++--- src/help/cargo_bootimage_help.txt | 20 ++++++++++++++++++++ src/help/help.txt | 4 ++++ src/help/mod.rs | 10 ++++++++++ src/help/run_help.txt | 5 ++++- src/help/runner_help.txt | 25 +++++++++++++++++++++++++ src/lib.rs | 3 ++- 7 files changed, 68 insertions(+), 5 deletions(-) create mode 100644 src/help/cargo_bootimage_help.txt create mode 100644 src/help/runner_help.txt diff --git a/src/help/build_help.txt b/src/help/build_help.txt index e92d588..e623053 100644 --- a/src/help/build_help.txt +++ b/src/help/build_help.txt @@ -12,9 +12,9 @@ BUILD_OPTS: disk image. CONFIGURATION: - The bootloader and 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: + 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 new file mode 100644 index 0000000..b257c10 --- /dev/null +++ b/src/help/cargo_bootimage_help.txt @@ -0,0 +1,20 @@ +Creates a bootable disk image from a Rust kernel + +USAGE: + cargo bootimage [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. + +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/help/help.txt b/src/help/help.txt index 4d594ea..3d265b9 100644 --- a/src/help/help.txt +++ b/src/help/help.txt @@ -5,6 +5,10 @@ USAGE: 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) For more information about a subcommand run `bootimage [subcommand] --help`. diff --git a/src/help/mod.rs b/src/help/mod.rs index 63bd8a1..31ff920 100644 --- a/src/help/mod.rs +++ b/src/help/mod.rs @@ -2,7 +2,9 @@ use std::process; 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() { @@ -13,10 +15,18 @@ pub(crate) fn build_help() { print!("{}", BUILD_HELP); } +pub(crate) fn cargo_bootimage_help() { + print!("{}", CARGO_BOOTIMAGE_HELP); +} + pub(crate) fn run_help() { print!("{}", RUN_HELP); } +pub(crate) fn runner_help() { + print!("{}", RUNNER_HELP); +} + pub(crate) fn test_help() { print!("{}", TEST_HELP); } diff --git a/src/help/run_help.txt b/src/help/run_help.txt index 09dfdce..4056ae3 100644 --- a/src/help/run_help.txt +++ b/src/help/run_help.txt @@ -16,6 +16,9 @@ CONFIGURATION: following options are available to configure run behavior: [package.metadata.bootimage] - # The command invoked on `bootimage run` + # The command invoked on `bootimage run` or `bootimage runner` # (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 runner on `bootimage run` or `bootimage runner` + # (this is useful when you want to add some arguments to the default QEMU command) + run-args = [] \ No newline at end of file diff --git a/src/help/runner_help.txt b/src/help/runner_help.txt new file mode 100644 index 0000000..d2bf3ed --- /dev/null +++ b/src/help/runner_help.txt @@ -0,0 +1,25 @@ +Creates a bootable disk image from a Rust kernel and launches it in QEMU + +USAGE: + bootimage runner EXECUTABLE Convert and run the given EXECUTABLE + + (for other forms of usage see `bootimage --help`) + + This subcommand can be used as a target runner in a `.cargo/config` file: + ``` + [target.'cfg(target_os = "none")'] + runner = "bootimage runner" + ``` + +CONFIGURATION: + The behavior of `bootimage runner` 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 on `bootimage run` or `bootimage runner` + # (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 runner on `bootimage run` or `bootimage runner` + # (this is useful when you want to add some arguments to the default QEMU command) + run-args = [] \ No newline at end of file diff --git a/src/lib.rs b/src/lib.rs index f99af11..70f2ea6 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -67,10 +67,11 @@ pub fn run() -> Result, ErrorMessage> { Command::NoSubcommand => help::no_subcommand(), 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::RunnerHelp | Command::CargoBootimageHelp => unimplemented!(), } } From bfd385804ac5837bc0482a300d9290e4b6e68b4c Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Tue, 2 Apr 2019 23:53:58 +0200 Subject: [PATCH 118/271] Replace remaining early exits with proper ErrorMessage returns --- src/help/mod.rs | 10 ++++------ src/lib.rs | 2 +- src/subcommand/build.rs | 10 ++++++---- src/subcommand/test.rs | 2 +- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/help/mod.rs b/src/help/mod.rs index 31ff920..9af62e7 100644 --- a/src/help/mod.rs +++ b/src/help/mod.rs @@ -1,4 +1,4 @@ -use std::process; +use crate::ErrorMessage; const HELP: &str = include_str!("help.txt"); const BUILD_HELP: &str = include_str!("build_help.txt"); @@ -31,9 +31,7 @@ pub(crate) fn test_help() { print!("{}", TEST_HELP); } -pub(crate) fn no_subcommand() -> ! { - println!("Please invoke `bootimage` with a subcommand (e.g. `bootimage build`)."); - println!(); - println!("See `bootimage --help` for more information."); - process::exit(1); +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() } diff --git a/src/lib.rs b/src/lib.rs index 70f2ea6..6d6ce73 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -64,7 +64,6 @@ pub fn run() -> Result, ErrorMessage> { 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::NoSubcommand => help::no_subcommand(), Command::Help => Ok(help::help()).map(none), Command::BuildHelp => Ok(help::build_help()).map(none), Command::CargoBootimageHelp => Ok(help::cargo_bootimage_help()).map(none), @@ -72,6 +71,7 @@ pub fn run() -> Result, ErrorMessage> { 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()), } } diff --git a/src/subcommand/build.rs b/src/subcommand/build.rs index 0a86d2d..1cc118e 100644 --- a/src/subcommand/build.rs +++ b/src/subcommand/build.rs @@ -15,7 +15,7 @@ pub(crate) fn build_impl( args: &Args, quiet: bool, ) -> Result, ErrorMessage> { - run_cargo_fetch(&args); + run_cargo_fetch(&args).map_err(|()| "cargo fetch failed")?; let executables = builder.build_kernel(&args.cargo_args, quiet)?; if executables.len() == 0 { @@ -40,14 +40,16 @@ pub(crate) fn build_impl( Ok(bootimages) } -fn run_cargo_fetch(args: &Args) { +fn run_cargo_fetch(args: &Args) -> Result<(), ()> { let mut command = process::Command::new("cargo"); command.arg("fetch"); if let Some(manifest_path) = args.manifest_path() { command.arg("--manifest-path"); command.arg(manifest_path); } - if !command.status().map(|s| s.success()).unwrap_or(false) { - process::exit(1); + if command.status().map(|s| s.success()).unwrap_or(false) { + Ok(()) + } else { + Err(()) } } diff --git a/src/subcommand/test.rs b/src/subcommand/test.rs index 6373959..7bf06b1 100644 --- a/src/subcommand/test.rs +++ b/src/subcommand/test.rs @@ -94,7 +94,7 @@ pub(crate) fn test(mut args: Args) -> Result<(), ErrorMessage> { for test in tests.iter().filter(|t| t.1 != TestResult::Ok) { writeln!(io::stderr(), " {}: {:?}", test.0, test.1)?; } - process::exit(1); + Err("Some tests failed".into()) } } From 400ba30e7bd54cde64b4ed75aaddac5fa90d7542 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Wed, 3 Apr 2019 10:59:53 +0200 Subject: [PATCH 119/271] Mention `bootimage 0.6.6` for older bootloader versions --- Readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Readme.md b/Readme.md index 03fa576..268ef02 100644 --- a/Readme.md +++ b/Readme.md @@ -19,7 +19,7 @@ First you need to add a dependency on the [`bootloader`](https://github.com/rust bootloader = "0.5.0" ``` -**Note**: At least bootloader version `0.5.0` is required. +**Note**: At least bootloader version `0.5.0` is required since `bootimage 0.7.0`. For earlier bootloader versions, use `bootimage 0.6.6`. If you want to use a custom bootloader with a different name, you can use Cargo's [rename functionality](https://doc.rust-lang.org/cargo/reference/specifying-dependencies.html#renaming-dependencies-in-cargotoml). From ef235ed941d6b1a19bbc4be63bf613117723e85a Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Thu, 4 Apr 2019 19:58:48 +0200 Subject: [PATCH 120/271] Use package.metadata.bootloader.target key for building bootloader Instead of using the default target from the `.cargo/config`. --- src/builder.rs | 35 ++++++++++++----------------------- 1 file changed, 12 insertions(+), 23 deletions(-) diff --git a/src/builder.rs b/src/builder.rs index f0e78ad..7e1f94d 100644 --- a/src/builder.rs +++ b/src/builder.rs @@ -167,29 +167,18 @@ impl Builder { ), )?; let bootloader_target = { - let cargo_config_content = match fs::read_to_string( - bootloader_root.join(".cargo").join("config"), - ) { - Err(ref err) if err.kind() == io::ErrorKind::NotFound => { - return Err(CreateBootimageError::BootloaderInvalid("No `.cargo/config` file found in bootloader crate\n\n\ - (If you're using the official bootloader crate, you need at least version 0.5.0.)".into())); - } - Err(err) => { - return Err(CreateBootimageError::Io { - message: "Failed to read `cargo/config` file of bootloader crate", - error: err, - }); - } - Ok(content) => content, - }; - let cargo_config: toml::Value = cargo_config_content.parse().map_err(|err| { - CreateBootimageError::BootloaderInvalid(format!( - "The `.cargo/config` file of the bootloader crate is not valid TOML: {}", - err - )) - })?; - let target = cargo_config.get("build").and_then(|v| v.get("target")).and_then(|v| v.as_str()).ok_or(CreateBootimageError::BootloaderInvalid("The `.cargo/config` file of the bootloader crate contains no build.target key or it is not valid".into()))?; - bootloader_root.join(target) + 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()))?; + bootloader_root.join(target_str) }; let bootloader_features = { From bea73ba39db4235fc3e52f04629d882584b492fd Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Fri, 5 Apr 2019 11:18:57 +0200 Subject: [PATCH 121/271] Require bootloader 0.5.1 --- Changelog.md | 2 +- Readme.md | 4 ++-- example-kernels/Cargo.lock | 16 ++++++++-------- example-kernels/basic/Cargo.toml | 2 +- .../default-target-bootimage/Cargo.toml | 2 +- example-kernels/default-target-cargo/Cargo.toml | 2 +- example-kernels/runner/Cargo.toml | 2 +- .../testing-qemu-exit-code/Cargo.toml | 2 +- example-kernels/testing-serial-result/Cargo.toml | 2 +- 9 files changed, 17 insertions(+), 17 deletions(-) diff --git a/Changelog.md b/Changelog.md index 2b3c486..27cedea 100644 --- a/Changelog.md +++ b/Changelog.md @@ -2,7 +2,7 @@ ## Breaking - Rewrite for new bootloader build system - - Compatible with bootloader 0.5.0+ + - Compatible with bootloader 0.5.1+ - Remove the following config options: `output`, `bootloader.*`, `minimum_image_size`, and `package_filepath` - The bootloader is now fully controlled through cargo dependencies. - For using a bootloader crate with name different than `bootloader` use [cargo's rename feature](https://doc.rust-lang.org/cargo/reference/specifying-dependencies.html#renaming-dependencies-in-cargotoml). diff --git a/Readme.md b/Readme.md index 268ef02..4e0a7fc 100644 --- a/Readme.md +++ b/Readme.md @@ -16,10 +16,10 @@ First you need to add a dependency on the [`bootloader`](https://github.com/rust # in your Cargo.toml [dependencies] -bootloader = "0.5.0" +bootloader = "0.5.1" ``` -**Note**: At least bootloader version `0.5.0` is required since `bootimage 0.7.0`. For earlier bootloader versions, use `bootimage 0.6.6`. +**Note**: At least bootloader version `0.5.1` is required since `bootimage 0.7.0`. For earlier bootloader versions, use `bootimage 0.6.6`. If you want to use a custom bootloader with a different name, you can use Cargo's [rename functionality](https://doc.rust-lang.org/cargo/reference/specifying-dependencies.html#renaming-dependencies-in-cargotoml). diff --git a/example-kernels/Cargo.lock b/example-kernels/Cargo.lock index 01c75f4..8d87baf 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.0 (registry+https://github.com/rust-lang/crates.io-index)", + "bootloader 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "x86_64 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -28,7 +28,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "bootloader" -version = "0.5.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "fixedvec 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -48,7 +48,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" name = "default-target-bootimage" version = "0.1.0" dependencies = [ - "bootloader 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "bootloader 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "x86_64 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -56,7 +56,7 @@ dependencies = [ name = "default-target-cargo" version = "0.1.0" dependencies = [ - "bootloader 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "bootloader 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "x86_64 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -177,7 +177,7 @@ dependencies = [ name = "runner" version = "0.1.0" dependencies = [ - "bootloader 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "bootloader 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "x86_64 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -234,7 +234,7 @@ dependencies = [ name = "testing-qemu-exit-code" version = "0.1.0" dependencies = [ - "bootloader 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "bootloader 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "x86_64 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -242,7 +242,7 @@ dependencies = [ name = "testing-serial-result" version = "0.1.0" dependencies = [ - "bootloader 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "bootloader 0.5.1 (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)", @@ -347,7 +347,7 @@ 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.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "228047a76f468627ca71776ecdebd732a3423081fcf5125585bcd7c49886ce12" -"checksum bootloader 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8668a7d724534aba1c3f2509eea122fcf611c31101662ecb947d502cc3cb96ae" +"checksum bootloader 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a70143804c70c39473b3d7e99b870fb4f7f319f3100386f5dedf06e11e1799f0" "checksum cc 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)" = "ad0daef304fa0b4238f5f7ed7178774b43b06f6a9b6509f6642bef4ff1f7b9b2" "checksum fixedvec 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7c6c16d316ccdac21a4dd648e314e76facbbaf316e83ca137d0857a9c07419d0" "checksum font8x8 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b81d84c3c978af7d05d31a2198af4b9ba956d819d15d8f6d58fc150e33f8dc1f" diff --git a/example-kernels/basic/Cargo.toml b/example-kernels/basic/Cargo.toml index 331b235..d3c4cec 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.5.0" +bootloader = "0.5.1" x86_64 = "0.5.3" diff --git a/example-kernels/default-target-bootimage/Cargo.toml b/example-kernels/default-target-bootimage/Cargo.toml index 5825f0a..3c12f8b 100644 --- a/example-kernels/default-target-bootimage/Cargo.toml +++ b/example-kernels/default-target-bootimage/Cargo.toml @@ -5,7 +5,7 @@ authors = ["Philipp Oppermann "] edition = "2018" [dependencies] -bootloader = "0.5.0" +bootloader = "0.5.1" x86_64 = "0.5.3" [package.metadata.bootimage] diff --git a/example-kernels/default-target-cargo/Cargo.toml b/example-kernels/default-target-cargo/Cargo.toml index 737b944..fb4142d 100644 --- a/example-kernels/default-target-cargo/Cargo.toml +++ b/example-kernels/default-target-cargo/Cargo.toml @@ -5,5 +5,5 @@ authors = ["Philipp Oppermann "] edition = "2018" [dependencies] -bootloader = "0.5.0" +bootloader = "0.5.1" x86_64 = "0.5.3" diff --git a/example-kernels/runner/Cargo.toml b/example-kernels/runner/Cargo.toml index 966cce4..15cf84b 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.5.0" +bootloader = "0.5.1" x86_64 = "0.5.3" [package.metadata.bootimage] diff --git a/example-kernels/testing-qemu-exit-code/Cargo.toml b/example-kernels/testing-qemu-exit-code/Cargo.toml index 6efb450..8e4d597 100644 --- a/example-kernels/testing-qemu-exit-code/Cargo.toml +++ b/example-kernels/testing-qemu-exit-code/Cargo.toml @@ -5,7 +5,7 @@ authors = ["Philipp Oppermann "] edition = "2018" [dependencies] -bootloader = "0.5.0" +bootloader = "0.5.1" x86_64 = "0.5.3" [package.metadata.bootimage] diff --git a/example-kernels/testing-serial-result/Cargo.toml b/example-kernels/testing-serial-result/Cargo.toml index bbe84a2..7412af8 100644 --- a/example-kernels/testing-serial-result/Cargo.toml +++ b/example-kernels/testing-serial-result/Cargo.toml @@ -5,7 +5,7 @@ authors = ["Philipp Oppermann "] edition = "2018" [dependencies] -bootloader = "0.5.0" +bootloader = "0.5.1" x86_64 = "0.5.3" spin = "0.4.9" uart_16550 = "0.1.0" From edc50cbd7e3ddccd57b63a12c845855039ceafbc Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Sat, 6 Apr 2019 15:24:10 +0200 Subject: [PATCH 122/271] bootimage 0.7.0 --- Cargo.lock | 2 +- Cargo.toml | 2 +- Changelog.md | 1 + 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 56481c0..cc66c69 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -10,7 +10,7 @@ dependencies = [ [[package]] name = "bootimage" -version = "0.6.6" +version = "0.7.0" 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 efc90fe..fe5b931 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.6.6" +version = "0.7.0" repository = "https://github.com/rust-osdev/bootimage" edition = "2018" diff --git a/Changelog.md b/Changelog.md index 27cedea..57f9572 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,3 +1,4 @@ +# 0.7.0 ## Breaking From 8746c15bf326cf8438a4e64ffdda332fbe59e30d Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Sat, 6 Apr 2019 16:34:32 +0200 Subject: [PATCH 123/271] Ignore `test-` executables for `bootimage run` --- Changelog.md | 4 ++++ src/args.rs | 4 ++++ src/subcommand/run.rs | 13 +++++++++++++ 3 files changed, 21 insertions(+) diff --git a/Changelog.md b/Changelog.md index 57f9572..628cf31 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,3 +1,7 @@ +- Fix for backwards compatibility: Ignore `test-` executables for `bootimage run`. + - This ensures that `bootimage run` still works without the need for a `--bin` argument if all other executables are integration tests. + - This only changes the default, you can still run test executables by passing `--bin test-.` + # 0.7.0 ## Breaking diff --git a/src/args.rs b/src/args.rs index 05ea511..fbcf7d6 100644 --- a/src/args.rs +++ b/src/args.rs @@ -186,6 +186,10 @@ impl Args { 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()); diff --git a/src/subcommand/run.rs b/src/subcommand/run.rs index e83b8dd..c370701 100644 --- a/src/subcommand/run.rs +++ b/src/subcommand/run.rs @@ -8,6 +8,19 @@ pub(crate) fn run(mut args: Args) -> Result { 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")?; From ef40a69e4b01119284c0d2e70f7c2a4616b5742a Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Sat, 6 Apr 2019 16:36:02 +0200 Subject: [PATCH 124/271] Remove cargo fetch step We no longer need this step because bootloader is now a normal dependency. --- src/subcommand/build.rs | 17 +---------------- 1 file changed, 1 insertion(+), 16 deletions(-) diff --git a/src/subcommand/build.rs b/src/subcommand/build.rs index 1cc118e..d012dfd 100644 --- a/src/subcommand/build.rs +++ b/src/subcommand/build.rs @@ -1,5 +1,5 @@ use crate::{args::Args, builder::Builder, config, ErrorMessage}; -use std::{path::PathBuf, process}; +use std::path::PathBuf; pub(crate) fn build(mut args: Args) -> Result<(), ErrorMessage> { let builder = Builder::new(args.manifest_path().clone())?; @@ -15,8 +15,6 @@ pub(crate) fn build_impl( args: &Args, quiet: bool, ) -> Result, ErrorMessage> { - run_cargo_fetch(&args).map_err(|()| "cargo fetch failed")?; - let executables = builder.build_kernel(&args.cargo_args, quiet)?; if executables.len() == 0 { Err("no executables built")?; @@ -40,16 +38,3 @@ pub(crate) fn build_impl( Ok(bootimages) } -fn run_cargo_fetch(args: &Args) -> Result<(), ()> { - let mut command = process::Command::new("cargo"); - command.arg("fetch"); - if let Some(manifest_path) = args.manifest_path() { - command.arg("--manifest-path"); - command.arg(manifest_path); - } - if command.status().map(|s| s.success()).unwrap_or(false) { - Ok(()) - } else { - Err(()) - } -} From 34aaec24588b4f0df878eb3a2b7c623f5c90f6fa Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Sat, 6 Apr 2019 16:37:07 +0200 Subject: [PATCH 125/271] bootimage 0.7.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 cc66c69..bed3725 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -10,7 +10,7 @@ dependencies = [ [[package]] name = "bootimage" -version = "0.7.0" +version = "0.7.1" 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 fe5b931..8c2b647 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.0" +version = "0.7.1" repository = "https://github.com/rust-osdev/bootimage" edition = "2018" diff --git a/Changelog.md b/Changelog.md index 628cf31..c0bd1ba 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,3 +1,5 @@ +# 0.7.1 + - Fix for backwards compatibility: Ignore `test-` executables for `bootimage run`. - This ensures that `bootimage run` still works without the need for a `--bin` argument if all other executables are integration tests. - This only changes the default, you can still run test executables by passing `--bin test-.` From f19395a125674ac0fe9a74997c1a07c45c55019c Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Thu, 11 Apr 2019 16:23:39 +0200 Subject: [PATCH 126/271] Pass additional arguments to `bootimage runner` to the run command --- Changelog.md | 3 +++ src/args.rs | 26 +++++++++++++++++++------- src/help/runner_help.txt | 4 +++- src/subcommand/runner.rs | 3 +++ 4 files changed, 28 insertions(+), 8 deletions(-) diff --git a/Changelog.md b/Changelog.md index c0bd1ba..6d861db 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,3 +1,6 @@ + +- Make `bootimage runner` pass additional arguments to the run command (e.g. QEMU). + # 0.7.1 - Fix for backwards compatibility: Ignore `test-` executables for `bootimage run`. diff --git a/src/args.rs b/src/args.rs index fbcf7d6..aac50f6 100644 --- a/src/args.rs +++ b/src/args.rs @@ -213,21 +213,33 @@ where { let mut executable = None; let mut quiet = false; + let mut runner_args = None; let mut arg_iter = args.into_iter().fuse(); loop { - match arg_iter.next().as_ref().map(|s| s.as_str()) { - Some("--help") | Some("-h") => { + 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); } - Some("--version") => { + "--version" => { return Ok(Command::Version); } - Some("--quiet") => { + "--quiet" => { quiet = true; } - Some(exe) if executable.is_none() => { + exe => { let path = Path::new(exe); let path_canonicalized = path.canonicalize().map_err(|err| { format!( @@ -238,14 +250,13 @@ where })?; executable = Some(path_canonicalized); } - Some(arg) => Err(format!("unexpected argument `{}`", arg))?, - None => break, } } Ok(Command::Runner(RunnerArgs { executable: executable.ok_or("excepted path to kernel executable as first argument")?, quiet, + runner_args, })) } @@ -254,4 +265,5 @@ pub struct RunnerArgs { pub executable: PathBuf, /// Suppress any output to stdout. pub quiet: bool, + pub runner_args: Option>, } diff --git a/src/help/runner_help.txt b/src/help/runner_help.txt index d2bf3ed..c3ec363 100644 --- a/src/help/runner_help.txt +++ b/src/help/runner_help.txt @@ -1,7 +1,7 @@ Creates a bootable disk image from a Rust kernel and launches it in QEMU USAGE: - bootimage runner EXECUTABLE Convert and run the given EXECUTABLE + bootimage runner EXECUTABLE [ARGS] Convert and run the given EXECUTABLE (for other forms of usage see `bootimage --help`) @@ -11,6 +11,8 @@ USAGE: runner = "bootimage runner" ``` + All ARGS are passed to the run command. + CONFIGURATION: The behavior of `bootimage runner` can be configured through a `[package.metadata.bootimage]` table in the `Cargo.toml`. The diff --git a/src/subcommand/runner.rs b/src/subcommand/runner.rs index f00e4de..413eaeb 100644 --- a/src/subcommand/runner.rs +++ b/src/subcommand/runner.rs @@ -28,6 +28,9 @@ pub(crate) fn runner(args: RunnerArgs) -> Result { if let Some(run_args) = config.run_args { command.args(run_args); } + if let Some(args) = args.runner_args { + command.args(args); + } println!("Running: {:?}", command); From 3e6397349ecec9879d4e23d70cae99e3c4c68e3e Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Thu, 11 Apr 2019 16:28:18 +0200 Subject: [PATCH 127/271] Detect whether executable is a test for `bootimage runner` --- src/subcommand/runner.rs | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/subcommand/runner.rs b/src/subcommand/runner.rs index 413eaeb..473cf4e 100644 --- a/src/subcommand/runner.rs +++ b/src/subcommand/runner.rs @@ -1,22 +1,24 @@ use crate::{args::RunnerArgs, builder::Builder, config, ErrorMessage}; -use std::process; +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_test = exe_parent.ends_with("deps"); let bootimage_bin = { - let parent = args - .executable - .parent() - .ok_or("kernel executable has no parent")?; 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")?; - parent.join(format!("bootimage-{}.bin", file_stem)) + exe_parent.join(format!("bootimage-{}.bin", file_stem)) }; builder.create_bootimage(&args.executable, &bootimage_bin, args.quiet)?; From fd3c1ba4777816fa09dc5bd9f8330596fd9851e3 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Thu, 11 Apr 2019 19:18:00 +0200 Subject: [PATCH 128/271] Apply `test-timeout` config key when running tests in `bootimage runner` --- Changelog.md | 2 ++ Readme.md | 2 +- src/config.rs | 2 +- src/help/runner_help.txt | 3 ++- src/subcommand/runner.rs | 34 ++++++++++++++++++++++++++++++---- 5 files changed, 36 insertions(+), 7 deletions(-) diff --git a/Changelog.md b/Changelog.md index 6d861db..2ae26b0 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,5 +1,7 @@ - Make `bootimage runner` pass additional arguments to the run command (e.g. QEMU). +- Apply `test-timeout` config key when running tests in `bootimage runner` + - All binaries in the `target/deps` folder are considered tests for this feature # 0.7.1 diff --git a/Readme.md b/Readme.md index 4e0a7fc..636beaa 100644 --- a/Readme.md +++ b/Readme.md @@ -75,7 +75,7 @@ Configuration is done through a through a `[package.metadata.bootimage]` table i # (this is useful when you want to add some arguments to the default QEMU command) run-args = [] - # The timeout for running an integration test through `bootimage test` in seconds + # The timeout for running a test through `bootimage test` or `bootimage runner` (in seconds) test-timeout = 300 ``` diff --git a/src/config.rs b/src/config.rs index 6c80bfd..536fc32 100644 --- a/src/config.rs +++ b/src/config.rs @@ -19,7 +19,7 @@ pub struct Config { pub run_command: Vec, /// Additional arguments passed to the runner on `bootimage run` or `bootimage runner` pub run_args: Option>, - /// The timeout for running an integration test through `bootimage test` in seconds + /// The timeout for running an test through `bootimage test` or `bootimage runner` in seconds pub test_timeout: u32, non_exhaustive: (), } diff --git a/src/help/runner_help.txt b/src/help/runner_help.txt index c3ec363..7c3fd25 100644 --- a/src/help/runner_help.txt +++ b/src/help/runner_help.txt @@ -24,4 +24,5 @@ CONFIGURATION: run-command = ["qemu-system-x86_64", "-drive", "format=raw,file={}"] # Additional arguments passed to the runner on `bootimage run` or `bootimage runner` # (this is useful when you want to add some arguments to the default QEMU command) - run-args = [] \ No newline at end of file + run-args = [] # The timeout for running a test (in seconds) + test-timeout = 300 diff --git a/src/subcommand/runner.rs b/src/subcommand/runner.rs index 473cf4e..a8c9f5d 100644 --- a/src/subcommand/runner.rs +++ b/src/subcommand/runner.rs @@ -36,9 +36,35 @@ pub(crate) fn runner(args: RunnerArgs) -> Result { println!("Running: {:?}", command); - let output = command - .output() - .map_err(|e| format!("Failed to execute `{:?}`: {}", command, e))?; + 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) => match config.test_success_exit_code { + Some(code) if exit_status.code() == Some(code) => 0, + other => other.unwrap_or(1), + }, + } + } else { + let status = command + .status() + .map_err(|e| format!("Failed to execute `{:?}`: {}", command, e))?; + status.code().unwrap_or(1) + }; - Ok(output.status.code().unwrap_or(1)) + Ok(exit_code) } From f42827a290ad85f0fa8b6a802e0653cff28e3428 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Thu, 11 Apr 2019 19:20:52 +0200 Subject: [PATCH 129/271] Print non-canonicalized path in run message --- src/args.rs | 10 +--------- src/subcommand/runner.rs | 28 +++++++++++++++++++--------- 2 files changed, 20 insertions(+), 18 deletions(-) diff --git a/src/args.rs b/src/args.rs index aac50f6..50382a9 100644 --- a/src/args.rs +++ b/src/args.rs @@ -240,15 +240,7 @@ where quiet = true; } exe => { - let path = Path::new(exe); - let path_canonicalized = path.canonicalize().map_err(|err| { - format!( - "Failed to canonicalize executable path `{}`: {}", - path.display(), - err - ) - })?; - executable = Some(path_canonicalized); + executable = Some(PathBuf::from(exe)); } } } diff --git a/src/subcommand/runner.rs b/src/subcommand/runner.rs index a8c9f5d..5ddefd5 100644 --- a/src/subcommand/runner.rs +++ b/src/subcommand/runner.rs @@ -21,20 +21,30 @@ pub(crate) fn runner(args: RunnerArgs) -> Result { exe_parent.join(format!("bootimage-{}.bin", file_stem)) }; - builder.create_bootimage(&args.executable, &bootimage_bin, args.quiet)?; + 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 command = process::Command::new(&config.run_command[0]); - for arg in &config.run_command[1..] { - command.arg(arg.replace("{}", &format!("{}", bootimage_bin.display()))); - } - if let Some(run_args) = config.run_args { - command.args(run_args); + let mut run_command: Vec<_> = config + .run_command + .iter() + .map(|arg| arg.replace("{}", &format!("{}", bootimage_bin.display()))) + .collect(); + if let Some(args) = config.run_args { + run_command.extend(args); } if let Some(args) = args.runner_args { - command.args(args); + run_command.extend(args); } - println!("Running: {:?}", command); + 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 From 44ce5edb6bfdea5c418df1144d8708092941fbf1 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Thu, 11 Apr 2019 19:25:07 +0200 Subject: [PATCH 130/271] Don't print on --quiet --- src/subcommand/runner.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/subcommand/runner.rs b/src/subcommand/runner.rs index 5ddefd5..6fd593f 100644 --- a/src/subcommand/runner.rs +++ b/src/subcommand/runner.rs @@ -42,7 +42,9 @@ pub(crate) fn runner(args: RunnerArgs) -> Result { run_command.extend(args); } - println!("Running: `{}`", run_command.join(" ")); + if !args.quiet { + println!("Running: `{}`", run_command.join(" ")); + } let mut command = process::Command::new(&run_command[0]); command.args(&run_command[1..]); From 7ff50b022b42b5e3eb141e48fb0af954e2f73f77 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Thu, 11 Apr 2019 19:26:42 +0200 Subject: [PATCH 131/271] Don't apply `run_args` for test executables --- src/config.rs | 4 +++- src/help/run_help.txt | 3 +-- src/help/runner_help.txt | 6 +++--- src/subcommand/runner.rs | 6 ++++-- 4 files changed, 11 insertions(+), 8 deletions(-) diff --git a/src/config.rs b/src/config.rs index 536fc32..15fca2b 100644 --- a/src/config.rs +++ b/src/config.rs @@ -17,7 +17,9 @@ pub struct Config { /// /// The substring "{}" will be replaced with the path to the bootable disk image. pub run_command: Vec, - /// Additional arguments passed to the runner on `bootimage run` or `bootimage runner` + /// Additional arguments passed to the runner for not-test binaries + /// + /// Applies to `bootimage run` and `bootimage runner`. pub run_args: Option>, /// The timeout for running an test through `bootimage test` or `bootimage runner` in seconds pub test_timeout: u32, diff --git a/src/help/run_help.txt b/src/help/run_help.txt index 4056ae3..7c28f0a 100644 --- a/src/help/run_help.txt +++ b/src/help/run_help.txt @@ -19,6 +19,5 @@ CONFIGURATION: # The command invoked on `bootimage run` or `bootimage runner` # (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 runner on `bootimage run` or `bootimage runner` - # (this is useful when you want to add some arguments to the default QEMU command) + # Additional arguments passed to the run command for non-test executables run-args = [] \ No newline at end of file diff --git a/src/help/runner_help.txt b/src/help/runner_help.txt index 7c3fd25..e143b40 100644 --- a/src/help/runner_help.txt +++ b/src/help/runner_help.txt @@ -22,7 +22,7 @@ CONFIGURATION: # The command invoked on `bootimage run` or `bootimage runner` # (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 runner on `bootimage run` or `bootimage runner` - # (this is useful when you want to add some arguments to the default QEMU command) - run-args = [] # The timeout for running a test (in seconds) + # Additional arguments passed to the run command for non-test executables + run-args = [] + # The timeout for running a test (in seconds) test-timeout = 300 diff --git a/src/subcommand/runner.rs b/src/subcommand/runner.rs index 6fd593f..206e1ba 100644 --- a/src/subcommand/runner.rs +++ b/src/subcommand/runner.rs @@ -35,8 +35,10 @@ pub(crate) fn runner(args: RunnerArgs) -> Result { .iter() .map(|arg| arg.replace("{}", &format!("{}", bootimage_bin.display()))) .collect(); - if let Some(args) = config.run_args { - run_command.extend(args); + if !is_test { + if let Some(args) = config.run_args { + run_command.extend(args); + } } if let Some(args) = args.runner_args { run_command.extend(args); From 436385270948f5abeafd4be423d019c2e893560a Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Thu, 11 Apr 2019 19:34:16 +0200 Subject: [PATCH 132/271] Add a `test-args` config key --- src/config.rs | 16 ++++++++++++++++ src/help/runner_help.txt | 2 ++ src/subcommand/runner.rs | 6 +++++- 3 files changed, 23 insertions(+), 1 deletion(-) diff --git a/src/config.rs b/src/config.rs index 15fca2b..5c1c78f 100644 --- a/src/config.rs +++ b/src/config.rs @@ -21,6 +21,10 @@ pub struct Config { /// /// Applies to `bootimage run` and `bootimage runner`. pub run_args: Option>, + /// Additional arguments passed to the runner for test binaries + /// + /// Applies to `bootimage runner`. + pub test_args: Option>, /// The timeout for running an test through `bootimage test` or `bootimage runner` in seconds pub test_timeout: u32, non_exhaustive: (), @@ -89,6 +93,16 @@ pub(crate) fn read_config_inner(manifest_path: &Path) -> Result { + let mut args = Vec::new(); + for value in array { + match value { + Value::String(s) => args.push(s), + _ => Err(format!("test-args must be a list of strings"))?, + } + } + config.test_args = Some(args); + } (key, value) => Err(format!( "unexpected `package.metadata.bootimage` \ key `{}` with value `{}`", @@ -104,6 +118,7 @@ struct ConfigBuilder { default_target: Option, run_command: Option>, run_args: Option>, + test_args: Option>, test_timeout: Option, } @@ -117,6 +132,7 @@ impl Into for ConfigBuilder { "format=raw,file={}".into(), ]), run_args: self.run_args, + test_args: self.test_args, test_timeout: self.test_timeout.unwrap_or(60 * 5), non_exhaustive: (), } diff --git a/src/help/runner_help.txt b/src/help/runner_help.txt index e143b40..b89fd37 100644 --- a/src/help/runner_help.txt +++ b/src/help/runner_help.txt @@ -24,5 +24,7 @@ CONFIGURATION: run-command = ["qemu-system-x86_64", "-drive", "format=raw,file={}"] # Additional arguments passed to the run command for non-test executables run-args = [] + # Additional arguments passed to the run command for test executables + test-args = [] # The timeout for running a test (in seconds) test-timeout = 300 diff --git a/src/subcommand/runner.rs b/src/subcommand/runner.rs index 206e1ba..90bf4e8 100644 --- a/src/subcommand/runner.rs +++ b/src/subcommand/runner.rs @@ -35,7 +35,11 @@ pub(crate) fn runner(args: RunnerArgs) -> Result { .iter() .map(|arg| arg.replace("{}", &format!("{}", bootimage_bin.display()))) .collect(); - if !is_test { + 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); } From d8fba558ee88349ecd7e0b284bdf05c7f0ceb7d4 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Thu, 11 Apr 2019 19:37:28 +0200 Subject: [PATCH 133/271] Update documentation for run-command --- Readme.md | 5 +++-- src/help/run_help.txt | 4 ++-- src/help/runner_help.txt | 4 ++-- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/Readme.md b/Readme.md index 636beaa..5701317 100644 --- a/Readme.md +++ b/Readme.md @@ -67,8 +67,9 @@ Configuration is done through a through a `[package.metadata.bootimage]` table i # This target is used if no `--target` is passed default-target = "" - # The command invoked on `bootimage run` or `bootimage runner` - # (the "{}" will be replaced with the path to the bootable disk image) + # 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 runner on `bootimage run` or `bootimage runner` diff --git a/src/help/run_help.txt b/src/help/run_help.txt index 7c28f0a..f6c0857 100644 --- a/src/help/run_help.txt +++ b/src/help/run_help.txt @@ -16,8 +16,8 @@ CONFIGURATION: following options are available to configure run behavior: [package.metadata.bootimage] - # The command invoked on `bootimage run` or `bootimage runner` - # (the "{}" will be replaced with the path to the bootable disk image) + # 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/runner_help.txt b/src/help/runner_help.txt index b89fd37..94120ce 100644 --- a/src/help/runner_help.txt +++ b/src/help/runner_help.txt @@ -19,8 +19,8 @@ CONFIGURATION: following options are available to configure run behavior: [package.metadata.bootimage] - # The command invoked on `bootimage run` or `bootimage runner` - # (the "{}" will be replaced with the path to the bootable disk image) + # 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 = [] From 2399c3262cef9d555b7df279f4d218460224fa5a Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Thu, 11 Apr 2019 19:40:34 +0200 Subject: [PATCH 134/271] Add a `test-success-exit-code` config key --- src/config.rs | 8 ++++++++ src/help/runner_help.txt | 2 ++ 2 files changed, 10 insertions(+) diff --git a/src/config.rs b/src/config.rs index 5c1c78f..ce7e964 100644 --- a/src/config.rs +++ b/src/config.rs @@ -27,6 +27,9 @@ pub struct Config { pub test_args: Option>, /// The timeout for running an test through `bootimage test` or `bootimage runner` in seconds pub test_timeout: u32, + /// An exit code that should be considered as success for test executables (applies to + /// `bootimage runner`) + pub test_success_exit_code: Option, non_exhaustive: (), } @@ -73,6 +76,9 @@ pub(crate) fn read_config_inner(manifest_path: &Path) -> Result { config.test_timeout = Some(timeout as u32); } + ("test-success-exit-code", Value::Integer(exit_code)) => { + config.test_success_exit_code = Some(exit_code as i32); + } ("run-command", Value::Array(array)) => { let mut command = Vec::new(); for value in array { @@ -120,6 +126,7 @@ struct ConfigBuilder { run_args: Option>, test_args: Option>, test_timeout: Option, + test_success_exit_code: Option, } impl Into for ConfigBuilder { @@ -134,6 +141,7 @@ impl Into for ConfigBuilder { run_args: self.run_args, 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/runner_help.txt b/src/help/runner_help.txt index 94120ce..a526b7e 100644 --- a/src/help/runner_help.txt +++ b/src/help/runner_help.txt @@ -26,5 +26,7 @@ CONFIGURATION: run-args = [] # Additional arguments passed to the run command for test executables test-args = [] + # An exit code that should be considered as success for test executables + test-success-exit-code = {integer} # The timeout for running a test (in seconds) test-timeout = 300 From fd4db333681a8e29fbdd6a954b35754a3df5e8a2 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Thu, 11 Apr 2019 19:41:05 +0200 Subject: [PATCH 135/271] Update configuration section in Readme --- Readme.md | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/Readme.md b/Readme.md index 5701317..f0ff3b3 100644 --- a/Readme.md +++ b/Readme.md @@ -72,10 +72,17 @@ Configuration is done through a through a `[package.metadata.bootimage]` table i # Applies to `bootimage run` and `bootimage runner` run-command = ["qemu-system-x86_64", "-drive", "format=raw,file={}"] - # Additional arguments passed to the runner on `bootimage run` or `bootimage runner` - # (this is useful when you want to add some arguments to the default QEMU command) + # 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 = [] + + # 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 ``` From 32cf1571e145bfe0df4f8f6c990e5729a0458022 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Thu, 11 Apr 2019 19:41:22 +0200 Subject: [PATCH 136/271] Run rustfmt --- src/builder.rs | 15 +++++++++++---- src/help/mod.rs | 3 ++- src/subcommand/build.rs | 1 - src/subcommand/run.rs | 11 ++++++++--- 4 files changed, 21 insertions(+), 9 deletions(-) diff --git a/src/builder.rs b/src/builder.rs index 7e1f94d..8ea1fd7 100644 --- a/src/builder.rs +++ b/src/builder.rs @@ -170,14 +170,21 @@ impl Builder { 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::() + 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( + 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()))?; + (If you're using the official bootloader crate, you need at least version 0.5.1)" + .into(), + ))?; bootloader_root.join(target_str) }; let bootloader_features = diff --git a/src/help/mod.rs b/src/help/mod.rs index 9af62e7..60991db 100644 --- a/src/help/mod.rs +++ b/src/help/mod.rs @@ -33,5 +33,6 @@ pub(crate) fn 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() + See `bootimage --help` for more information." + .into() } diff --git a/src/subcommand/build.rs b/src/subcommand/build.rs index d012dfd..4a85a42 100644 --- a/src/subcommand/build.rs +++ b/src/subcommand/build.rs @@ -37,4 +37,3 @@ pub(crate) fn build_impl( Ok(bootimages) } - diff --git a/src/subcommand/run.rs b/src/subcommand/run.rs index c370701..3d23ab2 100644 --- a/src/subcommand/run.rs +++ b/src/subcommand/run.rs @@ -9,14 +9,19 @@ pub(crate) fn run(mut args: Args) -> Result { args.apply_default_target(&config, builder.kernel_root()); if args.bin_name().is_none() { - let kernel_package = builder.kernel_package() + 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(); + 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")?; + Please specify the binary you want to run as a `--bin` argument")?; } args.set_bin_name(bin_name); } From 8d21c594f1395c3474c55d63c19063d38f8e54d8 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Thu, 11 Apr 2019 19:41:58 +0200 Subject: [PATCH 137/271] Check formatting on CI --- azure-pipelines.yml | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index f750360..75d89bd 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -198,3 +198,48 @@ jobs: if [ $? -eq 109 ]; then (exit 0); else (exit 1); fi workingDirectory: example-kernels/runner displayName: 'Run `cargo xrun` for "runner" 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 3788a77deaab7deb19a1582982f0bfde15e048cd Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Thu, 11 Apr 2019 19:48:45 +0200 Subject: [PATCH 138/271] Update changelog --- Changelog.md | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/Changelog.md b/Changelog.md index 2ae26b0..d844f1b 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,7 +1,13 @@ -- Make `bootimage runner` pass additional arguments to the run command (e.g. QEMU). -- Apply `test-timeout` config key when running tests in `bootimage runner` - - All binaries in the `target/deps` folder are considered tests for this feature +- New features for `bootimage runner` + - Pass additional arguments to the run command (e.g. QEMU) + - Consider all binaries in the `target/deps` folder as test executables + - Apply `test-timeout` config key when running tests in `bootimage runner` + - Don't apply `run-args` for test executables + - Add a new `test-args` config key for test arguments + - Add a new `test-success-exit-code` config key for interpreting an exit code as success + - This is useful when the `isa-debug-exit` QEMU device is used. + - Improve printing of the run command (print string instead of array, print non-canonicalized executable path, respect `--quiet`) # 0.7.1 From 778e393a8fed8c6c245d39d263cf7cdb9549019d Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Thu, 11 Apr 2019 20:21:26 +0200 Subject: [PATCH 139/271] Add a runner-test kernel for testing new runner functionality --- azure-pipelines.yml | 4 ++ example-kernels/Cargo.lock | 8 +++ example-kernels/Cargo.toml | 1 + example-kernels/runner-test/.cargo/config | 5 ++ example-kernels/runner-test/.gitignore | 2 + example-kernels/runner-test/Cargo.toml | 17 +++++ example-kernels/runner-test/src/lib.rs | 63 +++++++++++++++++++ example-kernels/runner-test/src/main.rs | 30 +++++++++ .../runner-test/tests/no-harness.rs | 21 +++++++ .../runner-test/tests/should-panic.rs | 35 +++++++++++ 10 files changed, 186 insertions(+) create mode 100644 example-kernels/runner-test/.cargo/config create mode 100644 example-kernels/runner-test/.gitignore create mode 100644 example-kernels/runner-test/Cargo.toml create mode 100644 example-kernels/runner-test/src/lib.rs create mode 100644 example-kernels/runner-test/src/main.rs create mode 100644 example-kernels/runner-test/tests/no-harness.rs create mode 100644 example-kernels/runner-test/tests/should-panic.rs diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 75d89bd..6c7d8ef 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -199,6 +199,10 @@ jobs: workingDirectory: example-kernels/runner displayName: 'Run `cargo xrun` for "runner" kernel' + - script: cargo xtest + workingDirectory: example-kernels/runner-test + displayName: 'Run `cargo xtest` for "runner-test" kernel' + - job: formatting displayName: Check Formatting diff --git a/example-kernels/Cargo.lock b/example-kernels/Cargo.lock index 8d87baf..12d8032 100644 --- a/example-kernels/Cargo.lock +++ b/example-kernels/Cargo.lock @@ -181,6 +181,14 @@ dependencies = [ "x86_64 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "runner-test" +version = "0.1.0" +dependencies = [ + "bootloader 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "x86_64 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "rustc_version" version = "0.2.3" diff --git a/example-kernels/Cargo.toml b/example-kernels/Cargo.toml index ede58ed..ee84626 100644 --- a/example-kernels/Cargo.toml +++ b/example-kernels/Cargo.toml @@ -4,6 +4,7 @@ members = [ "default-target-bootimage", "default-target-cargo", "runner", + "runner-test", "testing-qemu-exit-code", "testing-serial-result", ] \ No newline at end of file diff --git a/example-kernels/runner-test/.cargo/config b/example-kernels/runner-test/.cargo/config new file mode 100644 index 0000000..3b4d89e --- /dev/null +++ b/example-kernels/runner-test/.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-test/.gitignore b/example-kernels/runner-test/.gitignore new file mode 100644 index 0000000..eccd7b4 --- /dev/null +++ b/example-kernels/runner-test/.gitignore @@ -0,0 +1,2 @@ +/target/ +**/*.rs.bk diff --git a/example-kernels/runner-test/Cargo.toml b/example-kernels/runner-test/Cargo.toml new file mode 100644 index 0000000..b6bb6ea --- /dev/null +++ b/example-kernels/runner-test/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "runner-test" +version = "0.1.0" +authors = ["Philipp Oppermann "] +edition = "2018" + +[[test]] +name = "no-harness" +harness = false + +[dependencies] +bootloader = "0.5.1" +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-test/src/lib.rs b/example-kernels/runner-test/src/lib.rs new file mode 100644 index 0000000..64c2518 --- /dev/null +++ b/example-kernels/runner-test/src/lib.rs @@ -0,0 +1,63 @@ +#![no_std] +#![cfg_attr(test, no_main)] + +#![feature(custom_test_frameworks)] +#![test_runner(crate::test_runner)] +#![reexport_test_harness_main = "test_main"] + +pub fn test_runner(tests: &[&dyn Fn()]) { + for test in tests.iter() { + test(); + } + + unsafe { exit_qemu(ExitCode::Success); } +} + +#[test_case] +fn test1() { + assert_eq!(0, 0); +} + +#[test_case] +fn test2() { + assert_eq!(1, 1); +} + +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 {} +} diff --git a/example-kernels/runner-test/src/main.rs b/example-kernels/runner-test/src/main.rs new file mode 100644 index 0000000..67c5e90 --- /dev/null +++ b/example-kernels/runner-test/src/main.rs @@ -0,0 +1,30 @@ +#![no_std] +#![no_main] + +#![feature(custom_test_frameworks)] +#![test_runner(runner_test::test_runner)] +#![reexport_test_harness_main = "test_main"] + +use core::panic::PanicInfo; +use runner_test::{exit_qemu, ExitCode}; + +#[no_mangle] +pub extern "C" fn _start() -> ! { + #[cfg(test)] + test_main(); + + unsafe { exit_qemu(ExitCode::Failed); } + + loop {} +} + +#[test_case] +fn test1() { + assert_eq!(0, 0); +} + +#[panic_handler] +fn panic(_info: &PanicInfo) -> ! { + unsafe { exit_qemu(ExitCode::Failed); } + loop {} +} diff --git a/example-kernels/runner-test/tests/no-harness.rs b/example-kernels/runner-test/tests/no-harness.rs new file mode 100644 index 0000000..4c20516 --- /dev/null +++ b/example-kernels/runner-test/tests/no-harness.rs @@ -0,0 +1,21 @@ +#![no_std] +#![no_main] + +use runner_test::{exit_qemu, ExitCode}; +use core::panic::PanicInfo; + +#[no_mangle] +pub extern "C" fn _start() -> ! { + unsafe { + exit_qemu(ExitCode::Success); + } + loop {} +} + +#[panic_handler] +fn panic(_info: &PanicInfo) -> ! { + unsafe { + exit_qemu(ExitCode::Failed); + } + loop {} +} diff --git a/example-kernels/runner-test/tests/should-panic.rs b/example-kernels/runner-test/tests/should-panic.rs new file mode 100644 index 0000000..4dfb643 --- /dev/null +++ b/example-kernels/runner-test/tests/should-panic.rs @@ -0,0 +1,35 @@ +#![no_std] // don't link the Rust standard library +#![no_main] // disable all Rust-level entry points + +#![feature(custom_test_frameworks)] +#![test_runner(crate::test_runner)] +#![reexport_test_harness_main = "test_main"] + +use core::panic::PanicInfo; +use runner_test::{exit_qemu, ExitCode}; + +#[no_mangle] // don't mangle the name of this function +pub extern "C" fn _start() -> ! { + test_main(); + + unsafe { exit_qemu(ExitCode::Failed); } + + loop {} +} + +pub fn test_runner(tests: &[&dyn Fn()]) { + for test in tests.iter() { + test(); + } +} + +#[test_case] +fn should_panic() { + assert_eq!(1, 2); +} + +#[panic_handler] +fn panic(_info: &PanicInfo) -> ! { + unsafe { exit_qemu(ExitCode::Success); } + loop {} +} From 2dc7bb3b56d747654a9e73dfec23816a38fe4f82 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Thu, 11 Apr 2019 21:23:49 +0200 Subject: [PATCH 140/271] Run cargo update for example kernels --- example-kernels/Cargo.lock | 50 +++++++++++++++++++------------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/example-kernels/Cargo.lock b/example-kernels/Cargo.lock index 12d8032..adbdfec 100644 --- a/example-kernels/Cargo.lock +++ b/example-kernels/Cargo.lock @@ -12,8 +12,8 @@ dependencies = [ name = "basic" version = "0.1.0" dependencies = [ - "bootloader 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "x86_64 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "bootloader 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "x86_64 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -28,7 +28,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "bootloader" -version = "0.5.1" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "fixedvec 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -41,23 +41,23 @@ dependencies = [ [[package]] name = "cc" -version = "1.0.32" +version = "1.0.35" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "default-target-bootimage" version = "0.1.0" dependencies = [ - "bootloader 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "x86_64 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "bootloader 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "x86_64 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "default-target-cargo" version = "0.1.0" dependencies = [ - "bootloader 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "x86_64 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "bootloader 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "x86_64 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -131,7 +131,7 @@ dependencies = [ "libc 0.2.51 (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.6 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -153,7 +153,7 @@ version = "6.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "cc 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -170,23 +170,23 @@ name = "remove_dir_all" version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "runner" version = "0.1.0" dependencies = [ - "bootloader 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "x86_64 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "bootloader 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "x86_64 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "runner-test" version = "0.1.0" dependencies = [ - "bootloader 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "x86_64 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "bootloader 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "x86_64 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -242,19 +242,19 @@ dependencies = [ name = "testing-qemu-exit-code" version = "0.1.0" dependencies = [ - "bootloader 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "x86_64 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "bootloader 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "x86_64 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "testing-serial-result" version = "0.1.0" dependencies = [ - "bootloader 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "bootloader 0.5.3 (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.3 (registry+https://github.com/rust-lang/crates.io-index)", + "x86_64 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -283,7 +283,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "winapi" -version = "0.3.6" +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)", @@ -327,7 +327,7 @@ dependencies = [ [[package]] name = "x86_64" -version = "0.5.3" +version = "0.5.4" 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)", @@ -355,8 +355,8 @@ 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.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "228047a76f468627ca71776ecdebd732a3423081fcf5125585bcd7c49886ce12" -"checksum bootloader 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a70143804c70c39473b3d7e99b870fb4f7f319f3100386f5dedf06e11e1799f0" -"checksum cc 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)" = "ad0daef304fa0b4238f5f7ed7178774b43b06f6a9b6509f6642bef4ff1f7b9b2" +"checksum bootloader 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a8f7c11b70b5781deec899276f7d67611eaf296a8bd7dcc9b9d37c71a5389c52" +"checksum cc 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)" = "5e5f3fee5eeb60324c2781f1e41286bdee933850fff9b3c672587fed5ec58c83" "checksum fixedvec 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7c6c16d316ccdac21a4dd648e314e76facbbaf316e83ca137d0857a9c07419d0" "checksum font8x8 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b81d84c3c978af7d05d31a2198af4b9ba956d819d15d8f6d58fc150e33f8dc1f" "checksum fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" @@ -384,11 +384,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "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.6 (registry+https://github.com/rust-lang/crates.io-index)" = "92c1eb33641e276cfa214a0522acad57be5c56b10cb348b3c5117db75f3ac4b0" +"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.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "f9258d7e2dd25008d69e8c9e9ee37865887a5e1e3d06a62f1cb3f6c209e6f177" -"checksum x86_64 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8f7e92e985f4052118fd69f2b366c67e91288c0f01f4ae52610dce236425dfa0" +"checksum x86_64 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)" = "1d0a8201f52d2c7b373c7243dcdfb27c0dd5012f221ef6a126f507ee82005204" "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" From 28de59c0b58d7305a036848850bf9f86206e5253 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Fri, 12 Apr 2019 14:18:42 +0200 Subject: [PATCH 141/271] bootimage 0.7.2 --- 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 bed3725..f525cff 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -10,7 +10,7 @@ dependencies = [ [[package]] name = "bootimage" -version = "0.7.1" +version = "0.7.2" 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 8c2b647..d32eb3e 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.1" +version = "0.7.2" repository = "https://github.com/rust-osdev/bootimage" edition = "2018" diff --git a/Changelog.md b/Changelog.md index d844f1b..881b437 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,3 +1,5 @@ +0.7.2 + - New features for `bootimage runner` - Pass additional arguments to the run command (e.g. QEMU) From 50af2d515d012b9e4bda6140fe912e104ea27e81 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Fri, 12 Apr 2019 14:20:41 +0200 Subject: [PATCH 142/271] Fix changelog formatting --- Changelog.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Changelog.md b/Changelog.md index 881b437..3446b54 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,5 +1,4 @@ -0.7.2 - +# 0.7.2 - New features for `bootimage runner` - Pass additional arguments to the run command (e.g. QEMU) From 101eb43de403fd9f3cb3f044e2c263356d2c179a Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Sun, 21 Apr 2019 20:38:57 +0200 Subject: [PATCH 143/271] Fix `cargo bootimage` for Windows File names end with `.exe` on Windows. --- Changelog.md | 2 ++ src/args.rs | 8 ++++++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/Changelog.md b/Changelog.md index 3446b54..75930a7 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,3 +1,5 @@ +- Fix `cargo bootimage` on Windows (there was a bug in the argument parsing) + # 0.7.2 - New features for `bootimage runner` diff --git a/src/args.rs b/src/args.rs index 50382a9..72b4d70 100644 --- a/src/args.rs +++ b/src/args.rs @@ -6,11 +6,15 @@ use std::{env, mem}; pub(crate) fn parse_args() -> Result { let mut args = env::args(); - let executable_name = args.next().ok_or("no first argument (executable name)")?; + 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 executable_name.ends_with("cargo-bootimage") => parse_build_args(args) + Some("bootimage") if is_cargo_bootimage => parse_build_args(args) .map(|cmd| match cmd { Command::BuildHelp => Command::CargoBootimageHelp, cmd => cmd, From e55104ad2f95020ffadb774275a860b4f5a29463 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Sun, 21 Apr 2019 20:41:52 +0200 Subject: [PATCH 144/271] bootimage 0.7.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 f525cff..2cc75e7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -10,7 +10,7 @@ dependencies = [ [[package]] name = "bootimage" -version = "0.7.2" +version = "0.7.3" 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 d32eb3e..c579c45 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.2" +version = "0.7.3" repository = "https://github.com/rust-osdev/bootimage" edition = "2018" diff --git a/Changelog.md b/Changelog.md index 75930a7..badec0d 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,3 +1,5 @@ +# 0.7.3 + - Fix `cargo bootimage` on Windows (there was a bug in the argument parsing) # 0.7.2 From c2ce530bda246300b0d4ea14b0634dff4f48d4f0 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Sun, 21 Apr 2019 22:47:37 +0200 Subject: [PATCH 145/271] Run cargo fmt --- src/args.rs | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/args.rs b/src/args.rs index 72b4d70..3c2fb0f 100644 --- a/src/args.rs +++ b/src/args.rs @@ -8,17 +8,18 @@ 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()); + 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("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, From 7cc1c074fbf57c73411d6dbed09257de412d1600 Mon Sep 17 00:00:00 2001 From: Toothbrush Date: Fri, 24 May 2019 19:04:42 +0100 Subject: [PATCH 146/271] Pad boot image to block size (#39) --- src/builder.rs | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/src/builder.rs b/src/builder.rs index 8ea1fd7..7d0c0f9 100644 --- a/src/builder.rs +++ b/src/builder.rs @@ -297,6 +297,37 @@ impl Builder { }); } + // Pad to nearest block size + { + const BLOCK_SIZE: u64 = 512; + use std::fs::{File, OpenOptions}; + let mut 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(()) } } From ea6c99689006872e14f4e2e78e9f2cb3ad7f88f0 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Sun, 26 May 2019 15:30:09 +0200 Subject: [PATCH 147/271] Update changelog for #35 --- Changelog.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Changelog.md b/Changelog.md index badec0d..7c2d77f 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,3 +1,5 @@ +- Align boot image size on a 512 byte boundary to fix boot in VirtualBox (see [#35](https://github.com/rust-osdev/bootimage/issues/35)) + # 0.7.3 - Fix `cargo bootimage` on Windows (there was a bug in the argument parsing) From 8420b1d5a18763fd1115c0d14a18c856980072b8 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Sun, 26 May 2019 15:32:03 +0200 Subject: [PATCH 148/271] bootimage 0.7.4 --- 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 2cc75e7..6bb1a5d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -10,7 +10,7 @@ dependencies = [ [[package]] name = "bootimage" -version = "0.7.3" +version = "0.7.4" 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 c579c45..b38e38b 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.3" +version = "0.7.4" repository = "https://github.com/rust-osdev/bootimage" edition = "2018" diff --git a/Changelog.md b/Changelog.md index 7c2d77f..796f32b 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,3 +1,5 @@ +# 0.7.4 + - Align boot image size on a 512 byte boundary to fix boot in VirtualBox (see [#35](https://github.com/rust-osdev/bootimage/issues/35)) # 0.7.3 From 12a6a720da375fc88ef6f15562d74e96452f0329 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Mon, 3 Jun 2019 15:19:13 +0200 Subject: [PATCH 149/271] Set XBUILD_SYSROOT_PATH when building bootloader (#41) --- src/builder.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/builder.rs b/src/builder.rs index 7d0c0f9..3c01d37 100644 --- a/src/builder.rs +++ b/src/builder.rs @@ -222,7 +222,7 @@ impl Builder { cmd.arg("--release"); cmd.env("KERNEL", kernel_bin_path); cmd.env_remove("RUSTFLAGS"); - cmd.env("SYSROOT_DIR", target_dir.join("sysroot")); // for cargo-xbuild + cmd.env("XBUILD_SYSROOT_PATH", target_dir.join("bootloader-sysroot")); // for cargo-xbuild cmd }; From 3b7cebb8b45172dc1939b988a9527691b3a5909e Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Fri, 31 May 2019 11:34:35 +0200 Subject: [PATCH 150/271] Build all branches on azure pipelines --- azure-pipelines.yml | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 6c7d8ef..c8f133e 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -1,15 +1,11 @@ # Documentation: https://aka.ms/yaml trigger: - batch: true branches: include: - # This is where pull requests from "bors r+" are built. - - staging - # This is where pull requests from "bors try" are built. - - trying - # Build pull requests. - - master + - '*' + exclude: + - 'staging.tmp' jobs: - job: build From 1b6a0a6e2074fd5ff002d5dcde5bcb78c9c0e9b1 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Fri, 31 May 2019 12:13:46 +0200 Subject: [PATCH 151/271] Rustup is already included in latest Windows image --- azure-pipelines.yml | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index c8f133e..4e659e0 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -46,14 +46,12 @@ jobs: condition: or(eq( variables['Agent.OS'], 'Linux' ), eq( variables['Agent.OS'], 'Darwin' )) displayName: 'Install Rust (Linux/macOS)' - - script: curl -sSf -o rustup-init.exe https://win.rustup.rs && rustup-init.exe -y --default-toolchain %RUSTUP_TOOLCHAIN% + - bash: rustup default $RUSTUP_TOOLCHAIN condition: eq( variables['Agent.OS'], 'Windows_NT' ) - displayName: 'Install Rust (Windows)' + displayName: 'Set Rust Toolchain (Windows)' - - script: | - echo ##vso[task.setvariable variable=PATH;]%PATH%;%USERPROFILE%\.cargo\bin - condition: eq( variables['Agent.OS'], 'Windows_NT' ) - displayName: 'Add ~/.cargo/bin to PATH (Windows)' + - bash: rustup update $RUSTUP_TOOLCHAIN + displayName: 'Run Rustup Update' - script: | rustc -Vv @@ -107,14 +105,12 @@ jobs: condition: or(eq( variables['Agent.OS'], 'Linux' ), eq( variables['Agent.OS'], 'Darwin' )) displayName: 'Install Rust (Linux/macOS)' - - script: curl -sSf -o rustup-init.exe https://win.rustup.rs && rustup-init.exe -y --default-toolchain %RUSTUP_TOOLCHAIN% + - bash: rustup default $RUSTUP_TOOLCHAIN condition: eq( variables['Agent.OS'], 'Windows_NT' ) - displayName: 'Install Rust (Windows)' + displayName: 'Set Rust Toolchain (Windows)' - - script: | - echo ##vso[task.setvariable variable=PATH;]%PATH%;%USERPROFILE%\.cargo\bin - condition: eq( variables['Agent.OS'], 'Windows_NT' ) - displayName: 'Add ~/.cargo/bin to PATH (Windows)' + - bash: rustup update $RUSTUP_TOOLCHAIN + displayName: 'Run Rustup Update' - script: | rustc -Vv From d1d0ea57d10600a765a23c173de37c15566a02fb Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Mon, 3 Jun 2019 16:35:51 +0200 Subject: [PATCH 152/271] Update changelog for #40 and #41 --- Changelog.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Changelog.md b/Changelog.md index 796f32b..19de31c 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,3 +1,6 @@ +- Set XBUILD_SYSROOT_PATH when building bootloader ([#41](https://github.com/rust-osdev/bootimage/pull/41)) +- Update Azure Pipelines CI script ([#40](https://github.com/rust-osdev/bootimage/pull/40)) + # 0.7.4 - Align boot image size on a 512 byte boundary to fix boot in VirtualBox (see [#35](https://github.com/rust-osdev/bootimage/issues/35)) From 8c9bbd878350821fc0bd84e69f35f318812f10e9 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Mon, 3 Jun 2019 16:36:21 +0200 Subject: [PATCH 153/271] bootimage 0.7.5 --- 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 6bb1a5d..a00d40a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -10,7 +10,7 @@ dependencies = [ [[package]] name = "bootimage" -version = "0.7.4" +version = "0.7.5" 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 b38e38b..03c5442 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.4" +version = "0.7.5" repository = "https://github.com/rust-osdev/bootimage" edition = "2018" diff --git a/Changelog.md b/Changelog.md index 19de31c..db8cc27 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,3 +1,5 @@ +# 0.7.5 + - Set XBUILD_SYSROOT_PATH when building bootloader ([#41](https://github.com/rust-osdev/bootimage/pull/41)) - Update Azure Pipelines CI script ([#40](https://github.com/rust-osdev/bootimage/pull/40)) From 3d967dc4ce950003824abf68f1e1d650ab2ff4d9 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Thu, 18 Jul 2019 11:06:32 +0200 Subject: [PATCH 154/271] If the bootloader has a feature named `binary`, enable it This allows the bootloader to define dependencies that only apply to the main.rs (not the lib.rs), in order to reduce compile times. See https://github.com/rust-lang/cargo/issues/1982#issuecomment-319661478 for more information. --- src/builder.rs | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/builder.rs b/src/builder.rs index 3c01d37..59b156a 100644 --- a/src/builder.rs +++ b/src/builder.rs @@ -166,7 +166,7 @@ impl Builder { "bootloader manifest has no target directory".into(), ), )?; - let bootloader_target = { + 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)?; @@ -185,7 +185,13 @@ impl Builder { (If you're using the official bootloader crate, you need at least version 0.5.1)" .into(), ))?; - bootloader_root.join(target_str) + + 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 = { @@ -201,7 +207,11 @@ impl Builder { .ok_or(CreateBootimageError::CargoMetadataIncomplete { key: format!("resolve[\"{}\"]", bootloader_name), })?; - bootloader_resolve.features.clone() + let mut features = bootloader_resolve.features.clone(); + if binary_feature { + features.push("binary".into()); + } + features }; // build bootloader From efbf5b2ad79f0778d152951caa8fc1b152abbf34 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Thu, 18 Jul 2019 11:34:46 +0200 Subject: [PATCH 155/271] Pass `--bin` argument when building bootloader This allows the bootloader to use the `required-features` configuration. Without the `--bin` argument cargo just omits all binaries with unsatisfied required features, so that an unrelated 'no bootloader executable found' error would occur. --- src/builder.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/builder.rs b/src/builder.rs index 59b156a..173c285 100644 --- a/src/builder.rs +++ b/src/builder.rs @@ -225,6 +225,7 @@ impl Builder { 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(" ")); From 070f8d6f062c2928bc1fe181796708c23e04d65a Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Thu, 18 Jul 2019 11:36:41 +0200 Subject: [PATCH 156/271] Fix some warnings --- src/builder.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/builder.rs b/src/builder.rs index 173c285..3456b50 100644 --- a/src/builder.rs +++ b/src/builder.rs @@ -311,8 +311,8 @@ impl Builder { // Pad to nearest block size { const BLOCK_SIZE: u64 = 512; - use std::fs::{File, OpenOptions}; - let mut file = OpenOptions::new() + use std::fs::OpenOptions; + let file = OpenOptions::new() .write(true) .open(&output_bin_path) .map_err(|err| CreateBootimageError::Io { From e9fb5c23dfabf107d2da5ee1284a073adc48f0d4 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Thu, 18 Jul 2019 11:41:25 +0200 Subject: [PATCH 157/271] Improve error message on build failure Only print stderr if it's not empty. Stderr is always empty when running without `--quiet` because we then inherit stderr from the shell. --- src/builder.rs | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/src/builder.rs b/src/builder.rs index 3456b50..3815f6b 100644 --- a/src/builder.rs +++ b/src/builder.rs @@ -410,7 +410,11 @@ impl fmt::Display for BuildKernelError { Run `cargo install cargo-xbuild` to install it.") } BuildKernelError::XbuildFailed{stderr} => { - writeln!(f, "Kernel build failed:\n{}", String::from_utf8_lossy(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) @@ -481,11 +485,13 @@ impl fmt::Display for CreateBootimageError { "The `bootloader` dependency has not the right format: {}", err ), - CreateBootimageError::BootloaderBuildFailed { stderr } => writeln!( - f, - "Bootloader build failed:\n\n{}", - String::from_utf8_lossy(stderr) - ), + 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) } From a718354794c019b28be6809682c940b063c4fc37 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Thu, 18 Jul 2019 12:00:14 +0200 Subject: [PATCH 158/271] Tests: Update to bootloader 0.6.4 and update Cargo.lock --- Readme.md | 2 +- example-kernels/Cargo.lock | 70 ++++++++++--------- example-kernels/basic/Cargo.toml | 2 +- .../default-target-bootimage/Cargo.toml | 2 +- .../default-target-cargo/Cargo.toml | 2 +- example-kernels/runner-test/Cargo.toml | 2 +- example-kernels/runner/Cargo.toml | 2 +- .../testing-qemu-exit-code/Cargo.toml | 2 +- .../testing-serial-result/Cargo.toml | 2 +- 9 files changed, 46 insertions(+), 40 deletions(-) diff --git a/Readme.md b/Readme.md index f0ff3b3..41099c7 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.5.1" +bootloader = "0.6.4" ``` **Note**: At least bootloader version `0.5.1` is required since `bootimage 0.7.0`. For earlier bootloader versions, use `bootimage 0.6.6`. diff --git a/example-kernels/Cargo.lock b/example-kernels/Cargo.lock index adbdfec..8549198 100644 --- a/example-kernels/Cargo.lock +++ b/example-kernels/Cargo.lock @@ -13,7 +13,7 @@ name = "basic" version = "0.1.0" dependencies = [ "bootloader 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", - "x86_64 0.5.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]] @@ -23,7 +23,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "bitflags" -version = "1.0.4" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -32,16 +32,21 @@ version = "0.5.3" 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.4 (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)", "xmas-elf 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "cast" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "cc" -version = "1.0.35" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -49,7 +54,7 @@ name = "default-target-bootimage" version = "0.1.0" dependencies = [ "bootloader 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", - "x86_64 0.5.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]] @@ -57,7 +62,7 @@ name = "default-target-cargo" version = "0.1.0" dependencies = [ "bootloader 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", - "x86_64 0.5.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]] @@ -70,7 +75,7 @@ dependencies = [ [[package]] name = "font8x8" -version = "0.2.4" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -80,7 +85,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "getopts" -version = "0.2.18" +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)", @@ -96,7 +101,7 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.51" +version = "0.2.60" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -119,7 +124,7 @@ name = "pulldown-cmark" version = "0.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "getopts 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", + "getopts 0.2.19 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -128,7 +133,7 @@ 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.51 (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)", @@ -152,8 +157,8 @@ name = "raw-cpuid" version = "6.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "cc 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)", + "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)", ] @@ -167,7 +172,7 @@ dependencies = [ [[package]] name = "remove_dir_all" -version = "0.5.1" +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)", @@ -178,7 +183,7 @@ name = "runner" version = "0.1.0" dependencies = [ "bootloader 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", - "x86_64 0.5.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]] @@ -186,7 +191,7 @@ name = "runner-test" version = "0.1.0" dependencies = [ "bootloader 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", - "x86_64 0.5.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]] @@ -235,7 +240,7 @@ 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.1 (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]] @@ -243,7 +248,7 @@ name = "testing-qemu-exit-code" version = "0.1.0" dependencies = [ "bootloader 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", - "x86_64 0.5.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]] @@ -254,7 +259,7 @@ dependencies = [ "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.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]] @@ -262,7 +267,7 @@ name = "uart_16550" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "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)", ] @@ -306,7 +311,7 @@ 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.0.4 (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)", @@ -319,7 +324,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.0.4 (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)", @@ -327,14 +332,14 @@ dependencies = [ [[package]] name = "x86_64" -version = "0.5.4" +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.0.4 (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)", - "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)", ] @@ -354,15 +359,16 @@ 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.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "228047a76f468627ca71776ecdebd732a3423081fcf5125585bcd7c49886ce12" +"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 cc 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)" = "5e5f3fee5eeb60324c2781f1e41286bdee933850fff9b3c672587fed5ec58c83" +"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.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b81d84c3c978af7d05d31a2198af4b9ba956d819d15d8f6d58fc150e33f8dc1f" +"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.18 (registry+https://github.com/rust-lang/crates.io-index)" = "0a7292d30132fb5424b354f5dc02512a86e4c516fe544bb7a25e7f266951b797" +"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.51 (registry+https://github.com/rust-lang/crates.io-index)" = "bedcc7a809076656486ffe045abeeac163da1b558e963a31e29fbfbeba916917" +"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" @@ -372,7 +378,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "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.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3488ba1b9a2084d38645c4c08276a1752dcbf2c7130d74f1569681ad5d2799c5" +"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" @@ -389,6 +395,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "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.4 (registry+https://github.com/rust-lang/crates.io-index)" = "1d0a8201f52d2c7b373c7243dcdfb27c0dd5012f221ef6a126f507ee82005204" +"checksum x86_64 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)" = "bb8f09c32a991cc758ebcb9b7984f530095d32578a4e7b85db6ee1f0bbe4c9c6" "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/basic/Cargo.toml b/example-kernels/basic/Cargo.toml index d3c4cec..76b9db0 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.5.1" +bootloader = "0.6.4" x86_64 = "0.5.3" diff --git a/example-kernels/default-target-bootimage/Cargo.toml b/example-kernels/default-target-bootimage/Cargo.toml index 3c12f8b..befa7ff 100644 --- a/example-kernels/default-target-bootimage/Cargo.toml +++ b/example-kernels/default-target-bootimage/Cargo.toml @@ -5,7 +5,7 @@ authors = ["Philipp Oppermann "] edition = "2018" [dependencies] -bootloader = "0.5.1" +bootloader = "0.6.4" x86_64 = "0.5.3" [package.metadata.bootimage] diff --git a/example-kernels/default-target-cargo/Cargo.toml b/example-kernels/default-target-cargo/Cargo.toml index fb4142d..bb08c52 100644 --- a/example-kernels/default-target-cargo/Cargo.toml +++ b/example-kernels/default-target-cargo/Cargo.toml @@ -5,5 +5,5 @@ authors = ["Philipp Oppermann "] edition = "2018" [dependencies] -bootloader = "0.5.1" +bootloader = "0.6.4" x86_64 = "0.5.3" diff --git a/example-kernels/runner-test/Cargo.toml b/example-kernels/runner-test/Cargo.toml index b6bb6ea..27989c8 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.5.1" +bootloader = "0.6.4" x86_64 = "0.5.3" [package.metadata.bootimage] diff --git a/example-kernels/runner/Cargo.toml b/example-kernels/runner/Cargo.toml index 15cf84b..7b5de79 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.5.1" +bootloader = "0.6.4" x86_64 = "0.5.3" [package.metadata.bootimage] diff --git a/example-kernels/testing-qemu-exit-code/Cargo.toml b/example-kernels/testing-qemu-exit-code/Cargo.toml index 8e4d597..4abfbe8 100644 --- a/example-kernels/testing-qemu-exit-code/Cargo.toml +++ b/example-kernels/testing-qemu-exit-code/Cargo.toml @@ -5,7 +5,7 @@ authors = ["Philipp Oppermann "] edition = "2018" [dependencies] -bootloader = "0.5.1" +bootloader = "0.6.4" x86_64 = "0.5.3" [package.metadata.bootimage] diff --git a/example-kernels/testing-serial-result/Cargo.toml b/example-kernels/testing-serial-result/Cargo.toml index 7412af8..f280008 100644 --- a/example-kernels/testing-serial-result/Cargo.toml +++ b/example-kernels/testing-serial-result/Cargo.toml @@ -5,7 +5,7 @@ authors = ["Philipp Oppermann "] edition = "2018" [dependencies] -bootloader = "0.5.1" +bootloader = "0.6.4" x86_64 = "0.5.3" spin = "0.4.9" uart_16550 = "0.1.0" From 9846d649b1bb5884c40985a1decc96a8a2579948 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Fri, 19 Jul 2019 11:03:13 +0200 Subject: [PATCH 159/271] Update changelog for #43 --- Changelog.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Changelog.md b/Changelog.md index db8cc27..74379bd 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,3 +1,5 @@ +- If the bootloader has a feature named `binary`, enable it ([#43](https://github.com/rust-osdev/bootimage/pull/43)) + # 0.7.5 - Set XBUILD_SYSROOT_PATH when building bootloader ([#41](https://github.com/rust-osdev/bootimage/pull/41)) From 10df873c4a6aff445bd988e63b94a30d98f89ea0 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Fri, 19 Jul 2019 11:04:35 +0200 Subject: [PATCH 160/271] bootimage 0.7.6 --- 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 a00d40a..fc9a4fd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -10,7 +10,7 @@ dependencies = [ [[package]] name = "bootimage" -version = "0.7.5" +version = "0.7.6" 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 03c5442..7f01bd3 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.5" +version = "0.7.6" repository = "https://github.com/rust-osdev/bootimage" edition = "2018" diff --git a/Changelog.md b/Changelog.md index 74379bd..4c21e12 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,3 +1,5 @@ +# 0.7.6 + - If the bootloader has a feature named `binary`, enable it ([#43](https://github.com/rust-osdev/bootimage/pull/43)) # 0.7.5 From 42a9b1583fd5b71dd6bd65a3cabba8e52b0d8680 Mon Sep 17 00:00:00 2001 From: Matt Taylor Date: Mon, 5 Aug 2019 21:52:29 +0100 Subject: [PATCH 161/271] Pass location of kernel's Cargo.toml to bootloader --- src/builder.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/builder.rs b/src/builder.rs index 3815f6b..db78c58 100644 --- a/src/builder.rs +++ b/src/builder.rs @@ -232,6 +232,7 @@ impl Builder { 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_remove("RUSTFLAGS"); cmd.env("XBUILD_SYSROOT_PATH", target_dir.join("bootloader-sysroot")); // for cargo-xbuild cmd From c445810da453c4ff88a891f7d6fd9247445bf0e8 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Tue, 6 Aug 2019 11:56:41 +0200 Subject: [PATCH 162/271] 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 163/271] 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 164/271] 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 165/271] 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 166/271] 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 167/271] 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 168/271] 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 169/271] 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 170/271] 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 171/271] 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 172/271] 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 173/271] 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 174/271] 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 175/271] 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 176/271] 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 177/271] 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 178/271] 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 179/271] 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 180/271] 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 181/271] 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 182/271] 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 183/271] 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 184/271] 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 185/271] 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 186/271] 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 187/271] 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 188/271] 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 189/271] 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 190/271] 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 191/271] 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 192/271] 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 193/271] 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 194/271] 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 195/271] 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 196/271] 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 197/271] 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 198/271] 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 199/271] 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 200/271] 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 201/271] 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 202/271] 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 203/271] 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 204/271] 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 205/271] 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 206/271] 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 207/271] 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 208/271] 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 209/271] 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 210/271] 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 211/271] 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 212/271] 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 213/271] 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 214/271] 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 215/271] 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 216/271] 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 217/271] 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 218/271] 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 219/271] 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 220/271] 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 221/271] 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 222/271] 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 223/271] 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 224/271] 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 225/271] 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 226/271] 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 227/271] 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 228/271] 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 229/271] 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 230/271] 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 231/271] 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 232/271] 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 233/271] 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 234/271] 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 235/271] 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 236/271] 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 237/271] 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 238/271] 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 239/271] 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 240/271] 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 241/271] `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 242/271] 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 243/271] 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 244/271] 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 245/271] 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 246/271] 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 247/271] 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 248/271] 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 249/271] 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 250/271] 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 251/271] 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 252/271] 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 253/271] 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 254/271] 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 255/271] 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 256/271] 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 257/271] 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 258/271] 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 259/271] 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 260/271] 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 261/271] 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 262/271] 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 263/271] 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 264/271] 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 265/271] 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 266/271] 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 267/271] 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 268/271] 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 269/271] 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", -] From 7d9a53f892fb98fc4dbeea03d96828da30bd4ea1 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Mon, 18 Aug 2025 09:50:51 +0200 Subject: [PATCH 270/271] Run cargo update --- Cargo.lock | 78 +++++++++++++++++++++++++++++++----------------------- 1 file changed, 45 insertions(+), 33 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ec54604..b31b442 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,10 +1,12 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. +version = 4 + [[package]] name = "anyhow" -version = "1.0.32" +version = "1.0.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b602bfe940d21c130f3895acd65221e8a61270debe89d628b9cb4e3ccb8569b" +checksum = "b0674a1ddeecb70197781e945de4b3b8ffb61fa939a5597bcf48503737663100" [[package]] name = "bootimage" @@ -34,9 +36,9 @@ dependencies = [ [[package]] name = "itoa" -version = "0.4.6" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc6f3ad7b9d11a0c00842ff8de1b60ee58661048eb8049ed33c73594f359d7e6" +checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" [[package]] name = "json" @@ -46,9 +48,9 @@ checksum = "078e285eafdfb6c4b434e0d31e8cfcb5115b651496faca5749b88fafd4f23bfd" [[package]] name = "libc" -version = "0.2.76" +version = "0.2.175" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "755456fae044e6fa1ebbbd1b3e902ae19e73097ed4ed87bb79934a867c007bc3" +checksum = "6a82ae493e598baaea5209805c49bbf2ea7de956d50d7da0da1164f9c6d28543" [[package]] name = "llvm-tools" @@ -65,29 +67,35 @@ dependencies = [ "json", ] +[[package]] +name = "memchr" +version = "2.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0" + [[package]] name = "proc-macro2" -version = "1.0.19" +version = "1.0.101" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04f5f085b5d71e2188cb8271e5da0161ad52c3f227a661a3c135fdf28e258b12" +checksum = "89ae43fd86e4158d6db51ad8e2b80f313af9cc74f5c0e03ccb87de09998732de" dependencies = [ - "unicode-xid", + "unicode-ident", ] [[package]] name = "quote" -version = "1.0.7" +version = "1.0.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa563d17ecb180e500da1cfd2b028310ac758de548efdd203e18f283af693f37" +checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" dependencies = [ "proc-macro2", ] [[package]] name = "ryu" -version = "1.0.5" +version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" +checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" [[package]] name = "semver" @@ -107,15 +115,18 @@ checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" [[package]] name = "serde" -version = "1.0.115" +version = "1.0.219" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e54c9a88f2da7238af84b5101443f0c0d0a3bbdc455e34a5c9497b1903ed55d5" +checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" +dependencies = [ + "serde_derive", +] [[package]] name = "serde_derive" -version = "1.0.115" +version = "1.0.219" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "609feed1d0a73cc36a0182a840a9b37b4a82f0b1150369f0536a9e3f2a31dc48" +checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" dependencies = [ "proc-macro2", "quote", @@ -124,40 +135,41 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.57" +version = "1.0.142" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "164eacbdb13512ec2745fb09d51fd5b22b0d65ed294a1dcf7285a360c80a675c" +checksum = "030fedb782600dcbd6f02d479bf0d817ac3bb40d644745b769d6a96bc3afc5a7" dependencies = [ "itoa", + "memchr", "ryu", "serde", ] [[package]] name = "syn" -version = "1.0.39" +version = "2.0.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "891d8d6567fe7c7f8835a3a98af4208f3846fba258c1bc3c31d6e506239f11f9" +checksum = "ede7c438028d4436d71104916910f5bb611972c5cfd7f89b8300a8186e6fada6" dependencies = [ "proc-macro2", "quote", - "unicode-xid", + "unicode-ident", ] [[package]] name = "thiserror" -version = "1.0.20" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7dfdd070ccd8ccb78f4ad66bf1982dc37f620ef696c6b5028fe2ed83dd3d0d08" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.20" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd80fc12f73063ac132ac92aceea36734f04a1d93c1240c6944e23a3b8841793" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", @@ -166,24 +178,24 @@ dependencies = [ [[package]] name = "toml" -version = "0.5.6" +version = "0.5.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffc92d160b1eef40665be3a05630d003936a3bc7da7421277846c2613e92c71a" +checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234" dependencies = [ "serde", ] [[package]] -name = "unicode-xid" -version = "0.2.1" +name = "unicode-ident" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564" +checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" [[package]] name = "wait-timeout" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f200f5b12eb75f8c1ed65abd4b2db8a6e1b138a20de009dacee265a2498f3f6" +checksum = "09ac3b126d3914f9849036f826e054cbabdc8519970b8998ddaf3b5bd3c65f11" dependencies = [ "libc", ] From 5de435c2aba9826947fec74446c725d2f6ecb45f Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Mon, 18 Aug 2025 16:55:41 +0200 Subject: [PATCH 271/271] Fix example kernel target JSON --- 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 6f5613c..b982009 100644 --- a/example-kernels/x86_64-bootimage-example-kernels.json +++ b/example-kernels/x86_64-bootimage-example-kernels.json @@ -4,7 +4,7 @@ "arch": "x86_64", "target-endian": "little", "target-pointer-width": "64", - "target-c-int-width": "32", + "target-c-int-width": 32, "os": "none", "executables": true, "linker-flavor": "ld.lld",