diff --git a/src/lib.rs b/src/lib.rs index db5f32e3..b78c50cf 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -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. /// @@ -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, @@ -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 @@ -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<()> { @@ -198,7 +228,8 @@ impl DiskImageBuilder { fn create_fat_filesystem_image( &self, internal_files: BTreeMap<&str, FileDataSource>, - ) -> anyhow::Result { + partition_path: &Path, + ) -> anyhow::Result<()> { let mut local_map: BTreeMap<&str, _> = BTreeMap::new(); for (name, source) in &self.files { @@ -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(()) } }