Adding subdir functionality

Added FAT16 driver ability to list subdir entries
Removed structure of FAT32 (we won't be using it anytime soon)
This commit is contained in:
Nigel Barink 2023-02-24 21:31:20 +01:00
parent a77621faf5
commit 644ff5b1f5
3 changed files with 84 additions and 54 deletions

View File

@ -78,7 +78,6 @@ extern "C" void kernel ()
int fat_size = bpb->FATSz16;
int root_dir_sectors = FAT::RootDirSize(bpb);
int first_data_sector = bpb->RsvdSecCnt + (bpb->NumFATs * fat_size) + root_dir_sectors ;
int first_fat_sector = bpb->RsvdSecCnt;
int data_sectors = bpb->TotSec32 - (bpb->RsvdSecCnt + (bpb->NumFATs * fat_size) + root_dir_sectors);
int total_clusters = data_sectors / bpb->SecPerClus;
@ -98,6 +97,7 @@ extern "C" void kernel ()
continue;
}
if(entry->ATTR & FAT::ATTRIBUTES::ATTR_HIDDEN){
continue;
}
@ -105,9 +105,9 @@ extern "C" void kernel ()
if(entry->ATTR & FAT::ATTRIBUTES::ATTR_SYSTEM)
continue;
if(entry->ATTR & FAT::ATTRIBUTES::ATTR_VOLUME_ID){
continue;
}
if (!(entry->ATTR & FAT::ATTRIBUTES::ATTR_LONG_NAME)){
for(char n : entry->Name){
@ -116,10 +116,13 @@ extern "C" void kernel ()
kterm_put(n);
}
}else{
printf("Long file name detected!\n");
printf("Long file name detected!");
}
printf(" [Size: %d bytes, Attributes: %x\n", entry->ATTR, entry->FileSize);
printf(" [Size: %d bytes, Attributes: %d]\n", entry->ATTR, entry->FileSize);
if(entry->ATTR & FAT::ATTRIBUTES::ATTR_DIRECTORY ){
FAT::OpenSubdir(entry, bpb);
}
}

View File

@ -113,12 +113,7 @@ BiosParameterBlock* FAT::getBPB( bool DEBUG ){
return bpb;
}
uint16_t FAT::GetFATEntry (BiosParameterBlock* bpb, unsigned int cluster){
int FATSz =0;
if(bpb->FATSz16 != 0){
FATSz = bpb->FATSz16;
} else{
//FATSz = bpb->FATSz32;
}
int FATSz = bpb->FATSz16;
int FATOffset = 0;
FAT_TYPE type = FAT::determineFATType(bpb);
@ -130,7 +125,7 @@ uint16_t FAT::GetFATEntry (BiosParameterBlock* bpb, unsigned int cluster){
int thisFATSecNum = bpb->RsvdSecCnt + (FATOffset / bpb->BytsPerSec); // Sector number containing the entry for the cluster
// For any other FAT other then the default
// For any other FAT other than the default
// SectorNumber = (FATNumber * FATSz) + ThisFATSecNum
uint16_t buff[bpb->BytsPerSec];
@ -179,14 +174,10 @@ int FAT::GetSectorOfRootDirectory (BiosParameterBlock* bpb)
return (bpb->RsvdSecCnt + (bpb->NumFATs * bpb->FATSz16));
}
int FAT::RootDirSize(BiosParameterBlock* bpb)
unsigned int FAT::RootDirSize(BiosParameterBlock* bpb)
{
int size = bpb->RootEntCnt * 32;
if((size % bpb->BytsPerSec) != 0){
printf("ERR: Root entry count invalid!\n");
return -1;
}
return size;
return ((bpb->RootEntCnt * 32) + (bpb->BytsPerSec -1)) /bpb->BytsPerSec;
}
@ -208,6 +199,73 @@ uint16_t* ReadFAT (BiosParameterBlock& bpb , bool DEBUG = false ) {
return FAT;
}
void FAT::OpenSubdir(DIR* directory, BiosParameterBlock* bpb ){
unsigned int cluster = directory->FstClusLo;
printf("Listing contents of " );
for(unsigned char n : directory->Name){
if(n == 0x20)
continue;
kterm_put(n);
}
kterm_put('\n');
printf("FsCluHi: 0x%x , FsCluLo: 0x%x\n", directory->FstClusHi, directory->FstClusLo);
printf("Cluster: 0x%x\n", cluster);
unsigned int FATEntry = FAT::GetFATEntry(bpb, cluster);
printf("FAT_Entry: 0x%x\n", FATEntry);
unsigned int root_dir_sectors = FAT::RootDirSize(bpb);
unsigned int fat_size = bpb->FATSz16;
unsigned int first_data_sector = bpb->RsvdSecCnt + ( bpb->NumFATs * fat_size) + root_dir_sectors;
unsigned int first_directory_sector = ((cluster - 2) * bpb->SecPerClus) + first_data_sector;
printf("Directory first sector 0x%x\n" , first_directory_sector);
uint16_t data[256];
ATAPIO::Read(ATAPIO_PORT::Primary, DEVICE_DRIVE::MASTER, first_directory_sector, data);
auto* directoryContents = (DIR*) data;
for(int i = 0; i < sizeof(data) / sizeof(DIR); i++){
DIR* entry = (DIR*)((uint32_t)directoryContents + (i * sizeof(DIR)));
if(entry->Name[0] == FAT::FREE_DIR || entry->Name[0] == FAT::FREE_DIR_2 || entry->Name[0] == 0xE5)
continue;
if(entry->ATTR & FAT::ATTRIBUTES::ATTR_HIDDEN){
continue;
}
if(entry->ATTR & FAT::ATTRIBUTES::ATTR_SYSTEM)
continue;
if(entry->ATTR & FAT::ATTRIBUTES::ATTR_VOLUME_ID){
continue;
}
if (!(entry->ATTR & FAT::ATTRIBUTES::ATTR_LONG_NAME)){
for(char n : entry->Name){
if(n == 0x20)
continue;
kterm_put(n);
}
kterm_put('\n');
}else{
printf("LFN\n");
}
}
}
void readFile(uint32_t DataRegion, DIR* entry, uint16_t FATentry, BiosParameterBlock& bpb ){
printf("Show contents");

View File

@ -18,25 +18,6 @@ struct ExtendedBootRecord_FAT16{
uint8_t SecRmndr[512];
}__attribute__((packed));
struct ExtendedBootRecord_FAT32{
uint32_t SectorsPerFAT;
uint16_t Flags;
const uint16_t FAT_VERSION_NUMBER;
uint32_t rootDirectory_clusterNumber;// Often set to 2;
uint16_t FSInfo_SectorNumber;
uint16_t backup_bpb_sectorNumber;
uint8_t Reserved [12];
uint8_t DriveNumber;
uint8_t Reserved2;
uint8_t Signature; // must be 0x28 or 0x29
uint32_t VOLUME_ID_SERIAL;
uint8_t volume_label[11];
uint8_t SystemIdentifierString [8]; // ALWAYS "FAT32 " but spec says do not trust
uint8_t BootCode [420]; // NICE
uint16_t PartitionSignature; // 0xAA55
}__attribute__((packed));
struct BiosParameterBlock {
uint8_t jmpBoot[3];
uint8_t OEMName [8];
@ -66,25 +47,10 @@ struct DIR {
uint16_t FstClusHi; // High Word of first data cluster for file/directory described
uint16_t WrtTime; // Last Modification time | Must equal CrtTime
uint16_t WrtDate; // Last Modification date | Must equal CrtDate
uint16_t FstClusLO; // Low word of first data cluster for file/directory described
uint16_t FstClusLo; // Low word of first data cluster for file/directory described
uint32_t FileSize; // size in bytes of file/directory described
}__attribute__((packed));
typedef struct _DIRECTORY{
uint8_t Filename[8];
uint8_t Ext[3];
uint8_t Attrib;
uint8_t Reserved;
uint8_t TimeCreatedMs;
uint16_t TimeCreated;
uint16_t DateCreated;
uint16_t DateLastAccessed;
uint16_t FirstClusterHiBytes;
uint16_t LastModTime;
uint16_t LastModDate;
uint16_t FirstCluster;
uint32_t FileSize;
}__attribute__((packed)) DIRECTORY, *PDIRECTORY;
enum struct FAT_TYPE{
FAT12,
@ -115,7 +81,10 @@ public:
static uint16_t GetFATEntry(BiosParameterBlock*, unsigned int);
static uint16_t DetermineFreeSpace();
static int GetSectorOfRootDirectory(BiosParameterBlock*);
static int RootDirSize(BiosParameterBlock*);
static unsigned int RootDirSize(BiosParameterBlock*);
static void OpenSubdir (DIR*, BiosParameterBlock*);
static const int FREE = 0x0000;
static const int ALLOCATED = 0x0002;