1*731bc2b3SLoGin use core::{default::Default, mem::size_of}; 2*731bc2b3SLoGin 3*731bc2b3SLoGin use alloc::{ 4*731bc2b3SLoGin sync::{Arc, Weak}, 5*731bc2b3SLoGin vec::Vec, 6*731bc2b3SLoGin }; 7*731bc2b3SLoGin use system_error::SystemError; 8*731bc2b3SLoGin 9*731bc2b3SLoGin use crate::{ 10*731bc2b3SLoGin driver::base::block::{block_device::BlockDevice, disk_info::Partition, SeekFrom}, 11*731bc2b3SLoGin libs::vec_cursor::VecCursor, 12*731bc2b3SLoGin }; 13004e86ffSlogin 14004e86ffSlogin /// @brief MBR硬盘分区表项的结构 15004e86ffSlogin #[repr(packed)] 16b5b571e0SLoGin #[derive(Debug, Clone, Copy, Default)] 17004e86ffSlogin pub struct MbrDiskPartitionTableEntry { 18004e86ffSlogin pub flags: u8, // 引导标志符,标记此分区为活动分区 19004e86ffSlogin pub starting_head: u8, // 起始磁头号 20004e86ffSlogin pub starting_sector_cylinder: u16, // sector : 低6, cylinder : 高10; 起始扇区号 + 起始柱面号 21004e86ffSlogin pub part_type: u8, // 分区类型ID 22004e86ffSlogin pub ending_head: u8, // 结束磁头号 23*731bc2b3SLoGin pub ending_sector_cylinder: u16, // ending_sector : 低6, ending_cylinder : 高10; 结束扇区号 + 结束柱面号 24004e86ffSlogin pub starting_lba: u32, // 起始逻辑扇区 25004e86ffSlogin pub total_sectors: u32, // 分区占用的磁盘扇区数 26004e86ffSlogin } 27004e86ffSlogin 28004e86ffSlogin impl MbrDiskPartitionTableEntry { 29*731bc2b3SLoGin pub fn starting_sector(&self) -> u32 { 30*731bc2b3SLoGin return (self.starting_sector_cylinder & ((1 << 6) - 1)).into(); 31004e86ffSlogin } 32004e86ffSlogin pub fn starting_cylinder(&self) -> u16 { 33004e86ffSlogin return (self.starting_sector_cylinder >> 6) & ((1 << 10) - 1) as u16; 34004e86ffSlogin } 35*731bc2b3SLoGin pub fn ending_sector(&self) -> u32 { 36*731bc2b3SLoGin self.starting_sector() + self.total_sectors - 1 37004e86ffSlogin } 38*731bc2b3SLoGin 39004e86ffSlogin pub fn ending_cylinder(&self) -> u16 { 40*731bc2b3SLoGin return (self.ending_sector_cylinder >> 6) & ((1 << 10) - 1) as u16; 41*731bc2b3SLoGin } 42*731bc2b3SLoGin 43*731bc2b3SLoGin pub fn is_valid(&self) -> bool { 44*731bc2b3SLoGin // 其他更多的可能判断条件 45*731bc2b3SLoGin self.starting_sector() <= self.ending_sector() 46*731bc2b3SLoGin && self.starting_cylinder() <= self.ending_cylinder() 47*731bc2b3SLoGin && self.starting_lba != 0 48*731bc2b3SLoGin && self.total_sectors != 0 49*731bc2b3SLoGin && self.part_type != 0 50004e86ffSlogin } 51004e86ffSlogin } 52004e86ffSlogin 53004e86ffSlogin /// @brief MBR磁盘分区表结构体 54004e86ffSlogin #[repr(packed)] 55004e86ffSlogin #[derive(Debug, Clone, Copy)] 56004e86ffSlogin pub struct MbrDiskPartionTable { 57004e86ffSlogin pub reserved: [u8; 446], 58004e86ffSlogin pub dpte: [MbrDiskPartitionTableEntry; 4], // 磁盘分区表项 59004e86ffSlogin pub bs_trailsig: u16, 60004e86ffSlogin } 61004e86ffSlogin 62004e86ffSlogin impl Default for MbrDiskPartionTable { 63004e86ffSlogin fn default() -> Self { 64004e86ffSlogin MbrDiskPartionTable { 65004e86ffSlogin reserved: [0; 446], 66004e86ffSlogin dpte: [Default::default(); 4], 67004e86ffSlogin bs_trailsig: Default::default(), 68004e86ffSlogin } 69004e86ffSlogin } 70004e86ffSlogin } 71*731bc2b3SLoGin 72*731bc2b3SLoGin impl MbrDiskPartionTable { 73*731bc2b3SLoGin /// # 从磁盘读取MBR分区表 - 从磁盘设备中读取并解析MBR分区表 74*731bc2b3SLoGin /// 75*731bc2b3SLoGin /// 这个函数从提供的磁盘设备中读取MBR分区表,并将其解析为一个`MbrDiskPartionTable`实例。 76*731bc2b3SLoGin /// 77*731bc2b3SLoGin /// ## 参数 78*731bc2b3SLoGin /// 79*731bc2b3SLoGin /// - `disk`: Arc<dyn BlockDevice> - 一个磁盘设备的共享引用,用于从磁盘读取数据。 80*731bc2b3SLoGin /// 81*731bc2b3SLoGin /// ## 返回值 82*731bc2b3SLoGin /// 83*731bc2b3SLoGin /// - `Ok(MbrDiskPartionTable)`: 成功解析的分区表实例。 84*731bc2b3SLoGin /// - `Err(SystemError)`: 读取磁盘失败或其他系统错误。 85*731bc2b3SLoGin pub fn from_disk(disk: Arc<dyn BlockDevice>) -> Result<MbrDiskPartionTable, SystemError> { 86*731bc2b3SLoGin let mut table: MbrDiskPartionTable = Default::default(); 87*731bc2b3SLoGin 88*731bc2b3SLoGin // 数据缓冲区 89*731bc2b3SLoGin let mut buf: Vec<u8> = vec![0; size_of::<MbrDiskPartionTable>()]; 90*731bc2b3SLoGin buf.resize(size_of::<MbrDiskPartionTable>(), 0); 91*731bc2b3SLoGin 92*731bc2b3SLoGin disk.read_at_sync(0, 1, &mut buf)?; 93*731bc2b3SLoGin 94*731bc2b3SLoGin // 创建 Cursor 用于按字节读取 95*731bc2b3SLoGin let mut cursor = VecCursor::new(buf); 96*731bc2b3SLoGin cursor.seek(SeekFrom::SeekCurrent(446))?; 97*731bc2b3SLoGin 98*731bc2b3SLoGin for i in 0..4 { 99*731bc2b3SLoGin table.dpte[i].flags = cursor.read_u8()?; 100*731bc2b3SLoGin table.dpte[i].starting_head = cursor.read_u8()?; 101*731bc2b3SLoGin table.dpte[i].starting_sector_cylinder = cursor.read_u16()?; 102*731bc2b3SLoGin table.dpte[i].part_type = cursor.read_u8()?; 103*731bc2b3SLoGin table.dpte[i].ending_head = cursor.read_u8()?; 104*731bc2b3SLoGin table.dpte[i].ending_sector_cylinder = cursor.read_u16()?; 105*731bc2b3SLoGin table.dpte[i].starting_lba = cursor.read_u32()?; 106*731bc2b3SLoGin table.dpte[i].total_sectors = cursor.read_u32()?; 107*731bc2b3SLoGin 108*731bc2b3SLoGin kdebug!("dpte[{i}] = {:?}", table.dpte[i]); 109*731bc2b3SLoGin } 110*731bc2b3SLoGin table.bs_trailsig = cursor.read_u16()?; 111*731bc2b3SLoGin // kdebug!("bs_trailsig = {}", unsafe { 112*731bc2b3SLoGin // read_unaligned(addr_of!(table.bs_trailsig)) 113*731bc2b3SLoGin // }); 114*731bc2b3SLoGin 115*731bc2b3SLoGin if !table.is_valid() { 116*731bc2b3SLoGin return Err(SystemError::EINVAL); 117*731bc2b3SLoGin } 118*731bc2b3SLoGin 119*731bc2b3SLoGin return Ok(table); 120*731bc2b3SLoGin } 121*731bc2b3SLoGin 122*731bc2b3SLoGin /// # partitions - 获取磁盘的分区信息 123*731bc2b3SLoGin /// 124*731bc2b3SLoGin /// 该函数用于获取指定磁盘的分区信息,并将这些分区信息以分区对象的向量形式返回。分区对象包含了分区的类型、起始扇区和总扇区数等信息。 125*731bc2b3SLoGin /// 126*731bc2b3SLoGin /// ## 参数 127*731bc2b3SLoGin /// 128*731bc2b3SLoGin /// - `disk`: Weak<dyn BlockDevice>: 一个对磁盘设备的弱引用。这个磁盘设备必须实现`BlockDevice` trait。 129*731bc2b3SLoGin /// 130*731bc2b3SLoGin /// ## 返回值 131*731bc2b3SLoGin /// 132*731bc2b3SLoGin /// 返回一个包含分区信息的`Vec`。每个分区都是一个`Arc<Partition>`,它表示分区的一个强引用。 133*731bc2b3SLoGin /// 134*731bc2b3SLoGin pub fn partitions(&self, disk: Weak<dyn BlockDevice>) -> Vec<Arc<Partition>> { 135*731bc2b3SLoGin let mut partitions: Vec<Arc<Partition>> = Vec::new(); 136*731bc2b3SLoGin for i in 0..4 { 137*731bc2b3SLoGin if self.dpte[i].is_valid() { 138*731bc2b3SLoGin partitions.push(Partition::new( 139*731bc2b3SLoGin self.dpte[i].starting_sector() as u64, 140*731bc2b3SLoGin self.dpte[i].starting_lba as u64, 141*731bc2b3SLoGin self.dpte[i].total_sectors as u64, 142*731bc2b3SLoGin disk.clone(), 143*731bc2b3SLoGin i as u16, 144*731bc2b3SLoGin )); 145*731bc2b3SLoGin } 146*731bc2b3SLoGin } 147*731bc2b3SLoGin return partitions; 148*731bc2b3SLoGin } 149*731bc2b3SLoGin 150*731bc2b3SLoGin pub fn is_valid(&self) -> bool { 151*731bc2b3SLoGin self.bs_trailsig == 0xAA55 152*731bc2b3SLoGin } 153*731bc2b3SLoGin } 154