trios/kernel/fs/fat.c

60 lines
2.2 KiB
C

#include <string.h>
#include "../term.h"
#include "../panic.h"
#include "fat.h"
bool fat_init(struct FatInfo *fatinfo, struct AtaDevice dev, struct MbrPartition partition) {
uint8_t boot_sector[512] __attribute__((aligned(2)));
if(!ata_read(dev, partition.start_sector, 1, (void*)boot_sector)) return false;
memcpy(&fatinfo->bpb, boot_sector, sizeof(struct FatBpb));
memcpy(&fatinfo->ebpb.f16, boot_sector + sizeof(struct FatBpb), sizeof(struct Fat16Ebpb));
fatinfo->type = FAT16;
fatinfo->dev = dev;
fatinfo->partition = partition;
return true;
}
static int read_dir_entry_sector(struct FatFile *file, struct FatInfo *fatinfo, size_t sector, char* name) {
uint8_t buf[512] __attribute__((aligned(2)));
if(!ata_read(fatinfo->dev, fatinfo->partition.start_sector + sector, 1, (uint16_t*)buf)) panic("read fail");
for(int i = 0; i < 512; i += 32) {
if(buf[i] == 0) return 1; // reached end
if(buf[i] == 0xE5) continue;
if(buf[i+11] == 0x0F) continue;
int j;
for(j = 0; j < 11; j++) {
if(buf[i + j] != name[j]) break;
}
if(j != 11) continue;
memcpy(file->name, &buf[i], 11);
file->start_cluster = buf[i+26] | (buf[i+27] << 8) | (buf[i+20] << 16) | (buf[i+21] << 24);
file->size = buf[i+28] | (buf[i+29] << 8) | (buf[i+30] << 16) | (buf[i+31] << 24);
file->attributes = buf[i+11];
return 0; // found file
}
return 2; // next sector
}
static bool read_dir_entry(struct FatFile *file, struct FatInfo *fatinfo, size_t start_sector, size_t sector_count, char* name) {
for(size_t i = 0; i < sector_count; i++) {
int result = read_dir_entry_sector(file, fatinfo, start_sector + i, name);
if(result == 0) return true;
if(result == 1) break;
// continue if result == 2
}
return false;
}
bool fat_test(struct FatInfo *fatinfo) {
size_t root_start = fatinfo->bpb.reserved_sectors + fatinfo->bpb.fat_count * fatinfo->bpb.sectors_per_fat;
size_t root_sectors = (fatinfo->bpb.root_entries * 32 + 511) / 512;
printf("root start %d sectors %d\n", root_start, root_sectors);
printf("%X\n", root_start * 512);
struct FatFile file;
read_dir_entry(&file, fatinfo, root_start, root_sectors, "FILE3 ");
printf("start: 0x%X\n", file.start_cluster);
printf("size: 0x%X\n", file.size);
printf("attr: 0x%X\n", file.attributes);
return true;
}