4.1. fat16
— FAT16 filesystem¶
File Allocation Table (FAT) is a computer file system architecture and a family of industry-standard file systems utilizing it. The FAT file system is a legacy file system which is simple and robust. It offers good performance even in light-weight implementations, but cannot deliver the same performance, reliability and scalability as some modern file systems. It is, however, supported for compatibility reasons by nearly all currently developed operating systems for personal computers and many mobile devices and embedded systems, and thus is a well-suited format for data exchange between computers and devices of almost any type and age from 1981 up to the present.
4.1.1. Example¶
Here is the pseudo-code for mounting a file system, performing file operations and unmounting the file system.
All function arguments are omitted in this example.
/* Mount the file system. This is normally done once when the
application starts. */
fat16_init();
fat16_mount();
/* Perform file operations. */
fat16_file_open();
fat16_file_read();
fat16_file_close();
fat16_file_open();
fat16_file_write();
fat16_file_close();
/* Unmount the file system when it is no long needed. Normally when
the application stops. */
fat16_unmount();
Source code: src/filesystems/fat16.h, src/filesystems/fat16.c
Test code: tst/filesystems/fat16/main.c
Test coverage: src/filesystems/fat16.c
Example code: examples/fat16/main.c
Defines
-
FAT16_SEEK_SET
0¶
-
FAT16_SEEK_CUR
1¶ The offset is relative to the current position indicator.
-
FAT16_SEEK_END
2¶ The offset is relative to the end of the file.
-
FAT16_EOF
-1¶ End of file indicator.
-
O_READ
0x01¶ Open for reading.
-
O_RDONLY
O_READ¶ Same as O_READ.
-
O_WRITE
0x02¶ Open for write.
-
O_WRONLY
O_WRITE¶ Same as O_WRITE.
-
O_RDWR
(O_READ | O_WRITE)¶ Open for reading and writing.
-
O_APPEND
0x04¶ The file position indicator shall be set to the end of the file prior to each write.
-
O_SYNC
0x08¶ Synchronous writes.
-
O_CREAT
0x10¶ Create the file if non-existent.
-
O_EXCL
0x20¶ If O_CREAT and O_EXCL are set, file open shall fail if the file exists.
-
O_TRUNC
0x40¶ Truncate the file to zero length.
-
DIR_ATTR_READ_ONLY
0x01¶ File is read-only.
-
DIR_ATTR_HIDDEN
0x02¶ File should hidden in directory listings.
-
DIR_ATTR_SYSTEM
0x04¶ Entry is for a system file.
-
DIR_ATTR_VOLUME_ID
0x08¶ Directory entry contains the volume label.
-
DIR_ATTR_DIRECTORY
0x10¶ Entry is for a directory.
-
DIR_ATTR_ARCHIVE
0x20¶ Old DOS archive bit for backup support.
Typedefs
-
typedef ssize_t (*
fat16_read_t
)(void *arg_p, void *dst_p, uint32_t src_block)¶ Block read function callback.
-
typedef ssize_t (*
fat16_write_t
)(void *arg_p, uint32_t dst_block, const void *src_p)¶ Block write function callback.
-
typedef uint16_t
fat_t
¶ A FAT entry.
Functions
-
int
fat16_init
(struct fat16_t *self_p, fat16_read_t read, fat16_write_t write, void *arg_p, unsigned int partition)¶ Initialize a FAT16 volume.
- Return
- zero(0) or negative error code.
- Parameters
self_p
: FAT16 object to initialize.read
: Callback function used to read blocks of data.write
: Callback function used to write blocks of data.arg_p
: Argument passed as the first arguemtn to read() and write().partition
: Partition to be used. Legal values for a partition are 1-4 to use the corresponding partition on a device formatted with a MBR, Master Boot Record, or zero if the device is formatted as a super floppy with the FAT boot sector in block zero.
-
int
fat16_mount
(struct fat16_t *self_p)¶ Mount given FAT16 volume.
- Return
- zero(0) or negative error code.
- Parameters
self_p
: FAT16 object.
-
int
fat16_unmount
(struct fat16_t *self_p)¶ Unmount given FAT16 volume.
- Return
- zero(0) or negative error code.
- Parameters
self_p
: FAT16 object.
-
int
fat16_format
(struct fat16_t *self_p)¶ Create an empty FAT16 file system on the device.
- Parameters
self_p
: FAT16 object.
-
int
fat16_print
(struct fat16_t *self_p, void *chan_p)¶ Print volume information to given channel.
- Return
- zero(0) or negative error code.
- Parameters
self_p
: FAT16 object.chan_p
: Output channel.
-
int
fat16_file_open
(struct fat16_t *self_p, struct fat16_file_t *file_p, const char *path_p, int oflag)¶ Open a file by file path and mode flags.
- Return
- zero(0) or negative error code.
- Parameters
self_p
: FAT16 object.file_p
: File object to be initialized.path_p
: A valid 8.3 DOS name for a file path.oflag
: mode of file open (create, read, write, etc).
-
int
fat16_file_close
(struct fat16_file_t *file_p)¶ Close a file and force cached data and directory information to be written to the media.
- Return
- zero(0) or negative error code.
- Parameters
file_p
: File object.
-
ssize_t
fat16_file_read
(struct fat16_file_t *file_p, void *buf_p, size_t size)¶ Read data to given buffer with given size from the file.
- Return
- Number of bytes read or EOF(-1).
- Parameters
file_p
: File object.buf_p
: Buffer to read into.size
: number of bytes to read.
-
ssize_t
fat16_file_write
(struct fat16_file_t *file_p, const void *buf_p, size_t size)¶ Write data from buffer with given size to the file.
- Return
- Number of bytes written or EOF(-1).
- Parameters
file_p
: File object.buf_p
: Buffer to write.size
: number of bytes to write.
-
int
fat16_file_seek
(struct fat16_file_t *file_p, int pos, int whence)¶ Sets the file’s read/write position relative to mode.
- Return
- zero(0) or negative error code.
- Parameters
file_p
: File object.pos
: New position in bytes from given mode.whence
: Absolute, relative or from end.
-
ssize_t
fat16_file_tell
(struct fat16_file_t *file_p)¶ Return current position in the file.
- Return
- Current position or negative error code.
- Parameters
file_p
: File object.
-
int
fat16_file_truncate
(struct fat16_file_t *file_p, size_t size)¶ Truncate given file to a size of precisly
size
bytes.If the file previously was larger than this size, the extra data is lost. If the file previously was shorter, it is extended, and the extended part reads as null bytes (‘\0’).
- Return
- zero(0) or negative error code.
- Parameters
file_p
: File object.size
: New size of the file in bytes.
-
ssize_t
fat16_file_size
(struct fat16_file_t *file_p)¶ Return number of bytes in the file.
- Return
- File size in bytes or negative error code.
- Parameters
file_p
: File object.
-
int
fat16_file_sync
(struct fat16_file_t *file_p)¶ Causes all modified data and directory fields to be written to the storage device.
- Return
- zero(0) or negative error code.
- Parameters
file_p
: File object.
-
int
fat16_dir_open
(struct fat16_t *self_p, struct fat16_dir_t *dir_p, const char *path_p, int oflag)¶ Open a directory by directory path and mode flags.
- Return
- zero(0) or negative error code.
- Parameters
self_p
: FAT16 object.dir_p
: Directory object to be initialized.path_p
: A valid 8.3 DOS name for a directory path.oflag
: mode of the directory to open (create, read, etc).
-
int
fat16_dir_close
(struct fat16_dir_t *dir_p)¶ Close given directory.
- Return
- zero(0) or negative error code.
- Parameters
dir_p
: Directory object.
-
int
fat16_dir_read
(struct fat16_dir_t *dir_p, struct fat16_dir_entry_t *entry_p)¶ Read the next file or directory within the opened directory.
- Return
- true(1) if an entry was read or false(0) if no entry could be read, otherwise negative error code.
- Parameters
dir_p
: Directory object.entry_p
: Read entry.
-
int
fat16_stat
(struct fat16_t *self_p, const char *path_p, struct fat16_stat_t *stat_p)¶ Gets file status by path.
- Return
- zero(0) or negative error code.
- Parameters
self_p
: The file system struct.path_p
: The path of the file to stat.stat_p
: The stat struct to populate.
-
union
fat16_time_t
¶ - #include <fat16.h>
FAT Time Format. A FAT directory entry time stamp is a 16-bit field that has a granularity of 2 seconds. Here is the format (bit 0 is the LSB of the 16-bit word, bit 15 is the MSB of the 16-bit word).
Bits 0-4: 2-second count, valid value range 0-29 inclusive (0-58 seconds). Bits 5-10: Minutes, valid value range 0-59 inclusive. Bits 11-15: Hours, valid value range 0-23 inclusive.
The valid time range is from Midnight 00:00:00 to 23:59:58.
-
union
fat16_date_t
¶ - #include <fat16.h>
FAT date representation support Date Format. A FAT directory entry date stamp is a 16-bit field that is basically a date relative to the MS-DOS epoch of 01/01/1980. Here is the format (bit 0 is the LSB of the 16-bit word, bit 15 is the MSB of the 16-bit word):
Bits 0-4: Day of month, valid value range 1-31 inclusive. Bits 5-8: Month of year, 1 = January, valid value range 1-12 inclusive. Bits 9-15: Count of years from 1980, valid value range 0-127 inclusive (1980-2107).
-
struct
part_t
¶ - #include <fat16.h>
MBR partition table entry. A partition table entry for a MBR formatted storage device. The MBR partition table has four entries.
Public Members
-
uint8_t
boot
¶ Boot Indicator. Indicates whether the volume is the active partition. Legal values include: 0x00. Do not use for booting. 0x80 Active partition.
-
uint8_t
begin_head
¶ Head part of Cylinder-head-sector address of the first block in the partition. Legal values are 0-255. Only used in old PC BIOS.
-
unsigned
begin_sector
¶ Sector part of Cylinder-head-sector address of the first block in the partition. Legal values are 1-63. Only used in old PC BIOS.
-
unsigned
begin_cylinder_high
¶ High bits cylinder for first block in partition.
-
uint8_t
begin_cylinder_low
¶ Combine beginCylinderLow with beginCylinderHigh. Legal values are 0-1023. Only used in old PC BIOS.
-
uint8_t
type
¶ Partition type. See defines that begin with PART_TYPE_ for some Microsoft partition types.
-
uint8_t
end_head
¶ head part of cylinder-head-sector address of the last sector in the partition. Legal values are 0-255. Only used in old PC BIOS.
-
unsigned
end_sector
¶ Sector part of cylinder-head-sector address of the last sector in the partition. Legal values are 1-63. Only used in old PC BIOS.
-
unsigned
end_cylinder_high
¶ High bits of end cylinder
-
uint8_t
end_cylinder_low
¶ Combine endCylinderLow with endCylinderHigh. Legal values are 0-1023. Only used in old PC BIOS.
-
uint32_t
first_sector
¶ Logical block address of the first block in the partition.
-
uint32_t
total_sectors
¶ Length of the partition, in blocks.
-
uint8_t
-
struct
bpb_t
¶ - #include <fat16.h>
BIOS parameter block; The BIOS parameter block describes the physical layout of a FAT volume.
Public Members
-
uint16_t
bytes_per_sector
¶ Count of bytes per sector. This value may take on only the following values: 512, 1024, 2048 or 4096
-
uint8_t
sectors_per_cluster
¶ Number of sectors per allocation unit. This value must be a power of 2 that is greater than 0. The legal values are 1, 2, 4, 8, 16, 32, 64, and 128.
-
uint16_t
reserved_sector_count
¶ Number of sectors before the first FAT. This value must not be zero.
-
uint8_t
fat_count
¶ The count of FAT data structures on the volume. This field should always contain the value 2 for any FAT volume of any type.
-
uint16_t
root_dir_entry_count
¶ For FAT12 and FAT16 volumes, this field contains the count of 32-byte directory entries in the root directory. For FAT32 volumes, this field must be set to 0. For FAT12 and FAT16 volumes, this value should always specify a count that when multiplied by 32 results in a multiple of bytesPerSector. FAT16 volumes should use the value 512.
-
uint16_t
total_sectors_small
¶ This field is the old 16-bit total count of sectors on the volume. This count includes the count of all sectors in all four regions of the volume. This field can be 0; if it is 0, then totalSectors32 must be non-zero. For FAT32 volumes, this field must be 0. For FAT12 and FAT16 volumes, this field contains the sector count, and totalSectors32 is 0 if the total sector count fits (is less than 0x10000).
-
uint8_t
media_type
¶ This dates back to the old MS-DOS 1.x media determination and is no longer usually used for anything. 0xf8 is the standard value for fixed (non-removable) media. For removable media, 0xf0 is frequently used. Legal values are 0xf0 or 0xf8-0xff.
-
uint16_t
sectors_per_fat
¶ Count of sectors occupied by one FAT on FAT12/FAT16 volumes. On FAT32 volumes this field must be 0, and sectorsPerFat32 contains the FAT size count.
-
uint16_t
sectors_per_track
¶ Sectors per track for interrupt 0x13. Not used otherwise.
-
uint16_t
head_count
¶ Number of heads for interrupt 0x13. Not used otherwise.
-
uint32_t
hiddden_sectors
¶ Count of hidden sectors preceding the partition that contains this FAT volume. This field is generally only relevant for media visible on interrupt 0x13.
-
uint32_t
total_sectors_large
¶ This field is the new 32-bit total count of sectors on the volume. This count includes the count of all sectors in all four regions of the volume. This field can be 0; if it is 0, then totalSectors16 must be non-zero.
-
uint16_t
-
struct
fbs_t
¶ - #include <fat16.h>
Boot sector for a FAT16 or FAT32 volume.
Public Members
-
uint8_t
jmp_to_boot_code
[3]¶ X86 jmp to boot program
-
char
oem_name
[8]¶ Informational only - don’t depend on it
-
uint8_t
drive_number
¶ For int0x13 use value 0x80 for hard drive
-
uint8_t
reserved1
¶ Used by Windows NT - should be zero for FAT
-
uint8_t
boot_signature
¶ 0x29 if next three fields are valid
-
uint32_t
volume_serial_number
¶ Usually generated by combining date and time
-
char
volume_label
[11]¶ Should match volume label in root dir
-
char
file_system_type
[8]¶ Informational only - don’t depend on it
-
uint8_t
boot_code
[448]¶ X86 boot code
-
uint16_t
boot_sector_sig
¶ Must be 0x55AA
-
uint8_t
-
struct
mbr_t
¶ - #include <fat16.h>
Master Boot Record. The first block of a storage device that is formatted with a MBR.
-
struct
dir_t
¶ - #include <fat16.h>
FAT short directory entry. Short means short 8.3 name, not the entry size.
Public Members
-
uint8_t
name
[11]¶ Short 8.3 name. The first eight bytes contain the file name with blank fill. The last three bytes contain the file extension with blank fill.
-
uint8_t
attributes
¶ Entry attributes. The upper two bits of the attribute byte are reserved and should always be set to 0 when a file is created and never modified or looked at after that. See defines that begin with DIR_ATT_.
-
uint8_t
reserved1
¶ Reserved for use by Windows NT. Set value to 0 when a file is created and never modify or look at it after that.
-
uint8_t
creation_time_tenths
¶ The granularity of the seconds part of creationTime is 2 seconds so this field is a count of tenths of a second and its valid value range is 0-199 inclusive. (WHG note - seems to be hundredths)
-
uint16_t
creation_time
¶ Time file was created.
-
uint16_t
creation_date
¶ Date file was created.
-
uint16_t
last_access_date
¶ Last access date. Note that there is no last access time, only a date. This is the date of last read or write. In the case of a write, this should be set to the same date as lastWriteDate.
-
uint16_t
first_cluster_high
¶ High word of this entry’s first cluster number (always 0 for a FAT12 or FAT16 volume).
-
uint16_t
last_write_time
¶ Time of last write. File creation is considered a write.
-
uint16_t
last_write_date
¶ Date of last write. File creation is considered a write.
-
uint16_t
first_cluster_low
¶ Low word of this entry’s first cluster number.
-
uint32_t
file_size
¶ 32-bit unsigned holding this file’s size in bytes.
-
uint8_t
-
union
fat16_cache16_t
¶
-
struct
fat16_cache_t
¶ Public Members
-
uint32_t
block_number
¶
-
uint8_t
dirty
¶
-
uint32_t
mirror_block
¶
-
union fat16_cache16_t
buffer
¶
-
uint32_t
-
struct
fat16_t
¶ Public Members
-
fat16_read_t
read
¶
-
fat16_write_t
write
¶
-
void *
arg_p
¶
-
unsigned int
partition
¶
-
uint8_t
fat_count
¶
-
uint8_t
blocks_per_cluster
¶
-
uint16_t
root_dir_entry_count
¶
-
uint32_t
volume_start_block
¶
-
uint32_t
fat_start_block
¶
-
uint32_t
root_dir_start_block
¶
-
uint32_t
data_start_block
¶
-
struct fat16_cache_t
cache
¶
-
fat16_read_t
-
struct
fat16_file_t
¶
-
struct
fat16_dir_t
¶
-
struct
fat16_dir_entry_t
¶
-
struct
fat16_stat_t
¶