Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 7d2a579

Browse filesBrowse files
Embed bios and uefi binaries (#395)
1 parent 0fec6fd commit 7d2a579
Copy full SHA for 7d2a579

File tree

Expand file treeCollapse file tree

4 files changed

+140
-48
lines changed
Filter options
Expand file treeCollapse file tree

4 files changed

+140
-48
lines changed

‎build.rs

Copy file name to clipboardExpand all lines: build.rs
+100-13Lines changed: 100 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ async fn bios_main() {
2121
// BIOS crates don't have enough dependencies to utilize all cores on modern
2222
// CPUs. So by running the build commands in parallel, we increase the number
2323
// of utilized cores.)
24-
#[cfg(not(docsrs_dummy_build))]
2524
let (bios_boot_sector_path, bios_stage_2_path, bios_stage_3_path, bios_stage_4_path) = (
2625
build_bios_boot_sector(&out_dir),
2726
build_bios_stage_2(&out_dir),
@@ -30,14 +29,6 @@ async fn bios_main() {
3029
)
3130
.join()
3231
.await;
33-
// dummy implementations because docsrs builds have no network access
34-
#[cfg(docsrs_dummy_build)]
35-
let (bios_boot_sector_path, bios_stage_2_path, bios_stage_3_path, bios_stage_4_path) = (
36-
PathBuf::new(),
37-
PathBuf::new(),
38-
PathBuf::new(),
39-
PathBuf::new(),
40-
);
4132
println!(
4233
"cargo:rustc-env=BIOS_BOOT_SECTOR_PATH={}",
4334
bios_boot_sector_path.display()
@@ -60,11 +51,7 @@ async fn bios_main() {
6051
async fn uefi_main() {
6152
let out_dir = PathBuf::from(std::env::var("OUT_DIR").unwrap());
6253

63-
#[cfg(not(docsrs_dummy_build))]
6454
let uefi_path = build_uefi_bootloader(&out_dir).await;
65-
// dummy implementation because docsrs builds have no network access
66-
#[cfg(docsrs_dummy_build)]
67-
let uefi_path = PathBuf::new();
6855

6956
println!(
7057
"cargo:rustc-env=UEFI_BOOTLOADER_PATH={}",
@@ -109,6 +96,26 @@ async fn build_uefi_bootloader(out_dir: &Path) -> PathBuf {
10996
}
11097
}
11198

99+
// dummy implementation because docsrs builds have no network access.
100+
// This will put an empty file in out_dir and return its path.
101+
#[cfg(docsrs_dummy_build)]
102+
#[cfg(feature = "uefi")]
103+
async fn build_uefi_bootloader(out_dir: &Path) -> PathBuf {
104+
use std::fs::File;
105+
106+
let path = out_dir.join("bootloader-dummy-bootloader-uefi");
107+
108+
if File::create(&path).is_err() {
109+
panic!("Failed to create dummy uefi bootloader");
110+
}
111+
assert!(
112+
path.exists(),
113+
"uefi bootloader dummy file does not exist after file creation"
114+
);
115+
116+
path
117+
}
118+
112119
#[cfg(not(docsrs_dummy_build))]
113120
#[cfg(feature = "bios")]
114121
async fn build_bios_boot_sector(out_dir: &Path) -> PathBuf {
@@ -153,6 +160,26 @@ async fn build_bios_boot_sector(out_dir: &Path) -> PathBuf {
153160
convert_elf_to_bin(elf_path).await
154161
}
155162

163+
// dummy implementation because docsrs builds have no network access.
164+
// This will put an empty file in out_dir and return its path.
165+
#[cfg(docsrs_dummy_build)]
166+
#[cfg(feature = "bios")]
167+
async fn build_bios_boot_sector(out_dir: &Path) -> PathBuf {
168+
use std::fs::File;
169+
170+
let path = out_dir.join("bootloader-dummy-bios-boot-sector");
171+
172+
if File::create(&path).is_err() {
173+
panic!("Failed to create dummy bios boot sector");
174+
}
175+
assert!(
176+
path.exists(),
177+
"bios boot sector dummy file does not exist after file creation"
178+
);
179+
180+
path
181+
}
182+
156183
#[cfg(not(docsrs_dummy_build))]
157184
#[cfg(feature = "bios")]
158185
async fn build_bios_stage_2(out_dir: &Path) -> PathBuf {
@@ -199,6 +226,26 @@ async fn build_bios_stage_2(out_dir: &Path) -> PathBuf {
199226
convert_elf_to_bin(elf_path).await
200227
}
201228

229+
// dummy implementation because docsrs builds have no network access.
230+
// This will put an empty file in out_dir and return its path.
231+
#[cfg(docsrs_dummy_build)]
232+
#[cfg(feature = "bios")]
233+
async fn build_bios_stage_2(out_dir: &Path) -> PathBuf {
234+
use std::fs::File;
235+
236+
let path = out_dir.join("bootloader-dummy-bios-stage-2");
237+
238+
if File::create(&path).is_err() {
239+
panic!("Failed to create dummy bios second stage");
240+
}
241+
assert!(
242+
path.exists(),
243+
"bios second stage dummy file does not exist after file creation"
244+
);
245+
246+
path
247+
}
248+
202249
#[cfg(not(docsrs_dummy_build))]
203250
#[cfg(feature = "bios")]
204251
async fn build_bios_stage_3(out_dir: &Path) -> PathBuf {
@@ -241,6 +288,26 @@ async fn build_bios_stage_3(out_dir: &Path) -> PathBuf {
241288
convert_elf_to_bin(elf_path).await
242289
}
243290

291+
// dummy implementation because docsrs builds have no network access.
292+
// This will put an empty file in out_dir and return its path.
293+
#[cfg(docsrs_dummy_build)]
294+
#[cfg(feature = "bios")]
295+
async fn build_bios_stage_3(out_dir: &Path) -> PathBuf {
296+
use std::fs::File;
297+
298+
let path = out_dir.join("bootloader-dummy-bios-stage-3");
299+
300+
if File::create(&path).is_err() {
301+
panic!("Failed to create dummy bios stage-3");
302+
}
303+
assert!(
304+
path.exists(),
305+
"bios stage-3 dummy file does not exist after file creation"
306+
);
307+
308+
path
309+
}
310+
244311
#[cfg(not(docsrs_dummy_build))]
245312
#[cfg(feature = "bios")]
246313
async fn build_bios_stage_4(out_dir: &Path) -> PathBuf {
@@ -284,6 +351,26 @@ async fn build_bios_stage_4(out_dir: &Path) -> PathBuf {
284351
convert_elf_to_bin(elf_path).await
285352
}
286353

354+
// dummy implementation because docsrs builds have no network access.
355+
// This will put an empty file in out_dir and return its path.
356+
#[cfg(docsrs_dummy_build)]
357+
#[cfg(feature = "bios")]
358+
async fn build_bios_stage_4(out_dir: &Path) -> PathBuf {
359+
use std::fs::File;
360+
361+
let path = out_dir.join("bootloader-dummy-bios-stage-4");
362+
363+
if File::create(&path).is_err() {
364+
panic!("Failed to create dummy bios stage-4");
365+
}
366+
assert!(
367+
path.exists(),
368+
"bios stage-4 dummy file does not exist after file creation"
369+
);
370+
371+
path
372+
}
373+
287374
#[cfg(not(docsrs_dummy_build))]
288375
#[cfg(feature = "bios")]
289376
async fn convert_elf_to_bin(elf_path: PathBuf) -> PathBuf {

‎src/file_data_source.rs

Copy file name to clipboardExpand all lines: src/file_data_source.rs
+9Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ use std::{fs, io};
1111
pub enum FileDataSource {
1212
File(PathBuf),
1313
Data(Vec<u8>),
14+
Bytes(&'static [u8]),
1415
}
1516

1617
impl Debug for FileDataSource {
@@ -22,6 +23,9 @@ impl Debug for FileDataSource {
2223
FileDataSource::Data(d) => {
2324
f.write_fmt(format_args!("data source: {} raw bytes ", d.len()))
2425
}
26+
FileDataSource::Bytes(b) => {
27+
f.write_fmt(format_args!("data source: {} raw bytes ", b.len()))
28+
}
2529
}
2630
}
2731
}
@@ -34,6 +38,7 @@ impl FileDataSource {
3438
.with_context(|| format!("failed to read metadata of file `{}`", path.display()))?
3539
.len(),
3640
FileDataSource::Data(v) => v.len() as u64,
41+
FileDataSource::Bytes(s) => s.len() as u64,
3742
})
3843
}
3944
/// Copy this data source to the specified target that implements io::Write
@@ -51,6 +56,10 @@ impl FileDataSource {
5156
let mut cursor = Cursor::new(contents);
5257
io::copy(&mut cursor, target)?;
5358
}
59+
FileDataSource::Bytes(contents) => {
60+
let mut cursor = Cursor::new(contents);
61+
io::copy(&mut cursor, target)?;
62+
}
5463
};
5564

5665
Ok(())

‎src/lib.rs

Copy file name to clipboardExpand all lines: src/lib.rs
+23-26Lines changed: 23 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,17 @@ const KERNEL_FILE_NAME: &str = "kernel-x86_64";
4141
const RAMDISK_FILE_NAME: &str = "ramdisk";
4242
const CONFIG_FILE_NAME: &str = "boot.json";
4343

44+
#[cfg(feature = "uefi")]
45+
const UEFI_BOOTLOADER: &[u8] = include_bytes!(env!("UEFI_BOOTLOADER_PATH"));
46+
#[cfg(feature = "bios")]
47+
const BIOS_BOOT_SECTOR: &[u8] = include_bytes!(env!("BIOS_BOOT_SECTOR_PATH"));
48+
#[cfg(feature = "bios")]
49+
const BIOS_STAGE_2: &[u8] = include_bytes!(env!("BIOS_STAGE_2_PATH"));
50+
#[cfg(feature = "bios")]
51+
const BIOS_STAGE_3: &[u8] = include_bytes!(env!("BIOS_STAGE_3_PATH"));
52+
#[cfg(feature = "bios")]
53+
const BIOS_STAGE_4: &[u8] = include_bytes!(env!("BIOS_STAGE_4_PATH"));
54+
4455
/// Allows creating disk images for a specified set of files.
4556
///
4657
/// It can currently create `MBR` (BIOS), `GPT` (UEFI), and `TFTP` (UEFI) images.
@@ -98,28 +109,19 @@ impl DiskImageBuilder {
98109
#[cfg(feature = "bios")]
99110
/// Create an MBR disk image for booting on BIOS systems.
100111
pub fn create_bios_image(&self, image_path: &Path) -> anyhow::Result<()> {
101-
const BIOS_STAGE_3: &str = "boot-stage-3";
102-
const BIOS_STAGE_4: &str = "boot-stage-4";
103-
let bootsector_path = Path::new(env!("BIOS_BOOT_SECTOR_PATH"));
104-
let stage_2_path = Path::new(env!("BIOS_STAGE_2_PATH"));
105-
let stage_3_path = Path::new(env!("BIOS_STAGE_3_PATH"));
106-
let stage_4_path = Path::new(env!("BIOS_STAGE_4_PATH"));
112+
const BIOS_STAGE_3_NAME: &str = "boot-stage-3";
113+
const BIOS_STAGE_4_NAME: &str = "boot-stage-4";
114+
let stage_3 = FileDataSource::Bytes(BIOS_STAGE_3);
115+
let stage_4 = FileDataSource::Bytes(BIOS_STAGE_4);
107116
let mut internal_files = BTreeMap::new();
108-
internal_files.insert(
109-
BIOS_STAGE_3,
110-
FileDataSource::File(stage_3_path.to_path_buf()),
111-
);
112-
internal_files.insert(
113-
BIOS_STAGE_4,
114-
FileDataSource::File(stage_4_path.to_path_buf()),
115-
);
116-
117+
internal_files.insert(BIOS_STAGE_3_NAME, stage_3);
118+
internal_files.insert(BIOS_STAGE_4_NAME, stage_4);
117119
let fat_partition = self
118120
.create_fat_filesystem_image(internal_files)
119121
.context("failed to create FAT partition")?;
120122
mbr::create_mbr_disk(
121-
bootsector_path,
122-
stage_2_path,
123+
BIOS_BOOT_SECTOR,
124+
BIOS_STAGE_2,
123125
fat_partition.path(),
124126
image_path,
125127
)
@@ -135,12 +137,9 @@ impl DiskImageBuilder {
135137
/// Create a GPT disk image for booting on UEFI systems.
136138
pub fn create_uefi_image(&self, image_path: &Path) -> anyhow::Result<()> {
137139
const UEFI_BOOT_FILENAME: &str = "efi/boot/bootx64.efi";
138-
let bootloader_path = Path::new(env!("UEFI_BOOTLOADER_PATH"));
140+
139141
let mut internal_files = BTreeMap::new();
140-
internal_files.insert(
141-
UEFI_BOOT_FILENAME,
142-
FileDataSource::File(bootloader_path.to_path_buf()),
143-
);
142+
internal_files.insert(UEFI_BOOT_FILENAME, FileDataSource::Bytes(UEFI_BOOTLOADER));
144143
let fat_partition = self
145144
.create_fat_filesystem_image(internal_files)
146145
.context("failed to create FAT partition")?;
@@ -159,15 +158,13 @@ impl DiskImageBuilder {
159158
use std::{fs, ops::Deref};
160159

161160
const UEFI_TFTP_BOOT_FILENAME: &str = "bootloader";
162-
let bootloader_path = Path::new(env!("UEFI_BOOTLOADER_PATH"));
163161
fs::create_dir_all(tftp_path)
164162
.with_context(|| format!("failed to create out dir at {}", tftp_path.display()))?;
165163

166164
let to = tftp_path.join(UEFI_TFTP_BOOT_FILENAME);
167-
fs::copy(bootloader_path, &to).with_context(|| {
165+
fs::write(&to, UEFI_BOOTLOADER).with_context(|| {
168166
format!(
169-
"failed to copy bootloader from {} to {}",
170-
bootloader_path.display(),
167+
"failed to copy bootloader from the embedded binary to {}",
171168
to.display()
172169
)
173170
})?;

‎src/mbr.rs

Copy file name to clipboardExpand all lines: src/mbr.rs
+8-9Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,17 @@ use std::{
55
io::{self, Seek, SeekFrom},
66
path::Path,
77
};
8+
89
const SECTOR_SIZE: u32 = 512;
910

1011
pub fn create_mbr_disk(
11-
bootsector_path: &Path,
12-
second_stage_path: &Path,
12+
bootsector_binary: &[u8],
13+
second_stage_binary: &[u8],
1314
boot_partition_path: &Path,
1415
out_mbr_path: &Path,
1516
) -> anyhow::Result<()> {
16-
let mut boot_sector = File::open(bootsector_path).context("failed to open boot sector")?;
17+
use std::io::Cursor;
18+
let mut boot_sector = Cursor::new(bootsector_binary);
1719
let mut mbr =
1820
mbrman::MBR::read_from(&mut boot_sector, SECTOR_SIZE).context("failed to read MBR")?;
1921

@@ -23,12 +25,9 @@ pub fn create_mbr_disk(
2325
}
2426
}
2527

26-
let mut second_stage =
27-
File::open(second_stage_path).context("failed to open second stage binary")?;
28-
let second_stage_size = second_stage
29-
.metadata()
30-
.context("failed to read file metadata of second stage")?
31-
.len();
28+
let mut second_stage = Cursor::new(second_stage_binary);
29+
let second_stage_size = second_stage_binary.len() as u64;
30+
3231
let second_stage_start_sector = 1;
3332
let second_stage_sectors = ((second_stage_size - 1) / u64::from(SECTOR_SIZE) + 1)
3433
.try_into()

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.