kernel/fs/
mbr.rs

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        // SAFETY: This is a valid allocated memory
52        let mbr = unsafe { &*(sectors.as_ptr() as *const Mbr) };
53
54        // if valid
55        if mbr.signature == 0xAA55 {
56            Ok(mbr.clone())
57        } else {
58            Err(FileSystemError::PartitionTableNotFound)
59        }
60    }
61}