ghostfat/
boot.rs

1
2use packing::Packed;
3
4use crate::Config;
5
6/// Encodable Boot Block object
7#[derive(Clone, Copy, Eq, PartialEq, Debug, Packed)]
8#[cfg_attr(feature="defmt", derive(defmt::Format))]
9#[packed(little_endian, lsb0)]
10pub struct FatBootBlock {
11    #[pkd(7, 0, 0, 2)]
12    pub jump_instruction: [u8; 3],
13
14    #[pkd(7, 0, 3, 10)]
15    pub oem_info: [u8; 8],
16    
17    #[pkd(7, 0, 11, 12)]
18    pub bytes_per_sector: u16,
19    
20    #[pkd(7, 0, 13, 13)]
21    pub sectors_per_cluster: u8,
22    
23    #[pkd(7, 0, 14, 15)]
24    pub reserved_sectors: u16,
25    
26    #[pkd(7, 0, 16, 16)]
27    pub fat_copies: u8,
28    
29    #[pkd(7, 0, 17, 18)]
30    pub root_directory_entries: u16,
31    
32    #[pkd(7, 0, 19, 20)]
33    pub total_sectors16: u16,
34    
35    #[pkd(7, 0, 21, 21)]
36    pub media_descriptor: u8,
37    
38    #[pkd(7, 0, 22, 23)]
39    pub sectors_per_fat: u16,
40    
41    #[pkd(7, 0, 24, 25)]
42    pub sectors_per_track: u16,
43    
44    #[pkd(7, 0, 26, 27)]
45    pub heads: u16,
46    
47    #[pkd(7, 0, 28, 31)]
48    pub hidden_sectors: u32,
49    
50    #[pkd(7, 0, 32, 35)]
51    pub total_sectors32: u32,
52    
53    #[pkd(7, 0, 36, 36)]
54    pub physical_drive_num: u8,
55    
56    #[pkd(7, 0, 37, 37)]
57    _reserved: u8,
58    
59    #[pkd(7, 0, 38, 38)]
60    pub extended_boot_sig: u8,
61    
62    #[pkd(7, 0, 39, 42)]
63    pub volume_serial_number: u32,
64    
65    #[pkd(7, 0, 43, 53)]
66    pub volume_label: [u8; 11],
67    
68    #[pkd(7, 0, 54, 61)]
69    pub filesystem_identifier: [u8; 8],
70}
71
72impl FatBootBlock {
73
74    /// Create a new FAT BootBlock with the provided config
75    pub fn new<const BLOCK_SIZE: usize>(config: &Config<BLOCK_SIZE>) -> FatBootBlock {
76
77        let mut fat = FatBootBlock {
78            jump_instruction: [0xEB, 0x3C, 0x90],
79            oem_info: [0x20; 8],
80            bytes_per_sector: BLOCK_SIZE as u16,
81            sectors_per_cluster: 1,
82            reserved_sectors: config.reserved_sectors as u16,
83            fat_copies: 2,
84            root_directory_entries: (config.root_dir_sectors as u16 * 512 / 32),
85            total_sectors16: config.num_blocks as u16 - 2,
86            media_descriptor: 0xF8,
87            sectors_per_fat: config.sectors_per_fat() as u16,
88            sectors_per_track: 1,
89            heads: 1,
90            hidden_sectors: 0,
91            total_sectors32: 0,
92            physical_drive_num: 0,
93            _reserved: 0,
94            extended_boot_sig: 0x29,
95            volume_serial_number: 0x00420042,
96            volume_label: [0x20; 11],
97            filesystem_identifier: [0x20; 8],
98        };
99
100        let len = usize::min(fat.oem_info.len() - 1, config.oem_info.as_bytes().len());
101        fat.oem_info[..len].copy_from_slice(&config.oem_info.as_bytes()[..len]);
102
103        let len = usize::min(fat.volume_label.len() - 1, config.volume_label.as_bytes().len());
104        fat.volume_label[..len].copy_from_slice(&config.volume_label.as_bytes()[..len]);
105
106        let len = usize::min(fat.filesystem_identifier.len() - 1, config.filesystem_identifier.as_bytes().len());
107        fat.filesystem_identifier[..len].copy_from_slice(&config.filesystem_identifier.as_bytes()[..len]);
108
109        crate::debug!("BootBlock: {:?}", fat);
110
111        fat
112    }
113}