Open muellerpeter-pms opened 1 year ago
I got the tests to build by leaving a kernel/.cargo/config.toml
file:
[build]
target = "x86_64-unknown-none"
Actually running the tests runs into further issues: namely that it tries to run the ELF file as a binary. This was done in 0.9 by also having the following in the cargo config:
[target.'cfg(target_os = "none")']
runner = "bootimage runner"
What bootimage runner
seems to do is build a boot image from an executable passed as an argument and then execute qemu. The code to do that is now in build.rs
and src/main.rs
from the disk image template. I'm guessing I could create a new bin crate in the workspace that does what both of those files do but getting the kernel from std::env::args_os()
instead of std::env::var_os("CARGO_BIN_FILE_KERNEL_kernel")
.
Yup! I added the following runner to my OS workspace:
// runner/src/main.rs
use std::path::PathBuf;
fn main() {
let mut args = std::env::args_os().skip(1); // Skip runner name
let mut cmd = std::process::Command::new("qemu-system-x86_64");
cmd.args([
"-device",
"isa-debug-exit,iobase=0xf4,iosize=0x04",
"-serial",
"stdio",
]);
while args.len() > 1 {
cmd.arg(args.next().unwrap());
}
let kernel = PathBuf::from(args.next().unwrap());
// choose whether to start the UEFI or BIOS image
let uefi = false;
let mut image_path = std::env::temp_dir().join(kernel.file_name().unwrap());
image_path.set_extension("img");
if uefi {
todo!("Replace PIC with APIC before using UEFI");
/*
bootloader::UefiBoot::new(&kernel).create_disk_image(&image_path).unwrap();
cmd.arg("-bios").arg(ovmf_prebuilt::ovmf_pure_efi());
*/
} else {
// create a BIOS disk image
bootloader::BiosBoot::new(&kernel)
.create_disk_image(&image_path)
.unwrap();
}
let mut drive: std::ffi::OsString = "format=raw,file=".into();
drive.push(&image_path);
cmd.arg("-drive").arg(drive);
// Start QEMU and wait
let mut child = cmd.spawn().unwrap();
child.wait().unwrap();
std::fs::remove_file(&image_path).unwrap();
}
Edit: Above code used to use OUT_DIR, but that is apparently unreliable for a test runner. Now creates a file in temp_dir and removes after QEMU exits.
And my kernel/.cargo/config.toml
is
[build]
target = "x86_64-unknown-none"
[target.'cfg(target_os = "none")']
runner = ["../target/debug/runner", "-display", "none"]
Options to the runner are passed to QEMU, and I highly recommend removing -display none
until you get it to pass once (since the bootloader panics are shown on the framebuffer). Also note that you need to build the runner manually after you make changes to it.
I'm interested in this but I don't understand @Benabik fix, can you link the repo?
I was able to get my tests to run by first compiling the kernel with
cargo test -p kernel --no-run --target x86_64-unknown-none
Then replacing the kernel in build.rs
and running it like normal.
I don't yet know how to get cargo test
to work, but I'm watching https://github.com/rust-lang/cargo/issues/11680 for a solution
I migrated from 0.9.x to 0.11.
The build works fine but tests are broken the old way. When testing teh kernel there is no executable, what I can understand. But when testing the parent directory only the crate itself will be tested. When testing the parent directory with --workspace option there is no target transferred to the kernel build, which leads to the error:
I guess there is an option to pass the target even in test build mode. But I didn't find yet.
Thanks in advane!