Skip to content

Commit 4056453

Browse files
AlexJMohrphil-opp
authored andcommitted
move bios and uefi specific code into submodules gated by features
1 parent 8a7f6b1 commit 4056453

File tree

7 files changed

+156
-130
lines changed

7 files changed

+156
-130
lines changed

build.rs

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ fn main() {
4444
}
4545

4646
#[cfg(not(docsrs_dummy_build))]
47+
#[cfg(feature = "uefi")]
4748
fn build_uefi_bootloader(out_dir: &Path) -> PathBuf {
4849
let cargo = std::env::var("CARGO").unwrap_or_else(|_| "cargo".into());
4950
let mut cmd = Command::new(cargo);
@@ -78,6 +79,7 @@ fn build_uefi_bootloader(out_dir: &Path) -> PathBuf {
7879
}
7980

8081
#[cfg(not(docsrs_dummy_build))]
82+
#[cfg(feature = "bios")]
8183
fn build_bios_boot_sector(out_dir: &Path) -> PathBuf {
8284
let cargo = std::env::var("CARGO").unwrap_or_else(|_| "cargo".into());
8385
let mut cmd = Command::new(cargo);
@@ -121,6 +123,7 @@ fn build_bios_boot_sector(out_dir: &Path) -> PathBuf {
121123
}
122124

123125
#[cfg(not(docsrs_dummy_build))]
126+
#[cfg(feature = "bios")]
124127
fn build_bios_stage_2(out_dir: &Path) -> PathBuf {
125128
let cargo = std::env::var("CARGO").unwrap_or_else(|_| "cargo".into());
126129
let mut cmd = Command::new(cargo);
@@ -162,6 +165,7 @@ fn build_bios_stage_2(out_dir: &Path) -> PathBuf {
162165
}
163166

164167
#[cfg(not(docsrs_dummy_build))]
168+
#[cfg(feature = "bios")]
165169
fn build_bios_stage_3(out_dir: &Path) -> PathBuf {
166170
let cargo = std::env::var("CARGO").unwrap_or_else(|_| "cargo".into());
167171
let mut cmd = Command::new(cargo);
@@ -203,6 +207,7 @@ fn build_bios_stage_3(out_dir: &Path) -> PathBuf {
203207
}
204208

205209
#[cfg(not(docsrs_dummy_build))]
210+
#[cfg(feature = "bios")]
206211
fn build_bios_stage_4(out_dir: &Path) -> PathBuf {
207212
let cargo = std::env::var("CARGO").unwrap_or_else(|_| "cargo".into());
208213
let mut cmd = Command::new(cargo);
@@ -244,6 +249,7 @@ fn build_bios_stage_4(out_dir: &Path) -> PathBuf {
244249
convert_elf_to_bin(elf_path)
245250
}
246251

252+
#[cfg(feature = "bios")]
247253
fn convert_elf_to_bin(elf_path: PathBuf) -> PathBuf {
248254
let flat_binary_path = elf_path.with_extension("bin");
249255

@@ -273,23 +279,23 @@ fn convert_elf_to_bin(elf_path: PathBuf) -> PathBuf {
273279

274280
// dummy implementations because docsrs builds have no network access
275281

276-
#[cfg(docsrs_dummy_build)]
282+
#[cfg(any(docsrs_dummy_build, not(feature = "uefi")))]
277283
fn build_uefi_bootloader(_out_dir: &Path) -> PathBuf {
278284
PathBuf::new()
279285
}
280-
#[cfg(docsrs_dummy_build)]
286+
#[cfg(any(docsrs_dummy_build, not(feature = "bios")))]
281287
fn build_bios_boot_sector(_out_dir: &Path) -> PathBuf {
282288
PathBuf::new()
283289
}
284-
#[cfg(docsrs_dummy_build)]
290+
#[cfg(any(docsrs_dummy_build, not(feature = "bios")))]
285291
fn build_bios_stage_2(_out_dir: &Path) -> PathBuf {
286292
PathBuf::new()
287293
}
288-
#[cfg(docsrs_dummy_build)]
294+
#[cfg(any(docsrs_dummy_build, not(feature = "bios")))]
289295
fn build_bios_stage_3(_out_dir: &Path) -> PathBuf {
290296
PathBuf::new()
291297
}
292-
#[cfg(docsrs_dummy_build)]
298+
#[cfg(any(docsrs_dummy_build, not(feature = "bios")))]
293299
fn build_bios_stage_4(_out_dir: &Path) -> PathBuf {
294300
PathBuf::new()
295301
}
File renamed without changes.

src/bios/mod.rs

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
use crate::fat;
2+
use anyhow::Context;
3+
use std::{
4+
collections::BTreeMap,
5+
path::{Path, PathBuf},
6+
};
7+
use tempfile::NamedTempFile;
8+
9+
mod mbr;
10+
11+
const BIOS_STAGE_3: &str = "boot-stage-3";
12+
const BIOS_STAGE_4: &str = "boot-stage-4";
13+
14+
/// Create disk images for booting on legacy BIOS systems.
15+
pub struct BiosBoot {
16+
kernel: PathBuf,
17+
}
18+
19+
impl BiosBoot {
20+
/// Start creating a disk image for the given bootloader ELF executable.
21+
pub fn new(kernel_path: &Path) -> Self {
22+
Self {
23+
kernel: kernel_path.to_owned(),
24+
}
25+
}
26+
27+
/// Create a bootable UEFI disk image at the given path.
28+
pub fn create_disk_image(&self, out_path: &Path) -> anyhow::Result<()> {
29+
let bootsector_path = Path::new(env!("BIOS_BOOT_SECTOR_PATH"));
30+
let stage_2_path = Path::new(env!("BIOS_STAGE_2_PATH"));
31+
32+
let fat_partition = self
33+
.create_fat_partition()
34+
.context("failed to create FAT partition")?;
35+
36+
mbr::create_mbr_disk(
37+
bootsector_path,
38+
stage_2_path,
39+
fat_partition.path(),
40+
out_path,
41+
)
42+
.context("failed to create BIOS MBR disk image")?;
43+
44+
fat_partition
45+
.close()
46+
.context("failed to delete FAT partition after disk image creation")?;
47+
48+
Ok(())
49+
}
50+
51+
/// Creates an BIOS-bootable FAT partition with the kernel.
52+
fn create_fat_partition(&self) -> anyhow::Result<NamedTempFile> {
53+
let stage_3_path = Path::new(env!("BIOS_STAGE_3_PATH"));
54+
let stage_4_path = Path::new(env!("BIOS_STAGE_4_PATH"));
55+
56+
let mut files = BTreeMap::new();
57+
files.insert(crate::KERNEL_FILE_NAME, self.kernel.as_path());
58+
files.insert(BIOS_STAGE_3, stage_3_path);
59+
files.insert(BIOS_STAGE_4, stage_4_path);
60+
61+
let out_file = NamedTempFile::new().context("failed to create temp file")?;
62+
fat::create_fat_filesystem(files, out_file.path())
63+
.context("failed to create BIOS FAT filesystem")?;
64+
65+
Ok(out_file)
66+
}
67+
}

src/lib.rs

Lines changed: 9 additions & 125 deletions
Original file line numberDiff line numberDiff line change
@@ -4,132 +4,16 @@ An experimental x86_64 bootloader that works on both BIOS and UEFI systems.
44

55
#![warn(missing_docs)]
66

7-
use anyhow::Context;
8-
use std::{
9-
collections::BTreeMap,
10-
path::{Path, PathBuf},
11-
};
12-
use tempfile::NamedTempFile;
13-
7+
#[cfg(feature = "bios")]
8+
mod bios;
149
mod fat;
15-
mod gpt;
16-
mod mbr;
17-
mod pxe;
18-
19-
const KERNEL_FILE_NAME: &str = "kernel-x86_64";
20-
const BIOS_STAGE_3: &str = "boot-stage-3";
21-
const BIOS_STAGE_4: &str = "boot-stage-4";
22-
23-
/// Create disk images for booting on legacy BIOS systems.
24-
pub struct BiosBoot {
25-
kernel: PathBuf,
26-
}
27-
28-
impl BiosBoot {
29-
/// Start creating a disk image for the given bootloader ELF executable.
30-
pub fn new(kernel_path: &Path) -> Self {
31-
Self {
32-
kernel: kernel_path.to_owned(),
33-
}
34-
}
35-
36-
/// Create a bootable UEFI disk image at the given path.
37-
pub fn create_disk_image(&self, out_path: &Path) -> anyhow::Result<()> {
38-
let bootsector_path = Path::new(env!("BIOS_BOOT_SECTOR_PATH"));
39-
let stage_2_path = Path::new(env!("BIOS_STAGE_2_PATH"));
40-
41-
let fat_partition = self
42-
.create_fat_partition()
43-
.context("failed to create FAT partition")?;
44-
45-
mbr::create_mbr_disk(
46-
bootsector_path,
47-
stage_2_path,
48-
fat_partition.path(),
49-
out_path,
50-
)
51-
.context("failed to create BIOS MBR disk image")?;
52-
53-
fat_partition
54-
.close()
55-
.context("failed to delete FAT partition after disk image creation")?;
56-
57-
Ok(())
58-
}
59-
60-
/// Creates an BIOS-bootable FAT partition with the kernel.
61-
fn create_fat_partition(&self) -> anyhow::Result<NamedTempFile> {
62-
let stage_3_path = Path::new(env!("BIOS_STAGE_3_PATH"));
63-
let stage_4_path = Path::new(env!("BIOS_STAGE_4_PATH"));
64-
65-
let mut files = BTreeMap::new();
66-
files.insert(KERNEL_FILE_NAME, self.kernel.as_path());
67-
files.insert(BIOS_STAGE_3, stage_3_path);
68-
files.insert(BIOS_STAGE_4, stage_4_path);
69-
70-
let out_file = NamedTempFile::new().context("failed to create temp file")?;
71-
fat::create_fat_filesystem(files, out_file.path())
72-
.context("failed to create BIOS FAT filesystem")?;
10+
#[cfg(feature = "uefi")]
11+
mod uefi;
7312

74-
Ok(out_file)
75-
}
76-
}
13+
#[cfg(feature = "bios")]
14+
pub use bios::BiosBoot;
7715

78-
/// Create disk images for booting on UEFI systems.
79-
pub struct UefiBoot {
80-
kernel: PathBuf,
81-
}
16+
#[cfg(feature = "uefi")]
17+
pub use uefi::UefiBoot;
8218

83-
impl UefiBoot {
84-
/// Start creating a disk image for the given bootloader ELF executable.
85-
pub fn new(kernel_path: &Path) -> Self {
86-
Self {
87-
kernel: kernel_path.to_owned(),
88-
}
89-
}
90-
91-
/// Create a bootable BIOS disk image at the given path.
92-
pub fn create_disk_image(&self, out_path: &Path) -> anyhow::Result<()> {
93-
let fat_partition = self
94-
.create_fat_partition()
95-
.context("failed to create FAT partition")?;
96-
97-
gpt::create_gpt_disk(fat_partition.path(), out_path)
98-
.context("failed to create UEFI GPT disk image")?;
99-
100-
fat_partition
101-
.close()
102-
.context("failed to delete FAT partition after disk image creation")?;
103-
104-
Ok(())
105-
}
106-
107-
/// Prepare a folder for use with booting over UEFI_PXE.
108-
///
109-
/// This places the bootloader executable under the path "bootloader". The
110-
/// DHCP server should set the filename option to that path, otherwise the
111-
/// bootloader won't be found.
112-
pub fn create_pxe_tftp_folder(&self, out_path: &Path) -> anyhow::Result<()> {
113-
let bootloader_path = Path::new(env!("UEFI_BOOTLOADER_PATH"));
114-
115-
pxe::create_uefi_tftp_folder(bootloader_path, self.kernel.as_path(), out_path)
116-
.context("failed to create UEFI PXE tftp folder")?;
117-
118-
Ok(())
119-
}
120-
121-
/// Creates an UEFI-bootable FAT partition with the kernel.
122-
fn create_fat_partition(&self) -> anyhow::Result<NamedTempFile> {
123-
let bootloader_path = Path::new(env!("UEFI_BOOTLOADER_PATH"));
124-
125-
let mut files = BTreeMap::new();
126-
files.insert("efi/boot/bootx64.efi", bootloader_path);
127-
files.insert(KERNEL_FILE_NAME, self.kernel.as_path());
128-
129-
let out_file = NamedTempFile::new().context("failed to create temp file")?;
130-
fat::create_fat_filesystem(files, out_file.path())
131-
.context("failed to create UEFI FAT filesystem")?;
132-
133-
Ok(out_file)
134-
}
135-
}
19+
const KERNEL_FILE_NAME: &str = "kernel-x86_64";
File renamed without changes.

src/uefi/mod.rs

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
use crate::fat;
2+
use anyhow::Context;
3+
use std::{
4+
collections::BTreeMap,
5+
path::{Path, PathBuf},
6+
};
7+
use tempfile::NamedTempFile;
8+
9+
mod gpt;
10+
mod pxe;
11+
12+
/// Create disk images for booting on UEFI systems.
13+
pub struct UefiBoot {
14+
kernel: PathBuf,
15+
}
16+
17+
impl UefiBoot {
18+
/// Start creating a disk image for the given bootloader ELF executable.
19+
pub fn new(kernel_path: &Path) -> Self {
20+
Self {
21+
kernel: kernel_path.to_owned(),
22+
}
23+
}
24+
25+
/// Create a bootable BIOS disk image at the given path.
26+
pub fn create_disk_image(&self, out_path: &Path) -> anyhow::Result<()> {
27+
let fat_partition = self
28+
.create_fat_partition()
29+
.context("failed to create FAT partition")?;
30+
31+
gpt::create_gpt_disk(fat_partition.path(), out_path)
32+
.context("failed to create UEFI GPT disk image")?;
33+
34+
fat_partition
35+
.close()
36+
.context("failed to delete FAT partition after disk image creation")?;
37+
38+
Ok(())
39+
}
40+
41+
/// Prepare a folder for use with booting over UEFI_PXE.
42+
///
43+
/// This places the bootloader executable under the path "bootloader". The
44+
/// DHCP server should set the filename option to that path, otherwise the
45+
/// bootloader won't be found.
46+
pub fn create_pxe_tftp_folder(&self, out_path: &Path) -> anyhow::Result<()> {
47+
let bootloader_path = Path::new(env!("UEFI_BOOTLOADER_PATH"));
48+
49+
pxe::create_uefi_tftp_folder(bootloader_path, self.kernel.as_path(), out_path)
50+
.context("failed to create UEFI PXE tftp folder")?;
51+
52+
Ok(())
53+
}
54+
55+
/// Creates an UEFI-bootable FAT partition with the kernel.
56+
fn create_fat_partition(&self) -> anyhow::Result<NamedTempFile> {
57+
let bootloader_path = Path::new(env!("UEFI_BOOTLOADER_PATH"));
58+
59+
let mut files = BTreeMap::new();
60+
files.insert("efi/boot/bootx64.efi", bootloader_path);
61+
files.insert(crate::KERNEL_FILE_NAME, self.kernel.as_path());
62+
63+
let out_file = NamedTempFile::new().context("failed to create temp file")?;
64+
fat::create_fat_filesystem(files, out_file.path())
65+
.context("failed to create UEFI FAT filesystem")?;
66+
67+
Ok(out_file)
68+
}
69+
}
File renamed without changes.

0 commit comments

Comments
 (0)