Files
start-os/backend/src/os_install/mbr.rs
Aiden McClelland c7d82102ed Bugfix/gpt reflash (#2266)
* debug entry

* update magic numbers

* remove dbg

* fix hostname

* fix reinstall logic
2023-05-11 14:16:19 -06:00

89 lines
3.0 KiB
Rust

use color_eyre::eyre::eyre;
use mbrman::{MBRPartitionEntry, CHS, MBR};
use crate::disk::util::DiskInfo;
use crate::disk::OsPartitionInfo;
use crate::os_install::partition_for;
use crate::Error;
pub async fn partition(disk: &DiskInfo, overwrite: bool) -> Result<OsPartitionInfo, Error> {
{
let sectors = (disk.capacity / 512) as u32;
let disk = disk.clone();
tokio::task::spawn_blocking(move || {
let mut file = std::fs::File::options()
.read(true)
.write(true)
.open(&disk.logicalname)?;
let (mut mbr, guid_part) = if overwrite {
(MBR::new_from(&mut file, 512, rand::random())?, None)
} else {
let mut mbr = MBR::read_from(&mut file, 512)?;
let mut guid_part = None;
for (idx, part_info) in disk
.partitions
.iter()
.enumerate()
.map(|(idx, x)| (idx + 1, x))
{
if let Some(entry) = mbr.get_mut(idx) {
if part_info.guid.is_some() {
if entry.starting_lba < 33556480 {
return Err(Error::new(
eyre!("Not enough space before embassy data"),
crate::ErrorKind::InvalidRequest,
));
}
guid_part = Some(std::mem::replace(entry, MBRPartitionEntry::empty()));
}
*entry = MBRPartitionEntry::empty();
}
}
(mbr, guid_part)
};
mbr[1] = MBRPartitionEntry {
boot: 0x80,
first_chs: CHS::empty(),
sys: 0x0b,
last_chs: CHS::empty(),
starting_lba: 2048,
sectors: 2099200 - 2048,
};
mbr[2] = MBRPartitionEntry {
boot: 0,
first_chs: CHS::empty(),
sys: 0x83,
last_chs: CHS::empty(),
starting_lba: 2099200,
sectors: 33556480 - 2099200,
};
if overwrite {
mbr[3] = MBRPartitionEntry {
boot: 0,
first_chs: CHS::empty(),
sys: 0x8e,
last_chs: CHS::empty(),
starting_lba: 33556480,
sectors: sectors - 33556480,
}
} else if let Some(guid_part) = guid_part {
mbr[3] = guid_part;
}
mbr.write_into(&mut file)?;
Ok(())
})
.await
.unwrap()?;
}
Ok(OsPartitionInfo {
efi: None,
bios: None,
boot: partition_for(&disk.logicalname, 1),
root: partition_for(&disk.logicalname, 2),
})
}