fat16.h (7618B)
1 /* FAT16 Filesystem Driver for LuajitOS Boot Partition 2 * 3 * Simple FAT16 implementation for reading/writing the unencrypted boot partition. 4 * Used to store kernel, GRUB, and bootloader files. 5 */ 6 7 #ifndef FAT16_H 8 #define FAT16_H 9 10 #include <stdint.h> 11 #include <stddef.h> 12 13 #ifdef __cplusplus 14 extern "C" { 15 #endif 16 17 /* FAT16 constants */ 18 #define FAT16_SECTOR_SIZE 512 19 #define FAT16_DIR_ENTRY_SIZE 32 20 #define FAT16_ENTRIES_PER_SECTOR (FAT16_SECTOR_SIZE / FAT16_DIR_ENTRY_SIZE) 21 22 /* File attributes */ 23 #define FAT16_ATTR_READ_ONLY 0x01 24 #define FAT16_ATTR_HIDDEN 0x02 25 #define FAT16_ATTR_SYSTEM 0x04 26 #define FAT16_ATTR_VOLUME_ID 0x08 27 #define FAT16_ATTR_DIRECTORY 0x10 28 #define FAT16_ATTR_ARCHIVE 0x20 29 30 /* Special cluster values */ 31 #define FAT16_CLUSTER_FREE 0x0000 32 #define FAT16_CLUSTER_RESERVED 0x0001 33 #define FAT16_CLUSTER_BAD 0xFFF7 34 #define FAT16_CLUSTER_END_MIN 0xFFF8 35 #define FAT16_CLUSTER_END 0xFFFF 36 37 /* Error codes */ 38 #define FAT16_OK 0 39 #define FAT16_ERR_IO -1 40 #define FAT16_ERR_NOT_FAT16 -2 41 #define FAT16_ERR_NOT_FOUND -3 42 #define FAT16_ERR_NO_SPACE -4 43 #define FAT16_ERR_INVALID -5 44 #define FAT16_ERR_EXISTS -6 45 #define FAT16_ERR_DIR_NOT_EMPTY -7 46 47 /* Boot sector / BPB (BIOS Parameter Block) */ 48 typedef struct __attribute__((packed)) { 49 uint8_t jump[3]; /* Jump instruction */ 50 char oem_name[8]; /* OEM name */ 51 uint16_t bytes_per_sector; /* Bytes per sector (512) */ 52 uint8_t sectors_per_cluster; /* Sectors per cluster */ 53 uint16_t reserved_sectors; /* Reserved sectors before FAT */ 54 uint8_t num_fats; /* Number of FATs (usually 2) */ 55 uint16_t root_entries; /* Root directory entries */ 56 uint16_t total_sectors_16; /* Total sectors (16-bit, 0 if >65535) */ 57 uint8_t media_type; /* Media type (0xF8 for HDD) */ 58 uint16_t fat_sectors; /* Sectors per FAT */ 59 uint16_t sectors_per_track; /* Sectors per track */ 60 uint16_t num_heads; /* Number of heads */ 61 uint32_t hidden_sectors; /* Hidden sectors before partition */ 62 uint32_t total_sectors_32; /* Total sectors (32-bit) */ 63 /* Extended boot record (FAT16) */ 64 uint8_t drive_number; /* Drive number */ 65 uint8_t reserved1; /* Reserved */ 66 uint8_t boot_signature; /* Extended boot signature (0x29) */ 67 uint32_t volume_id; /* Volume serial number */ 68 char volume_label[11]; /* Volume label */ 69 char fs_type[8]; /* Filesystem type ("FAT16 ") */ 70 uint8_t boot_code[448]; /* Boot code */ 71 uint16_t signature; /* Boot signature (0xAA55) */ 72 } fat16_boot_sector_t; 73 74 /* Directory entry */ 75 typedef struct __attribute__((packed)) { 76 char name[8]; /* Filename (space-padded) */ 77 char ext[3]; /* Extension (space-padded) */ 78 uint8_t attributes; /* File attributes */ 79 uint8_t reserved; /* Reserved for Windows NT */ 80 uint8_t create_time_ms; /* Creation time (ms) */ 81 uint16_t create_time; /* Creation time */ 82 uint16_t create_date; /* Creation date */ 83 uint16_t access_date; /* Last access date */ 84 uint16_t cluster_high; /* High 16 bits of cluster (FAT32 only, 0 for FAT16) */ 85 uint16_t modify_time; /* Last modify time */ 86 uint16_t modify_date; /* Last modify date */ 87 uint16_t cluster_low; /* Starting cluster */ 88 uint32_t file_size; /* File size in bytes */ 89 } fat16_dir_entry_t; 90 91 /* FAT16 context (mounted filesystem) */ 92 typedef struct { 93 uint8_t bus; /* ATA bus */ 94 uint8_t drive; /* ATA drive */ 95 uint32_t partition_start; /* Partition start sector */ 96 uint32_t partition_size; /* Partition size in sectors */ 97 uint16_t bytes_per_sector; /* Bytes per sector */ 98 uint8_t sectors_per_cluster; /* Sectors per cluster */ 99 uint16_t reserved_sectors; /* Reserved sectors */ 100 uint8_t num_fats; /* Number of FATs */ 101 uint16_t root_entries; /* Root directory entries */ 102 uint16_t fat_sectors; /* Sectors per FAT */ 103 uint32_t total_sectors; /* Total sectors */ 104 uint32_t fat_start; /* FAT start sector (relative to partition) */ 105 uint32_t root_start; /* Root directory start sector */ 106 uint32_t data_start; /* Data area start sector */ 107 uint32_t data_clusters; /* Number of data clusters */ 108 uint8_t is_mounted; /* Is filesystem mounted? */ 109 } fat16_context_t; 110 111 /* ============================================================================ 112 * API Functions 113 * ========================================================================= */ 114 115 /** 116 * Format a partition with FAT16 117 * 118 * @param bus ATA bus 119 * @param drive ATA drive 120 * @param part_start Partition start sector 121 * @param part_size Partition size in sectors 122 * @param label Volume label (up to 11 chars) 123 * @return FAT16_OK on success, error code on failure 124 */ 125 int fat16_format(uint8_t bus, uint8_t drive, 126 uint32_t part_start, uint32_t part_size, 127 const char *label); 128 129 /** 130 * Mount a FAT16 partition 131 * 132 * @param ctx Context to initialize 133 * @param bus ATA bus 134 * @param drive ATA drive 135 * @param part_start Partition start sector 136 * @return FAT16_OK on success, error code on failure 137 */ 138 int fat16_mount(fat16_context_t *ctx, uint8_t bus, uint8_t drive, 139 uint32_t part_start); 140 141 /** 142 * Unmount a FAT16 partition 143 * 144 * @param ctx Context to unmount 145 * @return FAT16_OK on success 146 */ 147 int fat16_unmount(fat16_context_t *ctx); 148 149 /** 150 * Create a file or directory 151 * 152 * @param ctx Mounted FAT16 context 153 * @param path Path (e.g., "/BOOT/GRUB/GRUB.CFG") 154 * @param is_dir 1 to create directory, 0 for file 155 * @return FAT16_OK on success, error code on failure 156 */ 157 int fat16_create(fat16_context_t *ctx, const char *path, int is_dir); 158 159 /** 160 * Write data to a file 161 * 162 * @param ctx Mounted FAT16 context 163 * @param path File path 164 * @param data Data to write 165 * @param size Data size in bytes 166 * @return FAT16_OK on success, error code on failure 167 */ 168 int fat16_write_file(fat16_context_t *ctx, const char *path, 169 const void *data, uint32_t size); 170 171 /** 172 * Read data from a file 173 * 174 * @param ctx Mounted FAT16 context 175 * @param path File path 176 * @param buffer Buffer to read into 177 * @param max_size Maximum bytes to read 178 * @param bytes_read Output: actual bytes read 179 * @return FAT16_OK on success, error code on failure 180 */ 181 int fat16_read_file(fat16_context_t *ctx, const char *path, 182 void *buffer, uint32_t max_size, uint32_t *bytes_read); 183 184 /** 185 * Check if file/directory exists 186 * 187 * @param ctx Mounted FAT16 context 188 * @param path Path to check 189 * @return 1 if exists, 0 if not 190 */ 191 int fat16_exists(fat16_context_t *ctx, const char *path); 192 193 /** 194 * Get file size 195 * 196 * @param ctx Mounted FAT16 context 197 * @param path File path 198 * @return File size in bytes, or -1 on error 199 */ 200 int32_t fat16_file_size(fat16_context_t *ctx, const char *path); 201 202 /** 203 * Get error string 204 * 205 * @param error Error code 206 * @return Human-readable error string 207 */ 208 const char *fat16_error_string(int error); 209 210 #ifdef __cplusplus 211 } 212 #endif 213 214 #endif /* FAT16_H */