mbr.rs 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. use core::{default::Default, mem::size_of};
  2. use alloc::{
  3. sync::{Arc, Weak},
  4. vec::Vec,
  5. };
  6. use system_error::SystemError;
  7. use crate::{
  8. driver::base::block::{block_device::BlockDevice, disk_info::Partition, SeekFrom},
  9. libs::vec_cursor::VecCursor,
  10. };
  11. /// @brief MBR硬盘分区表项的结构
  12. #[repr(packed)]
  13. #[derive(Debug, Clone, Copy, Default)]
  14. pub struct MbrDiskPartitionTableEntry {
  15. pub flags: u8, // 引导标志符,标记此分区为活动分区
  16. pub starting_head: u8, // 起始磁头号
  17. pub starting_sector_cylinder: u16, // sector : 低6, cylinder : 高10; 起始扇区号 + 起始柱面号
  18. pub part_type: u8, // 分区类型ID
  19. pub ending_head: u8, // 结束磁头号
  20. pub ending_sector_cylinder: u16, // ending_sector : 低6, ending_cylinder : 高10; 结束扇区号 + 结束柱面号
  21. pub starting_lba: u32, // 起始逻辑扇区
  22. pub total_sectors: u32, // 分区占用的磁盘扇区数
  23. }
  24. impl MbrDiskPartitionTableEntry {
  25. pub fn starting_sector(&self) -> u32 {
  26. return (self.starting_sector_cylinder & ((1 << 6) - 1)).into();
  27. }
  28. pub fn starting_cylinder(&self) -> u16 {
  29. return (self.starting_sector_cylinder >> 6) & ((1 << 10) - 1) as u16;
  30. }
  31. pub fn ending_sector(&self) -> u32 {
  32. self.starting_sector() + self.total_sectors - 1
  33. }
  34. pub fn ending_cylinder(&self) -> u16 {
  35. return (self.ending_sector_cylinder >> 6) & ((1 << 10) - 1) as u16;
  36. }
  37. pub fn is_valid(&self) -> bool {
  38. // 其他更多的可能判断条件
  39. self.starting_sector() <= self.ending_sector()
  40. && self.starting_cylinder() <= self.ending_cylinder()
  41. && self.starting_lba != 0
  42. && self.total_sectors != 0
  43. && self.part_type != 0
  44. }
  45. }
  46. /// @brief MBR磁盘分区表结构体
  47. #[repr(packed)]
  48. #[derive(Debug, Clone, Copy)]
  49. pub struct MbrDiskPartionTable {
  50. pub _reserved: [u8; 446],
  51. pub dpte: [MbrDiskPartitionTableEntry; 4], // 磁盘分区表项
  52. pub bs_trailsig: u16,
  53. }
  54. impl Default for MbrDiskPartionTable {
  55. fn default() -> Self {
  56. MbrDiskPartionTable {
  57. _reserved: [0; 446],
  58. dpte: [Default::default(); 4],
  59. bs_trailsig: Default::default(),
  60. }
  61. }
  62. }
  63. impl MbrDiskPartionTable {
  64. /// # 从磁盘读取MBR分区表 - 从磁盘设备中读取并解析MBR分区表
  65. ///
  66. /// 这个函数从提供的磁盘设备中读取MBR分区表,并将其解析为一个`MbrDiskPartionTable`实例。
  67. ///
  68. /// ## 参数
  69. ///
  70. /// - `disk`: Arc<dyn BlockDevice> - 一个磁盘设备的共享引用,用于从磁盘读取数据。
  71. ///
  72. /// ## 返回值
  73. ///
  74. /// - `Ok(MbrDiskPartionTable)`: 成功解析的分区表实例。
  75. /// - `Err(SystemError)`: 读取磁盘失败或其他系统错误。
  76. pub fn from_disk(disk: Arc<dyn BlockDevice>) -> Result<MbrDiskPartionTable, SystemError> {
  77. let mut table: MbrDiskPartionTable = Default::default();
  78. // 数据缓冲区
  79. let mut buf: Vec<u8> = vec![0; size_of::<MbrDiskPartionTable>()];
  80. buf.resize(size_of::<MbrDiskPartionTable>(), 0);
  81. disk.read_at_sync(0, 1, &mut buf)?;
  82. // 创建 Cursor 用于按字节读取
  83. let mut cursor = VecCursor::new(buf);
  84. cursor.seek(SeekFrom::SeekCurrent(446))?;
  85. for i in 0..4 {
  86. table.dpte[i].flags = cursor.read_u8()?;
  87. table.dpte[i].starting_head = cursor.read_u8()?;
  88. table.dpte[i].starting_sector_cylinder = cursor.read_u16()?;
  89. table.dpte[i].part_type = cursor.read_u8()?;
  90. table.dpte[i].ending_head = cursor.read_u8()?;
  91. table.dpte[i].ending_sector_cylinder = cursor.read_u16()?;
  92. table.dpte[i].starting_lba = cursor.read_u32()?;
  93. table.dpte[i].total_sectors = cursor.read_u32()?;
  94. // debug!("dpte[{i}] = {:?}", table.dpte[i]);
  95. }
  96. table.bs_trailsig = cursor.read_u16()?;
  97. // debug!("bs_trailsig = {}", unsafe {
  98. // read_unaligned(addr_of!(table.bs_trailsig))
  99. // });
  100. if !table.is_valid() {
  101. return Err(SystemError::EINVAL);
  102. }
  103. return Ok(table);
  104. }
  105. /// # partitions - 获取磁盘的分区信息
  106. ///
  107. /// 该函数用于获取指定磁盘的分区信息,并将这些分区信息以分区对象的向量形式返回。分区对象包含了分区的类型、起始扇区和总扇区数等信息。
  108. ///
  109. /// ## 参数
  110. ///
  111. /// - `disk`: Weak<dyn BlockDevice>: 一个对磁盘设备的弱引用。这个磁盘设备必须实现`BlockDevice` trait。
  112. ///
  113. /// ## 返回值
  114. ///
  115. /// 返回一个包含分区信息的`Vec`。每个分区都是一个`Arc<Partition>`,它表示分区的一个强引用。
  116. ///
  117. pub fn partitions(&self, disk: Weak<dyn BlockDevice>) -> Vec<Arc<Partition>> {
  118. let mut partitions: Vec<Arc<Partition>> = Vec::new();
  119. for i in 0..4 {
  120. if self.dpte[i].is_valid() {
  121. partitions.push(Partition::new(
  122. self.dpte[i].starting_sector() as u64,
  123. self.dpte[i].starting_lba as u64,
  124. self.dpte[i].total_sectors as u64,
  125. disk.clone(),
  126. i as u16,
  127. ));
  128. }
  129. }
  130. return partitions;
  131. }
  132. /// # partitions_raw - 获取磁盘的分区信息,不包含磁盘设备信息
  133. pub fn partitions_raw(&self) -> MbrPartitionIter {
  134. MbrPartitionIter::new(self)
  135. }
  136. pub fn is_valid(&self) -> bool {
  137. self.bs_trailsig == 0xAA55
  138. }
  139. }
  140. pub struct MbrPartitionIter<'a> {
  141. table: &'a MbrDiskPartionTable,
  142. index: usize,
  143. }
  144. impl<'a> MbrPartitionIter<'a> {
  145. fn new(table: &'a MbrDiskPartionTable) -> Self {
  146. MbrPartitionIter { table, index: 0 }
  147. }
  148. }
  149. impl Iterator for MbrPartitionIter<'_> {
  150. type Item = Partition;
  151. fn next(&mut self) -> Option<Self::Item> {
  152. while self.index < 4 {
  153. let entry = &self.table.dpte[self.index];
  154. let index = self.index;
  155. self.index += 1;
  156. if entry.is_valid() {
  157. let p = Partition::new_raw(
  158. self.table.dpte[index].starting_sector() as u64,
  159. self.table.dpte[index].starting_lba as u64,
  160. self.table.dpte[index].total_sectors as u64,
  161. index as u16,
  162. );
  163. return Some(p);
  164. }
  165. }
  166. return None;
  167. }
  168. }