1use core::mem;
2
3use alloc::vec;
4
5use crate::{devices::ide::IdeDevice, io::NoDebug, memory_management::memory_layout::align_up};
6
7use super::FileSystemError;
8
9#[repr(C, packed)]
10#[derive(Copy, Clone, Debug)]
11pub struct PartitionEntry {
12 pub bootable: u8,
13 pub start_head: u8,
14 pub start_sector: u8,
15 pub start_cylinder: u8,
16 pub partition_type: u8,
17 pub end_head: u8,
18 pub end_sector: u8,
19 pub end_cylinder: u8,
20 pub start_lba: u32,
21 pub size_in_sectors: u32,
22}
23
24#[repr(C, packed)]
25#[derive(Debug, Clone)]
26pub struct Mbr {
27 pub boot_code: NoDebug<[u8; 220]>,
28 pub original_first_physical_drive: u8,
29 pub seconds: u8,
30 pub minutes: u8,
31 pub hours: u8,
32 pub extended_boot_code: NoDebug<[u8; 216]>,
33 pub disk_signature: u32,
34 pub copy_protection: u16,
35 pub partition_table: [PartitionEntry; 4],
36 pub signature: u16,
37}
38
39impl Mbr {
40 pub fn try_create_from_disk(device: &IdeDevice) -> Result<Self, FileSystemError> {
41 let size = align_up(mem::size_of::<Self>(), device.sector_size() as usize);
42 let mut sectors = vec![0; size];
43
44 device
45 .read_sync(0, &mut sectors)
46 .map_err(|e| FileSystemError::DiskReadError {
47 sector: 0,
48 error: e,
49 })?;
50
51 let mbr = unsafe { &*(sectors.as_ptr() as *const Mbr) };
53
54 if mbr.signature == 0xAA55 {
56 Ok(mbr.clone())
57 } else {
58 Err(FileSystemError::PartitionTableNotFound)
59 }
60 }
61}