From e2afc36daeaeefd0de214d114db071b63e4820bb Mon Sep 17 00:00:00 2001 From: Henry Gabryjelski Date: Sun, 10 Mar 2019 20:02:56 -0700 Subject: [PATCH 1/7] Fix media type mismatch Fix the boot sector media descriptor to match the first FAT entries. --- src/usb/uf2/ghostfat.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/usb/uf2/ghostfat.c b/src/usb/uf2/ghostfat.c index 1f41c10..5ac475d 100644 --- a/src/usb/uf2/ghostfat.c +++ b/src/usb/uf2/ghostfat.c @@ -106,7 +106,7 @@ static FAT_BootBlock const BootBlock = { .FATCopies = 2, .RootDirectoryEntries = (ROOT_DIR_SECTORS * 512 / 32), .TotalSectors16 = NUM_FAT_BLOCKS - 2, - .MediaDescriptor = 0xF8, + .MediaDescriptor = 0xF0, .SectorsPerFAT = SECTORS_PER_FAT, .SectorsPerTrack = 1, .Heads = 1, From 12bb62eaddabf57f50e0f244c81bd18d7adbd30c Mon Sep 17 00:00:00 2001 From: Henry Gabryjelski Date: Tue, 12 Mar 2019 12:09:49 -0700 Subject: [PATCH 2/7] Per request, keep hard drive type in boot block. Update the .PhysicalDrive in boot block. Update the first fat entries to match MediaDescriptor of boot block. --- src/usb/uf2/ghostfat.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/usb/uf2/ghostfat.c b/src/usb/uf2/ghostfat.c index 5ac475d..3d4e71f 100644 --- a/src/usb/uf2/ghostfat.c +++ b/src/usb/uf2/ghostfat.c @@ -106,10 +106,11 @@ static FAT_BootBlock const BootBlock = { .FATCopies = 2, .RootDirectoryEntries = (ROOT_DIR_SECTORS * 512 / 32), .TotalSectors16 = NUM_FAT_BLOCKS - 2, - .MediaDescriptor = 0xF0, + .MediaDescriptor = 0xF8, .SectorsPerFAT = SECTORS_PER_FAT, .SectorsPerTrack = 1, .Heads = 1, + .PhysicalDriveNum = 0x80, // to match MediaDescriptor of 0xF8 .ExtendedBootSig = 0x29, .VolumeSerialNumber = 0x00420042, .VolumeLabel = VOLUME_LABEL, @@ -187,7 +188,7 @@ void read_block(uint32_t block_no, uint8_t *data) { if (sectionIdx >= SECTORS_PER_FAT) sectionIdx -= SECTORS_PER_FAT; if (sectionIdx == 0) { - data[0] = 0xf0; + data[0] = 0xf8; for (int i = 1; i < NUM_INFO * 2 + 4; ++i) { data[i] = 0xff; } @@ -210,7 +211,7 @@ void read_block(uint32_t block_no, uint8_t *data) { d->startCluster = i + 2; padded_memcpy(d->name, inf->name, 11); } - } + } } else { sectionIdx -= START_CLUSTERS; if (sectionIdx < NUM_INFO - 1) { From e0251415e76cd6778ad4507aa742f23b47b582d8 Mon Sep 17 00:00:00 2001 From: Henry Gabryjelski Date: Tue, 12 Mar 2019 12:29:05 -0700 Subject: [PATCH 3/7] Add some additional comments. --- src/usb/uf2/ghostfat.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/usb/uf2/ghostfat.c b/src/usb/uf2/ghostfat.c index 3d4e71f..1f0e60f 100644 --- a/src/usb/uf2/ghostfat.c +++ b/src/usb/uf2/ghostfat.c @@ -177,30 +177,30 @@ void read_block(uint32_t block_no, uint8_t *data) { memset(data, 0, 512); uint32_t sectionIdx = block_no; - if (block_no == 0) { + if (block_no == 0) { // Requested boot block memcpy(data, &BootBlock, sizeof(BootBlock)); data[510] = 0x55; data[511] = 0xaa; // logval("data[0]", data[0]); - } else if (block_no < START_ROOTDIR) { + } else if (block_no < START_ROOTDIR) { // Requested FAT table sector sectionIdx -= START_FAT0; // logval("sidx", sectionIdx); if (sectionIdx >= SECTORS_PER_FAT) - sectionIdx -= SECTORS_PER_FAT; + sectionIdx -= SECTORS_PER_FAT; // second FAT is same as the first... if (sectionIdx == 0) { - data[0] = 0xf8; + data[0] = 0xf8; // first FAT entry must match BPB MediaDescriptor for (int i = 1; i < NUM_INFO * 2 + 4; ++i) { data[i] = 0xff; } } - for (int i = 0; i < 256; ++i) { + for (int i = 0; i < 256; ++i) { // Generate the FAT chain for the firmware "file" uint32_t v = sectionIdx * 256 + i; if (UF2_FIRST_SECTOR <= v && v <= UF2_LAST_SECTOR) ((uint16_t *)(void *)data)[i] = v == UF2_LAST_SECTOR ? 0xffff : v + 1; } - } else if (block_no < START_CLUSTERS) { + } else if (block_no < START_CLUSTERS) { // Requested root directory sector sectionIdx -= START_ROOTDIR; - if (sectionIdx == 0) { + if (sectionIdx == 0) { // only one sector of directory entries generated DirEntry *d = (void *)data; padded_memcpy(d->name, (char const *) BootBlock.VolumeLabel, 11); d->attrs = 0x28; @@ -212,7 +212,7 @@ void read_block(uint32_t block_no, uint8_t *data) { padded_memcpy(d->name, inf->name, 11); } } - } else { + } else { // else Generate the UF2 file data on-the-fly sectionIdx -= START_CLUSTERS; if (sectionIdx < NUM_INFO - 1) { memcpy(data, info[sectionIdx].content, strlen(info[sectionIdx].content)); From a258c6d988bf695e01fa7b25988b8a253b560c0f Mon Sep 17 00:00:00 2001 From: Henry Gabryjelski Date: Tue, 12 Mar 2019 12:57:51 -0700 Subject: [PATCH 4/7] Avoid returning uninitialized memory --- src/usb/msc_uf2.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/usb/msc_uf2.c b/src/usb/msc_uf2.c index 4f9109a..4682154 100644 --- a/src/usb/msc_uf2.c +++ b/src/usb/msc_uf2.c @@ -64,6 +64,7 @@ int32_t tud_msc_scsi_cb (uint8_t lun, uint8_t const scsi_cmd[16], void* buffer, { void const* response = NULL; uint16_t resplen = 0; + memset(buffer, 0, bufsize); switch ( scsi_cmd[0] ) { @@ -114,6 +115,7 @@ int32_t tud_msc_scsi_cb (uint8_t lun, uint8_t const scsi_cmd[16], void* buffer, int32_t tud_msc_read10_cb (uint8_t lun, uint32_t lba, uint32_t offset, void* buffer, uint32_t bufsize) { (void) lun; + memset(buffer, 0, bufsize); // since we return block size each, offset should always be zero TU_ASSERT(offset == 0, -1); From 52cfdaa2d2c1f7cd494cf7ca40f6d6eeef665fe7 Mon Sep 17 00:00:00 2001 From: Henry Gabryjelski Date: Tue, 12 Mar 2019 13:05:21 -0700 Subject: [PATCH 5/7] Fix signed/unsigned bug. --- src/usb/msc_uf2.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/usb/msc_uf2.c b/src/usb/msc_uf2.c index 4f9109a..fb0f41d 100644 --- a/src/usb/msc_uf2.c +++ b/src/usb/msc_uf2.c @@ -63,7 +63,7 @@ int write_block(uint32_t block_no, uint8_t *data, bool quiet, WriteState *state) int32_t tud_msc_scsi_cb (uint8_t lun, uint8_t const scsi_cmd[16], void* buffer, uint16_t bufsize) { void const* response = NULL; - uint16_t resplen = 0; + int32_t resplen = 0; switch ( scsi_cmd[0] ) { @@ -98,7 +98,7 @@ int32_t tud_msc_scsi_cb (uint8_t lun, uint8_t const scsi_cmd[16], void* buffer, } // return len must not larger than bufsize - if ( resplen > bufsize ) resplen = bufsize; + if ( resplen > (int32_t)bufsize ) resplen = bufsize; // copy response to stack's buffer if any if ( response && resplen ) From 0f216b8618d78c43abf6037b75bbfefe28fea563 Mon Sep 17 00:00:00 2001 From: Henry Gabryjelski Date: Tue, 12 Mar 2019 13:13:58 -0700 Subject: [PATCH 6/7] Fix spacing --- src/usb/uf2/ghostfat.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/usb/uf2/ghostfat.c b/src/usb/uf2/ghostfat.c index 1f0e60f..c5ae379 100644 --- a/src/usb/uf2/ghostfat.c +++ b/src/usb/uf2/ghostfat.c @@ -210,7 +210,7 @@ void read_block(uint32_t block_no, uint8_t *data) { d->size = inf->content ? strlen(inf->content) : UF2_SIZE; d->startCluster = i + 2; padded_memcpy(d->name, inf->name, 11); - } + } } } else { // else Generate the UF2 file data on-the-fly sectionIdx -= START_CLUSTERS; From b8a0551678bc08569c0e24e7085732d3f001060e Mon Sep 17 00:00:00 2001 From: Henry Gabryjelski Date: Tue, 12 Mar 2019 13:41:33 -0700 Subject: [PATCH 7/7] Use local variable to store partially-calculated size. This avoid re-entrancy problems, such as if this is ever interrupted mid-execution, and called a second time before the initial execution completes. --- src/usb/uf2/ghostfat.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/usb/uf2/ghostfat.c b/src/usb/uf2/ghostfat.c index 1f41c10..c640814 100644 --- a/src/usb/uf2/ghostfat.c +++ b/src/usb/uf2/ghostfat.c @@ -123,35 +123,37 @@ static FAT_BootBlock const BootBlock = { static uint32_t current_flash_size(void) { static uint32_t flash_sz = 0; + uint32_t result = flash_sz; // presumes atomic 32-bit read/write and static result // only need to compute once - if ( flash_sz == 0 ) + if ( result == 0 ) { // return 1 block of 256 bytes if ( !bootloader_app_is_valid(DFU_BANK_0_REGION_START) ) { - flash_sz = 256; + result = 256; }else { bootloader_settings_t const * boot_setting; bootloader_util_settings_get(&boot_setting); - flash_sz = boot_setting->bank_0_size; + result = boot_setting->bank_0_size; // Copy size must be multiple of 256 bytes // else we will got an issue copying current.uf2 - if (flash_sz & 0xff) + if (result & 0xff) { - flash_sz = (flash_sz & ~0xff) + 256; + result = (result & ~0xff) + 256; } // if bank0 size is not valid, happens when flashed with jlink // use maximum application size - if ( (flash_sz == 0) || (flash_sz == 0xFFFFFFFFUL) ) + if ( (result == 0) || (result == 0xFFFFFFFFUL) ) { - flash_sz = FLASH_SIZE; + result = FLASH_SIZE; } } + flash_sz = result; // presumes atomic 32-bit read/write and static result } return flash_sz;