2024-07-07 03:15:17 +03:00

291 lines
9.1 KiB
C

/*
This file is part of Fennix Drivers.
Fennix Drivers is free software: you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version.
Fennix Drivers is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Fennix Drivers. If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef __FENNIX_DRIVER_FAT_H__
#define __FENNIX_DRIVER_FAT_H__
#include <types.h>
/* Source: https://wiki.osdev.org/FAT */
struct BIOSParameterBlock
{
/** The first three bytes EB 3C 90 disassemble to JMP SHORT 3C NOP.
* (The 3C value may be different.) The reason for this is to jump
* over the disk format information (the BPB and EBPB). Since the
* first sector of the disk is loaded into ram at location
* 0x0000:0x7c00 and executed, without this jump, the processor
* would attempt to execute data that isn't code. Even for
* non-bootable volumes, code matching this pattern (or using the
* E9 jump opcode) is required to be present by both Windows and
* OS X. To fulfil this requirement, an infinite loop can be placed
* here with the bytes EB FE 90. */
uint8_t JumpBoot[3];
/** OEM identifier. The first 8 Bytes (3 - 10) is the version of DOS
* being used. The next eight Bytes 29 3A 63 7E 2D 49 48 and 43 read
* out the name of the version. The official FAT Specification from
* Microsoft says that this field is really meaningless and is ignored
* by MS FAT Modules, however it does recommend the value "MSWIN4.1"
* as some 3rd party drivers supposedly check it and expect it to
* have that value. Older versions of dos also report MSDOS5.1,
* linux-formatted floppy will likely to carry "mkdosfs" here, and
* FreeDOS formatted disks have been observed to have "FRDOS5.1" here.
* If the string is less than 8 bytes, it is padded with spaces. */
uint8_t OEM[8];
/** The number of Bytes per sector (remember, all numbers are in the
* little-endian format). */
uint16_t BytesPerSector;
/** Number of sectors per cluster. */
uint8_t SectorsPerCluster;
/** Number of reserved sectors. The boot record sectors are included
* in this value. */
uint16_t ReservedSectors;
/** Number of File Allocation Tables (FAT's) on the storage media.
* Often this value is 2. */
uint8_t NumberOfFATs;
/** Number of root directory entries (must be set so that the root
* directory occupies entire sectors). */
uint16_t RootDirectoryEntries;
/** The total sectors in the logical volume. If this value is 0, it
* means there are more than 65535 sectors in the volume, and the
* actual count is stored in the Large Sector Count entry at 0x20. */
uint16_t Sectors16;
/** This Byte indicates the media descriptor type. */
uint8_t Media;
/** Number of sectors per FAT. FAT12/FAT16 only. */
uint16_t SectorsPerFAT;
/** Number of sectors per track. */
uint16_t SectorsPerTrack;
/** Number of heads or sides on the storage media. */
uint16_t NumberOfHeads;
/** Number of hidden sectors. (i.e. the LBA of the beginning of
* the partition). */
uint32_t HiddenSectors;
/** Large sector count. This field is set if there are more than
* 65535 sectors in the volume, resulting in a value which does not
* fit in the Number of Sectors entry at 0x13. */
uint32_t Sectors32;
} __packed;
struct ExtendedBootRecord_FAT12_16
{
/** Drive number. The value here should be identical to the value
* returned by BIOS interrupt 0x13, or passed in the DL register;
* i.e. 0x00 for a floppy disk and 0x80 for hard disks. This number
* is useless because the media is likely to be moved to another
* machine and inserted in a drive with a different drive number. */
uint8_t DriveNumber;
/** Flags in Windows NT. Reserved otherwise. */
uint8_t Flags;
/** Signature (must be 0x28 or 0x29). */
uint8_t Signature;
/** VolumeID 'Serial' number. Used for tracking volumes between
* computers. You can ignore this if you want. */
uint32_t VolumeID;
/** Volume label string. This field is padded with spaces. */
uint8_t VolumeLabel[11];
/** System identifier string. This field is a string representation
* of the FAT file system type. It is padded with spaces. The spec
* says never to trust the contents of this string for any use. */
uint8_t SystemIdentifier[8];
/** Boot code. */
uint8_t BootCode[448];
/** Bootable partition signature 0xAA55. */
uint16_t BootSignature;
} __packed;
struct ExtendedBootRecord_FAT32
{
/** Sectors per FAT. The size of the FAT in sectors. */
uint32_t SectorsPerFAT;
/** Flags. */
uint16_t Flags;
/** FAT version number. The high byte is the major version and the
* low byte is the minor version. FAT drivers should respect this
* field. */
uint16_t FATVersion;
/** The cluster number of the root directory. Often this field is
* set to 2. */
uint32_t RootDirectoryCluster;
/** The sector number of the FSInfo structure. */
uint16_t FSInfoSector;
/** The sector number of the backup boot sector. */
uint16_t BackupBootSector;
/** Reserved. When the volume is formated these bytes should be zero. */
uint8_t Reserved[12];
/** Drive number. The values here are identical to the values returned
* by the BIOS interrupt 0x13. 0x00 for a floppy disk and 0x80 for
* hard disks. */
uint8_t DriveNumber;
/** Flags in Windows NT. Reserved otherwise. */
uint8_t Flags2;
/** Signature (must be 0x28 or 0x29). */
uint8_t Signature;
/** Volume ID 'Serial' number. Used for tracking volumes between
* computers. You can ignore this if you want. */
uint32_t VolumeID;
/** Volume label string. This field is padded with spaces. */
uint8_t VolumeLabel[11];
/** System identifier string. Always "FAT32 ". The spec says never
* to trust the contents of this string for any use. */
uint8_t SystemIdentifier[8];
/** Boot code. */
uint8_t BootCode[420];
/** Bootable partition signature 0xAA55. */
uint16_t BootSignature;
} __packed;
struct FSInfo
{
/** Lead signature (must be 0x41615252 to indicate a valid FSInfo
* structure). */
uint32_t LeadSignature;
/** Reserved, these bytes should never be used. */
uint8_t Reserved1[480];
/** Another signature (must be 0x61417272). */
uint32_t AnotherSignature;
/** Contains the last known free cluster count on the volume. If the
* value is 0xFFFFFFFF, then the free count is unknown and must be
* computed. However, this value might be incorrect and should at
* least be range checked (<= volume cluster count). */
uint32_t FreeClusterCount;
/** Indicates the cluster number at which the filesystem driver should
* start looking for available clusters. If the value is 0xFFFFFFFF,
* then there is no hint and the driver should start searching at 2.
* Typically this value is set to the last allocated cluster number.
* As the previous field, this value should be range checked. */
uint32_t NextFreeCluster;
/** Reserved. */
uint8_t Reserved2[12];
/** Trail signature (0xAA550000). */
uint32_t TrailSignature;
} __packed;
struct exFATBootRecord
{
/** The first three bytes EB 3C 90 disassemble to JMP SHORT 3C NOP.
* (The 3C value may be different.) The reason for this is to jump
* over the disk format information (the BPB and EBPB). Since the
* first sector of the disk is loaded into ram at location
* 0x0000:0x7c00 and executed, without this jump, the processor
* would attempt to execute data that isn't code. Even for
* non-bootable volumes, code matching this pattern (or using the
* E9 jump opcode) is required to be present by both Windows and
* OS X. To fulfil this requirement, an infinite loop can be placed
* here with the bytes EB FE 90. */
uint8_t JumpBoot[3];
/** OEM identifier. This contains the string "EXFAT ". Not to be
* used for filesystem determination, but it's a nice hint. */
uint8_t OEM[8];
/** Set to zero. This makes sure any FAT driver will not be able to
* load it. */
uint8_t Reserved1[53];
/** Partition offset. No idea why the partition itself would have
* this, but it's here. Might be wrong. Probably best to just ignore. */
uint64_t PartitionOffset;
/** Volume length. */
uint64_t VolumeLength;
/** FAT offset (in sectors) from start of partition. */
uint32_t FATOffset;
/** FAT length (in sectors). */
uint32_t FATLength;
/** Cluster heap offset (in sectors). */
uint32_t ClusterHeapOffset;
/** Cluster count. */
uint32_t ClusterCount;
/** Root directory cluster. Typically 4 (but just read this value). */
uint32_t RootDirectoryCluster;
/** Serial number of partition. */
uint32_t SerialNumber;
/** Filesystem revision. */
uint16_t FilesystemRevision;
/** Flags. */
uint16_t Flags;
/** Sector shift. */
uint8_t SectorShift;
/** Cluster shift. */
uint8_t ClusterShift;
/** Number of FATs. */
uint8_t NumberOfFATs;
/** Drive select. */
uint8_t DriveSelect;
/** Percentage in use. */
uint8_t PercentageInUse;
/** Reserved (set to 0). */
uint8_t Reserved2[7];
} __packed;
#endif // !__FENNIX_DRIVER_FAT_H__