Skip to content

Commit

Permalink
Add pxe, bios, and uefi features, all enabled by default
Browse files Browse the repository at this point in the history
  • Loading branch information
jasoncouture committed Jan 9, 2023
1 parent 79c4868 commit 9731b68
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 47 deletions.
11 changes: 9 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,19 @@ bootloader_api = { version = "0.11.0", path = "api" }
bootloader-x86_64-common = { version = "0.11.0", path = "common" }
bootloader-x86_64-bios-common = { version = "0.11.0", path = "bios/common" }


[features]
default = ["bios", "uefi", "pxe"]
bios = ["mbrman"]
uefi = ["gpt"]
pxe = ["uefi"]

[dependencies]
anyhow = "1.0.32"
fatfs = "0.3.4"
gpt = "3.0.0"
mbrman = "0.5.1"
tempfile = "3.3.0"
mbrman = { version = "0.5.1", optional = true }
gpt = { version = "3.0.0", optional = true }

[dev-dependencies]
bootloader_test_runner = { path = "tests/runner" }
Expand Down
70 changes: 30 additions & 40 deletions build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,28 @@ use std::{
process::Command,
};

const BOOTLOADER_X86_64_UEFI_VERSION: &str = env!("CARGO_PKG_VERSION");

const BOOTLOADER_X86_64_BIOS_BOOT_SECTOR_VERSION: &str = env!("CARGO_PKG_VERSION");
const BOOTLOADER_X86_64_BIOS_STAGE_2_VERSION: &str = env!("CARGO_PKG_VERSION");
const BOOTLOADER_X86_64_BIOS_STAGE_3_VERSION: &str = env!("CARGO_PKG_VERSION");
const BOOTLOADER_X86_64_BIOS_STAGE_4_VERSION: &str = env!("CARGO_PKG_VERSION");
const BOOTLOADER_VERSION: &str = env!("CARGO_PKG_VERSION");

fn main() {
let out_dir = PathBuf::from(std::env::var("OUT_DIR").unwrap());
#[cfg(any(feature = "uefi", feature = "pxe"))]
uefi_main();
#[cfg(feature = "bios")]
bios_main();
}

#[cfg(all(any(feature = "uefi", feature = "pxe"), not(docsrs_dummy_build)))]
fn uefi_main() {
let out_dir = PathBuf::from(std::env::var("OUT_DIR").unwrap());
let uefi_path = build_uefi_bootloader(&out_dir);
println!(
"cargo:rustc-env=UEFI_BOOTLOADER_PATH={}",
uefi_path.display()
);
}

#[cfg(all(feature = "bios", not(docsrs_dummy_build)))]
fn bios_main() {
let out_dir = PathBuf::from(std::env::var("OUT_DIR").unwrap());
let bios_boot_sector_path = build_bios_boot_sector(&out_dir);
println!(
"cargo:rustc-env=BIOS_BOOT_SECTOR_PATH={}",
Expand All @@ -43,7 +49,7 @@ fn main() {
);
}

#[cfg(not(docsrs_dummy_build))]
#[cfg(all(any(feature = "uefi", feature = "pxe"), not(docsrs_dummy_build)))]
fn build_uefi_bootloader(out_dir: &Path) -> PathBuf {
let cargo = std::env::var("CARGO").unwrap_or_else(|_| "cargo".into());
let mut cmd = Command::new(cargo);
Expand All @@ -53,7 +59,7 @@ fn build_uefi_bootloader(out_dir: &Path) -> PathBuf {
cmd.arg("--path").arg("uefi");
println!("cargo:rerun-if-changed=uefi");
} else {
cmd.arg("--version").arg(BOOTLOADER_X86_64_UEFI_VERSION);
cmd.arg("--version").arg(BOOTLOADER_VERSION);
}
cmd.arg("--locked");
cmd.arg("--target").arg("x86_64-unknown-uefi");
Expand All @@ -77,7 +83,7 @@ fn build_uefi_bootloader(out_dir: &Path) -> PathBuf {
}
}

#[cfg(not(docsrs_dummy_build))]
#[cfg(all(feature = "bios", not(docsrs_dummy_build)))]
fn build_bios_boot_sector(out_dir: &Path) -> PathBuf {
let cargo = std::env::var("CARGO").unwrap_or_else(|_| "cargo".into());
let mut cmd = Command::new(cargo);
Expand All @@ -90,8 +96,7 @@ fn build_bios_boot_sector(out_dir: &Path) -> PathBuf {
cmd.arg("--path").arg(&local_path);
println!("cargo:rerun-if-changed={}", local_path.display());
} else {
cmd.arg("--version")
.arg(BOOTLOADER_X86_64_BIOS_BOOT_SECTOR_VERSION);
cmd.arg("--version").arg(BOOTLOADER_VERSION);
}
cmd.arg("--locked");
cmd.arg("--target").arg("i386-code16-boot-sector.json");
Expand Down Expand Up @@ -120,7 +125,7 @@ fn build_bios_boot_sector(out_dir: &Path) -> PathBuf {
convert_elf_to_bin(elf_path)
}

#[cfg(not(docsrs_dummy_build))]
#[cfg(all(feature = "bios", not(docsrs_dummy_build)))]
fn build_bios_stage_2(out_dir: &Path) -> PathBuf {
let cargo = std::env::var("CARGO").unwrap_or_else(|_| "cargo".into());
let mut cmd = Command::new(cargo);
Expand All @@ -133,8 +138,7 @@ fn build_bios_stage_2(out_dir: &Path) -> PathBuf {
cmd.arg("--path").arg(&local_path);
println!("cargo:rerun-if-changed={}", local_path.display());
} else {
cmd.arg("--version")
.arg(BOOTLOADER_X86_64_BIOS_STAGE_2_VERSION);
cmd.arg("--version").arg(BOOTLOADER_VERSION);
}
cmd.arg("--locked");
cmd.arg("--target").arg("i386-code16-stage-2.json");
Expand All @@ -161,7 +165,7 @@ fn build_bios_stage_2(out_dir: &Path) -> PathBuf {
convert_elf_to_bin(elf_path)
}

#[cfg(not(docsrs_dummy_build))]
#[cfg(all(feature = "bios", not(docsrs_dummy_build)))]
fn build_bios_stage_3(out_dir: &Path) -> PathBuf {
let cargo = std::env::var("CARGO").unwrap_or_else(|_| "cargo".into());
let mut cmd = Command::new(cargo);
Expand All @@ -174,8 +178,7 @@ fn build_bios_stage_3(out_dir: &Path) -> PathBuf {
cmd.arg("--path").arg(&local_path);
println!("cargo:rerun-if-changed={}", local_path.display());
} else {
cmd.arg("--version")
.arg(BOOTLOADER_X86_64_BIOS_STAGE_3_VERSION);
cmd.arg("--version").arg(BOOTLOADER_VERSION);
}
cmd.arg("--locked");
cmd.arg("--target").arg("i686-stage-3.json");
Expand All @@ -202,7 +205,7 @@ fn build_bios_stage_3(out_dir: &Path) -> PathBuf {
convert_elf_to_bin(elf_path)
}

#[cfg(not(docsrs_dummy_build))]
#[cfg(all(feature = "bios", not(docsrs_dummy_build)))]
fn build_bios_stage_4(out_dir: &Path) -> PathBuf {
let cargo = std::env::var("CARGO").unwrap_or_else(|_| "cargo".into());
let mut cmd = Command::new(cargo);
Expand All @@ -215,8 +218,7 @@ fn build_bios_stage_4(out_dir: &Path) -> PathBuf {
cmd.arg("--path").arg(&local_path);
println!("cargo:rerun-if-changed={}", local_path.display());
} else {
cmd.arg("--version")
.arg(BOOTLOADER_X86_64_BIOS_STAGE_4_VERSION);
cmd.arg("--version").arg(BOOTLOADER_VERSION);
}
cmd.arg("--locked");
cmd.arg("--target").arg("x86_64-stage-4.json");
Expand Down Expand Up @@ -244,6 +246,7 @@ fn build_bios_stage_4(out_dir: &Path) -> PathBuf {
convert_elf_to_bin(elf_path)
}

#[cfg(all(feature = "bios", not(docsrs_dummy_build)))]
fn convert_elf_to_bin(elf_path: PathBuf) -> PathBuf {
let flat_binary_path = elf_path.with_extension("bin");

Expand Down Expand Up @@ -273,23 +276,10 @@ fn convert_elf_to_bin(elf_path: PathBuf) -> PathBuf {

// dummy implementations because docsrs builds have no network access

#[cfg(docsrs_dummy_build)]
fn build_uefi_bootloader(_out_dir: &Path) -> PathBuf {
PathBuf::new()
}
#[cfg(docsrs_dummy_build)]
fn build_bios_boot_sector(_out_dir: &Path) -> PathBuf {
PathBuf::new()
}
#[cfg(docsrs_dummy_build)]
fn build_bios_stage_2(_out_dir: &Path) -> PathBuf {
PathBuf::new()
}
#[cfg(docsrs_dummy_build)]
fn build_bios_stage_3(_out_dir: &Path) -> PathBuf {
PathBuf::new()
}
#[cfg(docsrs_dummy_build)]
fn build_bios_stage_4(_out_dir: &Path) -> PathBuf {
PathBuf::new()
#[cfg(all(feature = "uefi", docsrs_dummy_build))]
fn uefi_main() {
// stub
}

#[cfg(all(feature = "bios", docsrs_dummy_build))]
fn bios_main() {}
16 changes: 11 additions & 5 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,14 @@ use std::{
use tempfile::NamedTempFile;

mod fat;
#[cfg(feature = "uefi")]
mod gpt;

#[cfg(feature = "bios")]
mod mbr;

const KERNEL_FILE_NAME: &str = "kernel-x86_64";
const RAMDISK_FILE_NAME: &str = "ramdisk";
const BIOS_STAGE_3: &str = "boot-stage-3";
const BIOS_STAGE_4: &str = "boot-stage-4";
const UEFI_BOOT_FILENAME: &str = "efi/boot/bootx64.efi";
const UEFI_TFTP_BOOT_FILENAME: &str = "bootloader";

struct DiskImageFile<'a> {
source: &'a PathBuf,
Expand Down Expand Up @@ -87,9 +86,11 @@ impl<'a> DiskImageBuilder<'a> {

Ok(out_file)
}

#[cfg(feature = "bios")]
/// Create an MBR disk image for booting on BIOS systems.
pub fn create_bios_image(&self, image_filename: &Path) -> anyhow::Result<()> {
const BIOS_STAGE_3: &str = "boot-stage-3";
const BIOS_STAGE_4: &str = "boot-stage-4";
let bootsector_path = Path::new(env!("BIOS_BOOT_SECTOR_PATH"));
let stage_2_path = Path::new(env!("BIOS_STAGE_2_PATH"));
let stage_3_path = Path::new(env!("BIOS_STAGE_3_PATH"));
Expand All @@ -114,8 +115,11 @@ impl<'a> DiskImageBuilder<'a> {
.context("failed to delete FAT partition after disk image creation")?;
Ok(())
}

#[cfg(feature = "uefi")]
/// Create a GPT disk image for booting on UEFI systems.
pub fn create_uefi_image(&self, image_filename: &Path) -> anyhow::Result<()> {
const UEFI_BOOT_FILENAME: &str = "efi/boot/bootx64.efi";
let bootloader_path = Path::new(env!("UEFI_BOOTLOADER_PATH"));
let mut internal_files = BTreeMap::new();
internal_files.insert(UEFI_BOOT_FILENAME, bootloader_path);
Expand All @@ -131,8 +135,10 @@ impl<'a> DiskImageBuilder<'a> {
Ok(())
}

#[cfg(all(feature = "uefi", feature = "pxe"))]
/// Create a folder containing the needed files for UEFI TFTP/PXE booting.
pub fn create_uefi_tftp_folder(&self, tftp_path: &Path) -> anyhow::Result<()> {
const UEFI_TFTP_BOOT_FILENAME: &str = "bootloader";
let bootloader_path = Path::new(env!("UEFI_BOOTLOADER_PATH"));
std::fs::create_dir_all(tftp_path)
.with_context(|| format!("failed to create out dir at {}", tftp_path.display()))?;
Expand Down

0 comments on commit 9731b68

Please sign in to comment.