From 169f21fbb158a07ee628d86f3c20339fcf490939 Mon Sep 17 00:00:00 2001 From: Dean Camera Date: Mon, 25 Mar 2013 20:58:33 +0000 Subject: Add Long File Name (VFAT) entry to the Mass Storage class bootloader, so that systems such as Linux that load a VFAT filesystem driver instead of the legacy MSDOS filesystem do not corrupt the volume by trying to write a LFN entry. --- Bootloaders/MassStorage/Lib/VirtualFAT.c | 71 ++++++++++++++++++++++++-------- Bootloaders/MassStorage/Lib/VirtualFAT.h | 70 +++++++++++++++++++++++++++---- 2 files changed, 114 insertions(+), 27 deletions(-) (limited to 'Bootloaders') diff --git a/Bootloaders/MassStorage/Lib/VirtualFAT.c b/Bootloaders/MassStorage/Lib/VirtualFAT.c index e0541f436..c0d9786ee 100644 --- a/Bootloaders/MassStorage/Lib/VirtualFAT.c +++ b/Bootloaders/MassStorage/Lib/VirtualFAT.c @@ -72,33 +72,68 @@ static const FATBootBlock_t BootBlock = }; /** FAT 8.3 style directory entry, for the virtual FLASH contents file. */ -static FATDirectoryEntry_t FirmwareFileEntries[2] = +static FATDirectoryEntry_t FirmwareFileEntries[] = { /* Root volume label entry; disk label is contained in the Filename and * Extension fields (concatenated) with a special attribute flag - other * fields are ignored. Should be the same as the label in the boot block. */ { - .Filename = "LUFA BOO", - .Extension = "T ", - .Attributes = (1 << 3), - .Reserved = {0}, - .CreationTime = 0, - .CreationDate = 0, - .StartingCluster = 0, - .FileSizeBytes = 0, + .MSDOS = + { + .Filename = "LUFA BOO", + .Extension = "T ", + .Attributes = FAT_FLAG_VOLUME_NAME, + .Reserved = {0}, + .CreationTime = 0, + .CreationDate = 0, + .StartingCluster = 0, + .FileSizeBytes = 0, + } }, - /* File entry for the virtual Firmware image. */ + /* VFAT Long File Name entry for the virtual firmware file; required to + * prevent corruption of systems that are unable to detect the device + * as being a legacy MSDOS style FAT12 volume to prevent corruption. */ { - .Filename = "FIRMWARE", - .Extension = "BIN", - .Attributes = 0, - .Reserved = {0}, - .CreationTime = FAT_TIME(1, 1, 0), - .CreationDate = FAT_DATE(14, 2, 1989), - .StartingCluster = 2, - .FileSizeBytes = FIRMWARE_FILE_SIZE_BYTES, + .VFAT = + { + .Ordinal = FAT_ORDINAL_LAST_ENTRY | 1, + .Attribute = FAT_FLAG_LONG_FILE_NAME, + .Reserved1 = 0, + .Reserved2 = 0, + + .Checksum = 0x57, + + .Unicode1 = 'F', + .Unicode2 = 'I', + .Unicode3 = 'R', + .Unicode4 = 'M', + .Unicode5 = 'W', + .Unicode6 = 'A', + .Unicode7 = 'R', + .Unicode8 = 'E', + .Unicode9 = '.', + .Unicode10 = 'B', + .Unicode11 = 'I', + .Unicode12 = 'N', + .Unicode13 = 0, + } + }, + + /* MSDOS file entry for the virtual Firmware image. */ + { + .MSDOS = + { + .Filename = "FIRMWARE", + .Extension = "BIN", + .Attributes = 0, + .Reserved = {0}, + .CreationTime = FAT_TIME(1, 1, 0), + .CreationDate = FAT_DATE(14, 2, 1989), + .StartingCluster = 2, + .FileSizeBytes = FIRMWARE_FILE_SIZE_BYTES, + } }, }; diff --git a/Bootloaders/MassStorage/Lib/VirtualFAT.h b/Bootloaders/MassStorage/Lib/VirtualFAT.h index 7eacdd952..440b65d1a 100644 --- a/Bootloaders/MassStorage/Lib/VirtualFAT.h +++ b/Bootloaders/MassStorage/Lib/VirtualFAT.h @@ -94,6 +94,33 @@ */ #define FAT_DATE(dd, mm, yyyy) (((yyyy - 1980) << 9) | (mm << 5) | (dd << 0)) + /** \name FAT Filesystem Flags */ + //@{ + /** FAT attribute flag to indicate a read-only file. */ + #define FAT_FLAG_READONLY (1 << 0) + + /** FAT attribute flag to indicate a hidden file. */ + #define FAT_FLAG_HIDDEN (1 << 1) + + /** FAT attribute flag to indicate a system file. */ + #define FAT_FLAG_SYSTEM (1 << 2) + + /** FAT attribute flag to indicate a Volume name entry. */ + #define FAT_FLAG_VOLUME_NAME (1 << 3) + + /** FAT attribute flag to indicate a directory entry. */ + #define FAT_FLAG_DIRECTORY (1 << 4) + + /** FAT attribute flag to indicate a file ready for archiving. */ + #define FAT_FLAG_ARCHIVE (1 << 5) + + /** FAT pseudo-attribute flag to indicate a Long File Name entry. */ + #define FAT_FLAG_LONG_FILE_NAME 0x0F + + /** Ordinal flag marker for FAT Long File Name entries to mark the last entry. */ + #define FAT_ORDINAL_LAST_ENTRY (1 << 6) + //@} + /* Type Definitions: */ /** FAT boot block structure definition, used to identify the core * parameters of a FAT filesystem stored on a disk. @@ -130,16 +157,41 @@ /** FAT legacy 8.3 style directory entry structure definition, used to * identify the files and folders of FAT filesystem stored on a disk. */ - typedef struct + typedef union { - uint8_t Filename[8]; - uint8_t Extension[3]; - uint8_t Attributes; - uint8_t Reserved[10]; - uint16_t CreationTime; - uint16_t CreationDate; - uint16_t StartingCluster; - uint32_t FileSizeBytes; + struct + { + uint8_t Ordinal; + uint16_t Unicode1; + uint16_t Unicode2; + uint16_t Unicode3; + uint16_t Unicode4; + uint16_t Unicode5; + uint8_t Attribute; + uint8_t Reserved1; + uint8_t Checksum; + uint16_t Unicode6; + uint16_t Unicode7; + uint16_t Unicode8; + uint16_t Unicode9; + uint16_t Unicode10; + uint16_t Unicode11; + uint16_t Reserved2; + uint16_t Unicode12; + uint16_t Unicode13; + } VFAT; + + struct + { + uint8_t Filename[8]; + uint8_t Extension[3]; + uint8_t Attributes; + uint8_t Reserved[10]; + uint16_t CreationTime; + uint16_t CreationDate; + uint16_t StartingCluster; + uint32_t FileSizeBytes; + } MSDOS; } FATDirectoryEntry_t; /* Function Prototypes: */ -- cgit v1.2.3