//! This test builds and runs a basic UEFI application on QEMU for various targets. //! //! You must have the relevant OVMF or AAVMF firmware installed for this to work. //! //! Requires: qemu-system-x86_64, qemu-system-aarch64 //! OVMF/AAVMF firmware //! //! Note: test assumes `/uefi_qemu_test` exists and is a self-contained crate. //@ only-uefi use std::path::Path; use run_make_support::{cargo, cmd, path, rfs}; fn main() { let target = run_make_support::target(); let (boot_filename, ovmf_dir, ovmf_code_name, ovmf_vars_name, qemu, machine, cpu) = match target.as_str() { "aarch64-unknown-uefi" => ( "bootaa64.efi", Path::new("/usr/share/AAVMF"), "AAVMF_CODE.fd", "AAVMF_VARS.fd", "qemu-system-aarch64", "virt", "cortex-a72", ), "i686-unknown-uefi" => ( "bootia32.efi", Path::new("/usr/share/OVMF"), "OVMF32_CODE_4M.secboot.fd", "OVMF32_VARS_4M.fd", "qemu-system-x86_64", "q35", "qemu64", ), "x86_64-unknown-uefi" => ( "bootx64.efi", Path::new("/usr/share/OVMF"), "OVMF_CODE_4M.fd", "OVMF_VARS_4M.fd", "qemu-system-x86_64", "q35", "qemu64", ), _ => panic!("unsupported target {target}"), }; let tmp = std::env::temp_dir(); let test_crate = tmp.join("uefi_qemu_test"); rfs::copy_dir_all(path("uefi_qemu_test"), &test_crate); cargo().args(&["build", "--target", &target]).current_dir(&test_crate).run(); // Prepare ESP let esp = test_crate.join("esp"); let boot = esp.join("efi/boot"); rfs::create_dir_all(&boot); let src_efi = test_crate.join("target").join(&target).join("debug/uefi_qemu_test.efi"); let dst_efi = boot.join(boot_filename); rfs::copy(&src_efi, &dst_efi); // Copy OVMF files let code = ovmf_dir.join(ovmf_code_name); let vars_src = ovmf_dir.join(ovmf_vars_name); let vars_dst = tmp.join("vars.fd"); rfs::copy(&vars_src, &vars_dst); let output = cmd(qemu) .args(["-machine", machine]) .args(["-cpu", cpu]) .args(["-display", "none"]) .args(["-serial", "stdio"]) .args(["-drive", &format!("if=pflash,format=raw,readonly=on,file={}", code.display())]) .args(["-drive", &format!("if=pflash,format=raw,readonly=off,file={}", vars_dst.display())]) .args(["-drive", &format!("format=raw,file=fat:rw:{}", esp.display())]) .run() .stdout_utf8(); assert!(output.contains("Hello World!"), "invalid output for {target}:\n{output}"); }