1
2use packing::Packed;
3
4use crate::Config;
5
6#[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 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}