1731bc2b3SLoGin use core::{default::Default, mem::size_of}; 2731bc2b3SLoGin 3731bc2b3SLoGin use alloc::{ 4731bc2b3SLoGin sync::{Arc, Weak}, 5731bc2b3SLoGin vec::Vec, 6731bc2b3SLoGin }; 72eab6dd7S曾俊 use log::debug; 8731bc2b3SLoGin use system_error::SystemError; 9731bc2b3SLoGin 10731bc2b3SLoGin use crate::{ 11731bc2b3SLoGin driver::base::block::{block_device::BlockDevice, disk_info::Partition, SeekFrom}, 12731bc2b3SLoGin libs::vec_cursor::VecCursor, 13731bc2b3SLoGin }; 14004e86ffSlogin 15004e86ffSlogin /// @brief MBR硬盘分区表项的结构 16004e86ffSlogin #[repr(packed)] 17b5b571e0SLoGin #[derive(Debug, Clone, Copy, Default)] 18004e86ffSlogin pub struct MbrDiskPartitionTableEntry { 19004e86ffSlogin pub flags: u8, // 引导标志符,标记此分区为活动分区 20004e86ffSlogin pub starting_head: u8, // 起始磁头号 21004e86ffSlogin pub starting_sector_cylinder: u16, // sector : 低6, cylinder : 高10; 起始扇区号 + 起始柱面号 22004e86ffSlogin pub part_type: u8, // 分区类型ID 23004e86ffSlogin pub ending_head: u8, // 结束磁头号 24731bc2b3SLoGin pub ending_sector_cylinder: u16, // ending_sector : 低6, ending_cylinder : 高10; 结束扇区号 + 结束柱面号 25004e86ffSlogin pub starting_lba: u32, // 起始逻辑扇区 26004e86ffSlogin pub total_sectors: u32, // 分区占用的磁盘扇区数 27004e86ffSlogin } 28004e86ffSlogin 29004e86ffSlogin impl MbrDiskPartitionTableEntry { starting_sector(&self) -> u3230731bc2b3SLoGin pub fn starting_sector(&self) -> u32 { 31731bc2b3SLoGin return (self.starting_sector_cylinder & ((1 << 6) - 1)).into(); 32004e86ffSlogin } starting_cylinder(&self) -> u1633004e86ffSlogin pub fn starting_cylinder(&self) -> u16 { 34004e86ffSlogin return (self.starting_sector_cylinder >> 6) & ((1 << 10) - 1) as u16; 35004e86ffSlogin } ending_sector(&self) -> u3236731bc2b3SLoGin pub fn ending_sector(&self) -> u32 { 37731bc2b3SLoGin self.starting_sector() + self.total_sectors - 1 38004e86ffSlogin } 39731bc2b3SLoGin ending_cylinder(&self) -> u1640004e86ffSlogin pub fn ending_cylinder(&self) -> u16 { 41731bc2b3SLoGin return (self.ending_sector_cylinder >> 6) & ((1 << 10) - 1) as u16; 42731bc2b3SLoGin } 43731bc2b3SLoGin is_valid(&self) -> bool44731bc2b3SLoGin pub fn is_valid(&self) -> bool { 45731bc2b3SLoGin // 其他更多的可能判断条件 46731bc2b3SLoGin self.starting_sector() <= self.ending_sector() 47731bc2b3SLoGin && self.starting_cylinder() <= self.ending_cylinder() 48731bc2b3SLoGin && self.starting_lba != 0 49731bc2b3SLoGin && self.total_sectors != 0 50731bc2b3SLoGin && self.part_type != 0 51004e86ffSlogin } 52004e86ffSlogin } 53004e86ffSlogin 54004e86ffSlogin /// @brief MBR磁盘分区表结构体 55004e86ffSlogin #[repr(packed)] 56004e86ffSlogin #[derive(Debug, Clone, Copy)] 57004e86ffSlogin pub struct MbrDiskPartionTable { 58bd70d2d1SLoGin pub _reserved: [u8; 446], 59004e86ffSlogin pub dpte: [MbrDiskPartitionTableEntry; 4], // 磁盘分区表项 60004e86ffSlogin pub bs_trailsig: u16, 61004e86ffSlogin } 62004e86ffSlogin 63004e86ffSlogin impl Default for MbrDiskPartionTable { default() -> Self64004e86ffSlogin fn default() -> Self { 65004e86ffSlogin MbrDiskPartionTable { 66bd70d2d1SLoGin _reserved: [0; 446], 67004e86ffSlogin dpte: [Default::default(); 4], 68004e86ffSlogin bs_trailsig: Default::default(), 69004e86ffSlogin } 70004e86ffSlogin } 71004e86ffSlogin } 72731bc2b3SLoGin 73731bc2b3SLoGin impl MbrDiskPartionTable { 74731bc2b3SLoGin /// # 从磁盘读取MBR分区表 - 从磁盘设备中读取并解析MBR分区表 75731bc2b3SLoGin /// 76731bc2b3SLoGin /// 这个函数从提供的磁盘设备中读取MBR分区表,并将其解析为一个`MbrDiskPartionTable`实例。 77731bc2b3SLoGin /// 78731bc2b3SLoGin /// ## 参数 79731bc2b3SLoGin /// 80731bc2b3SLoGin /// - `disk`: Arc<dyn BlockDevice> - 一个磁盘设备的共享引用,用于从磁盘读取数据。 81731bc2b3SLoGin /// 82731bc2b3SLoGin /// ## 返回值 83731bc2b3SLoGin /// 84731bc2b3SLoGin /// - `Ok(MbrDiskPartionTable)`: 成功解析的分区表实例。 85731bc2b3SLoGin /// - `Err(SystemError)`: 读取磁盘失败或其他系统错误。 from_disk(disk: Arc<dyn BlockDevice>) -> Result<MbrDiskPartionTable, SystemError>86731bc2b3SLoGin pub fn from_disk(disk: Arc<dyn BlockDevice>) -> Result<MbrDiskPartionTable, SystemError> { 87731bc2b3SLoGin let mut table: MbrDiskPartionTable = Default::default(); 88731bc2b3SLoGin 89731bc2b3SLoGin // 数据缓冲区 90731bc2b3SLoGin let mut buf: Vec<u8> = vec![0; size_of::<MbrDiskPartionTable>()]; 91731bc2b3SLoGin buf.resize(size_of::<MbrDiskPartionTable>(), 0); 92731bc2b3SLoGin 93731bc2b3SLoGin disk.read_at_sync(0, 1, &mut buf)?; 94731bc2b3SLoGin 95731bc2b3SLoGin // 创建 Cursor 用于按字节读取 96731bc2b3SLoGin let mut cursor = VecCursor::new(buf); 97731bc2b3SLoGin cursor.seek(SeekFrom::SeekCurrent(446))?; 98731bc2b3SLoGin 99731bc2b3SLoGin for i in 0..4 { 100731bc2b3SLoGin table.dpte[i].flags = cursor.read_u8()?; 101731bc2b3SLoGin table.dpte[i].starting_head = cursor.read_u8()?; 102731bc2b3SLoGin table.dpte[i].starting_sector_cylinder = cursor.read_u16()?; 103731bc2b3SLoGin table.dpte[i].part_type = cursor.read_u8()?; 104731bc2b3SLoGin table.dpte[i].ending_head = cursor.read_u8()?; 105731bc2b3SLoGin table.dpte[i].ending_sector_cylinder = cursor.read_u16()?; 106731bc2b3SLoGin table.dpte[i].starting_lba = cursor.read_u32()?; 107731bc2b3SLoGin table.dpte[i].total_sectors = cursor.read_u32()?; 108731bc2b3SLoGin 1092eab6dd7S曾俊 debug!("dpte[{i}] = {:?}", table.dpte[i]); 110731bc2b3SLoGin } 111731bc2b3SLoGin table.bs_trailsig = cursor.read_u16()?; 1122eab6dd7S曾俊 // debug!("bs_trailsig = {}", unsafe { 113731bc2b3SLoGin // read_unaligned(addr_of!(table.bs_trailsig)) 114731bc2b3SLoGin // }); 115731bc2b3SLoGin 116731bc2b3SLoGin if !table.is_valid() { 117731bc2b3SLoGin return Err(SystemError::EINVAL); 118731bc2b3SLoGin } 119731bc2b3SLoGin 120731bc2b3SLoGin return Ok(table); 121731bc2b3SLoGin } 122731bc2b3SLoGin 123731bc2b3SLoGin /// # partitions - 获取磁盘的分区信息 124731bc2b3SLoGin /// 125731bc2b3SLoGin /// 该函数用于获取指定磁盘的分区信息,并将这些分区信息以分区对象的向量形式返回。分区对象包含了分区的类型、起始扇区和总扇区数等信息。 126731bc2b3SLoGin /// 127731bc2b3SLoGin /// ## 参数 128731bc2b3SLoGin /// 129731bc2b3SLoGin /// - `disk`: Weak<dyn BlockDevice>: 一个对磁盘设备的弱引用。这个磁盘设备必须实现`BlockDevice` trait。 130731bc2b3SLoGin /// 131731bc2b3SLoGin /// ## 返回值 132731bc2b3SLoGin /// 133731bc2b3SLoGin /// 返回一个包含分区信息的`Vec`。每个分区都是一个`Arc<Partition>`,它表示分区的一个强引用。 134731bc2b3SLoGin /// partitions(&self, disk: Weak<dyn BlockDevice>) -> Vec<Arc<Partition>>135731bc2b3SLoGin pub fn partitions(&self, disk: Weak<dyn BlockDevice>) -> Vec<Arc<Partition>> { 136731bc2b3SLoGin let mut partitions: Vec<Arc<Partition>> = Vec::new(); 137731bc2b3SLoGin for i in 0..4 { 138731bc2b3SLoGin if self.dpte[i].is_valid() { 139731bc2b3SLoGin partitions.push(Partition::new( 140731bc2b3SLoGin self.dpte[i].starting_sector() as u64, 141731bc2b3SLoGin self.dpte[i].starting_lba as u64, 142731bc2b3SLoGin self.dpte[i].total_sectors as u64, 143731bc2b3SLoGin disk.clone(), 144731bc2b3SLoGin i as u16, 145731bc2b3SLoGin )); 146731bc2b3SLoGin } 147731bc2b3SLoGin } 148731bc2b3SLoGin return partitions; 149731bc2b3SLoGin } 150731bc2b3SLoGin 151*9fa0e95eSLoGin /// # partitions_raw - 获取磁盘的分区信息,不包含磁盘设备信息 partitions_raw(&self) -> MbrPartitionIter152*9fa0e95eSLoGin pub fn partitions_raw(&self) -> MbrPartitionIter { 153*9fa0e95eSLoGin MbrPartitionIter::new(self) 154*9fa0e95eSLoGin } 155*9fa0e95eSLoGin is_valid(&self) -> bool156731bc2b3SLoGin pub fn is_valid(&self) -> bool { 157731bc2b3SLoGin self.bs_trailsig == 0xAA55 158731bc2b3SLoGin } 159731bc2b3SLoGin } 160*9fa0e95eSLoGin 161*9fa0e95eSLoGin pub struct MbrPartitionIter<'a> { 162*9fa0e95eSLoGin table: &'a MbrDiskPartionTable, 163*9fa0e95eSLoGin index: usize, 164*9fa0e95eSLoGin } 165*9fa0e95eSLoGin 166*9fa0e95eSLoGin impl<'a> MbrPartitionIter<'a> { new(table: &'a MbrDiskPartionTable) -> Self167*9fa0e95eSLoGin fn new(table: &'a MbrDiskPartionTable) -> Self { 168*9fa0e95eSLoGin MbrPartitionIter { table, index: 0 } 169*9fa0e95eSLoGin } 170*9fa0e95eSLoGin } 171*9fa0e95eSLoGin 172*9fa0e95eSLoGin impl<'a> Iterator for MbrPartitionIter<'a> { 173*9fa0e95eSLoGin type Item = Partition; 174*9fa0e95eSLoGin next(&mut self) -> Option<Self::Item>175*9fa0e95eSLoGin fn next(&mut self) -> Option<Self::Item> { 176*9fa0e95eSLoGin while self.index < 4 { 177*9fa0e95eSLoGin let entry = &self.table.dpte[self.index]; 178*9fa0e95eSLoGin let index = self.index; 179*9fa0e95eSLoGin self.index += 1; 180*9fa0e95eSLoGin if entry.is_valid() { 181*9fa0e95eSLoGin let p = Partition::new_raw( 182*9fa0e95eSLoGin self.table.dpte[index].starting_sector() as u64, 183*9fa0e95eSLoGin self.table.dpte[index].starting_lba as u64, 184*9fa0e95eSLoGin self.table.dpte[index].total_sectors as u64, 185*9fa0e95eSLoGin index as u16, 186*9fa0e95eSLoGin ); 187*9fa0e95eSLoGin return Some(p); 188*9fa0e95eSLoGin } 189*9fa0e95eSLoGin } 190*9fa0e95eSLoGin return None; 191*9fa0e95eSLoGin } 192*9fa0e95eSLoGin } 193