fat: Implement FAT12

This commit is contained in:
mintsuki 2021-05-11 06:04:23 +02:00
parent e228745e5c
commit 9174a241dc

View File

@ -13,6 +13,7 @@
#define FAT32_VALID_SIGNATURE_2 0x29 #define FAT32_VALID_SIGNATURE_2 0x29
#define FAT32_VALID_SYSTEM_IDENTIFIER "FAT32 " #define FAT32_VALID_SYSTEM_IDENTIFIER "FAT32 "
#define FAT16_VALID_SYSTEM_IDENTIFIER "FAT16 " #define FAT16_VALID_SYSTEM_IDENTIFIER "FAT16 "
#define FAT12_VALID_SYSTEM_IDENTIFIER "FAT12 "
#define FAT32_SECTOR_SIZE 512 #define FAT32_SECTOR_SIZE 512
#define FAT32_ATTRIBUTE_SUBDIRECTORY 0x10 #define FAT32_ATTRIBUTE_SUBDIRECTORY 0x10
#define FAT32_LFN_ATTRIBUTE 0x0F #define FAT32_LFN_ATTRIBUTE 0x0F
@ -86,6 +87,11 @@ static int fat32_init_context(struct fat32_context* context, struct volume *part
goto valid; goto valid;
} }
if (strncmp((((void *)&bpb) + 0x36), FAT12_VALID_SYSTEM_IDENTIFIER, SIZEOF_ARRAY(bpb.system_identifier)) == 0) {
context->type = 12;
goto valid;
}
return 1; return 1;
valid: valid:
@ -100,6 +106,7 @@ valid:
context->root_start = context->reserved_sectors + context->number_of_fats * context->sectors_per_fat; context->root_start = context->reserved_sectors + context->number_of_fats * context->sectors_per_fat;
context->root_size = DIV_ROUNDUP(context->root_entries * sizeof(struct fat32_directory_entry), FAT32_SECTOR_SIZE); context->root_size = DIV_ROUNDUP(context->root_entries * sizeof(struct fat32_directory_entry), FAT32_SECTOR_SIZE);
switch (context->type) { switch (context->type) {
case 12:
case 16: case 16:
context->data_start_lba = context->root_start + context->root_size; context->data_start_lba = context->root_start + context->root_size;
break; break;
@ -115,6 +122,17 @@ valid:
static int read_cluster_from_map(struct fat32_context *context, uint32_t cluster, uint32_t *out) { static int read_cluster_from_map(struct fat32_context *context, uint32_t cluster, uint32_t *out) {
switch (context->type) { switch (context->type) {
case 12: {
*out = 0;
uint16_t tmp = 0;
volume_read(context->part, &tmp, context->fat_start_lba * FAT32_SECTOR_SIZE + (cluster + cluster / 2), sizeof(uint16_t));
if (cluster % 2 == 0) {
*out = tmp & 0xfff;
} else {
*out = tmp >> 4;
}
break;
}
case 16: case 16:
*out = 0; *out = 0;
volume_read(context->part, out, context->fat_start_lba * FAT32_SECTOR_SIZE + cluster * sizeof(uint16_t), sizeof(uint16_t)); volume_read(context->part, out, context->fat_start_lba * FAT32_SECTOR_SIZE + cluster * sizeof(uint16_t), sizeof(uint16_t));
@ -133,7 +151,8 @@ static int read_cluster_from_map(struct fat32_context *context, uint32_t cluster
static uint32_t *cache_cluster_chain(struct fat32_context *context, static uint32_t *cache_cluster_chain(struct fat32_context *context,
uint32_t initial_cluster, uint32_t initial_cluster,
size_t *_chain_length) { size_t *_chain_length) {
uint32_t cluster_limit = (context->type == 16 ? 0xffef : 0) uint32_t cluster_limit = (context->type == 12 ? 0xfef : 0)
| (context->type == 16 ? 0xffef : 0)
| (context->type == 32 ? 0xfffffef : 0); | (context->type == 32 ? 0xfffffef : 0);
if (initial_cluster < 0x2 || initial_cluster > cluster_limit) if (initial_cluster < 0x2 || initial_cluster > cluster_limit)
return NULL; return NULL;
@ -321,6 +340,7 @@ int fat32_open(struct fat32_file_handle* ret, struct volume *part, const char* p
// walk down the directory tree // walk down the directory tree
switch (context.type) { switch (context.type) {
case 12:
case 16: case 16:
current_directory = NULL; current_directory = NULL;
break; break;