Skip to content

Commit f157069

Browse files
committed
Static assertions and additional #defines
1 parent 9470452 commit f157069

File tree

1 file changed

+39
-18
lines changed

1 file changed

+39
-18
lines changed

src/usb/uf2/ghostfat.c

Lines changed: 39 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -65,9 +65,31 @@ struct TextFile {
6565

6666
#define NUM_FAT_BLOCKS CFG_UF2_NUM_BLOCKS
6767

68-
#define RESERVED_SECTORS 1
69-
#define ROOT_DIR_SECTORS 4
70-
#define SECTORS_PER_FAT ((NUM_FAT_BLOCKS * 2 + 511) / 512)
68+
#define BPB_SECTOR_SIZE ( 512)
69+
#define BPB_SECTORS_PER_CLUSTER ( 1)
70+
#define BPB_RESERVED_SECTORS ( 1)
71+
#define BPB_NUMBER_OF_FATS ( 2)
72+
#define BPB_ROOT_DIR_ENTRIES ( 64)
73+
// Static assertions ensure CFG_UF2_NUM_BLOCKS will result in a valid file system.
74+
#define BPB_TOTAL_SECTORS CFG_UF2_NUM_BLOCKS // Configuration ... up to 0x10209 / 0x101e9?
75+
#define BPB_MEDIA_DESCRIPTOR_BYTE (0xF8)
76+
#define FAT_ENTRY_SIZE (2)
77+
#define FAT_ENTRIES_PER_SECTOR (BPB_SECTOR_SIZE / FAT_ENTRY_SIZE)
78+
// NOTE: MS specification explicitly allows FAT to be larger than necessary
79+
#define BPB_SECTORS_PER_FAT ( (BPB_TOTAL_SECTORS / FAT_ENTRIES_PER_SECTOR) + \
80+
((BPB_TOTAL_SECTORS % FAT_ENTRIES_PER_SECTOR) ? 1 : 0))
81+
#define DIRENTRIES_PER_SECTOR (BPB_SECTOR_SIZE/sizeof(DirEntry))
82+
#define ROOT_DIR_SECTORS (BPB_ROOT_DIR_ENTRIES/DIRENTRIES_PER_SECTOR)
83+
84+
STATIC_ASSERT(BPB_SECTOR_SIZE == 512); // GhostFAT does not support other sector sizes (currently)
85+
STATIC_ASSERT(BPB_SECTORS_PER_CLUSTER == 1); // GhostFAT presumes one sector == one cluster (for simplicity)
86+
STATIC_ASSERT(BPB_NUMBER_OF_FATS == 2); // FAT highest compatibility
87+
STATIC_ASSERT(sizeof(DirEntry) == 32); // FAT requirement
88+
STATIC_ASSERT(BPB_SECTOR_SIZE % sizeof(DirEntry) == 0); // FAT requirement
89+
STATIC_ASSERT(BPB_ROOT_DIR_ENTRIES % DIRENTRIES_PER_SECTOR == 0); // FAT requirement
90+
STATIC_ASSERT(BPB_SECTOR_SIZE * BPB_SECTORS_PER_CLUSTER <= (32*1024)); // FAT requirement (64k+ has known compatibility problems)
91+
92+
STATIC_ASSERT(ROOT_DIR_SECTORS == 4); // Not required ... just validating equal to prior code
7193

7294
#define STR0(x) #x
7395
#define STR(x) STR0(x)
@@ -94,12 +116,12 @@ static struct TextFile const info[] = {
94116
// current.uf2 must be the last element and its content must be NULL
95117
{.name = "CURRENT UF2", .content = NULL},
96118
};
119+
// FAT requires a final unused entry
120+
STATIC_ASSERT(ARRAY_SIZE(info) < BPB_ROOT_DIR_ENTRIES);
97121

98-
// code presumes each non-UF2 file content fits in single sector
99-
// Cannot programmatically statically assert .content length
100-
// for each element above.
101-
STATIC_ASSERT(ARRAY_SIZE(indexFile) < 512);
102-
122+
// GhostFAT presumes each non-UF2 file content fits in single sector
123+
STATIC_ASSERT(ARRAY_SIZE(infoUf2File) < BPB_SECTOR_SIZE);
124+
STATIC_ASSERT(ARRAY_SIZE(indexFile) < BPB_SECTOR_SIZE);
103125

104126
#define NUM_FILES (ARRAY_SIZE(info))
105127
#define NUM_DIRENTRIES (NUM_FILES + 1) // Code adds volume label as first root directory entry
@@ -109,28 +131,27 @@ STATIC_ASSERT(ARRAY_SIZE(indexFile) < 512);
109131
#define UF2_FIRST_SECTOR (NUM_FILES + 1) // WARNING -- code presumes each non-UF2 file content fits in single sector
110132
#define UF2_LAST_SECTOR (UF2_FIRST_SECTOR + UF2_SECTORS - 1)
111133

112-
#define START_FAT0 RESERVED_SECTORS
113-
#define START_FAT1 (START_FAT0 + SECTORS_PER_FAT)
114-
#define START_ROOTDIR (START_FAT1 + SECTORS_PER_FAT)
134+
#define START_FAT0 BPB_RESERVED_SECTORS
135+
#define START_FAT1 (START_FAT0 + BPB_SECTORS_PER_FAT)
136+
#define START_ROOTDIR (START_FAT1 + BPB_SECTORS_PER_FAT)
115137
#define START_CLUSTERS (START_ROOTDIR + ROOT_DIR_SECTORS)
116138

139+
STATIC_ASSERT(NUM_DIRENTRIES < BPB_ROOT_DIR_ENTRIES);
117140
// all directory entries must fit in a single sector
118141
// because otherwise current code overflows buffer
119-
#define DIRENTRIES_PER_SECTOR (512/sizeof(DirEntry))
120-
121-
STATIC_ASSERT(NUM_DIRENTRIES < DIRENTRIES_PER_SECTOR * ROOT_DIR_SECTORS);
142+
STATIC_ASSERT(NUM_DIRENTRIES < DIRENTRIES_PER_SECTOR);
122143

123144
static FAT_BootBlock const BootBlock = {
124145
.JumpInstruction = {0xeb, 0x3c, 0x90},
125146
.OEMInfo = "UF2 UF2 ",
126147
.SectorSize = 512,
127148
.SectorsPerCluster = 1,
128-
.ReservedSectors = RESERVED_SECTORS,
149+
.ReservedSectors = BPB_RESERVED_SECTORS,
129150
.FATCopies = 2,
130151
.RootDirectoryEntries = (ROOT_DIR_SECTORS * DIRENTRIES_PER_SECTOR),
131152
.TotalSectors16 = NUM_FAT_BLOCKS - 2,
132153
.MediaDescriptor = 0xF8,
133-
.SectorsPerFAT = SECTORS_PER_FAT,
154+
.SectorsPerFAT = BPB_SECTORS_PER_FAT,
134155
.SectorsPerTrack = 1,
135156
.Heads = 1,
136157
.PhysicalDriveNum = 0x80, // to match MediaDescriptor of 0xF8
@@ -226,8 +247,8 @@ void read_block(uint32_t block_no, uint8_t *data) {
226247
} else if (block_no < START_ROOTDIR) { // Requested FAT table sector
227248
sectionIdx -= START_FAT0;
228249
// logval("sidx", sectionIdx);
229-
if (sectionIdx >= SECTORS_PER_FAT)
230-
sectionIdx -= SECTORS_PER_FAT; // second FAT is same as the first...
250+
if (sectionIdx >= BPB_SECTORS_PER_FAT)
251+
sectionIdx -= BPB_SECTORS_PER_FAT; // second FAT is same as the first...
231252
if (sectionIdx == 0) {
232253
data[0] = 0xf8; // first FAT entry must match BPB MediaDescriptor
233254
// WARNING -- code presumes only one NULL .content for .UF2 file

0 commit comments

Comments
 (0)