Skip to content

Commit 3812a86

Browse files
committed
Refactor GPT creation and move it to separate module
1 parent d8b50dc commit 3812a86

File tree

2 files changed

+73
-47
lines changed

2 files changed

+73
-47
lines changed

src/gpt.rs

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
use anyhow::Context;
2+
use std::{
3+
fs::{self, File},
4+
io::{self, Seek},
5+
path::Path,
6+
};
7+
8+
pub fn create_gpt_disk(fat_image: &Path, out_gpt_path: &Path) -> anyhow::Result<()> {
9+
// create new file
10+
let mut disk = fs::OpenOptions::new()
11+
.create(true)
12+
.truncate(true)
13+
.read(true)
14+
.write(true)
15+
.open(&out_gpt_path)
16+
.with_context(|| format!("failed to create GPT file at `{}`", out_gpt_path.display()))?;
17+
18+
// set file size
19+
let partition_size: u64 = fs::metadata(&fat_image)
20+
.context("failed to read metadata of fat image")?
21+
.len();
22+
let disk_size = partition_size + 1024 * 64; // for GPT headers
23+
disk.set_len(disk_size)
24+
.context("failed to set GPT image file length")?;
25+
26+
// create a protective MBR at LBA0 so that disk is not considered
27+
// unformatted on BIOS systems
28+
let mbr = gpt::mbr::ProtectiveMBR::with_lb_size(
29+
u32::try_from((disk_size / 512) - 1).unwrap_or(0xFF_FF_FF_FF),
30+
);
31+
mbr.overwrite_lba0(&mut disk)
32+
.context("failed to write protective MBR")?;
33+
34+
// create new GPT structure
35+
let block_size = gpt::disk::LogicalBlockSize::Lb512;
36+
let mut gpt = gpt::GptConfig::new()
37+
.writable(true)
38+
.initialized(false)
39+
.logical_block_size(block_size)
40+
.create_from_device(Box::new(&mut disk), None)
41+
.context("failed to create GPT structure in file")?;
42+
gpt.update_partitions(Default::default())
43+
.context("failed to update GPT partitions")?;
44+
45+
// add new EFI system partition and get its byte offset in the file
46+
let partition_id = gpt
47+
.add_partition("boot", partition_size, gpt::partition_types::EFI, 0, None)
48+
.context("failed to add boot EFI partition")?;
49+
let partition = gpt
50+
.partitions()
51+
.get(&partition_id)
52+
.context("failed to open boot partition after creation")?;
53+
let start_offset = partition
54+
.bytes_start(block_size)
55+
.context("failed to get start offset of boot partition")?;
56+
57+
// close the GPT structure and write out changes
58+
gpt.write().context("failed to write out GPT changes")?;
59+
60+
// place the FAT filesystem in the newly created partition
61+
disk.seek(io::SeekFrom::Start(start_offset))
62+
.context("failed to seek to start offset")?;
63+
io::copy(
64+
&mut File::open(&fat_image).context("failed to open FAT image")?,
65+
&mut disk,
66+
)
67+
.context("failed to copy FAT image to GPT disk")?;
68+
69+
Ok(())
70+
}

src/lib.rs

Lines changed: 3 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ use std::{
7676
};
7777

7878
mod fat;
79+
mod gpt;
7980

8081
const KERNEL_FILE_NAME: &str = "kernel-x86_64";
8182

@@ -92,54 +93,9 @@ pub fn create_uefi_disk_image(
9293

9394
fat::create_fat_filesystem(files, &out_fat_path)
9495
.context("failed to create UEFI FAT filesystem")?;
95-
create_gpt_disk(out_fat_path, out_gpt_path);
96+
gpt::create_gpt_disk(out_fat_path, out_gpt_path)
97+
.context("failed to create UEFI GPT disk image")?;
9698

9799
Ok(())
98100
}
99101

100-
fn create_gpt_disk(fat_image: &Path, out_gpt_path: &Path) {
101-
// create new file
102-
let mut disk = fs::OpenOptions::new()
103-
.create(true)
104-
.truncate(true)
105-
.read(true)
106-
.write(true)
107-
.open(&out_gpt_path)
108-
.unwrap();
109-
110-
// set file size
111-
let partition_size: u64 = fs::metadata(&fat_image).unwrap().len();
112-
let disk_size = partition_size + 1024 * 64; // for GPT headers
113-
disk.set_len(disk_size).unwrap();
114-
115-
// create a protective MBR at LBA0 so that disk is not considered
116-
// unformatted on BIOS systems
117-
let mbr = gpt::mbr::ProtectiveMBR::with_lb_size(
118-
u32::try_from((disk_size / 512) - 1).unwrap_or(0xFF_FF_FF_FF),
119-
);
120-
mbr.overwrite_lba0(&mut disk).unwrap();
121-
122-
// create new GPT structure
123-
let block_size = gpt::disk::LogicalBlockSize::Lb512;
124-
let mut gpt = gpt::GptConfig::new()
125-
.writable(true)
126-
.initialized(false)
127-
.logical_block_size(block_size)
128-
.create_from_device(Box::new(&mut disk), None)
129-
.unwrap();
130-
gpt.update_partitions(Default::default()).unwrap();
131-
132-
// add new EFI system partition and get its byte offset in the file
133-
let partition_id = gpt
134-
.add_partition("boot", partition_size, gpt::partition_types::EFI, 0, None)
135-
.unwrap();
136-
let partition = gpt.partitions().get(&partition_id).unwrap();
137-
let start_offset = partition.bytes_start(block_size).unwrap();
138-
139-
// close the GPT structure and write out changes
140-
gpt.write().unwrap();
141-
142-
// place the FAT filesystem in the newly created partition
143-
disk.seek(io::SeekFrom::Start(start_offset)).unwrap();
144-
io::copy(&mut File::open(&fat_image).unwrap(), &mut disk).unwrap();
145-
}

0 commit comments

Comments
 (0)