From dbb147e110f7157126c061cdd446cdea0df3b4a4 Mon Sep 17 00:00:00 2001 From: Nigel Date: Sun, 19 Feb 2023 14:17:47 +0100 Subject: [PATCH] Primitie listing rootdir of FAT16 filesystem --- features.md | 17 ++- source/kernel/drivers/ata/ataDevice.cpp | 4 +- source/kernel/drivers/ata/ataDevice.h | 4 - source/kernel/interrupts/idt.cpp | 4 +- source/kernel/memory/KernelHeap.cpp | 10 +- .../supervisorterminal/superVisorTerminal.cpp | 10 +- source/kernel/vfs/VFS.cpp | 107 ++++++++++-------- todo.md | 4 +- 8 files changed, 86 insertions(+), 74 deletions(-) diff --git a/features.md b/features.md index 577e666..a6d8e97 100644 --- a/features.md +++ b/features.md @@ -1,14 +1,17 @@ # TODO list ## Basics - Setup Cross-Compiler \ - Multiboot to kernel \ - Printing string to the screen \ + + Setup Cross-Compiler + Multiboot to kernel \ + Printing string to the screen \ Printing values/numbers to the screen \ Basic Terminal \ Extend Multiboot implementation \ Output to serial port \ Move to protected mode \ - Enabel CMOS clock \ + Enable CMOS clock \ Time measurement (PIC &| PIT) \ Detect CPU speed \ Interrupt / exception system (API) \ @@ -22,16 +25,13 @@ Virtual memory management \ The heap: allocating memory at runtime (malloc and free) is almost impossible to go without. \ Enable SIMD Extensions (SSE) - -## Other features I am thinking of: PCI support \ - ATA PIO Mode support \ + ATA PIO Mode support \ USTAR Filesystem ( For its simplicity this is very likely the first filesystem the OS is going to support) \ ACPI support ( Or some other basic way to support shutdown, reboot and possibly hibernation ) \ ATAPI support \ Memory Management (MMU) Hardware Management system - Preemptive multi tasking \ Processes \ Threads @@ -44,7 +44,6 @@ ACPI support \ ATAPI support \ -## Optional Basic Window server/client \ EXT2 Filesystem USTAR Filesystem \ diff --git a/source/kernel/drivers/ata/ataDevice.cpp b/source/kernel/drivers/ata/ataDevice.cpp index 05947f1..873aa0e 100644 --- a/source/kernel/drivers/ata/ataDevice.cpp +++ b/source/kernel/drivers/ata/ataDevice.cpp @@ -128,7 +128,7 @@ void ATA_DEVICE::Read(uint16_t DEVICE_CHANNEL, DEVICE_DRIVE drive, uint32_t LBA return ; } - printf("Read LBA: 0x%x\n", LBA); + //printf("Read LBA: 0x%x\n", LBA); // Send 0xE0 for the "master" or 0xF0 for the "slave", ORed with the highest 4 bits of the LBA to port 0x1F6: outb(0x1F6, 0xE0 | (slavebit << 4) | ((LBA >> 24) & 0x0F)) outb(DEVICE_CHANNEL | 6 , ( 0xE0 | (LBA >>28) ) ); // Send a NULL byte to port 0x1F1, if you like (it is ignored and wastes lots of CPU time): outb(0x1F1, 0x00) @@ -156,7 +156,7 @@ void ATA_DEVICE::Read(uint16_t DEVICE_CHANNEL, DEVICE_DRIVE drive, uint32_t LBA return; } - printf("Status: %x\n", status); + //printf("Status: %x\n", status); // Check if busy! while((status & 0x80) == 0x80){ printf("Reading....\r"); diff --git a/source/kernel/drivers/ata/ataDevice.h b/source/kernel/drivers/ata/ataDevice.h index 730de3c..30e75dc 100644 --- a/source/kernel/drivers/ata/ataDevice.h +++ b/source/kernel/drivers/ata/ataDevice.h @@ -10,7 +10,6 @@ * This first driver wil make use of IO ports. * Doing so means reading or writing from disk is going * to be very cpu intensive. -* */ enum DEVICE_DRIVE{ @@ -18,9 +17,6 @@ enum DEVICE_DRIVE{ SLAVE = 0xB0 }; - - - namespace ATA_DEVICE{ void Identify(uint16_t, DEVICE_DRIVE); void Read (uint16_t, DEVICE_DRIVE, uint32_t, uint16_t*); diff --git a/source/kernel/interrupts/idt.cpp b/source/kernel/interrupts/idt.cpp index 7448de0..50acd47 100644 --- a/source/kernel/interrupts/idt.cpp +++ b/source/kernel/interrupts/idt.cpp @@ -308,8 +308,8 @@ void irq_handler (registers regs) { break; default: - printf("Interrupt happened!"); - printf("Received INT: 0x%x\n", regs.int_no); + //printf("Interrupt happened!"); + //printf("Received INT: 0x%x\n", regs.int_no); break; } diff --git a/source/kernel/memory/KernelHeap.cpp b/source/kernel/memory/KernelHeap.cpp index 4483d2d..c935fb1 100644 --- a/source/kernel/memory/KernelHeap.cpp +++ b/source/kernel/memory/KernelHeap.cpp @@ -1,7 +1,7 @@ #include "KernelHeap.h" #include "VirtualMemoryManager.h" extern "C" const uint32_t kernel_end; -// Size of heap meta data is 5 bytes +// Size of heap metadata is 5 bytes struct heap_block{ uint8_t Used; uint32_t Size; @@ -12,7 +12,7 @@ heap_block* start ; void* malloc(size_t size) { - printf("Received request for %d bytes of memory\n", size); + //printf("Received request for %d bytes of memory\n", size); heap_block* current = start; // look for a free block @@ -21,14 +21,14 @@ void* malloc(size_t size) if(current->Size >= size && current->Used == false ) { // We found a spot - printf("Block found!\n"); + // printf("Block found!\n"); // Set the spot to in-use current->Used = true; // split the block - printf("Split block.\n"); + //printf("Split block.\n"); uint32_t oldSize = current->Size; current->Size = size; @@ -57,7 +57,7 @@ void free(void* addr) { // clear the free boolean that corresponds to this adddress // This should be fairly simple - heap_block* allocatedBlock = (heap_block*)(addr - sizeof(heap_block)); + heap_block* allocatedBlock = (heap_block*)((uint32_t)addr - sizeof(heap_block)); allocatedBlock->Used = false; } diff --git a/source/kernel/supervisorterminal/superVisorTerminal.cpp b/source/kernel/supervisorterminal/superVisorTerminal.cpp index f2790e8..d574b65 100644 --- a/source/kernel/supervisorterminal/superVisorTerminal.cpp +++ b/source/kernel/supervisorterminal/superVisorTerminal.cpp @@ -70,9 +70,17 @@ extern "C" void startSuperVisorTerminal() kterm_init(); printf("|=== BarinkOS ===|\n"); } - if(strncmp("LIST", command, characterCount) == 0) + if(strncmp("LIST", command, 4) == 0) { + + // slice off the command part + char args[characterCount - 4]; + for(int i = 5 ; i < characterCount; i++) { + args[i] = command[i]; + } + printf("=============== DIRECTORY LISTING =================\n"); + printf("Path to show %s\n", args); } if(strncmp("DEVICES", command, characterCount) == 0){ diff --git a/source/kernel/vfs/VFS.cpp b/source/kernel/vfs/VFS.cpp index 1c5cc17..cdb787c 100644 --- a/source/kernel/vfs/VFS.cpp +++ b/source/kernel/vfs/VFS.cpp @@ -80,7 +80,7 @@ bool driveAvailable(){ return true; } -MBR* getPartitions(){ +MBR* getPartitions(bool DEBUG = false){ const int C = 0; const int H = 0; const int HPC = 16; @@ -92,67 +92,91 @@ MBR* getPartitions(){ ATA_DEVICE::Read(BUS_PORT::Primary, DEVICE_DRIVE::MASTER, LBA, (uint16_t*)mbr); - printf("BootSector: 0x%x\n", mbr->ValidBootsector ); - for( int i = 0 ; i < 4 ; i ++){ - PartitionTableEntry PT = mbr->TableEntries[i]; + if(DEBUG){ + printf("BootSector: 0x%x\n", mbr->ValidBootsector ); + for( int i = 0 ; i < 4 ; i ++){ + PartitionTableEntry PT = mbr->TableEntries[i]; + + printf("Partition %d [ %d sectors, PartitionType: 0x%x, 0x%x, \nLBA Start: 0x%x ]\n" , + i, PT.Number_sectors_inPartition, PT.PartitionType, mbr->uniqueID, PT.LBA_partition_start ); + } - printf("Partition %d [ %d sectors, PartitionType: %x, 0x%x, \nLBA Start: 0x%x ]\n" , - i, PT.Number_sectors_inPartition, PT.PartitionType, mbr->uniqueID, PT.LBA_partition_start ); } return mbr; } -BiosParameterBlock* getBPB(MBR* mbr){ +BiosParameterBlock* getBPB(MBR* mbr, bool DEBUG =false ){ BiosParameterBlock* bpb = (BiosParameterBlock*) malloc(sizeof(BiosParameterBlock)); - ATA_DEVICE::Read(BUS_PORT::Primary, DEVICE_DRIVE::MASTER, mbr->TableEntries[0].LBA_partition_start, (uint16_t*) bpb); - 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); + 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); + } + return bpb; } -uint16_t* ReadFAT (BiosParameterBlock& bpb , MBR& mbr) { +uint16_t* ReadFAT (BiosParameterBlock& bpb , MBR& mbr, bool DEBUG = false ) { uint32_t FATAddress = mbr.TableEntries[0].LBA_partition_start + bpb.ReservedSectors ; uint16_t* FAT = (uint16_t*)malloc(sizeof (uint16_t) * 256); ATA_DEVICE::Read(BUS_PORT::Primary, DEVICE_DRIVE::MASTER, FATAddress, FAT ); // Show data in terminal - /* - for(unsigned short i : FAT) { - printf("%x ", i); + if(DEBUG){ + for( unsigned int i =0 ; i < 256 ; i++) { + printf("0x%x ", (unsigned short)FAT[i]); + } + kterm_put('\n'); } - kterm_put('\n');*/ return FAT; - } +void readFile(uint32_t DataRegion, DirectoryEntry* entry, uint16_t FATentry, BiosParameterBlock& bpb ){ + printf("Show contents"); + printf("Start cluster of the file: 0x%x\n", entry->StartingCluster); + + printf("IS it only 1 cluster? %s\n", FATentry == 0xFFFF ? "Yes" : "No"); + + uint32_t sector = DataRegion + ((entry->StartingCluster - 0x02) * bpb.SectorsPerCluster); + + + uint16_t dataBlob[256]; + ATA_DEVICE::Read(BUS_PORT::Primary, DEVICE_DRIVE::MASTER, sector, dataBlob); + for (unsigned short n: dataBlob) { + kterm_put(n & 0x00ff); + + kterm_put(n >> 8); + } + 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 < bpb.NumberOfDirectoryEntries ; i++ ) { + 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) - break; // There are no more entries in this directory or the entry is free + continue; // There are no more entries in this directory or the entry is free if ((entry->attribute & 0x01) == 0x01 || (entry->attribute & 0x20) == 0x20) continue; // Skip listing if hidden or Achieve flag is set @@ -163,40 +187,21 @@ void listFilesInRoot(MBR& mbr, BiosParameterBlock& bpb ){ break; kterm_put(n); } - 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 & 0x8) == 0x0) { - printf("Show contents"); - - printf("Start cluster of the file: 0x%x\n", entry->StartingCluster); - - printf("IS it only 1 cluster? %s\n", FAT[i] == 0xFFFF ? "Yes" : "No"); - - uint32_t sector = DataRegion + ((entry->StartingCluster - 0x02) * bpb.SectorsPerCluster); - - - uint16_t dataBlob[256]; - ATA_DEVICE::Read(BUS_PORT::Primary, DEVICE_DRIVE::MASTER, sector, dataBlob); - for (unsigned short n: dataBlob) { - kterm_put(n & 0x00ff); - - kterm_put(n >> 8); - } - kterm_put('\n'); - - + if (entry->FilesizeInBytes != 0x0 && (entry->attribute == 0x08)) { + readFile(DataRegion,entry, FAT[i], bpb); } - printf("======================\n"); } + free(FAT); } @@ -341,6 +346,9 @@ void FileSystem::initialize() MBR* mbr = getPartitions(); BiosParameterBlock* bootsector = getBPB(mbr); listFilesInRoot(*mbr, *bootsector); + + free(mbr); + free(bootsector); /* mountInfo.numSectors = bootsector->NumberOfSectorsPerFAT; mountInfo.fatOffset = 1; @@ -348,7 +356,8 @@ void FileSystem::initialize() mountInfo.fatEntrySize = 8; mountInfo.numRootEntries = bootsector->NumberOfDirectoryEntries; mountInfo.rootOffset = (bootsector->NumberOfFileAllocationTables * bootsector->NumberOfSectorsPerFAT) + 1; - mountInfo.rootSize = (bootsector->NumberOfDirectoryEntries * 32) / bootsector->BytesPerSector;*/ + mountInfo.rootSize = (bootsector->NumberOfDirectoryEntries * 32) / bootsector->BytesPerSector; +*/ } \ No newline at end of file diff --git a/todo.md b/todo.md index a47a9f3..cb71d04 100644 --- a/todo.md +++ b/todo.md @@ -13,9 +13,9 @@ to do on a more in depth level. [x] Setup a proper HEAP \ [ ] Setup a proper Stack \ [x] Setup KMalloc and KFree \ -[ ] Merge Functioning Feature branches into sandboxKernelDev \ +[x] Merge Functioning Feature branches into sandboxKernelDev \ [ ] Remove merged feature branches \ [ ] Merge sandboxKernelDev with dev \ -[ ] Remove sandboxKernelDev branch \ +[x] Remove sandboxKernelDev branch \ [ ] Implement proper virtual filesystem