#include "vfs.h" #include #include "../../memory/KernelHeap.h" #include "../ata pio/ATAPIO.h" #include "../partitiontables/mbr/MasterBootRecord.h" #include "../filesystems/FAT/FAT.h" #include "vfs_types.h" #include "../../../CoreLib/Memory.h" #include vfsmount* VirtualFileSystem::rootfs; int VirtualFileSystem::mount_number = 0; int VirtualFileSystem::superblock_number =0; int VirtualFileSystem::filesystem_number =0; filesystem* VirtualFileSystem::filesystems[4]; FS_SUPER* VirtualFileSystem::superblocks[8]; vfsmount* VirtualFileSystem::mounts[12]; void VirtualFileSystem::Mount(filesystem* fs, const char* name) { vfsmount* mnt_point = (vfsmount*) malloc(sizeof(vfsmount)); FS_SUPER* sb = fs->mount(fs, name, mnt_point); if( sb == nullptr){ printf("mount failed!\n"); return; } mounts[mount_number++] = mnt_point; superblocks[superblock_number++] = sb; mnt_point->mnt_count = 1; rootfs = mnt_point; } void VirtualFileSystem::initialize() { // TODO: setup memory pools etc to speed things up // a bit // TODO: Add a devfs, procfs etc... 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, "/"); }; int VirtualFileSystem::register_filesystem(struct filesystem* fs) { // register the filesystem to the kernel. filesystems[filesystem_number] = fs; filesystem_number++; } FILE* VirtualFileSystem::open(const char* pathname, int flags){ // 1. Lookup pathname from the root node // 2. Create a new file descriptor for this inode if found. // 3. Create a new file if O_CREATE is specified in the flags. FILE* file = (FILE*) malloc(sizeof (FILE)) ; auto* rootentry = rootfs->root; char* tokstate = nullptr; auto nextdir = strtok ((char*)pathname, "/", &tokstate ); // look up children if not filled if(rootentry->children == nullptr) { rootentry = rootentry->node->lookup(rootentry->node, rootentry); } if(rootentry->children == nullptr) { file->flags =1; return file; } // let's just loop through the folder first printf("looking for: "); for(int i = 0; i < 5; i++) kterm_put(nextdir[i]); kterm_put('\n'); auto* child = rootentry->children; while(child->next != nullptr){ auto* directory = (DirectoryNode*)child->data; for(int i = 0; i < 11 ; i++) kterm_put(directory->name[i]); kterm_put('\n'); if( directory->compare(directory, directory->name, nextdir) == 0){ nextdir = strtok(nullptr, "/", &tokstate); printf("Found dir!\n"); if(nextdir == NULL){ file->root = directory->node; file->flags =0; file->read = FAT::Read; return file; } printf("continue searching next directory!\n"); if(directory->children == nullptr) directory->node->lookup(directory->node, directory); child = directory->children; }else{ child = child->next; } } file->flags = 1; return file; } int VirtualFileSystem::close (struct FILE* file){ // 1. release the file descriptor } int VirtualFileSystem::write(struct FILE* file, const void* buf, unsigned int 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, unsigned int 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 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 } } */