From 4cabc9d09f74b1f055c3093ca94ac348912bf2e5 Mon Sep 17 00:00:00 2001 From: RocketRobz Date: Thu, 7 Mar 2024 23:06:17 -0700 Subject: [PATCH] Update fat.c --- bootloader/source/fat.c | 157 ++++++++++++++++------------------------ 1 file changed, 61 insertions(+), 96 deletions(-) diff --git a/bootloader/source/fat.c b/bootloader/source/fat.c index f405f75b..ed57c899 100644 --- a/bootloader/source/fat.c +++ b/bootloader/source/fat.c @@ -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; @@ -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 @@ -106,7 +111,7 @@ typedef struct u8 fileSysType[8]; // Bootcode u8 bootCode[448]; - } fat16; + } __PACKED fat16; struct { // FAT32 extended block @@ -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 { @@ -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; @@ -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; @@ -304,8 +309,7 @@ bool FAT_InitFiles (bool initCard) int bootSector; BOOT_SEC* bootSec; - if (initCard && !CARD_StartUp()) - { + if (initCard && !CARD_StartUp()) { return (false); } @@ -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 @@ -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 { @@ -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)); } @@ -425,8 +408,7 @@ u32 getBootFileCluster (const char* bootName) // Check if fat has been initialised - if (discBytePerSec == 0) - { + if (discBytePerSec == 0) { return (CLUSTER_FREE); } @@ -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; } @@ -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); } @@ -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 @@ -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++; }