about summary refs log tree commit diff
path: root/tests/run-make-cargo/uefi-qemu/rmake.rs
blob: 55d42fba5e7ec30f4f9d5dd8e97fbfb4f89b3940 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
//! 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}");
}