Merge branch 'partitionlib_improvements' into 'master'

Vendor and cleanup partitionlib

See merge request redox-os/drivers!247
This commit is contained in:
Jeremy Soller
2025-03-07 01:51:31 +00:00
12 changed files with 206 additions and 4 deletions
Generated
-1
View File
@@ -937,7 +937,6 @@ dependencies = [
[[package]]
name = "partitionlib"
version = "0.1.0"
source = "git+https://gitlab.redox-os.org/redox-os/partitionlib.git#9e48718a0553a4d0d4070994053e1c402bb33b91"
dependencies = [
"gpt",
"scroll",
+1 -1
View File
@@ -4,6 +4,6 @@ version = "0.1.0"
edition = "2021"
[dependencies]
partitionlib = { git = "https://gitlab.redox-os.org/redox-os/partitionlib.git" }
partitionlib = { path = "../partitionlib" }
redox_syscall = "0.5"
+1 -1
View File
@@ -13,7 +13,7 @@ redox-daemon = "0.1"
redox_syscall = { version = "0.5", features = ["std"] }
redox-scheme = { git = "https://gitlab.redox-os.org/redox-os/redox-scheme.git" }
redox_event = "0.4"
partitionlib = { git = "https://gitlab.redox-os.org/redox-os/partitionlib.git" }
partitionlib = { path = "../partitionlib" }
smallvec = "1"
common = { path = "../../common" }
+11
View File
@@ -0,0 +1,11 @@
[package]
name = "partitionlib"
version = "0.1.0"
authors = ["Deepak Sirone <deepaksirone94@gmail.com>"]
edition = "2021"
license = "MIT"
[dependencies]
gpt = { version = "3.0.1" }
scroll = { version = "0.10", features = ["derive"] }
uuid = { version = "1.0", features = ["v4"] }
Binary file not shown.
Binary file not shown.
+3
View File
@@ -0,0 +1,3 @@
mod mbr;
mod partition;
pub use self::partition::*;
+57
View File
@@ -0,0 +1,57 @@
use scroll::{Pread, Pwrite};
use std::io::{self, Read, Seek};
#[derive(Clone, Copy, Debug, Pread, Pwrite)]
pub(crate) struct Entry {
pub(crate) drive_attrs: u8,
pub(crate) start_head: u8,
pub(crate) start_cs: u16,
pub(crate) sys_id: u8,
pub(crate) end_head: u8,
pub(crate) end_cs: u16,
pub(crate) rel_sector: u32,
pub(crate) len: u32,
}
#[derive(Pread, Pwrite)]
pub(crate) struct Header {
pub(crate) bootstrap: [u8; 446],
pub(crate) first_entry: Entry,
pub(crate) second_entry: Entry,
pub(crate) third_entry: Entry,
pub(crate) fourth_entry: Entry,
pub(crate) last_signature: u16, // 0xAA55
}
pub(crate) fn read_header<D: Read + Seek>(device: &mut D) -> io::Result<Option<Header>> {
device.seek(io::SeekFrom::Start(0))?;
let mut bytes = [0u8; 512];
device.read_exact(&mut bytes)?;
let header: Header = bytes.pread_with(0, scroll::LE).unwrap();
if header.last_signature != 0xAA55 {
return Ok(None);
}
Ok(Some(header))
}
impl Header {
pub(crate) fn partitions(&self) -> impl Iterator<Item = Entry> {
[
self.first_entry,
self.second_entry,
self.third_entry,
self.fourth_entry,
]
.into_iter()
.filter(Entry::is_valid)
}
}
impl Entry {
fn is_valid(&self) -> bool {
(self.drive_attrs == 0 || self.drive_attrs == 0x80) && self.len != 0
}
}
+84
View File
@@ -0,0 +1,84 @@
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
}
}
+45
View File
@@ -0,0 +1,45 @@
use std::fs::File;
use partitionlib::{
get_partitions, LogicalBlockSize, Partition, PartitionTable, PartitionTableKind,
};
fn get_partitions_from_file(path: &str) -> PartitionTable {
let mut file = File::open(path).unwrap();
get_partitions(&mut file, LogicalBlockSize::Lb512)
.unwrap()
.unwrap()
}
// NOTE: The following tests rely on outside resource files being correct.
#[test]
fn gpt() {
let table = get_partitions_from_file("./resources/disk.img");
assert_eq!(table.kind, PartitionTableKind::Gpt);
assert_eq!(
&table.partitions,
&[Partition {
flags: Some(0),
name: Some("bug".to_owned()),
uuid: Some(uuid::Uuid::parse_str("b665fba9-74d5-4069-a6b9-5ba3a164fdfe").unwrap()), // Microsoft basic data
size: 957,
start_lba: 34,
}]
);
}
#[test]
fn mbr() {
let table = get_partitions_from_file("./resources/disk_mbr.img");
assert_eq!(table.kind, PartitionTableKind::Mbr);
assert_eq!(
&table.partitions,
&[Partition {
flags: None,
name: None,
uuid: None,
size: 3,
start_lba: 1,
}]
);
}
+1 -1
View File
@@ -15,7 +15,7 @@ spin = "*"
redox-daemon = "0.1"
redox_syscall = { version = "0.5", features = ["std"] }
redox-scheme = { git = "https://gitlab.redox-os.org/redox-os/redox-scheme.git" }
partitionlib = { git = "https://gitlab.redox-os.org/redox-os/partitionlib.git" }
partitionlib = { path = "../partitionlib" }
common = { path = "../../common" }
driver-block = { path = "../driver-block" }
+3
View File
@@ -191,6 +191,9 @@ impl<'a> DiskScheme<'a> {
block_bytes: &mut [0u8; 4096],
};
//driver_block::DiskWrapper::new(disk)
// FIXME use DiskWrapper instead
let part_table = partitionlib::get_partitions(&mut shim, LogicalBlockSize::Lb512)
.ok()
.flatten();