Skip to content

Commit 47256d8

Browse files
authored
Merge pull request #237 from Freax13/uefi-pxe
add UEFI PXE support
2 parents 5fd3115 + ca31f96 commit 47256d8

File tree

6 files changed

+197
-43
lines changed

6 files changed

+197
-43
lines changed

Cargo.lock

+17-17
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/lib.rs

+15
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ use std::{
7878
mod fat;
7979
mod gpt;
8080
mod mbr;
81+
mod pxe;
8182

8283
const KERNEL_FILE_NAME: &str = "kernel-x86_64";
8384

@@ -121,3 +122,17 @@ pub fn create_bios_disk_image(
121122

122123
Ok(())
123124
}
125+
126+
/// Prepare a folder for use with booting over UEFI_PXE.
127+
///
128+
/// This places the bootloader executable under the path "bootloader". The
129+
/// DHCP server should set the filename option to that path, otherwise the
130+
/// bootloader won't be found.
131+
pub fn create_uefi_pxe_tftp_folder(kernel_binary: &Path, out_path: &Path) -> anyhow::Result<()> {
132+
let bootloader_path = Path::new(env!("UEFI_BOOTLOADER_PATH"));
133+
134+
pxe::create_uefi_tftp_folder(bootloader_path, kernel_binary, out_path)
135+
.context("failed to create UEFI PXE tftp folder")?;
136+
137+
Ok(())
138+
}

src/pxe.rs

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
use std::path::Path;
2+
3+
use anyhow::Context;
4+
5+
pub fn create_uefi_tftp_folder(
6+
bootloader_path: &Path,
7+
kernel_binary: &Path,
8+
out_path: &Path,
9+
) -> anyhow::Result<()> {
10+
std::fs::create_dir_all(out_path)
11+
.with_context(|| format!("failed to create out dir at {}", out_path.display()))?;
12+
13+
let to = out_path.join("bootloader");
14+
std::fs::copy(bootloader_path, &to).with_context(|| {
15+
format!(
16+
"failed to copy bootloader from {} to {}",
17+
bootloader_path.display(),
18+
to.display()
19+
)
20+
})?;
21+
22+
let to = out_path.join("kernel-x86_64");
23+
std::fs::copy(kernel_binary, &to).with_context(|| {
24+
format!(
25+
"failed to copy kernel from {} to {}",
26+
kernel_binary.display(),
27+
to.display()
28+
)
29+
})?;
30+
31+
Ok(())
32+
}

tests/runner/src/lib.rs

+36-2
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,12 @@ const QEMU_ARGS: &[&str] = &[
1111
];
1212

1313
pub fn run_test_kernel(kernel_binary_path: &str) {
14+
run_test_kernel_on_uefi(kernel_binary_path);
15+
run_test_kernel_on_uefi_pxe(kernel_binary_path);
16+
// TODO: run tests with BIOS bootloader too
17+
}
18+
19+
pub fn run_test_kernel_on_uefi(kernel_binary_path: &str) {
1420
let kernel_path = Path::new(kernel_binary_path);
1521
let out_fat_path = kernel_path.with_extension("fat");
1622
bootloader::create_boot_partition(kernel_path, &out_fat_path).unwrap();
@@ -19,8 +25,6 @@ pub fn run_test_kernel(kernel_binary_path: &str) {
1925
let out_mbr_path = kernel_path.with_extension("mbr");
2026
bootloader::create_bios_disk_image(&out_fat_path, &out_mbr_path).unwrap();
2127

22-
// TODO: run tests with BIOS bootloader too
23-
2428
let mut run_cmd = Command::new("qemu-system-x86_64");
2529
run_cmd
2630
.arg("-drive")
@@ -42,3 +46,33 @@ pub fn run_test_kernel(kernel_binary_path: &str) {
4246
other => panic!("Test failed with unexpected exit code `{:?}`", other),
4347
}
4448
}
49+
50+
pub fn run_test_kernel_on_uefi_pxe(kernel_binary_path: &str) {
51+
let kernel_path = Path::new(kernel_binary_path);
52+
let out_tftp_path = kernel_path.with_extension(".tftp");
53+
54+
bootloader::create_uefi_pxe_tftp_folder(kernel_path, &out_tftp_path).unwrap();
55+
56+
let mut run_cmd = Command::new("qemu-system-x86_64");
57+
run_cmd.arg("-netdev").arg(format!(
58+
"user,id=net0,net=192.168.17.0/24,tftp={},bootfile=bootloader,id=net0",
59+
out_tftp_path.display()
60+
));
61+
run_cmd.arg("-device").arg("virtio-net-pci,netdev=net0");
62+
run_cmd.args(QEMU_ARGS);
63+
run_cmd.arg("-bios").arg(ovmf_prebuilt::ovmf_pure_efi());
64+
65+
let child_output = run_cmd.output().unwrap();
66+
strip_ansi_escapes::Writer::new(std::io::stderr())
67+
.write_all(&child_output.stderr)
68+
.unwrap();
69+
strip_ansi_escapes::Writer::new(std::io::stderr())
70+
.write_all(&child_output.stdout)
71+
.unwrap();
72+
73+
match child_output.status.code() {
74+
Some(33) => {} // success
75+
Some(35) => panic!("Test failed"),
76+
other => panic!("Test failed with unexpected exit code `{:?}`", other),
77+
}
78+
}

uefi/Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,5 @@ license = "MIT/Apache-2.0"
1111
bootloader_api = { version = "0.1.0-alpha.0", path = "../api" }
1212
bootloader-x86_64-common = { version = "0.1.0-alpha.0", path = "../common" }
1313
log = "0.4.14"
14-
uefi = "0.13.0"
14+
uefi = "0.16.0"
1515
x86_64 = "0.14.8"

0 commit comments

Comments
 (0)