Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
78 changes: 54 additions & 24 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,15 +42,20 @@ const RAMDISK_FILE_NAME: &str = "ramdisk";
const CONFIG_FILE_NAME: &str = "boot.json";

#[cfg(feature = "uefi")]
const UEFI_BOOTLOADER: &[u8] = include_bytes!(env!("UEFI_BOOTLOADER_PATH"));
/// The byte data of the UEFI bootloader
pub const UEFI_BOOTLOADER: &[u8] = include_bytes!(env!("UEFI_BOOTLOADER_PATH"));
#[cfg(feature = "bios")]
const BIOS_BOOT_SECTOR: &[u8] = include_bytes!(env!("BIOS_BOOT_SECTOR_PATH"));
/// The byte data of the BIOS boot sector
pub const BIOS_BOOT_SECTOR: &[u8] = include_bytes!(env!("BIOS_BOOT_SECTOR_PATH"));
#[cfg(feature = "bios")]
const BIOS_STAGE_2: &[u8] = include_bytes!(env!("BIOS_STAGE_2_PATH"));
/// The byte data of the second stage of the BIOS bootloader
pub const BIOS_STAGE_2: &[u8] = include_bytes!(env!("BIOS_STAGE_2_PATH"));
#[cfg(feature = "bios")]
const BIOS_STAGE_3: &[u8] = include_bytes!(env!("BIOS_STAGE_3_PATH"));
/// The byte data of the third stage of the BIOS bootloader
pub const BIOS_STAGE_3: &[u8] = include_bytes!(env!("BIOS_STAGE_3_PATH"));
#[cfg(feature = "bios")]
const BIOS_STAGE_4: &[u8] = include_bytes!(env!("BIOS_STAGE_4_PATH"));
/// The byte data of the fourth stage of the BIOS bootloader
pub const BIOS_STAGE_4: &[u8] = include_bytes!(env!("BIOS_STAGE_4_PATH"));

/// Allows creating disk images for a specified set of files.
///
Expand Down Expand Up @@ -109,16 +114,11 @@ impl DiskImageBuilder {
#[cfg(feature = "bios")]
/// Create an MBR disk image for booting on BIOS systems.
pub fn create_bios_image(&self, image_path: &Path) -> anyhow::Result<()> {
const BIOS_STAGE_3_NAME: &str = "boot-stage-3";
const BIOS_STAGE_4_NAME: &str = "boot-stage-4";
let stage_3 = FileDataSource::Bytes(BIOS_STAGE_3);
let stage_4 = FileDataSource::Bytes(BIOS_STAGE_4);
let mut internal_files = BTreeMap::new();
internal_files.insert(BIOS_STAGE_3_NAME, stage_3);
internal_files.insert(BIOS_STAGE_4_NAME, stage_4);
let fat_partition = self
.create_fat_filesystem_image(internal_files)
let fat_partition = NamedTempFile::new().context("failed to create temp file")?;

self.create_bios_fat_partition(fat_partition.path())
.context("failed to create FAT partition")?;

mbr::create_mbr_disk(
BIOS_BOOT_SECTOR,
BIOS_STAGE_2,
Expand All @@ -133,16 +133,33 @@ impl DiskImageBuilder {
Ok(())
}

#[cfg(feature = "bios")]
/// create a bootable fat-partition for a BIOS system.
///
/// Note that for the partition to work as a boot-partition [BIOS_BOOT_SECTOR] and [BIOS_STAGE_2]
/// have to be properly loaded into the MBR disk image.
pub fn create_bios_fat_partition(&self, partition_path: &Path) -> anyhow::Result<()> {
const BIOS_STAGE_3_NAME: &str = "boot-stage-3";
const BIOS_STAGE_4_NAME: &str = "boot-stage-4";
let stage_3 = FileDataSource::Bytes(BIOS_STAGE_3);
let stage_4 = FileDataSource::Bytes(BIOS_STAGE_4);
let mut internal_files = BTreeMap::new();
internal_files.insert(BIOS_STAGE_3_NAME, stage_3);
internal_files.insert(BIOS_STAGE_4_NAME, stage_4);

self.create_fat_filesystem_image(internal_files, partition_path)
.context("failed to create FAT partition")?;

Ok(())
}

#[cfg(feature = "uefi")]
/// Create a GPT disk image for booting on UEFI systems.
pub fn create_uefi_image(&self, image_path: &Path) -> anyhow::Result<()> {
const UEFI_BOOT_FILENAME: &str = "efi/boot/bootx64.efi";

let mut internal_files = BTreeMap::new();
internal_files.insert(UEFI_BOOT_FILENAME, FileDataSource::Bytes(UEFI_BOOTLOADER));
let fat_partition = self
.create_fat_filesystem_image(internal_files)
let fat_partition = NamedTempFile::new().context("failed to create temp file")?;
self.create_uefi_fat_partition(fat_partition.path())
.context("failed to create FAT partition")?;

gpt::create_gpt_disk(fat_partition.path(), image_path)
.context("failed to create UEFI GPT disk image")?;
fat_partition
Expand All @@ -152,6 +169,19 @@ impl DiskImageBuilder {
Ok(())
}

#[cfg(feature = "uefi")]
/// create a bootable fat-partition for a UEFI system.
pub fn create_uefi_fat_partition(&self, partition_path: &Path) -> anyhow::Result<()> {
const UEFI_BOOT_FILENAME: &str = "efi/boot/bootx64.efi";

let mut internal_files = BTreeMap::new();
internal_files.insert(UEFI_BOOT_FILENAME, FileDataSource::Bytes(UEFI_BOOTLOADER));
self.create_fat_filesystem_image(internal_files, partition_path)
.context("failed to create FAT partition")?;

Ok(())
}

#[cfg(feature = "uefi")]
/// Create a folder containing the needed files for UEFI TFTP/PXE booting.
pub fn create_uefi_tftp_folder(&self, tftp_path: &Path) -> anyhow::Result<()> {
Expand Down Expand Up @@ -198,7 +228,8 @@ impl DiskImageBuilder {
fn create_fat_filesystem_image(
&self,
internal_files: BTreeMap<&str, FileDataSource>,
) -> anyhow::Result<NamedTempFile> {
partition_path: &Path,
) -> anyhow::Result<()> {
let mut local_map: BTreeMap<&str, _> = BTreeMap::new();

for (name, source) in &self.files {
Expand All @@ -214,10 +245,9 @@ impl DiskImageBuilder {
}
}

let out_file = NamedTempFile::new().context("failed to create temp file")?;
fat::create_fat_filesystem(local_map, out_file.path())
fat::create_fat_filesystem(local_map, partition_path)
.context("failed to create FAT filesystem")?;

Ok(out_file)
Ok(())
}
}
Loading