Files
RedBear-OS/recipes/drivers/storage/partitionlib/src/partition.rs
T
vasilito b9874d0941 feat: USB storage read/write proof + full Red Bear OS tree sync
Add redbear-usb-storage-check in-guest binary that validates USB mass
storage read and write I/O: discovers /scheme/disk/ devices, writes a
test pattern to sector 2048, reads it back, verifies match, restores
original content. Updates test-usb-storage-qemu.sh with write-proof
verification step.

Includes all accumulated Red Bear OS work: kernel patches, relibc
patches, driver infrastructure, DRM/GPU, KDE recipes, firmware,
validation tooling, build system hardening, and documentation.
2026-05-03 23:03:24 +01:00

85 lines
2.6 KiB
Rust

pub use gpt::disk::LogicalBlockSize;
use std::io::{self, Read, Seek};
use uuid::Uuid;
/// A union of the MBR and GPT partition entry
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
pub struct Partition {
/// The starting logical block number
pub start_lba: u64,
/// The size of the partition in sectors
pub size: u64,
pub flags: Option<u64>,
pub name: Option<String>,
pub uuid: Option<Uuid>,
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum PartitionTableKind {
Mbr,
Gpt,
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct PartitionTable {
pub partitions: Vec<Partition>,
pub kind: PartitionTableKind,
}
fn get_gpt_partitions<D: Read + Seek>(
device: &mut D,
sector_size: LogicalBlockSize,
) -> io::Result<PartitionTable> {
let header = gpt::header::read_header_from_arbitrary_device(device, sector_size)?;
Ok(PartitionTable {
partitions: gpt::partition::file_read_partitions(device, &header, sector_size).map(
|btree| {
btree
.into_iter()
.map(|(_, part)| Partition {
flags: Some(part.flags),
size: part.last_lba - part.first_lba + 1,
name: Some(part.name.clone()),
uuid: Some(part.part_guid),
start_lba: part.first_lba,
})
.collect()
},
)?,
kind: PartitionTableKind::Gpt,
})
}
fn get_mbr_partitions<D: Read + Seek>(device: &mut D) -> io::Result<Option<PartitionTable>> {
let Some(header) = crate::mbr::read_header(device)? else {
return Ok(None);
};
Ok(Some(PartitionTable {
kind: PartitionTableKind::Mbr,
partitions: header
.partitions()
.map(|partition: crate::mbr::Entry| Partition {
name: None,
uuid: None, // TODO: Some kind of one-way conversion should be possible
flags: None, // TODO
size: partition.len.into(),
start_lba: partition.rel_sector.into(),
})
.collect(),
}))
}
pub fn get_partitions<D: Read + Seek>(
device: &mut D,
sector_size: LogicalBlockSize,
) -> io::Result<Option<PartitionTable>> {
get_gpt_partitions(device, sector_size)
.map(Some)
.or_else(|_| get_mbr_partitions(device))
}
impl Partition {
pub fn to_offset(&self, sector_size: LogicalBlockSize) -> u64 {
let blksize: u64 = sector_size.into();
self.start_lba * blksize
}
}