From a77621faf50bf8cc39f88a6f6bad64897c47cd76 Mon Sep 17 00:00:00 2001 From: Nigel Date: Thu, 23 Feb 2023 23:54:02 +0100 Subject: [PATCH] Shellscript improvement plus FAT driver implementations - Improved the run bash script to exit when an error occurs in one of the sub tasks - Wrote basic FAT16 functions that should give enough information to properly implement the rest of the driver - FAT structure namings are now in accordence with the microsoft spec of March 2005 --- kernel/Makefile | 6 +- kernel/kernel.cpp | 75 ++++- .../filesystems/FAT/BiosParameterBlock.h | 21 -- .../storage/filesystems/FAT/DirectoryEntry.h | 37 --- .../filesystems/FAT/ExtendBootRecord.h | 32 -- kernel/storage/filesystems/FAT/FAT.cpp | 307 ++++++++++-------- kernel/storage/filesystems/FAT/FAT.h | 156 +++++++-- kernel/storage/filesystems/FAT/msdosDate.h | 40 +++ .../storage/partitions/partitionManager.cpp | 18 + kernel/storage/partitions/partitionManager.h | 11 + kernel/storage/vfs/FileSystem.cpp | 41 --- kernel/storage/vfs/FileSystem.h | 18 - kernel/storage/vfs/Inode.cpp | 5 - kernel/storage/vfs/Inode.h | 24 -- kernel/storage/vfs/StorageTypes.h | 40 --- kernel/storage/vfs/vfs.cpp | 250 ++++++++------ kernel/storage/vfs/vfs.h | 34 +- kernel/storage/vfs/vfs_types.h | 116 +++++++ .../supervisorterminal/superVisorTerminal.cpp | 3 +- run.sh | 21 +- 20 files changed, 760 insertions(+), 495 deletions(-) delete mode 100644 kernel/storage/filesystems/FAT/BiosParameterBlock.h delete mode 100644 kernel/storage/filesystems/FAT/DirectoryEntry.h delete mode 100644 kernel/storage/filesystems/FAT/ExtendBootRecord.h create mode 100644 kernel/storage/filesystems/FAT/msdosDate.h create mode 100644 kernel/storage/partitions/partitionManager.cpp create mode 100644 kernel/storage/partitions/partitionManager.h delete mode 100644 kernel/storage/vfs/FileSystem.cpp delete mode 100644 kernel/storage/vfs/FileSystem.h delete mode 100644 kernel/storage/vfs/Inode.cpp delete mode 100644 kernel/storage/vfs/Inode.h delete mode 100644 kernel/storage/vfs/StorageTypes.h create mode 100644 kernel/storage/vfs/vfs_types.h diff --git a/kernel/Makefile b/kernel/Makefile index 4d333d1..0c8f291 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -1,6 +1,6 @@ -AS = ${HOME}/opt/cross/bin/i686-elf-as -CC = ${HOME}/opt/cross/bin/i686-elf-gcc -CPP = ${HOME}/opt/cross/bin/i686-elf-g++ +AS = /opt/cross/bin/i686-elf-as +CC = /opt/cross/bin/i686-elf-gcc +CPP = /opt/cross/bin/i686-elf-g++ CFLAGS = -ffreestanding -Og -ggdb -Wall -Wextra -I ../build/CoreLib/include BUILD_DIR = ../build/kernel OBJ_DIR = ../bin/kernel diff --git a/kernel/kernel.cpp b/kernel/kernel.cpp index 7609e71..1ca7bf7 100644 --- a/kernel/kernel.cpp +++ b/kernel/kernel.cpp @@ -15,6 +15,8 @@ #include "interrupts/idt.h" #include "serial.h" #include "storage/vfs/vfs.h" +#include "storage/filesystems/FAT/FAT.h" + extern "C" void LoadGlobalDescriptorTable(); extern "C" void jump_usermode(); @@ -54,20 +56,83 @@ extern "C" void kernel () printf("booted from floppy disk\n"); printf("Part1: %d, Part2: %d, Part3: %d\n", part1, part2 , part3); + ATAPIO::Identify(ATAPIO_PORT::Primary, DEVICE_DRIVE::MASTER); + auto* bpb = FAT::getBPB(false); + auto* mbr = GetPartitions(false); + auto fsType = FAT::determineFATType(bpb); + switch (fsType) { + case FAT_TYPE::FAT12: + printf("FAT12 Disk!\n"); + break; + case FAT_TYPE::FAT16: + printf("FAT16 Disk!\n"); + break; + case FAT_TYPE::FAT32: + printf("FAT32 Disk!\n"); + break; + } - VirtualFileSystem::initialize(); + // list files in root + int total_sectors = bpb->TotSec32; + 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; - // Try and open hello.txt file - VirtualFileSystem::OpenFile("a:hello.txt"); + + int first_root_dir_sector = first_data_sector - root_dir_sectors; + //int first_sector_of_cluster = ((cluster - 2) * bpb->SecPerClus) + first_data_sector; + uint16_t data[256]; + ATAPIO::Read(ATAPIO_PORT::Primary, DEVICE_DRIVE::MASTER, first_root_dir_sector, data); + + auto* RootDirectory = (DIR*)data; + for(int i = 0; i < sizeof(data) / sizeof (DIR); i++) + { + DIR* entry = (DIR*)((uint32_t)RootDirectory + (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); + } + }else{ + printf("Long file name detected!\n"); + } + printf(" [Size: %d bytes, Attributes: %x\n", entry->ATTR, entry->FileSize); + + + } - // Try and open grub.cfg file - VirtualFileSystem::OpenFile("a:boot/grub/grub.cfg"); + // VirtualFileSystem::initialize(); + + // VirtualFileSystem::open("/hello.txt", 0); + + #ifdef USERMODE_RELEASE // Lets jump into user mode jump_usermode(); diff --git a/kernel/storage/filesystems/FAT/BiosParameterBlock.h b/kernel/storage/filesystems/FAT/BiosParameterBlock.h deleted file mode 100644 index 3bf2de3..0000000 --- a/kernel/storage/filesystems/FAT/BiosParameterBlock.h +++ /dev/null @@ -1,21 +0,0 @@ -#pragma once -#include -#include "./ExtendBootRecord.h" - -struct BiosParameterBlock { - uint8_t BootLoaderCodeSection [3]; - uint8_t OEM_id [8]; - uint16_t BytesPerSector ; // I suspect would be 512 - uint8_t SectorsPerCluster ; - uint16_t ReservedSectors; - uint8_t NumberOfFileAllocationTables; // Probably equals 2 - uint16_t NumberOfDirectoryEntries; // Root directory must contain entire sectors - uint16_t TotalSectorsInLogicalVolume ; // 0 means >65535 sectors in volume , actual count can be found in LargeSectorCount - uint8_t MediaDescriptor ; // Indication the media descriptor type - uint16_t NumberOfSectorsPerFAT;// only in FAT12 / FAT 16 - uint16_t NumberOfSectorsPerTrack; - uint16_t NumberOfHeadsOnMedia; - uint32_t NumberOfHiddenSectors; - uint32_t LargeSectorCount; - ExtendedBootRecord_FAT16 ebpb; -}__attribute__((packed)); \ No newline at end of file diff --git a/kernel/storage/filesystems/FAT/DirectoryEntry.h b/kernel/storage/filesystems/FAT/DirectoryEntry.h deleted file mode 100644 index bbc3a9a..0000000 --- a/kernel/storage/filesystems/FAT/DirectoryEntry.h +++ /dev/null @@ -1,37 +0,0 @@ -#pragma once -#include - -struct DirectoryEntry { - uint8_t filename [8]; - uint8_t Extension [3]; - uint8_t attribute; - uint8_t Reserved; - uint8_t creation; // Creation in tenths of a second - uint16_t CreationTime; // Time Created NOTE: Multiply the seconds by 2 - uint16_t CreationDate; // Date Created - uint16_t LastAccessDate; - uint16_t ReservedFAT32; - uint16_t LastWriteTime; - uint16_t LastWriteDate; - uint16_t StartingCluster; - uint32_t FilesizeInBytes; - -}__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; \ No newline at end of file diff --git a/kernel/storage/filesystems/FAT/ExtendBootRecord.h b/kernel/storage/filesystems/FAT/ExtendBootRecord.h deleted file mode 100644 index 38a40b7..0000000 --- a/kernel/storage/filesystems/FAT/ExtendBootRecord.h +++ /dev/null @@ -1,32 +0,0 @@ -#pragma once -#include - -struct ExtendedBootRecord_FAT16{ - uint8_t DriveNumber; - uint8_t Reserved; - uint8_t Signature; - const uint32_t VOLUME_ID_SERIAL_NUMBER; - uint8_t volume_label [11]; - uint8_t Identifier_string [8]; - uint8_t bootCode [448]; - uint16_t partitionSignature; -}__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)); \ No newline at end of file diff --git a/kernel/storage/filesystems/FAT/FAT.cpp b/kernel/storage/filesystems/FAT/FAT.cpp index 9161c6b..84a77f4 100644 --- a/kernel/storage/filesystems/FAT/FAT.cpp +++ b/kernel/storage/filesystems/FAT/FAT.cpp @@ -4,105 +4,198 @@ #include "FAT.h" #include "../../ata pio/ATAPIO.h" #include "../../../memory/KernelHeap.h" +#include "../../../../CoreLib/Memory.h" +#include "../../partitiontables/mbr/MasterBootRecord.h" #include - -void FAT::Read(PFILE file, unsigned char* buffer , unsigned int length) +superblock* FAT::Mount(filesystem *fs, const char* name ,vfsmount *mnt) { -} - -FILE FAT::Open(char* filename) -{ - - char* tokstate = NULL; - char* nextdir = strtok(filename, "/", &tokstate); - - while (nextdir) + if( strncmp (fs->name, "fat", 3 ) != 0 ) { - - // Read the root directory - printf("First entry to look for: %s\n", nextdir); - - - - nextdir = strtok(NULL, "/", &tokstate); + printf("Can't mount filesystem with none fat type!\n"); + return nullptr; } - FILE file; - file.flags = FS_INVALID; - return file; + superblock* sb = (superblock*) malloc(sizeof(superblock)); + directoryEntry* root = (directoryEntry*) malloc(sizeof (directoryEntry)); + root->name = (char*) name; + root->node = nullptr; + root->parent = nullptr; + dentry_operations* op = (dentry_operations*) malloc(sizeof(dentry_operations)); + op->compare = FAT::compare; + + + root->op = op; + + + mnt->mnt_count =1; + mnt->mnt_devname = "QEMU HDD"; + mnt->mnt_flags = 0; + mnt->mnt_parent = nullptr; + + mnt->root = root; + mnt->sb = sb; + + sb->type = fs; + sb->root = root; + //sb->fs_info = getBPB(); + + return sb; } - -void FAT::Write(PFILE file, unsigned char* buffer, unsigned int length) +int FAT::Read(file* file, void* buffer , int length) { - + return 0; } - -void ParseDateInteger(unsigned int date){ - printf("Date (hex) 0x%x\n", date); - unsigned int year = (date >> 9 )+ 1980; - unsigned int month = (date & 0xf0 ) >> 4; - unsigned int day = date & 0xf ; - printf("Date: (D,M,Y) %d, %d ,%d\n", day , month, year ); - +int FAT::Write(file* file, const void* buffer, int length) +{ + return 0; } +int FAT::compare (directoryEntry*, char* filename, char* filename2) +{ + // use the size of the smallest string + int a = strlen(filename); + int b = strlen(filename2); + + if( a == b ){ + return strncmp(filename, filename2, a); + } + return a-b; +} +int FAT::create(inode* dir_node, inode** target, const char* component_name){} +int FAT::lookup (inode*, inode**, const char*){} -BiosParameterBlock* getBPB(PTR_PARTITION partition, bool DEBUG =false ){ +FAT_TYPE FAT::determineFATType(BiosParameterBlock* bpb){ + int RootDirSector = ((bpb->RootEntCnt * 32) + (bpb->BytsPerSec -1)) / bpb->BytsPerSec; + int FATSz = 0; + if(bpb->FATSz16 != 0){ + FATSz = bpb->FATSz16; + } else{ + // FATSz = bpb->FATSz32; + + } + int TotSec = 0; + if(bpb->TotSec16 != 0){ + TotSec= bpb->TotSec16; + }else{ + TotSec = bpb->TotSec32; + } + + int DataSec = TotSec - (bpb->RsvdSecCnt + (bpb->NumFATs * FATSz) + RootDirSector); + int CountofClusters = DataSec / bpb->SecPerClus; + + if(CountofClusters < 4085){ + return FAT_TYPE::FAT12; + } else if (CountofClusters < 65525) { + return FAT_TYPE::FAT16; + } else{ + return FAT_TYPE::FAT32; + } +}; +BiosParameterBlock* FAT::getBPB( bool DEBUG ){ BiosParameterBlock* bpb = (BiosParameterBlock*) malloc(sizeof(BiosParameterBlock)); - - ATAPIO_PORT port = (ATAPIO_PORT)(partition->Disk & 0x01FF); - DEVICE_DRIVE drive = (DEVICE_DRIVE)(partition->Disk >> 16); - - printf("ATAPIO_PORT: 0x%x DEVICE_DRIVE: 0x%x\n",port, drive); - printf("Partition Start Address (LBA): 0x%x\n", partition->StartAddress); - - ATAPIO::Read(ATAPIO_PORT::Primary, DEVICE_DRIVE::MASTER, partition->StartAddress, (uint16_t*) bpb); + uint16_t StartAddress = 0x00 ; + ATAPIO::Read(ATAPIO_PORT::Primary, DEVICE_DRIVE::MASTER, StartAddress, (uint16_t*) bpb); if(DEBUG) { - printf("OEM ID: %s\n", bpb->OEM_id); - printf("Bytes per sector: %d\n", bpb->BytesPerSector); - printf("Sectors per cluster: %d\n", bpb->SectorsPerCluster); - printf("Reserved sectors: %d\n", bpb->ReservedSectors); - printf("Number of FAT: %d\n", bpb->NumberOfFileAllocationTables); - printf("Number of Dir entries: %d\n", bpb->NumberOfDirectoryEntries); - printf("Total Sectors in volume: %d\n", bpb->TotalSectorsInLogicalVolume); - printf("Sectors per FAT: %d\n", bpb->NumberOfSectorsPerFAT); + printf("OEM ID: %s\n", bpb->OEMName); + printf("Bytes per sector: %d\n", bpb->BytsPerSec); + printf("Sectors per cluster: %d\n", bpb->SecPerClus); + printf("Reserved sectors: %d\n", bpb->RsvdSecCnt); + printf("Number of FAT: %d\n", bpb->NumFATs); + printf("Number of Dir entries: %d\n", bpb->RootEntCnt); + printf("Total Sectors in volume: %d\n", bpb->TotSec16 == 0 ? bpb->TotSec32 : bpb->TotSec16); + printf("Sectors per FAT: %d\n", bpb->FATSz16 ); } return bpb; } - -bool FAT::Validate(PTR_PARTITION partition ) -{ - - auto* bootParams = getBPB(partition, true); - - if(bootParams->OEM_id) { - return true; +uint16_t FAT::GetFATEntry (BiosParameterBlock* bpb, unsigned int cluster){ + int FATSz =0; + if(bpb->FATSz16 != 0){ + FATSz = bpb->FATSz16; + } else{ + //FATSz = bpb->FATSz32; } - return false; + int FATOffset = 0; + FAT_TYPE type = FAT::determineFATType(bpb); + if( type == FAT_TYPE::FAT16){ + FATOffset = cluster *2; + } else if( type == FAT_TYPE::FAT32){ + FATOffset = cluster * 4; + } + + int thisFATSecNum = bpb->RsvdSecCnt + (FATOffset / bpb->BytsPerSec); // Sector number containing the entry for the cluster + + // For any other FAT other then the default + // SectorNumber = (FATNumber * FATSz) + ThisFATSecNum + + uint16_t buff[bpb->BytsPerSec]; + + ATAPIO::Read(ATAPIO_PORT::Primary, DEVICE_DRIVE::MASTER, thisFATSecNum, buff ); + + int thisFATEntOffset = FATOffset % bpb->BytsPerSec; // offset for the entry in the sector containing the entry for the cluster + uint16_t ClusterEntryValue = 0; + // Get the FATEntry + if(type == FAT_TYPE::FAT16){ + return *((uint16_t*) &buff[thisFATEntOffset]); + + } + else{ + // FAT32 logic + return 0; + } } -void FAT::Info(_PARTITION *pPartition, PFS pSystem) { - pSystem->Read = FAT::Read; - pSystem->Write = FAT::Write; - pSystem->Open = FAT::Open; + + +uint16_t FAT::DetermineFreeSpace() +{ + // Loop through all FAT entries in all FAT's + // to construct a list of free/available clusters + // Free clusters are recorded with all 0's except on FAT32 where + // the highest order 4 bits should be ignored. + +/* + * The number of sectors reserved for each FAT (count of sectors in the BPB_FATSz16 or +BPB_FATSz32 fields) may be bigger than the actual number of sectors required for +containing the entire FAT. Therefore, there may be totally unused FAT sectors at the end of +each FAT in the FAT region of the volume. Each implementation must determine the value +for the last valid sector in the FAT using CountOfClusters (the last valid sector in the FAT +is the one containing the FAT entry numbered CountOfClusters + 1). +All sectors reserved for the FAT beyond the last valid sector (defined as the one containing +the FAT entry for the last cluster) must be set to 0x0 during volume initialization/format. + */ } -uint16_t* ReadFAT (BiosParameterBlock& bpb , PTR_PARTITION partition, bool DEBUG = false ) { - uint32_t FATAddress = partition->StartAddress + bpb.ReservedSectors ; +int FAT::GetSectorOfRootDirectory (BiosParameterBlock* bpb) +{ + return (bpb->RsvdSecCnt + (bpb->NumFATs * bpb->FATSz16)); +} + +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; +} + + + +uint16_t* ReadFAT (BiosParameterBlock& bpb , bool DEBUG = false ) { + uint32_t FATAddress = /*StartAddress*/ 0x00 + bpb.RsvdSecCnt ; uint16_t* FAT = (uint16_t*)malloc(sizeof (uint16_t) * 256); - ATAPIO_PORT port = (ATAPIO_PORT)(partition->Disk & 0x01FF); - DEVICE_DRIVE drive = (DEVICE_DRIVE)(partition->Disk >> 16); - ATAPIO::Read(port, drive, FATAddress, FAT ); + ATAPIO::Read(ATAPIO_PORT::Primary, DEVICE_DRIVE::MASTER, FATAddress, FAT ); // Show data in terminal if(DEBUG){ @@ -115,14 +208,15 @@ uint16_t* ReadFAT (BiosParameterBlock& bpb , PTR_PARTITION partition, bool DEBUG return FAT; } -void readFile(uint32_t DataRegion, DirectoryEntry* entry, uint16_t FATentry, BiosParameterBlock& bpb ){ + +void readFile(uint32_t DataRegion, DIR* entry, uint16_t FATentry, BiosParameterBlock& bpb ){ printf("Show contents"); - printf("Start cluster of the file: 0x%x\n", entry->StartingCluster); + printf("Start cluster of the file: 0x%x\n", entry->FileSize); printf("IS it only 1 cluster? %s\n", FATentry == 0xFFFF ? "Yes" : "No"); - uint32_t sector = DataRegion + ((entry->StartingCluster - 0x02) * bpb.SectorsPerCluster); + uint32_t sector = DataRegion + ((entry->FileSize - 0x02) * bpb.SecPerClus); uint16_t dataBlob[256]; @@ -134,66 +228,21 @@ void readFile(uint32_t DataRegion, DirectoryEntry* entry, uint16_t FATentry, Bio } kterm_put('\n'); } + + + /* -void listFilesInRoot(MBR& mbr, BiosParameterBlock& bpb ){ - auto FATAddress = mbr.TableEntries[0].LBA_partition_start + bpb.ReservedSectors; - uint32_t RootDirectoryRegion = FATAddress + ( bpb.NumberOfFileAllocationTables * bpb.NumberOfSectorsPerFAT ); - uint32_t DataRegion = RootDirectoryRegion + ((bpb.NumberOfDirectoryEntries * 32) / bpb.BytesPerSector ); - uint16_t* FAT = ReadFAT(bpb, mbr); - - uint16_t data2 [256]; - ATA_DEVICE::Read(BUS_PORT::Primary, DEVICE_DRIVE::MASTER, RootDirectoryRegion, data2 ); - auto* RootDirectory = (DirectoryEntry*) data2; - - // List files in root - for(int i= 0; i < sizeof (data2) / sizeof (DirectoryEntry); i++ ) { - auto *entry = (DirectoryEntry * )((uint32_t) RootDirectory + (i * sizeof(DirectoryEntry))); - - if (entry->filename[0] == (uint8_t) 0x00) - continue; // There are no more entries in this directory or the entry is free - - if (entry->attribute & ATTRIBUTES::ATT_HIDDEN) - continue; - if(entry->attribute & ATTRIBUTES::ATTR_SYSTEM) - continue; - if(entry->attribute & ATTRIBUTES::ATTR_VOLUME_ID) - continue; - - // Print the filename; - for (char n: entry->filename) { - if (n == 0x20) - break; - kterm_put(n); - } - for (unsigned char n: entry->Extension) { - kterm_put(n); - } - kterm_put('\n'); - - - printf("Attribute: %x \n", entry->attribute); - printf("FileSize: %d Bytes\n", entry->FilesizeInBytes); - - if (entry->FilesizeInBytes != 0x0 && (entry->attribute != 0x10)) { - readFile(DataRegion,entry, FAT[i], bpb); - } - - } - free(FAT); - -} - -FILE fsysFatDirectory (const char* DirectoryName){ - FILE file; +file fsysFatDirectory (const char* DirectoryName){ + file file; unsigned char* buf; PDIRECTORY directory; char DosFileName[11]; - ToDosFileName(DirectoryName, DosFileName, 11); + //ToDosFileName(DirectoryName, DosFileName, 11); DosFileName[11] =0; for (int sector=0; sector <14 ; sector++){ - ATA_DEVICE::Read(BUS_PORT::Primary, DEVICE_DRIVE::MASTER, mountInfo.rootOffset + sector, (uint16_t*)buf); + ATAPIO::Read(BUS_PORT::Primary, DEVICE_DRIVE::MASTER, mountInfo.rootOffset + sector, (uint16_t*)buf); directory = (PDIRECTORY) buf; for (int i =0; i < 16; i++){ @@ -209,9 +258,9 @@ FILE fsysFatDirectory (const char* DirectoryName){ file.filelength = directory->FileSize; if(directory->Attrib == 0x10){ - file.flags = FS_DIRECTORY; + file.flags = 2; } else { - file.flags = FS_FILE; + file.flags = 1; } return file; } @@ -220,7 +269,7 @@ FILE fsysFatDirectory (const char* DirectoryName){ } // Can't find file - file.flags = FS_INVALID; + file.flags = -1; return file; } @@ -300,9 +349,9 @@ FILE fsysFatOpenSubDir(FILE kFile, const char* filename){ // set file type; if(pkDir->Attrib == 0x10){ - file.flags = FS_DIRECTORY; + file.flags = 2; } else{ - file.flags = FS_FILE; + file.flags = 1; } return file; @@ -312,7 +361,7 @@ FILE fsysFatOpenSubDir(FILE kFile, const char* filename){ } } // unable to find file - file.flags = FS_INVALID; + file.flags = -1; return file; } - */ +*/ diff --git a/kernel/storage/filesystems/FAT/FAT.h b/kernel/storage/filesystems/FAT/FAT.h index bf8cce9..388811e 100644 --- a/kernel/storage/filesystems/FAT/FAT.h +++ b/kernel/storage/filesystems/FAT/FAT.h @@ -2,48 +2,152 @@ // Created by nigel on 21/02/23. // #pragma once -#include "ExtendBootRecord.h" -#include "BiosParameterBlock.h" -#include "DirectoryEntry.h" -#include "../../vfs/StorageTypes.h" +#include "../../vfs/vfs_types.h" +#include "../../vfs/vfs_types.h" +#include "../../partitiontables/mbr/MasterBootRecord.h" -// Date Format -// [0..4] Day -// [5..8] Month -// [9..15] Year +struct ExtendedBootRecord_FAT16{ + uint8_t DrvNum; + uint8_t Reserved1; + uint8_t BootSig; + const uint32_t VolID; + uint8_t VolLab [11]; + uint8_t FilSysType [8]; + uint8_t bootCode [448]; + uint16_t Signature_word; + uint8_t SecRmndr[512]; +}__attribute__((packed)); -// Time Format -// [0..4] Seconds -// [5..10] Minute -// [11..15] Hour +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]; + uint16_t BytsPerSec ; // I suspect would be 512 + uint8_t SecPerClus ; + uint16_t RsvdSecCnt; + uint8_t NumFATs; // Probably equals 2 + uint16_t RootEntCnt; // Root directory must contain entire sectors + uint16_t TotSec16 ; // 0 means >65535 sectors in volume , actual count can be found in LargeSectorCount + uint8_t Media ; // Indication the media descriptor type + uint16_t FATSz16;// only in FAT12 / FAT 16 + uint16_t SecPerTrk; + uint16_t NumHeads; + uint32_t HiddSec; + uint32_t TotSec32; + ExtendedBootRecord_FAT16 ebpb; +}__attribute__((packed)); + +struct DIR { + uint8_t Name [11]; + uint8_t ATTR ; + uint8_t NTRes; + uint8_t CrtTimeTenth; // File Creation time component - count of tenths of a second (between 0 and 199) + uint16_t CrtTime; // Creation time. Granularity is 2 seconds + uint16_t CrtDate; // Creation date. + uint16_t LstAccDate; // Last Access Date (Last read or write date) + 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 + 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, + FAT16, + FAT32, + VFAT, + UNKOWN +}; class FAT { public: + // Wanted API for vfs + static file Open(char* filename); + static int close(file* file); + static int Read(file* file, void* buffer , int length); + static int Write(file* file, const void* buffer, int length); + static int create(inode* dir_node, inode** target, const char* component_name); + static int lookup(inode* , inode**, const char*); + static int compare(directoryEntry* , char* , char*); + static superblock* Mount(filesystem* fs, const char* name ,vfsmount* mount); - static bool Validate(PTR_PARTITION partition ); + // TEMP + static void listFilesInRoot(MBR* mbr, BiosParameterBlock* bpb ); + static BiosParameterBlock* getBPB( bool DEBUG =false ); + static FAT_TYPE determineFATType(BiosParameterBlock* bpb); + static uint16_t GetFATEntry(BiosParameterBlock*, unsigned int); + static uint16_t DetermineFreeSpace(); + static int GetSectorOfRootDirectory(BiosParameterBlock*); + static int RootDirSize(BiosParameterBlock*); - static FILE Open(char* filename); - static void Read(PFILE file, unsigned char* buffer , unsigned int length); - static void Write(PFILE file, unsigned char* buffer, unsigned int length); + static const int FREE = 0x0000; + static const int ALLOCATED = 0x0002; + static const int BAD = 0xFFF7; + static const int EOF = 0xFFFF; - static void Info(_PARTITION *pPartition, PFS pSystem); + static const int ClnShutBitMask = 0x8000; + static const int HrdErrBitMask = 0x4000; + + static const char DOS_TRAILING_SPACE = 0x20; + static const char FREE_DIR = 0xE5; // If KANJI charset 0x05 + static const char FREE_DIR_2 = 0x00; // All directories after this are free including this one -private: - enum struct TYPE{ - FAT, - FAT16, - FAT32, - VFAT - }; enum ATTRIBUTES { ATTR_READ_ONLY = 0x01, - ATT_HIDDEN = 0x02, + ATTR_HIDDEN = 0x02, ATTR_SYSTEM = 0x04, ATTR_VOLUME_ID = 0x08, ATTR_DIRECTORY = 0x10, - ATTR_ARCHIVE = 0x20 + ATTR_ARCHIVE = 0x20, + ATTR_LONG_NAME = (ATTR_READ_ONLY | ATTR_HIDDEN | ATTR_SYSTEM | ATTR_VOLUME_ID) }; + +private: + + + enum ENTRY_SIZE { + FAT12 = 12, + FAT16 = 16, + FAT32 = 32 + }; + + + }; diff --git a/kernel/storage/filesystems/FAT/msdosDate.h b/kernel/storage/filesystems/FAT/msdosDate.h new file mode 100644 index 0000000..c1fff64 --- /dev/null +++ b/kernel/storage/filesystems/FAT/msdosDate.h @@ -0,0 +1,40 @@ +// +// Created by nigel on 23/02/23. +// + +#pragma once + +#include "../../../terminal/kterm.h" + +// Date Format +// [0..4] Day +// [5..8] Month +// [9..15] Year +class MSDOSDATE { + static void ParseDate(unsigned int date){ + printf("Date (hex) 0x%x\n", date); + unsigned int year = (date >> 9 )+ 1980; + unsigned int month = (date & 0xf0 ) >> 4; + unsigned int day = date & 0xf ; + printf("Date: (D,M,Y) %d, %d ,%d\n", day , month, year ); + } +}; + + + +// Time Format +// [0..4] Seconds +// [5..10] Minute +// [11..15] Hour +class MSDOSTIME { + static void ParseTime(unsigned int time) + { + printf("Time (hex) 0x%x\n", time); + unsigned int seconds = ( time & 0x0f) * 2; + unsigned int minutes = (time & 0xf0); + unsigned int hours = (time & 0xf00); + printf("Time (H:M:S) %d:%d:%d\n", hours, minutes, seconds); + } +}; + + diff --git a/kernel/storage/partitions/partitionManager.cpp b/kernel/storage/partitions/partitionManager.cpp new file mode 100644 index 0000000..ef62452 --- /dev/null +++ b/kernel/storage/partitions/partitionManager.cpp @@ -0,0 +1,18 @@ +// +// Created by nigel on 23/02/23. +// + +#include "partitionManager.h" + +bool partitionManager::Validate( ) +{ + + //auto* bootParams = getBPB(this, true); + + //if(bootParams->OEM_id) { + // return true; + //} + + return true; + +} diff --git a/kernel/storage/partitions/partitionManager.h b/kernel/storage/partitions/partitionManager.h new file mode 100644 index 0000000..56cbee9 --- /dev/null +++ b/kernel/storage/partitions/partitionManager.h @@ -0,0 +1,11 @@ +// +// Created by nigel on 23/02/23. +// +#pragma once + +class partitionManager { +public: + static bool Validate(); + +}; + diff --git a/kernel/storage/vfs/FileSystem.cpp b/kernel/storage/vfs/FileSystem.cpp deleted file mode 100644 index fe92789..0000000 --- a/kernel/storage/vfs/FileSystem.cpp +++ /dev/null @@ -1,41 +0,0 @@ -// -// Created by nigel on 21/02/23. -// -#include "FileSystem.h" - -void FileSystem::WriteFile(int file, unsigned char* buffer, unsigned int length) { - -} - -void FileSystem::ReadFile(int file, unsigned char* buffer, unsigned int length) { - -} - -FILE FileSystem::OpenFile(const char* fname){ - if(fname){ - unsigned char device = 'a'; - char* filename = (char*) fname; - - if(fname[1]== ':'){ - device = fname[0]; - filename += 2; // strip the volume component from the path - } - - if(_filesystems[device - 'a']){ - FILE file = _filesystems[device-'a']->Open(filename); - file.device = device; - return file; - } - } - FILE file; - file.flags = FS_INVALID; - return file; -} - -void FileSystem::CloseFile(PFILE file) { - if(file->device < DEVICE_MAX){ - // _filesystems[file->device]->Close(file); - } -} - - diff --git a/kernel/storage/vfs/FileSystem.h b/kernel/storage/vfs/FileSystem.h deleted file mode 100644 index 939eab9..0000000 --- a/kernel/storage/vfs/FileSystem.h +++ /dev/null @@ -1,18 +0,0 @@ -// -// Created by nigel on 21/02/23. -// -#pragma once -#include "StorageTypes.h" - -class FileSystem { -public: - static void WriteFile(PFILE file, unsigned char* beffer, unsigned int length); - static void ReadFile(PFILE file, unsigned char* buffer, unsigned int length); - static FILE OpenFile(const char* fname); - static void CloseFile(PFILE file); - - -}; - - - diff --git a/kernel/storage/vfs/Inode.cpp b/kernel/storage/vfs/Inode.cpp deleted file mode 100644 index a01eebb..0000000 --- a/kernel/storage/vfs/Inode.cpp +++ /dev/null @@ -1,5 +0,0 @@ -// -// Created by nigel on 21/02/23. -// - -#include "Inode.h" diff --git a/kernel/storage/vfs/Inode.h b/kernel/storage/vfs/Inode.h deleted file mode 100644 index 59d7ee5..0000000 --- a/kernel/storage/vfs/Inode.h +++ /dev/null @@ -1,24 +0,0 @@ -// -// Created by nigel on 21/02/23. -// -#pragma once -enum struct NODE_TYPE { - FILESYSTEM, - FILE, - DIRECTORY -}; - -enum struct PERMISSIONS { - READ, - WRITE, - EXECUTE -}; - -struct Inode { - NODE_TYPE type; - PERMISSIONS permissions; - Inode* Parent; - Inode* sibling; -}; - - diff --git a/kernel/storage/vfs/StorageTypes.h b/kernel/storage/vfs/StorageTypes.h deleted file mode 100644 index 5acdc27..0000000 --- a/kernel/storage/vfs/StorageTypes.h +++ /dev/null @@ -1,40 +0,0 @@ -// -// Created by nigel on 21/02/23. -// -#pragma once -#include - -enum FS_TYPES { - FS_FILE =0, - FS_DIRECTORY =1, - FS_INVALID=2 -}; - -typedef struct _FILE { - char name [32]; - uint32_t flags; - uint32_t filelength; - uint32_t id; - uint32_t eof; - uint32_t position; - uint32_t currentCluster; - uint32_t device; -}FILE, *PFILE; - -typedef struct _FILE_SYSTEM{ - char name[8]; - FILE (*Directory) (const char* Directoryname); - void (*Mount) (); - void (*Read) (PFILE file, unsigned char* buffer, unsigned int length); - void (*Write)(PFILE file, unsigned char* buffer, unsigned int length); - void (*Close) (PFILE); - FILE (*Open) (char* filename); -}FILESYSTEM, *PFS; - -typedef struct _PARTITION { - uint32_t Disk; - uint32_t StartAddress; - uint32_t Sectors; - uint8_t Fs_hint; - uint8_t Attributes; -}PARTITION, *PTR_PARTITION; diff --git a/kernel/storage/vfs/vfs.cpp b/kernel/storage/vfs/vfs.cpp index 5597ebc..7d67144 100644 --- a/kernel/storage/vfs/vfs.cpp +++ b/kernel/storage/vfs/vfs.cpp @@ -4,127 +4,183 @@ #include "../ata pio/ATAPIO.h" #include "../partitiontables/mbr/MasterBootRecord.h" #include "../filesystems/FAT/FAT.h" -#include "StorageTypes.h" - +#include "vfs_types.h" +#include "../../../CoreLib/Memory.h" #include -PFS VirtualFileSystem::_filesystems[VirtualFileSystem::DEVICE_MAX]; -PTR_PARTITION VirtualFileSystem::_partitions [VirtualFileSystem::PARTITION_MAX]; -unsigned int VirtualFileSystem::num_partitions = 0; +vfsmount* VirtualFileSystem::rootfs; +int VirtualFileSystem::mount_number = 0; +int VirtualFileSystem::superblock_number =0; +int VirtualFileSystem::filesystem_number =0; + +filesystem* VirtualFileSystem::filesystems[4]; +superblock* VirtualFileSystem::superblocks[8]; +vfsmount* VirtualFileSystem::mounts[12]; + +void VirtualFileSystem::Mount(filesystem* fs, const char* name) +{ + vfsmount* mnt_point = (vfsmount*) malloc(sizeof(vfsmount)); + superblock* sb = fs->mount(fs, name, mnt_point); + + mounts[mount_number++] = mnt_point; + superblocks[superblock_number++] = sb; + + rootfs = mnt_point; +} void VirtualFileSystem::initialize() { + // TODO: setup memory pools etc to speed things up + // a bit + // TODO: Add a devfs, procfs etc... - // Mount the boot disk - // NOTE: we assume for now that it is the only disk in the system - // This information could possibly be had from the bootloader (GRUB) - // We als assume it is the primary device on the Master port. - ATAPIO::Soft_Reset(ATAPIO_PORT::Primary, DEVICE_DRIVE::MASTER); - bool isAvailable = ATAPIO::Identify(ATAPIO_PORT::Primary, DEVICE_DRIVE::MASTER); - if(!isAvailable){ - // PANIC!!! - printf("Failed to mount root filesystem!\n"); - return; - } - - auto masterbootrecord = GetPartitions(false); - - for (auto partition : masterbootrecord->TableEntries) - { - if(partition.PartitionType == 0x0) continue; // Consider marked as free - - PTR_PARTITION found_partition = (PARTITION*) malloc(sizeof(PARTITION)); - found_partition->Disk = ATAPIO_PORT::Primary | ( DEVICE_DRIVE::MASTER << 16); - printf("Disk Identifier: 0x%x\n", found_partition->Disk); - found_partition->Attributes = partition.driveAttribute; - found_partition->StartAddress = partition.LBA_partition_start; - found_partition->Sectors = partition.Number_sectors_inPartition; - found_partition->Fs_hint = partition.PartitionType; - - VirtualFileSystem::RegisterPartition(found_partition); - } - - printf("Found %d partitions on disk!\n", num_partitions); - - for (int i = 0; i < num_partitions; i++) - { - auto* partition = _partitions[i]; - // Check the fs_hint for a proper driver - if ( partition->Fs_hint != 0x06){ - printf("Assumed Unkown filesystem!\n"); - continue; - } - // Check if filesystem OK - - printf("Partition Start Address (LBA): 0x%x\n", partition->StartAddress); - bool valid = FAT::Validate(partition); - if(!valid) - { - printf("Not a valid FAT fs!\n"); - continue; - } - - // setup FileSystem Description before mounting - PFS FS_FAT = (PFS)malloc(sizeof(FILESYSTEM)); - - FAT::Info(partition, FS_FAT); - - // Mount the partition/filesystem - Mount(FS_FAT , i); - } - - + filesystem* fat_fs = (filesystem*) malloc(sizeof (filesystem)); + fat_fs->name = "fat"; + fat_fs->mount = FAT::Mount; + //register_filesystem(fat_fs); + // Mount the bootdrive + // NOTE: for now will hardcode this + Mount(fat_fs, "/"); }; -void VirtualFileSystem::RegisterPartition(PTR_PARTITION partition) { - _partitions[num_partitions] = partition; - num_partitions++; + +int VirtualFileSystem::register_filesystem(struct filesystem* fs) { + // register the filesystem to the kernel. + filesystems[filesystem_number] = fs; + filesystem_number++; + + } -FILE VirtualFileSystem::OpenFile(const char* path) -{ +struct file* VirtualFileSystem::open(const char* pathname, int flags){ + // 1. Lookup pathname from the root node + // 2. Create a new file descriptor for this v_node if found. + // 3. Create a new file if O_CREATE is specified in the flags. + // See reference material (1) https://man7.org/linux/man-pages/man7/path_resolution.7.html - unsigned char device = 'a'; - char* filename = (char*)path; - char* cpy = filename; - - if(filename[1] == ':'){ - device = filename[0]; - filename += 2; + // FILE file = ->Open(filename); + if(pathname[0] != '/'){ + printf("We won't handle relative paths yet!"); + file file; + file.flags = 1; + return &file; } - if ( _filesystems[device - 'a']){ - // Unfortunately this way the FAT Driver doesn't know which device and which partition to read from - // leaving us hopeless of finding the file. - FILE file = _filesystems[device-'a']->Open(filename); - file.device = device; - free(cpy); - return file; + + auto* dentry = rootfs->root; + + int result = dentry->op->compare(dentry, "/", dentry->name); + if(result != 0 ){ + printf("rootfs not called / \n"); + file file; + file.flags = 1; + return &file; } - free(cpy); - FILE file; - file.flags = FS_INVALID; - return file; + char* tokstate = nullptr; + auto nextdir = strtok ((char*)pathname, "/", &tokstate ); + while (nextdir) + { + printf("Look for dentry: %s\n", nextdir); + // look to its children + if (dentry->children ) { + printf("No children | children unknown!\n"); + break; + } + if (dentry->op->compare(dentry, nextdir, dentry->name)) + { + // file found + nextdir = strtok(nullptr, "/", &tokstate); + } + + } + + file file; + file.flags = 1; + return &file; } -void VirtualFileSystem::Mount(PFS filesystemDescriptor, unsigned int DeviceID) -{ - if(DeviceID < DEVICE_MAX) - if(filesystemDescriptor) - _filesystems[DeviceID] = filesystemDescriptor; +int VirtualFileSystem::close (struct file* file){ + // 1. release the file descriptor +} +int VirtualFileSystem::write(struct file* file, const void* buf, size_t len){ + // 1. Write len bytes from buf to the opened file. + // 2. return written size or error code if an error occurs +} +int VirtualFileSystem::read (struct file* file, void* buf, size_t len){ + // 1. read min(len, readable file data size) bytes ro buf from the opened file. + // 2. return read size or error code if an error occurs } -void VirtualFileSystem::Unmount(unsigned int DeviceID) { - if(DeviceID < DEVICE_MAX) - _filesystems[DeviceID] = nullptr; +/* + +void fs_discovery(){ + + + // Mount the boot disk + // NOTE: we assume for now that it is the only disk in the system + // This information could possibly be had from the bootloader (GRUB) + // We als assume it is the primary device on the Master port. + ATAPIO::Soft_Reset(ATAPIO_PORT::Primary, DEVICE_DRIVE::MASTER); + bool isAvailable = ATAPIO::Identify(ATAPIO_PORT::Primary, DEVICE_DRIVE::MASTER); + if(!isAvailable){ + // PANIC!!! + printf("Failed to mount root filesystem!\n"); + return; + } + + auto masterbootrecord = GetPartitions(false); + + for (auto partition : masterbootrecord->TableEntries) + { + if(partition.PartitionType == 0x0) continue; // Consider marked as free + + PTR_PARTITION found_partition = (PARTITION*) malloc(sizeof(PARTITION)); + found_partition->Disk = ATAPIO_PORT::Primary | ( DEVICE_DRIVE::MASTER << 16); + printf("Disk Identifier: 0x%x\n", found_partition->Disk); + found_partition->Attributes = partition.driveAttribute; + found_partition->StartAddress = partition.LBA_partition_start; + found_partition->Sectors = partition.Number_sectors_inPartition; + found_partition->Fs_hint = partition.PartitionType; + + + } + + printf("Found %d partitions on disk!\n", num_partitions); + + for (int i = 0; i < num_partitions; i++) + { + auto* partition = _partitions[i]; + // Check the fs_hint for a proper driver + if ( partition->Fs_hint != 0x06){ + printf("Assumed Unkown filesystem!\n"); + continue; + } + // Check if filesystem OK + + printf("Partition Start Address (LBA): 0x%x\n", partition->StartAddress); + bool valid = FAT::Validate(partition); + if(!valid) + { + printf("Not a valid FAT fs!\n"); + continue; + } + + // setup FileSystem Description before mounting + PFS FS_FAT = (PFS)malloc(sizeof(FILESYSTEM)); + + FAT::Info(partition, FS_FAT); + + // Mount the partition/filesystem + } + + } - - +*/ \ No newline at end of file diff --git a/kernel/storage/vfs/vfs.h b/kernel/storage/vfs/vfs.h index 4c91792..804f09a 100644 --- a/kernel/storage/vfs/vfs.h +++ b/kernel/storage/vfs/vfs.h @@ -1,20 +1,32 @@ #pragma once #include #include "../../../CoreLib/Path.h" -#include "StorageTypes.h" +#include "vfs_types.h" +#include "vfs_types.h" class VirtualFileSystem { public: static void initialize(); - static void Mount(PFS fs, unsigned int DeviceID); - static void Unmount(unsigned int DeviceID); - static FILE OpenFile(const char* path); - static void RegisterPartition(PTR_PARTITION partition); + static void Mount(filesystem* fs, const char* name); + + static int register_filesystem(struct filesystem* fs); + + static struct file* open(const char* pathname, int flags); + static int close(struct file* file); + static int write(struct file* file, const void* buf, size_t len); + static int read(struct file* file, void* buf, size_t len); private: - static const unsigned int DEVICE_MAX = 26; - static const unsigned int PARTITION_MAX = 4 * DEVICE_MAX; - static PFS _filesystems[DEVICE_MAX]; - static unsigned int num_partitions; - static PTR_PARTITION _partitions [PARTITION_MAX]; - }; \ No newline at end of file + static vfsmount* rootfs; + + + static int mount_number; + static int superblock_number; + static int filesystem_number; + + static filesystem* filesystems[]; + static superblock* superblocks[]; + static vfsmount* mounts[]; + + }; + diff --git a/kernel/storage/vfs/vfs_types.h b/kernel/storage/vfs/vfs_types.h new file mode 100644 index 0000000..c989dbe --- /dev/null +++ b/kernel/storage/vfs/vfs_types.h @@ -0,0 +1,116 @@ +// +// Created by nigel on 21/02/23. +// +#pragma once +// grasslab.github.io/osdi/en/labs/lab7.html +#include +#include + +struct inode_operations; +struct vfsmount; +struct superblock; +struct inode; +struct dentry_operations; +struct directoryEntry; +struct filesystem; +struct superblock; +struct file; + +struct file_operations{ + int(*write) (file* file, const void* buf, size_t len); + int(*read) (file* file, void* buf, size_t len); +}; +struct inode_operations { + int (*create)(inode*, directoryEntry*, const char* ); + directoryEntry* (*lookup)(inode* , directoryEntry*); + int (*link)(directoryEntry*, inode* , directoryEntry*); + int (*unlink)(inode*, directoryEntry*); + int (*symlink)(inode*, directoryEntry*); + int (*mkdir)(inode*, directoryEntry*, const char*); + int (*rmdir)(inode*, directoryEntry*); + int (*rename)(inode*, directoryEntry*, inode*, directoryEntry*); + void (*truncate)(inode*); + int (*permission)(inode*, int); + int (*setattr)(directoryEntry, unsigned long*); + int (*getattr)(vfsmount* mnt, directoryEntry*, unsigned long*); +}; +// Describes a mount +struct vfsmount { + vfsmount* mnt_parent; // fs we are mounted on + directoryEntry* mountpoint; // dentry of mount point + directoryEntry* root; // root of the mounted tree + superblock* sb; // pointer to the superblock + unsigned int mnt_count; // keep track of users of this structure + int mnt_flags; + char* mnt_devname; // name of device eg /dev/dsk/hda1 + +}; +struct superblock; +// Represents a filesystem object (i.e. a file or directory or device) +struct inode { + unsigned long mode; // access permissions + unsigned long uid; // user id owner + unsigned long gid; // group id owner + unsigned int flags; + inode_operations* i_op; // operations possible on inode + superblock* sb; + unsigned long ino; // unique number of this inode + unsigned int links; // number of hard links + void* device; + unsigned long size; // size of inode contents in bytes + unsigned long atime; // Access time + unsigned long mtime; // Modify time + unsigned long ctime; // Creation time + unsigned short bytes; // bytes consumed + file_operations* fop; + void* internal; // point to underlying representation of this virtual node (e.g. FAT entry or Directory Entry) +}; +// Represents the possible operations on a directory entry +struct dentry_operations +{ + int (*compare)(directoryEntry*, char*, char* ); + int (*o_delete)(directoryEntry*); + void (*release)(directoryEntry*); + void (*iput)(directoryEntry*, inode* ); + +}; +// Represents the name of files in the filesystem +// it identifies the file that an inode represents +struct directoryEntry { + char* name; // name of the file on the disk + directoryEntry* parent; // parent of the file + inode* node; // node belongs to... + dentry_operations* op; + directoryEntry* children[]; + +}; +// Represents a filesystem type +struct filesystem { + const char* name; + superblock* (*mount)(filesystem* self, const char* name, vfsmount* mnt); +}; + +// Represents a mounted filesystem +struct superblock { + + void* device; // device associated with the filesystem + unsigned long blocksize; + unsigned long maxbytes; + filesystem* type; + unsigned long magic; // IDK + directoryEntry* root; // Root dentry + int count; // IDK + void* fs_info; // pointer to raw filesystem info + dentry_operations* d_op; + inode* inodes[]; +}; + +// Represents an opened file +struct file { + inode* root; + size_t f_pos; // The next read/write position of this file descriptor; + file_operations* f_ops; + int flags; +}; + + diff --git a/kernel/supervisorterminal/superVisorTerminal.cpp b/kernel/supervisorterminal/superVisorTerminal.cpp index bee1a3e..ea6e9b2 100644 --- a/kernel/supervisorterminal/superVisorTerminal.cpp +++ b/kernel/supervisorterminal/superVisorTerminal.cpp @@ -1,8 +1,7 @@ #include "superVisorTerminal.h" #include "../storage/ata pio/ATAPIO.h" #include "../storage/partitiontables/mbr/MasterBootRecord.h" -#include "../storage/filesystems/FAT/BiosParameterBlock.h" -#include "../storage/filesystems/FAT/DirectoryEntry.h" +#include "../storage/filesystems/FAT/FAT.h" bool isRunning = true; extern "C" void startSuperVisorTerminal() diff --git a/run.sh b/run.sh index a97e584..99d34c5 100755 --- a/run.sh +++ b/run.sh @@ -1,12 +1,25 @@ #!/bin/bash +PROC=$$ +# Build the Corelib static library +(cd CoreLib +if ! make; then + echo "Build failed!" + kill -10 $PROC +fi) -cd CoreLib -make -cd ../kernel +# Build the kernel image +(cd kernel make clean make -cd .. +if ! make; then + echo "Build failed!" + kill -10 $PROC +fi) ./scripts/update_harddrive.sh + + + ./scripts/run_qemu.sh +