FATStructures.h 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. /*
  2. * Copyright (c) 2022, Undefine <undefine@undefine.pl>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #pragma once
  7. #include <AK/Types.h>
  8. namespace Kernel {
  9. // This structure represents the DOS 3.31 BIOS Partition Block.
  10. // While DOS 3.31 predates FAT verions 12/16/32 (the versions supported by this driver),
  11. // the fields in this block are common with the DOS 4 and DOS 7 BIOS Parameter blocks.
  12. // This structure will be followed by an "Extended BIOS Partition Block" (EBPB).
  13. //
  14. // The DOS 4 EBPB is *typically* used by FAT 12/16 file systems, while the DOS 7 EBPB
  15. // is *typically* used by FAT 32. _However_, any combination is possible, as the FAT
  16. // version is only determined by the number of clusters.
  17. //
  18. // Note that the DOS 4 and DOS 7 EBPB extensions are incompatible with each other
  19. // (contain fields in different orders and of different lenghts) and do not contain
  20. // an explicit indication to differentiate them.
  21. // This driver uses heuristics to identify the EBPB version (based on the signature bytes
  22. // and sector counts).
  23. // FIXME: Consider also using the MBR parition type field in the future.
  24. struct [[gnu::packed]] DOS3BIOSParameterBlock {
  25. u8 boot_jump[3];
  26. char oem_identifier[8];
  27. u16 bytes_per_sector; // Offset 0x0B -- beginning of DOS 3.31 BPB.
  28. u8 sectors_per_cluster;
  29. u16 reserved_sector_count;
  30. u8 fat_count;
  31. u16 root_directory_entry_count;
  32. u16 sector_count_16bit;
  33. u8 media_descriptor_type;
  34. u16 sectors_per_fat_16bit;
  35. u16 sectors_per_track;
  36. u16 head_count;
  37. u32 hidden_sector_count;
  38. u32 sector_count_32bit; // 0x020 -- end of DOS 3.31 BPB.
  39. };
  40. // 11 is the boot jump/OEM identifier prefix prior to the official BPB.
  41. static_assert(AssertSize<DOS3BIOSParameterBlock, 11 + 25>());
  42. struct [[gnu::packed]] DOS4BIOSParameterBlock {
  43. // Begins at sector offset 0x024.
  44. u8 drive_number; // 0x024
  45. u8 flags;
  46. u8 signature;
  47. u32 volume_id;
  48. char volume_label_string[11];
  49. char file_system_type[8];
  50. };
  51. static_assert(AssertSize<DOS4BIOSParameterBlock, 26>());
  52. struct [[gnu::packed]] DOS7BIOSParameterBlock {
  53. // Begins at sector offset 0x024.
  54. u32 sectors_per_fat_32bit; // 0x024
  55. u16 flags;
  56. u16 fat_version; // Expected value 0x2b2a.
  57. u32 root_directory_cluster;
  58. u16 fs_info_sector;
  59. u16 backup_boot_sector;
  60. u8 unused3[12];
  61. u8 drive_number;
  62. u8 unused4;
  63. u8 signature;
  64. u32 volume_id;
  65. char volume_label_string[11];
  66. char file_system_type[8];
  67. };
  68. static_assert(AssertSize<DOS7BIOSParameterBlock, 54>());
  69. struct [[gnu::packed]] FAT32FSInfo {
  70. u32 lead_signature;
  71. u8 unused1[480];
  72. u32 struct_signature;
  73. u32 last_known_free_cluster_count;
  74. u32 next_free_cluster_hint;
  75. u8 unused2[12];
  76. u32 trailing_signature;
  77. };
  78. static_assert(AssertSize<FAT32FSInfo, 512>());
  79. }