Skip to content

Commit

Permalink
Update fat.c
Browse files Browse the repository at this point in the history
  • Loading branch information
RocketRobz committed Mar 8, 2024
1 parent c96b8e1 commit 4cabc9d
Showing 1 changed file with 61 additions and 96 deletions.
157 changes: 61 additions & 96 deletions bootloader/source/fat.c
Original file line number Diff line number Diff line change
Expand Up @@ -75,12 +75,9 @@

#define __PACKED __attribute__ ((__packed__))

// Boot Sector - must be packed
typedef struct
{
u8 jmpBoot[3];
u8 OEMName[8];
// BIOS Parameter Block
// BIOS Parameter Block
typedef struct {

u16 bytesPerSector;
u8 sectorsPerCluster;
u16 reservedSectors;
Expand All @@ -93,6 +90,14 @@ typedef struct
u16 numHeads;
u32 numHiddenSectors;
u32 numSectors;
} __PACKED BIOS_BPB;

// Boot Sector - must be packed
typedef struct
{
u8 jmpBoot[3];
u8 OEMName[8];
BIOS_BPB bpb;
union // Different types of extended BIOS Parameter Block for FAT16 and FAT32
{
struct
Expand All @@ -106,7 +111,7 @@ typedef struct
u8 fileSysType[8];
// Bootcode
u8 bootCode[448];
} fat16;
} __PACKED fat16;
struct
{
// FAT32 extended block
Expand All @@ -126,13 +131,15 @@ typedef struct
u8 fileSysType[8];
// Bootcode
u8 bootCode[420];
} fat32;
} extBlock;
} __PACKED fat32;
} __PACKED extBlock;

__PACKED u16 bootSig;

} __PACKED BOOT_SEC;

_Static_assert(sizeof(BOOT_SEC) == 512);

// Directory entry - must be packed
typedef struct
{
Expand Down Expand Up @@ -251,8 +258,7 @@ u32 FAT_NextCluster(u32 cluster)
// read the nextCluster value
nextCluster = ((u16*)globalBuffer)[offset];

if (nextCluster >= 0xFFF7)
{
if (nextCluster >= 0xFFF7) {
nextCluster = CLUSTER_EOF;
}
break;
Expand All @@ -265,8 +271,7 @@ u32 FAT_NextCluster(u32 cluster)
// read the nextCluster value
nextCluster = (((u32*)globalBuffer)[offset]) & 0x0FFFFFFF;

if (nextCluster >= 0x0FFFFFF7)
{
if (nextCluster >= 0x0FFFFFF7) {
nextCluster = CLUSTER_EOF;
}
break;
Expand Down Expand Up @@ -304,8 +309,7 @@ bool FAT_InitFiles (bool initCard)
int bootSector;
BOOT_SEC* bootSec;

if (initCard && !CARD_StartUp())
{
if (initCard && !CARD_StartUp()) {
return (false);
}

Expand All @@ -314,17 +318,10 @@ bool FAT_InitFiles (bool initCard)
{
return false;
}
// Check if there is a FAT string, which indicates this is a boot sector
if ((globalBuffer[0x36] == 'F') && (globalBuffer[0x37] == 'A') && (globalBuffer[0x38] == 'T'))
{
bootSector = 0;
}
// Check for FAT32
else if ((globalBuffer[0x52] == 'F') && (globalBuffer[0x53] == 'A') && (globalBuffer[0x54] == 'T'))
{
if (((globalBuffer[0x36] == 'F') && (globalBuffer[0x37] == 'A') && (globalBuffer[0x38] == 'T')) // Check if there is a FAT string, which indicates this is a boot sector
|| ((globalBuffer[0x52] == 'F') && (globalBuffer[0x53] == 'A') && (globalBuffer[0x54] == 'T'))) { // Check for FAT32
bootSector = 0;
}
else // This is an MBR
} else // This is an MBR
{
// Find first valid partition from MBR
// First check for an active partition
Expand All @@ -334,7 +331,7 @@ bool FAT_InitFiles (bool initCard)
for (i=0x1BE; (i < 0x1FE) && (globalBuffer[i+0x04] == 0x00); i+= 0x10);

// Go to first valid partition
if ( i != 0x1FE) // Make sure it found a partition
if (i != 0x1FE) // Make sure it found a partition
{
bootSector = globalBuffer[0x8 + i] + (globalBuffer[0x9 + i] << 8) + (globalBuffer[0xA + i] << 16) + ((globalBuffer[0xB + i] << 24) & 0x0F);
} else {
Expand All @@ -347,55 +344,41 @@ bool FAT_InitFiles (bool initCard)
CARD_ReadSector (bootSector, bootSec);

// Store required information about the file system
if (bootSec->sectorsPerFAT != 0)
{
discSecPerFAT = bootSec->sectorsPerFAT;
}
else
{
if (bootSec->bpb.sectorsPerFAT != 0) {
discSecPerFAT = bootSec->bpb.sectorsPerFAT;
} else {
discSecPerFAT = bootSec->extBlock.fat32.sectorsPerFAT32;
}

if (bootSec->numSectorsSmall != 0)
{
discNumSec = bootSec->numSectorsSmall;
}
else
{
discNumSec = bootSec->numSectors;
if (bootSec->bpb.numSectorsSmall != 0) {
discNumSec = bootSec->bpb.numSectorsSmall;
} else {
discNumSec = bootSec->bpb.numSectors;
}

discBytePerSec = BYTES_PER_SECTOR; // Sector size is redefined to be 512 bytes
discSecPerClus = bootSec->sectorsPerCluster * bootSec->bytesPerSector / BYTES_PER_SECTOR;
discSecPerClus = bootSec->bpb.sectorsPerCluster * bootSec->bpb.bytesPerSector / BYTES_PER_SECTOR;
discBytePerClus = discBytePerSec * discSecPerClus;
discFAT = bootSector + bootSec->reservedSectors;
discFAT = bootSector + bootSec->bpb.reservedSectors;

discRootDir = discFAT + (bootSec->numFATs * discSecPerFAT);
discData = discRootDir + ((bootSec->rootEntries * sizeof(DIR_ENT)) / BYTES_PER_SECTOR);
discRootDir = discFAT + (bootSec->bpb.numFATs * discSecPerFAT);
discData = discRootDir + ((bootSec->bpb.rootEntries * sizeof(DIR_ENT)) / BYTES_PER_SECTOR);

if ((discNumSec - discData) / bootSec->sectorsPerCluster < 4085)
{
if ((discNumSec - discData) / bootSec->bpb.sectorsPerCluster < 4085) {
discFileSystem = FS_FAT12;
}
else if ((discNumSec - discData) / bootSec->sectorsPerCluster < 65525)
{
} else if ((discNumSec - discData) / bootSec->bpb.sectorsPerCluster < 65525) {
discFileSystem = FS_FAT16;
}
else
{
} else {
discFileSystem = FS_FAT32;
}

if (discFileSystem != FS_FAT32)
{
if (discFileSystem != FS_FAT32) {
discRootDirClus = FAT16_ROOT_DIR_CLUSTER;
}
else // Set up for the FAT32 way
} else // Set up for the FAT32 way
{
discRootDirClus = bootSec->extBlock.fat32.rootClus;
// Check if FAT mirroring is enabled
if (!(bootSec->extBlock.fat32.extFlags & 0x80))
{
if (!(bootSec->extBlock.fat32.extFlags & 0x80)) {
// Use the active FAT
discFAT = discFAT + ( discSecPerFAT * (bootSec->extBlock.fat32.extFlags & 0x0F));
}
Expand Down Expand Up @@ -425,8 +408,7 @@ u32 getBootFileCluster (const char* bootName)


// Check if fat has been initialised
if (discBytePerSec == 0)
{
if (discBytePerSec == 0) {
return (CLUSTER_FREE);
}

Expand All @@ -443,52 +425,42 @@ u32 getBootFileCluster (const char* bootName)
wrkDirOffset = -1; // Start at entry zero, Compensating for increment
while (!found && !notFound) {
wrkDirOffset++;
if (wrkDirOffset == BYTES_PER_SECTOR / sizeof (DIR_ENT))
{
if (wrkDirOffset == BYTES_PER_SECTOR / sizeof (DIR_ENT)) {
wrkDirOffset = 0;
wrkDirSector++;
if ((wrkDirSector == discSecPerClus) && (wrkDirCluster != FAT16_ROOT_DIR_CLUSTER))
{
if ((wrkDirSector == discSecPerClus) && (wrkDirCluster != FAT16_ROOT_DIR_CLUSTER)) {
wrkDirSector = 0;
wrkDirCluster = FAT_NextCluster(wrkDirCluster);
if (wrkDirCluster == CLUSTER_EOF)
{
if (wrkDirCluster == CLUSTER_EOF) {
notFound = true;
}
firstSector = FAT_ClustToSect(wrkDirCluster);
}
else if ((wrkDirCluster == FAT16_ROOT_DIR_CLUSTER) && (wrkDirSector == (discData - discRootDir)))
{
} else if ((wrkDirCluster == FAT16_ROOT_DIR_CLUSTER) && (wrkDirSector == (discData - discRootDir))) {
notFound = true; // Got to end of root dir
}
CARD_ReadSector (firstSector + wrkDirSector, globalBuffer);
}
dir = ((DIR_ENT*) globalBuffer)[wrkDirOffset];
found = true;
if ((dir.attrib & ATTRIB_DIR) || (dir.attrib & ATTRIB_VOL))
{
if ((dir.attrib & ATTRIB_DIR) || (dir.attrib & ATTRIB_VOL)) {
found = false;
}
if(namelen<8 && dir.name[namelen]!=0x20) found = false;
for (nameOffset = 0; nameOffset < namelen && found; nameOffset++)
{
if (namelen<8 && dir.name[namelen]!=0x20) found = false;
for (nameOffset = 0; nameOffset < namelen && found; nameOffset++) {
if (ucase(dir.name[nameOffset]) != bootName[nameOffset])
found = false;
}
for (nameOffset = 0; nameOffset < 3 && found; nameOffset++)
{
for (nameOffset = 0; nameOffset < 3 && found; nameOffset++) {
if (ucase(dir.ext[nameOffset]) != bootName[nameOffset+namelen+1])
found = false;
}
if (dir.name[0] == FILE_LAST)
{
if (dir.name[0] == FILE_LAST) {
notFound = true;
}
}

// If no file is found, return CLUSTER_FREE
if (notFound)
{
if (notFound) {
return CLUSTER_FREE;
}

Expand All @@ -513,8 +485,7 @@ u32 fileRead (char* buffer, u32 cluster, u32 startOffset, u32 length)
}

// Follow cluster list until desired one is found
for (chunks = startOffset / discBytePerClus; chunks > 0; chunks--)
{
for (chunks = startOffset / discBytePerClus; chunks > 0; chunks--) {
cluster = FAT_NextCluster (cluster);
}

Expand All @@ -524,33 +495,30 @@ u32 fileRead (char* buffer, u32 cluster, u32 startOffset, u32 length)
curByte = startOffset % BYTES_PER_SECTOR;

// Load sector buffer for new position in file
CARD_ReadSector( curSect + FAT_ClustToSect(cluster), globalBuffer);
CARD_ReadSector(curSect + FAT_ClustToSect(cluster), globalBuffer);
curSect++;

// Number of bytes needed to read to align with a sector
beginBytes = (BYTES_PER_SECTOR < length + curByte ? (BYTES_PER_SECTOR - curByte) : length);

// Read first part from buffer, to align with sector boundary
for (dataPos = 0 ; dataPos < beginBytes; dataPos++)
{
for (dataPos = 0 ; dataPos < beginBytes; dataPos++) {
buffer[dataPos] = globalBuffer[curByte++];
}

// Read in all the 512 byte chunks of the file directly, saving time
for ( chunks = ((int)length - beginBytes) / BYTES_PER_SECTOR; chunks > 0;)
{
for (chunks = ((int)length - beginBytes) / BYTES_PER_SECTOR; chunks > 0;) {
int sectorsToRead;

// Move to the next cluster if necessary
if (curSect >= discSecPerClus)
{
if (curSect >= discSecPerClus) {
curSect = 0;
cluster = FAT_NextCluster (cluster);
}

// Calculate how many sectors to read (read a maximum of discSecPerClus at a time)
sectorsToRead = discSecPerClus - curSect;
if(chunks < sectorsToRead)
if (chunks < sectorsToRead)
sectorsToRead = chunks;

// Read the sectors
Expand All @@ -561,21 +529,18 @@ u32 fileRead (char* buffer, u32 cluster, u32 startOffset, u32 length)
}

// Take care of any bytes left over before end of read
if (dataPos < length)
{
if (dataPos < length) {

// Update the read buffer
curByte = 0;
if (curSect >= discSecPerClus)
{
if (curSect >= discSecPerClus) {
curSect = 0;
cluster = FAT_NextCluster (cluster);
}
CARD_ReadSector( curSect + FAT_ClustToSect( cluster), globalBuffer);
CARD_ReadSector(curSect + FAT_ClustToSect(cluster), globalBuffer);

// Read in last partial chunk
for (; dataPos < length; dataPos++)
{
for (; dataPos < length; dataPos++) {
buffer[dataPos] = globalBuffer[curByte];
curByte++;
}
Expand Down

0 comments on commit 4cabc9d

Please sign in to comment.