diff --git a/Cargo.lock b/Cargo.lock index 79923916..c86f3e3e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -14,6 +14,12 @@ version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" +[[package]] +name = "build_const" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39092a32794787acd8525ee150305ff051b0aa6cc2abaf193924f5ab05425f39" + [[package]] name = "byteorder" version = "1.4.2" @@ -39,11 +45,21 @@ dependencies = [ "winapi", ] +[[package]] +name = "crc" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d663548de7f5cca343f1e0a48d14dcfb0e9eb4e079ec58883b7251539fa10aeb" +dependencies = [ + "build_const", +] + [[package]] name = "disk_image" version = "0.1.0" dependencies = [ "fatfs", + "gpt", ] [[package]] @@ -58,6 +74,29 @@ dependencies = [ "log", ] +[[package]] +name = "getrandom" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9495705279e7140bf035dde1f6e750c162df8b625267cd52cc44e0b156732c8" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "gpt" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a30b0e3659ffee31427c4aaa68c1e5115c8c86ba71ff11da5a16e5b70f3471d" +dependencies = [ + "bitflags", + "crc", + "log", + "uuid", +] + [[package]] name = "libc" version = "0.2.86" @@ -107,6 +146,15 @@ dependencies = [ name = "uefi_app" version = "0.1.0" +[[package]] +name = "uuid" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7" +dependencies = [ + "getrandom", +] + [[package]] name = "wasi" version = "0.10.0+wasi-snapshot-preview1" diff --git a/disk_image/Cargo.toml b/disk_image/Cargo.toml index c1380d61..d6ad2e4f 100644 --- a/disk_image/Cargo.toml +++ b/disk_image/Cargo.toml @@ -8,3 +8,4 @@ edition = "2018" [dependencies] fatfs = "0.3.5" +gpt = "2.0.0" diff --git a/disk_image/src/main.rs b/disk_image/src/main.rs index ae4097cd..9e6928f8 100644 --- a/disk_image/src/main.rs +++ b/disk_image/src/main.rs @@ -1,4 +1,9 @@ -use std::{fs, io, path::Path}; +use std::{ + convert::TryFrom, + fs::{self, File}, + io::{self, Seek}, + path::Path, +}; fn main() { println!("Hello, world!"); @@ -34,3 +39,50 @@ fn create_fat_filesystem(fat_path: &Path, efi_file: &Path) { bootx64.truncate().unwrap(); io::copy(&mut fs::File::open(&efi_file).unwrap(), &mut bootx64).unwrap(); } + +fn create_gpt_disk(disk_path: &Path, fat_image: &Path) { + // create new file + let mut disk = fs::OpenOptions::new() + .create(true) + .truncate(true) + .read(true) + .write(true) + .open(&disk_path) + .unwrap(); + + // set file size + let partition_size: u64 = fs::metadata(&fat_image).unwrap().len(); + let disk_size = partition_size + 1024 * 64; // for GPT headers + disk.set_len(disk_size).unwrap(); + + // create a protective MBR at LBA0 so that disk is not considered + // unformatted on BIOS systems + let mbr = gpt::mbr::ProtectiveMBR::with_lb_size( + u32::try_from((disk_size / 512) - 1).unwrap_or(0xFF_FF_FF_FF), + ); + mbr.overwrite_lba0(&mut disk).unwrap(); + + // create new GPT structure + let block_size = gpt::disk::LogicalBlockSize::Lb512; + let mut gpt = gpt::GptConfig::new() + .writable(true) + .initialized(false) + .logical_block_size(block_size) + .create_from_device(Box::new(&mut disk), None) + .unwrap(); + gpt.update_partitions(Default::default()).unwrap(); + + // add new EFI system partition and get its byte offset in the file + let partition_id = gpt + .add_partition("boot", partition_size, gpt::partition_types::EFI, 0) + .unwrap(); + let partition = gpt.partitions().get(&partition_id).unwrap(); + let start_offset = partition.bytes_start(block_size).unwrap(); + + // close the GPT structure and write out changes + gpt.write().unwrap(); + + // place the FAT filesystem in the newly created partition + disk.seek(io::SeekFrom::Start(start_offset)).unwrap(); + io::copy(&mut File::open(&fat_image).unwrap(), &mut disk).unwrap(); +}