From 2c0db035f4f9e53a28440ae4e1a87fb54c876171 Mon Sep 17 00:00:00 2001 From: Aman Priyadarshi Date: Sat, 18 Mar 2017 00:47:24 +0530 Subject: [PATCH 1/4] New Virtual FileSystem --- src/Compiler/Atomixilc/Lib/Memory.cs | 2 +- src/Compiler/Atomixilc/Lib/Plugs/String.cs | 2 +- .../Atomix.Kernel_H/Atomix.Kernel_H.csproj | 10 +- src/Kernel/Atomix.Kernel_H/Boot.cs | 3 - src/Kernel/Atomix.Kernel_H/IO/Directory.cs | 33 +++++ src/Kernel/Atomix.Kernel_H/IO/FSObject.cs | 19 +++ src/Kernel/Atomix.Kernel_H/IO/File.cs | 22 +++ src/Kernel/Atomix.Kernel_H/IO/FileMode.cs | 16 +++ src/Kernel/Atomix.Kernel_H/IO/FileSeek.cs | 16 +++ .../IO/FileSystem/FAT/Comparison.cs | 14 ++ .../IO/FileSystem/FAT/Entry.cs | 28 ++++ .../IO/FileSystem/FAT/FatFileAttribute.cs | 58 ++++++++ .../IO/FileSystem/{ => FAT}/FatFileSystem.cs | 127 ++++++++++-------- .../IO/FileSystem/FAT/FatType.cs | 28 ++++ .../IO/FileSystem/FAT/FileLocation.cs | 2 +- .../IO/FileSystem/FAT/FileNameAttribute.cs | 18 +++ .../Atomix.Kernel_H/IO/FileSystem/FAT/misc.cs | 114 ---------------- .../IO/FileSystem/GenericFileSystem.cs | 32 ++--- .../IO/FileSystem/RFS/FileStream.cs | 93 ------------- .../IO/FileSystem/RFS/RamFile.cs | 20 ++- .../IO/FileSystem/RFS/RamFileSystem.cs | 65 +++++++++ .../IO/FileSystem/RamFileSystem.cs | 70 ---------- .../IO/FileSystem/VirtualFileSystem.cs | 77 ----------- src/Kernel/Atomix.Kernel_H/IO/MemoryStream.cs | 100 ++++++++++++++ src/Kernel/Atomix.Kernel_H/IO/Pipe.cs | 4 +- src/Kernel/Atomix.Kernel_H/IO/Stream.cs | 33 +---- src/Kernel/Atomix.Kernel_H/IO/VFN.cs | 37 +++++ .../Atomix.Kernel_H/IO/VirtualFileSystem.cs | 56 ++++++++ src/Kernel/Atomix.Kernel_H/Lib/Marshal.cs | 2 +- src/Kernel/Atomix.Kernel_H/Start-x86.cs | 4 +- 30 files changed, 626 insertions(+), 479 deletions(-) create mode 100644 src/Kernel/Atomix.Kernel_H/IO/Directory.cs create mode 100644 src/Kernel/Atomix.Kernel_H/IO/FSObject.cs create mode 100644 src/Kernel/Atomix.Kernel_H/IO/File.cs create mode 100644 src/Kernel/Atomix.Kernel_H/IO/FileMode.cs create mode 100644 src/Kernel/Atomix.Kernel_H/IO/FileSeek.cs create mode 100644 src/Kernel/Atomix.Kernel_H/IO/FileSystem/FAT/Comparison.cs create mode 100644 src/Kernel/Atomix.Kernel_H/IO/FileSystem/FAT/Entry.cs create mode 100644 src/Kernel/Atomix.Kernel_H/IO/FileSystem/FAT/FatFileAttribute.cs rename src/Kernel/Atomix.Kernel_H/IO/FileSystem/{ => FAT}/FatFileSystem.cs (73%) create mode 100644 src/Kernel/Atomix.Kernel_H/IO/FileSystem/FAT/FatType.cs create mode 100644 src/Kernel/Atomix.Kernel_H/IO/FileSystem/FAT/FileNameAttribute.cs delete mode 100644 src/Kernel/Atomix.Kernel_H/IO/FileSystem/FAT/misc.cs delete mode 100644 src/Kernel/Atomix.Kernel_H/IO/FileSystem/RFS/FileStream.cs create mode 100644 src/Kernel/Atomix.Kernel_H/IO/FileSystem/RFS/RamFileSystem.cs delete mode 100644 src/Kernel/Atomix.Kernel_H/IO/FileSystem/RamFileSystem.cs delete mode 100644 src/Kernel/Atomix.Kernel_H/IO/FileSystem/VirtualFileSystem.cs create mode 100644 src/Kernel/Atomix.Kernel_H/IO/MemoryStream.cs create mode 100644 src/Kernel/Atomix.Kernel_H/IO/VFN.cs create mode 100644 src/Kernel/Atomix.Kernel_H/IO/VirtualFileSystem.cs diff --git a/src/Compiler/Atomixilc/Lib/Memory.cs b/src/Compiler/Atomixilc/Lib/Memory.cs index 1ed082d..a1461df 100644 --- a/src/Compiler/Atomixilc/Lib/Memory.cs +++ b/src/Compiler/Atomixilc/Lib/Memory.cs @@ -129,7 +129,7 @@ public static void Write8(uint aAddress, byte Value) [NoException] [Assembly(false)] - public static void FastCopy(uint aDest, uint aSrc, uint aLen) + public static void FastCopy(uint aDest, uint aSrc, int aLen) { new Mov { DestinationReg = Register.EAX, SourceReg = Register.ESP, SourceDisplacement = 0x4, SourceIndirect = true }; new Mov { DestinationReg = Register.ESI, SourceReg = Register.ESP, SourceDisplacement = 0x8, SourceIndirect = true }; diff --git a/src/Compiler/Atomixilc/Lib/Plugs/String.cs b/src/Compiler/Atomixilc/Lib/Plugs/String.cs index ce9ed9a..9048315 100644 --- a/src/Compiler/Atomixilc/Lib/Plugs/String.cs +++ b/src/Compiler/Atomixilc/Lib/Plugs/String.cs @@ -132,7 +132,7 @@ internal static char[] ToCharArray(string aStr) { int len = aStr.Length; var aArray = new char[len]; - Memory.FastCopy(aArray.GetDataOffset(), aStr.GetDataOffset(), (uint)(len << 1)); + Memory.FastCopy(aArray.GetDataOffset(), aStr.GetDataOffset(), (len << 1)); return aArray; } diff --git a/src/Kernel/Atomix.Kernel_H/Atomix.Kernel_H.csproj b/src/Kernel/Atomix.Kernel_H/Atomix.Kernel_H.csproj index 91c956a..0f7462d 100644 --- a/src/Kernel/Atomix.Kernel_H/Atomix.Kernel_H.csproj +++ b/src/Kernel/Atomix.Kernel_H/Atomix.Kernel_H.csproj @@ -91,6 +91,9 @@ + + + @@ -99,14 +102,17 @@ - - + + + + + diff --git a/src/Kernel/Atomix.Kernel_H/Boot.cs b/src/Kernel/Atomix.Kernel_H/Boot.cs index 365634f..5c8ea6b 100644 --- a/src/Kernel/Atomix.Kernel_H/Boot.cs +++ b/src/Kernel/Atomix.Kernel_H/Boot.cs @@ -231,8 +231,6 @@ private static unsafe void DrawTaskbar(GuiRequest* request, byte[] xData) internal static void LoadIDE(bool IsPrimary, bool IsMaster) { var xIDE = new IDE(IsPrimary, IsMaster); - - bool Clean = true; if (xIDE.IsValid) { switch(xIDE.Device) @@ -256,7 +254,6 @@ internal static void LoadIDE(bool IsPrimary, bool IsMaster) if (xFileSystem.IsValid) { VirtualFileSystem.MountDevice(null, xFileSystem); - Clean = false; } } } diff --git a/src/Kernel/Atomix.Kernel_H/IO/Directory.cs b/src/Kernel/Atomix.Kernel_H/IO/Directory.cs new file mode 100644 index 0000000..4831bb5 --- /dev/null +++ b/src/Kernel/Atomix.Kernel_H/IO/Directory.cs @@ -0,0 +1,33 @@ +/* +* PROJECT: Atomix Development +* LICENSE: BSD 3-Clause (LICENSE.md) +* PURPOSE: VFS Directory +* PROGRAMMERS: Aman Priyadarshi (aman.eureka@gmail.com) +*/ + +namespace Atomix.Kernel_H.IO +{ + internal abstract class Directory : FSObject + { + internal Directory(string aName) + : base(aName) + { + + } + + internal virtual FSObject FindEntry(string aName) + { + return null; + } + + internal virtual File CreateFile(string aName) + { + return null; + } + + internal virtual Directory CreateDirectory(string aName) + { + return null; + } + } +} \ No newline at end of file diff --git a/src/Kernel/Atomix.Kernel_H/IO/FSObject.cs b/src/Kernel/Atomix.Kernel_H/IO/FSObject.cs new file mode 100644 index 0000000..ecc27b2 --- /dev/null +++ b/src/Kernel/Atomix.Kernel_H/IO/FSObject.cs @@ -0,0 +1,19 @@ +/* +* PROJECT: Atomix Development +* LICENSE: BSD 3-Clause (LICENSE.md) +* PURPOSE: VFS Object +* PROGRAMMERS: Aman Priyadarshi (aman.eureka@gmail.com) +*/ + +namespace Atomix.Kernel_H.IO +{ + internal abstract class FSObject + { + internal readonly string Name; + + internal FSObject(string aName) + { + Name = aName; + } + } +} \ No newline at end of file diff --git a/src/Kernel/Atomix.Kernel_H/IO/File.cs b/src/Kernel/Atomix.Kernel_H/IO/File.cs new file mode 100644 index 0000000..10d92d5 --- /dev/null +++ b/src/Kernel/Atomix.Kernel_H/IO/File.cs @@ -0,0 +1,22 @@ +/* +* PROJECT: Atomix Development +* LICENSE: BSD 3-Clause (LICENSE.md) +* PURPOSE: VFS File +* PROGRAMMERS: Aman Priyadarshi (aman.eureka@gmail.com) +*/ + +namespace Atomix.Kernel_H.IO +{ + internal abstract class File : FSObject + { + internal uint SizeInBytes; + + internal File(string aName) + : base(aName) + { + + } + + internal abstract Stream Open(FileMode aMode); + } +} \ No newline at end of file diff --git a/src/Kernel/Atomix.Kernel_H/IO/FileMode.cs b/src/Kernel/Atomix.Kernel_H/IO/FileMode.cs new file mode 100644 index 0000000..ac93543 --- /dev/null +++ b/src/Kernel/Atomix.Kernel_H/IO/FileMode.cs @@ -0,0 +1,16 @@ +/* +* PROJECT: Atomix Development +* LICENSE: BSD 3-Clause (LICENSE.md) +* PURPOSE: VFS File Mode +* PROGRAMMERS: Aman Priyadarshi (aman.eureka@gmail.com) +*/ + +namespace Atomix.Kernel_H.IO +{ + internal enum FileMode : int + { + Read = 1, + Write = 2, + Append = 4 + }; +} \ No newline at end of file diff --git a/src/Kernel/Atomix.Kernel_H/IO/FileSeek.cs b/src/Kernel/Atomix.Kernel_H/IO/FileSeek.cs new file mode 100644 index 0000000..a52bead --- /dev/null +++ b/src/Kernel/Atomix.Kernel_H/IO/FileSeek.cs @@ -0,0 +1,16 @@ +/* +* PROJECT: Atomix Development +* LICENSE: BSD 3-Clause (LICENSE.md) +* PURPOSE: VFS File Seek +* PROGRAMMERS: Aman Priyadarshi (aman.eureka@gmail.com) +*/ + +namespace Atomix.Kernel_H.IO +{ + public enum FileSeek : int + { + Origin = 0, + Current = 1, + End = 2, + } +} diff --git a/src/Kernel/Atomix.Kernel_H/IO/FileSystem/FAT/Comparison.cs b/src/Kernel/Atomix.Kernel_H/IO/FileSystem/FAT/Comparison.cs new file mode 100644 index 0000000..e983616 --- /dev/null +++ b/src/Kernel/Atomix.Kernel_H/IO/FileSystem/FAT/Comparison.cs @@ -0,0 +1,14 @@ +/* +* PROJECT: Atomix Development +* LICENSE: BSD 3-Clause (LICENSE.md) +* PURPOSE: FAT Comparator +* PROGRAMMERS: Aman Priyadarshi (aman.eureka@gmail.com) +*/ + +namespace Atomix.Kernel_H.IO.FileSystem.FAT +{ + internal abstract class Comparison + { + internal abstract bool Compare(byte[] data, int offset, FatType type); + } +} diff --git a/src/Kernel/Atomix.Kernel_H/IO/FileSystem/FAT/Entry.cs b/src/Kernel/Atomix.Kernel_H/IO/FileSystem/FAT/Entry.cs new file mode 100644 index 0000000..0024942 --- /dev/null +++ b/src/Kernel/Atomix.Kernel_H/IO/FileSystem/FAT/Entry.cs @@ -0,0 +1,28 @@ +/* +* PROJECT: Atomix Development +* LICENSE: BSD 3-Clause (LICENSE.md) +* PURPOSE: FAT Entry Enum +* PROGRAMMERS: Aman Priyadarshi (aman.eureka@gmail.com) +*/ + + +namespace Atomix.Kernel_H.IO.FileSystem.FAT +{ + internal enum Entry : int + { + DOSName = 0x00, // 8 + DOSExtension = 0x08, // 3 + FileAttributes = 0x0B, // 1 + Reserved = 0x0C, // 1 + CreationTimeFine = 0x0D, // 1 + CreationTime = 0x0E, // 2 + CreationDate = 0x10, // 2 + LastAccessDate = 0x12, // 2 + EAIndex = 0x14, // 2 + LastModifiedTime = 0x16, // 2 + LastModifiedDate = 0x18, // 2 + FirstCluster = 0x1A, // 2 + FileSize = 0x1C, // 4 + EntrySize = 32, + } +} diff --git a/src/Kernel/Atomix.Kernel_H/IO/FileSystem/FAT/FatFileAttribute.cs b/src/Kernel/Atomix.Kernel_H/IO/FileSystem/FAT/FatFileAttribute.cs new file mode 100644 index 0000000..6bfd654 --- /dev/null +++ b/src/Kernel/Atomix.Kernel_H/IO/FileSystem/FAT/FatFileAttribute.cs @@ -0,0 +1,58 @@ +/* +* PROJECT: Atomix Development +* LICENSE: BSD 3-Clause (LICENSE.md) +* PURPOSE: FAT File Attribute Enum +* PROGRAMMERS: Aman Priyadarshi (aman.eureka@gmail.com) +*/ + + +namespace Atomix.Kernel_H.IO.FileSystem.FAT +{ + internal enum FatFileAttributes : byte + { + /// + /// Flag represents the file is read-only. + /// + ReadOnly = 0x01, + + /// + /// Flag represents the file is hidden. + /// + Hidden = 0x02, + + /// + /// Flag represents the file is a system file. + /// + System = 0x04, + + /// + /// Flag represents the file entry is a volume label. + /// + VolumeLabel = 0x08, + + /// + /// Flag represents the file entry is a subdirectory. + /// + SubDirectory = 0x10, + + /// + /// Flag represents the file has the archive bit set. + /// + Archive = 0x20, + + /// + /// Flag represents the file entry is for a device. + /// + Device = 0x40, + + /// + /// Flag is unused. + /// + Unused = 0x80, + + /// + /// Flag represents the file has a long file name. + /// + LongFileName = 0x0F + }; +} diff --git a/src/Kernel/Atomix.Kernel_H/IO/FileSystem/FatFileSystem.cs b/src/Kernel/Atomix.Kernel_H/IO/FileSystem/FAT/FatFileSystem.cs similarity index 73% rename from src/Kernel/Atomix.Kernel_H/IO/FileSystem/FatFileSystem.cs rename to src/Kernel/Atomix.Kernel_H/IO/FileSystem/FAT/FatFileSystem.cs index 4ee7484..70cd0d5 100644 --- a/src/Kernel/Atomix.Kernel_H/IO/FileSystem/FatFileSystem.cs +++ b/src/Kernel/Atomix.Kernel_H/IO/FileSystem/FAT/FatFileSystem.cs @@ -16,41 +16,40 @@ namespace Atomix.Kernel_H.IO.FileSystem { - internal class FatFileSystem : GenericFileSystem + internal unsafe class FatFileSystem : GenericFileSystem { - // They should be private set only, so take care of this later - internal UInt32 BytePerSector; - internal UInt32 SectorsPerCluster; - internal UInt32 ReservedSector; - internal UInt32 TotalFAT; - internal UInt32 DirectoryEntry; - internal UInt32 TotalSectors; - internal UInt32 SectorsPerFAT; - internal UInt32 DataSectorCount; - internal UInt32 ClusterCount; - internal UInt32 SerialNo; - internal UInt32 RootCluster; - internal UInt32 RootSector; - internal UInt32 RootSectorCount; - internal UInt32 DataSector; - internal UInt32 EntriesPerSector; - internal UInt32 fatEntries; - - protected FatType FatType; - - protected string VolumeLabel; - - public FatFileSystem(Storage Device) + int BytePerSector; + int SectorsPerCluster; + int ReservedSector; + int TotalFAT; + int DirectoryEntry; + int TotalSectors; + int SectorsPerFAT; + int DataSectorCount; + int ClusterCount; + int SerialNo; + int RootCluster; + int RootSector; + int RootSectorCount; + int DataSector; + int EntriesPerSector; + int fatEntries; + + FatType FatType; + + string VolumeLabel; + + public FatFileSystem(string aName, Stream aDevice) + :base(aName, aDevice) { - IDevice = Device; - mIsValid = IsFAT(); + BytePerSector = 512; } - private unsafe bool IsFAT() + internal override bool Detect() { var BootSector = new byte[512]; - if (!IDevice.Read(0U, 1U, BootSector)) + if (!ReadBlock(BootSector, 0, 1)) return false; var xSig = BitConverter.ToUInt16(BootSector, 510); @@ -67,7 +66,7 @@ private unsafe bool IsFAT() if (BitConverter.ToUInt16(BootSector, 19) == 0) { /* Large amount of sector on media. This field is set if there are more than 65535 sectors in the volume. */ - TotalSectors = BitConverter.ToUInt32(BootSector, 32); + TotalSectors = BitConverter.ToInt32(BootSector, 32); } else { @@ -80,7 +79,7 @@ private unsafe bool IsFAT() if (SectorsPerFAT == 0) { /* FAT 32 ONLY */ - SectorsPerFAT = BitConverter.ToUInt32(BootSector, 36); + SectorsPerFAT = BitConverter.ToInt32(BootSector, 36); } /* Not Necessary, To Avoid Crashes during corrupted BPB Info */ @@ -89,7 +88,7 @@ private unsafe bool IsFAT() return false; /* Some basic calculations to check basic error :P */ - uint RootDirSectors = 0; + int RootDirSectors = 0; DataSectorCount = TotalSectors - (ReservedSector + (TotalFAT * SectorsPerFAT) + RootDirSectors); ClusterCount = DataSectorCount / SectorsPerCluster; @@ -104,39 +103,44 @@ private unsafe bool IsFAT() /* Now we open door of gold coins xDD */ if (FatType == FatType.FAT32) { - SerialNo = BitConverter.ToUInt32(BootSector, 39); + SerialNo = BitConverter.ToInt32(BootSector, 39); VolumeLabel = new string((sbyte*)BootSector.GetDataOffset(), 71, 11); // for checking - RootCluster = BitConverter.ToUInt32(BootSector, 44); + RootCluster = BitConverter.ToInt32(BootSector, 44); RootSector = 0; RootSectorCount = 0; } /* The key is of another door */ else { - SerialNo = BitConverter.ToUInt32(BootSector, 67); + SerialNo = BitConverter.ToInt32(BootSector, 67); VolumeLabel = new string((sbyte*)BootSector.GetDataOffset(), 43, 11); RootSector = ReservedSector + (TotalFAT * SectorsPerFAT); - RootSectorCount = (UInt32)((DirectoryEntry * 32 + (BytePerSector - 1)) / BytePerSector); + RootSectorCount = (DirectoryEntry * 32 + (BytePerSector - 1)) / BytePerSector; fatEntries = SectorsPerFAT * 512 / 4; } /* Now it shows our forward path ;) */ - EntriesPerSector = (UInt32)(BytePerSector / 32); + EntriesPerSector = BytePerSector / 32; DataSector = ReservedSector + (TotalFAT * SectorsPerFAT) + RootSectorCount; - - mFSType = FileSystemType.FAT; return true; } - internal override bool CreateFile(string[] path, int pointer) + internal override Directory CreateDirectory(string aName) { - return false; + return null; } - internal override Stream GetFile(string[] path, int pointer) + internal override File CreateFile(string aName) { - if (!mIsValid) - return null; + return null; + } + + internal override FSObject FindEntry(string aName) + { + throw new NotImplementedException(); + } + internal override Stream GetFile(string[] path, int pointer) + { FatFileLocation FileLocation = ChangeDirectory(path, pointer); if (FileLocation == null) return null; @@ -147,7 +151,7 @@ internal override Stream GetFile(string[] path, int pointer) private FatFileLocation ChangeDirectory(string[] path, int pointer) { - uint CurrentCluster = RootCluster; + int CurrentCluster = RootCluster; var Compare = new WithName(null); FatFileLocation location = null; while (pointer < path.Length) @@ -163,15 +167,15 @@ private FatFileLocation ChangeDirectory(string[] path, int pointer) return location; } - private FatFileLocation FindEntry(Comparison compare, uint startCluster) + private FatFileLocation FindEntry(Comparison compare, int startCluster) { - uint activeSector = ((startCluster - RootCluster) * SectorsPerCluster) + DataSector; + int activeSector = ((startCluster - RootCluster) * SectorsPerCluster) + DataSector; if (startCluster == 0) activeSector = (FatType == FatType.FAT32) ? GetSectorByCluster(RootCluster) : RootSector; byte[] aData = new byte[BytePerSector * SectorsPerCluster]; - this.IDevice.Read(activeSector, SectorsPerCluster, aData); + ReadBlock(aData, activeSector, SectorsPerCluster); for (uint index = 0; index < EntriesPerSector * SectorsPerCluster; index++) { @@ -194,20 +198,20 @@ private FatFileLocation FindEntry(Comparison compare, uint startCluster) return null; } - internal uint GetClusterEntryValue(uint cluster) + internal uint GetClusterEntryValue(int cluster) { - uint fatoffset = cluster<<2; - uint sector = ReservedSector + (fatoffset / BytePerSector); + int fatoffset = cluster<<2; + int sector = ReservedSector + (fatoffset / BytePerSector); int sectorOffset = (int)(fatoffset % BytePerSector); var aData = new byte[512]; - IDevice.Read(sector, 1U, aData); + ReadBlock(aData, sector, 1); var xNextCluster = (BitConverter.ToUInt32(aData, sectorOffset) & 0x0FFFFFFF); return xNextCluster; } - private uint GetSectorByCluster(uint cluster) + private int GetSectorByCluster(int cluster) { return DataSector + ((cluster - RootCluster) * SectorsPerCluster); } @@ -249,8 +253,23 @@ internal static bool IsClusterLast(uint Cluster) return (Cluster == 0x0FFFFFF8); } - internal byte[] NewBlockArray - { get { return new byte[SectorsPerCluster * BytePerSector]; } } + internal bool ReadBlock(byte[] aBuffer, int aBlockIndex, int aBlockCount) + { + int Count = BytePerSector * aBlockCount; + if (Count > aBuffer.Length) + return false; + Device.Seek(aBlockIndex * BytePerSector, FileSeek.Origin); + return Device.Read(aBuffer, Count) == Count; + } + + internal bool WriteBlock(byte[] aBuffer, int aBlockIndex, int aBlockCount) + { + int Count = BytePerSector * aBlockCount; + if (Count > aBuffer.Length) + return false; + Device.Seek(aBlockIndex * BytePerSector, FileSeek.Origin); + return Device.Write(aBuffer, Count) == Count; + } internal void PrintDebugInfo() { diff --git a/src/Kernel/Atomix.Kernel_H/IO/FileSystem/FAT/FatType.cs b/src/Kernel/Atomix.Kernel_H/IO/FileSystem/FAT/FatType.cs new file mode 100644 index 0000000..e69cd84 --- /dev/null +++ b/src/Kernel/Atomix.Kernel_H/IO/FileSystem/FAT/FatType.cs @@ -0,0 +1,28 @@ +/* +* PROJECT: Atomix Development +* LICENSE: BSD 3-Clause (LICENSE.md) +* PURPOSE: FAT Type Enum +* PROGRAMMERS: Aman Priyadarshi (aman.eureka@gmail.com) +*/ + + +namespace Atomix.Kernel_H.IO.FileSystem.FAT +{ + public enum FatType : byte + { + /// + /// Represents a 12-bit FAT. + /// + FAT12 = 12, + + /// + /// Represents a 16-bit FAT. + /// + FAT16 = 16, + + /// + /// Represents a 32-bit FAT. + /// + FAT32 = 32 + } +} diff --git a/src/Kernel/Atomix.Kernel_H/IO/FileSystem/FAT/FileLocation.cs b/src/Kernel/Atomix.Kernel_H/IO/FileSystem/FAT/FileLocation.cs index 38d2216..ab09a6c 100644 --- a/src/Kernel/Atomix.Kernel_H/IO/FileSystem/FAT/FileLocation.cs +++ b/src/Kernel/Atomix.Kernel_H/IO/FileSystem/FAT/FileLocation.cs @@ -1,7 +1,7 @@ /* * PROJECT: Atomix Development * LICENSE: BSD 3-Clause (LICENSE.md) -* PURPOSE: FAT Helper +* PURPOSE: FAT File Location * PROGRAMMERS: Aman Priyadarshi (aman.eureka@gmail.com) */ diff --git a/src/Kernel/Atomix.Kernel_H/IO/FileSystem/FAT/FileNameAttribute.cs b/src/Kernel/Atomix.Kernel_H/IO/FileSystem/FAT/FileNameAttribute.cs new file mode 100644 index 0000000..5a1087d --- /dev/null +++ b/src/Kernel/Atomix.Kernel_H/IO/FileSystem/FAT/FileNameAttribute.cs @@ -0,0 +1,18 @@ +/* +* PROJECT: Atomix Development +* LICENSE: BSD 3-Clause (LICENSE.md) +* PURPOSE: FAT Name Attribute Enum +* PROGRAMMERS: Aman Priyadarshi (aman.eureka@gmail.com) +*/ + +namespace Atomix.Kernel_H.IO.FileSystem.FAT +{ + internal enum FileNameAttribute : uint + { + LastEntry = 0x00, + /* special msdos hack where 0x05 really means 0xE5 (since 0xE5 was already used for delete) */ + Escape = 0x05, + Dot = 0x2E, + Deleted = 0xE5, + }; +} diff --git a/src/Kernel/Atomix.Kernel_H/IO/FileSystem/FAT/misc.cs b/src/Kernel/Atomix.Kernel_H/IO/FileSystem/FAT/misc.cs deleted file mode 100644 index e50b4d5..0000000 --- a/src/Kernel/Atomix.Kernel_H/IO/FileSystem/FAT/misc.cs +++ /dev/null @@ -1,114 +0,0 @@ -/* -* PROJECT: Atomix Development -* LICENSE: BSD 3-Clause (LICENSE.md) -* PURPOSE: FAT Helper -* PROGRAMMERS: Aman Priyadarshi (aman.eureka@gmail.com) -*/ - -namespace Atomix.Kernel_H.IO.FileSystem.FAT -{ - public enum FatType : byte - { - /// - /// Represents a 12-bit FAT. - /// - FAT12 = 12, - - /// - /// Represents a 16-bit FAT. - /// - FAT16 = 16, - - /// - /// Represents a 32-bit FAT. - /// - FAT32 = 32 - } - - internal enum Entry : int - { - DOSName = 0x00, // 8 - DOSExtension = 0x08, // 3 - FileAttributes = 0x0B, // 1 - Reserved = 0x0C, // 1 - CreationTimeFine = 0x0D, // 1 - CreationTime = 0x0E, // 2 - CreationDate = 0x10, // 2 - LastAccessDate = 0x12, // 2 - EAIndex = 0x14, // 2 - LastModifiedTime = 0x16, // 2 - LastModifiedDate = 0x18, // 2 - FirstCluster = 0x1A, // 2 - FileSize = 0x1C, // 4 - EntrySize = 32, - } - - internal enum FindEntry - { - Any = 0x1, - ByCluster = 0x2, - Empty = 0x3, - WithName = 0x4, - } - - internal enum FileNameAttribute : uint - { - LastEntry = 0x00, - Escape = 0x05, // special msdos hack where 0x05 really means 0xE5 (since 0xE5 was already used for delete) - Dot = 0x2E, - Deleted = 0xE5, - } - - internal enum FatFileAttributes : byte - { - /// - /// Flag represents the file is read-only. - /// - ReadOnly = 0x01, - - /// - /// Flag represents the file is hidden. - /// - Hidden = 0x02, - - /// - /// Flag represents the file is a system file. - /// - System = 0x04, - - /// - /// Flag represents the file entry is a volume label. - /// - VolumeLabel = 0x08, - - /// - /// Flag represents the file entry is a subdirectory. - /// - SubDirectory = 0x10, - - /// - /// Flag represents the file has the archive bit set. - /// - Archive = 0x20, - - /// - /// Flag represents the file entry is for a device. - /// - Device = 0x40, - - /// - /// Flag is unused. - /// - Unused = 0x80, - - /// - /// Flag represents the file has a long file name. - /// - LongFileName = 0x0F - } - - internal abstract class Comparison - { - internal abstract bool Compare(byte[] data, int offset, FatType type); - } -} diff --git a/src/Kernel/Atomix.Kernel_H/IO/FileSystem/GenericFileSystem.cs b/src/Kernel/Atomix.Kernel_H/IO/FileSystem/GenericFileSystem.cs index f7a169e..2159c3d 100644 --- a/src/Kernel/Atomix.Kernel_H/IO/FileSystem/GenericFileSystem.cs +++ b/src/Kernel/Atomix.Kernel_H/IO/FileSystem/GenericFileSystem.cs @@ -1,34 +1,22 @@ /* * PROJECT: Atomix Development * LICENSE: BSD 3-Clause (LICENSE.md) -* PURPOSE: Generic File System class +* PURPOSE: Generic File System * PROGRAMMERS: Aman Priyadarshi (aman.eureka@gmail.com) */ -using Atomix.Kernel_H.Devices; - namespace Atomix.Kernel_H.IO.FileSystem { - public abstract class GenericFileSystem + internal abstract class GenericFileSystem : Directory { - internal Storage IDevice; - protected bool mIsValid; - protected FileSystemType mFSType; - - internal bool IsValid - { get { return mIsValid; } } - - internal FileSystemType FileSystem - { get { return mFSType; } } + internal readonly Stream Device; - internal abstract Stream GetFile(string[] path, int pointer); + internal GenericFileSystem(string aName, Stream aDevice) + : base(aName) + { + Device = aDevice; + } - internal abstract bool CreateFile(string[] path, int pointer); - } - - public enum FileSystemType : byte - { - None = 0x0, - FAT = 0x1 + internal abstract bool Detect(); } -} +} \ No newline at end of file diff --git a/src/Kernel/Atomix.Kernel_H/IO/FileSystem/RFS/FileStream.cs b/src/Kernel/Atomix.Kernel_H/IO/FileSystem/RFS/FileStream.cs deleted file mode 100644 index dfde690..0000000 --- a/src/Kernel/Atomix.Kernel_H/IO/FileSystem/RFS/FileStream.cs +++ /dev/null @@ -1,93 +0,0 @@ -/* -* PROJECT: Atomix Development -* LICENSE: BSD 3-Clause (LICENSE.md) -* PURPOSE: RFS (Ram File System) File Stream class -* PROGRAMMERS: Aman Priyadarshi (aman.eureka@gmail.com) -*/ - -using System; - -using Atomixilc.Lib; - -using Atomix.Kernel_H.Core; - -namespace Atomix.Kernel_H.IO.FileSystem.RFS -{ - internal unsafe class FileStream : Stream - { - internal readonly RamFile RamFile; - int mPosition; - - internal FileStream(RamFile aRamFile) - :base(aRamFile.Name, aRamFile.Length) - { - RamFile = aRamFile; - mPosition = 0; - } - - internal override int Read(byte[] aBuffer, int aCount) - { - if (aBuffer.Length > aCount) - aCount = aBuffer.Length; - - return Read((byte*)aBuffer.GetDataOffset(), aCount); - } - - internal override unsafe int Read(byte* aBuffer, int aCount) - { - if (aCount + mPosition > RamFile.Length) - aCount = RamFile.Length - mPosition; - - Memory.FastCopy((uint)aBuffer, RamFile.StartAddress + (uint)mPosition, (uint)aCount); - - mPosition += aCount; - return aCount; - } - - internal override int Write(byte[] aBuffer, int aCount) - { - return 0; - } - - internal override unsafe int Write(byte* aBuffer, int aCount) - { - return 0; - } - - internal override bool CanRead() - { return true; } - - internal override bool CanSeek() - { return false; } - - internal override bool CanWrite() - { return false; } - - internal override int Position() - { return mPosition; } - - internal override int Seek(int val, SEEK pos) - { - switch(pos) - { - case SEEK.SEEK_FROM_CURRENT: - mPosition += val; - break; - case SEEK.SEEK_FROM_ORIGIN: - mPosition += val; - break; - case SEEK.SEEK_FROM_END: - mPosition = RamFile.Length + val; - break; - } - - mPosition %= RamFile.Length; - return mPosition; - } - - internal override bool Close() - { - return true; - } - } -} diff --git a/src/Kernel/Atomix.Kernel_H/IO/FileSystem/RFS/RamFile.cs b/src/Kernel/Atomix.Kernel_H/IO/FileSystem/RFS/RamFile.cs index 6e0d9a0..9817729 100644 --- a/src/Kernel/Atomix.Kernel_H/IO/FileSystem/RFS/RamFile.cs +++ b/src/Kernel/Atomix.Kernel_H/IO/FileSystem/RFS/RamFile.cs @@ -7,17 +7,23 @@ namespace Atomix.Kernel_H.IO.FileSystem.RFS { - internal class RamFile + internal class RamFile : File { - internal readonly string Name; - internal readonly uint StartAddress; - internal readonly int Length; + int mLength; + uint mStartAddress; internal RamFile(string aName, uint aStartAddress, int aLength) + :base(aName) { - Name = aName; - StartAddress = aStartAddress; - Length = aLength; + mLength = aLength; + mStartAddress = aStartAddress; + } + + internal override Stream Open(FileMode aMode) + { + if ((aMode & FileMode.Append) != 0 || (aMode & FileMode.Write) != 0) + return null; + return new MemoryStream(mStartAddress, mLength); } } } diff --git a/src/Kernel/Atomix.Kernel_H/IO/FileSystem/RFS/RamFileSystem.cs b/src/Kernel/Atomix.Kernel_H/IO/FileSystem/RFS/RamFileSystem.cs new file mode 100644 index 0000000..e95c649 --- /dev/null +++ b/src/Kernel/Atomix.Kernel_H/IO/FileSystem/RFS/RamFileSystem.cs @@ -0,0 +1,65 @@ +/* +* PROJECT: Atomix Development +* LICENSE: BSD 3-Clause (LICENSE.md) +* PURPOSE: Ram File System +* PROGRAMMERS: Aman Priyadarshi (aman.eureka@gmail.com) +*/ + +using System; +using System.Runtime.InteropServices; + +using Atomixilc.Lib; + +using Atomix.Kernel_H.Lib; +using Atomix.Kernel_H.IO.FileSystem.RFS; + +namespace Atomix.Kernel_H.IO.FileSystem +{ + internal unsafe class RamFileSystem : GenericFileSystem + { + IDictionary mFiles; + + internal RamFileSystem(string aName, Stream aDevice) + :base(aName, aDevice) + { + mFiles = new IDictionary(Internals.GetHashCode, string.Equals); + } + + internal override bool Detect() + { + if (!(Device is MemoryStream)) + return false; + + var stream = (MemoryStream)Device; + var data = new byte[sizeof(FileEntry)]; + var entry = (FileEntry*)data.GetDataOffset(); + + stream.Read(data, sizeof(FileEntry)); + while (entry->StartAddress != 0) + { + var name = new string(entry->Name); + mFiles.Add(name, new RamFile(name, stream.Address + entry->StartAddress, entry->Length)); + Device.Read(data, sizeof(FileEntry)); + } + return true; + } + + internal override FSObject FindEntry(string aName) + { + throw new NotImplementedException(); + } + + [StructLayout(LayoutKind.Explicit, Size = 40)] + struct FileEntry + { + [FieldOffset(0)] + public fixed sbyte Name[32]; + + [FieldOffset(32)] + public uint StartAddress; + + [FieldOffset(36)] + public int Length; + } + } +} diff --git a/src/Kernel/Atomix.Kernel_H/IO/FileSystem/RamFileSystem.cs b/src/Kernel/Atomix.Kernel_H/IO/FileSystem/RamFileSystem.cs deleted file mode 100644 index b1bbef0..0000000 --- a/src/Kernel/Atomix.Kernel_H/IO/FileSystem/RamFileSystem.cs +++ /dev/null @@ -1,70 +0,0 @@ -/* -* PROJECT: Atomix Development -* LICENSE: BSD 3-Clause (LICENSE.md) -* PURPOSE: Ram File System -* PROGRAMMERS: Aman Priyadarshi (aman.eureka@gmail.com) -*/ - -using Atomixilc.Lib; - -using Atomix.Kernel_H.Lib; -using Atomix.Kernel_H.IO.FileSystem.RFS; - -using System.Runtime.InteropServices; - -namespace Atomix.Kernel_H.IO.FileSystem -{ - internal unsafe class RamFileSystem : GenericFileSystem - { - uint DataAddress; - uint DataLength; - IDictionary Files; - - internal RamFileSystem(uint aAddress, uint aLength) - { - DataAddress = aAddress; - DataLength = aLength; - Files = new IDictionary(Internals.GetHashCode, string.Equals); - mIsValid = LoadFileSystem(); - } - - private bool LoadFileSystem() - { - var Entries = (FileEntry*)DataAddress; - Entries++; - while(Entries->StartAddress != 0) - { - var FileName = new string(Entries->Name); - Files.Add(FileName, new RamFile(FileName, Entries->StartAddress + DataAddress, Entries->Length)); - Entries++; - } - return true; - } - - internal override Stream GetFile(string[] path, int pointer) - { - var FileName = path[pointer]; - if (Files.ContainsKey(FileName)) - return new FileStream(Files[FileName]); - return null; - } - - internal override bool CreateFile(string[] path, int pointer) - { - return false; - } - - [StructLayout(LayoutKind.Explicit, Size = 40)] - struct FileEntry - { - [FieldOffset(0)] - public fixed sbyte Name[32]; - - [FieldOffset(32)] - public uint StartAddress; - - [FieldOffset(36)] - public int Length; - } - } -} diff --git a/src/Kernel/Atomix.Kernel_H/IO/FileSystem/VirtualFileSystem.cs b/src/Kernel/Atomix.Kernel_H/IO/FileSystem/VirtualFileSystem.cs deleted file mode 100644 index e38a338..0000000 --- a/src/Kernel/Atomix.Kernel_H/IO/FileSystem/VirtualFileSystem.cs +++ /dev/null @@ -1,77 +0,0 @@ -/* -* PROJECT: Atomix Development -* LICENSE: BSD 3-Clause (LICENSE.md) -* PURPOSE: Virtual File System -* PROGRAMMERS: Aman Priyadarshi (aman.eureka@gmail.com) -*/ - -using System; - -using Atomixilc.Lib; - -using Atomix.Kernel_H.Lib; -using Atomix.Kernel_H.Core; - -namespace Atomix.Kernel_H.IO.FileSystem -{ - internal static class VirtualFileSystem - { - static IDictionary MountedFS; - - internal static void Setup() - { - MountedFS = new IDictionary(Internals.GetHashCode, string.Equals); - } - - internal static GenericFileSystem GetFS(string aDevice) - { - if (!MountedFS.ContainsKey(aDevice)) - return null; - return MountedFS[aDevice]; - } - - internal static Stream GetFile(string aPath) - { - var paths = Marshal.Split(aPath, '/'); - var FileSystem = GetFS(paths[0]); - if (FileSystem == null) - return null; - var xStream = FileSystem.GetFile(paths, 1); - return xStream; - } - - internal static bool CreateFile(string aPath) - { - var paths = Marshal.Split(aPath, '/'); - var FileSystem = GetFS(paths[0]); - if (FileSystem == null) - return false; - var xValue = FileSystem.CreateFile(paths, 1); - return xValue; - } - - internal static bool MountDevice(string aDeviceName, GenericFileSystem aFS) - { - if (!aFS.IsValid) - return false; - - if (aDeviceName == null) - aDeviceName = GetDeviceLabel(); - - if (MountedFS.ContainsKey(aDeviceName)) - return false; - - MountedFS.Add(aDeviceName, aFS); - Debug.Write("Directory Mounted: %s\n", aDeviceName); - return true; - } - - static uint mDeviceLabelCounter = 0; - private static string GetDeviceLabel() - { - string suffix = Convert.ToString(mDeviceLabelCounter++); - string Label = ("disk") + suffix; - return Label; - } - } -} diff --git a/src/Kernel/Atomix.Kernel_H/IO/MemoryStream.cs b/src/Kernel/Atomix.Kernel_H/IO/MemoryStream.cs new file mode 100644 index 0000000..1ebe43d --- /dev/null +++ b/src/Kernel/Atomix.Kernel_H/IO/MemoryStream.cs @@ -0,0 +1,100 @@ +/* +* PROJECT: Atomix Development +* LICENSE: BSD 3-Clause (LICENSE.md) +* PURPOSE: Memory Stream Class +* PROGRAMMERS: Aman Priyadarshi (aman.eureka@gmail.com) +*/ + +using Atomixilc.Lib; + +namespace Atomix.Kernel_H.IO +{ + internal unsafe class MemoryStream : Stream + { + uint mAddress; + int mLength; + + int mPointer; + + internal uint Address + { get { return mAddress; } } + + internal int Length + { get { return mLength; } } + + internal MemoryStream(uint aAddress, int aLength) + { + mAddress = aAddress; + mLength = aLength; + mPointer = 0; + } + + internal override int Read(byte[] aBuffer, int aCount) + { + int aOffset = mPointer; + if (aOffset + aCount >= mLength) + aCount = mLength - aOffset; + Memory.FastCopy(aBuffer.GetDataOffset(), mAddress, aCount); + mPointer = aOffset + aCount; + return aCount; + } + + internal override int Read(byte[] aBuffer, int aOffset, int aCount) + { + if (aOffset + aCount >= mLength) + aCount = mLength - aOffset; + Memory.FastCopy(aBuffer.GetDataOffset(), mAddress, aCount); + return aCount; + } + + internal override int Write(byte[] aBuffer, int aCount) + { + int aOffset = mPointer; + if (aOffset + aCount >= mLength) + aCount = mLength - aOffset; + Memory.FastCopy(mAddress, aBuffer.GetDataOffset(), aCount); + mPointer = aOffset + aCount; + return aCount; + } + + internal override int Write(byte[] aBuffer, int aOffset, int aCount) + { + if (aOffset + aCount >= mLength) + aCount = mLength - aOffset; + Memory.FastCopy(mAddress, aBuffer.GetDataOffset(), aCount); + return aCount; + } + + internal override bool Seek(int aValue, FileSeek aSeek) + { + switch (aSeek) + { + case FileSeek.Origin: + { + mPointer = 0; + } + break; + case FileSeek.Current: + { + if (mPointer + aValue > mLength) + return false; + mPointer += aValue; + } + break; + case FileSeek.End: + { + if (aValue > mLength) + return false; + mPointer = mLength - aValue; + } + break; + } + return true; + } + + internal override bool Close() + { + return true; + } + } +} diff --git a/src/Kernel/Atomix.Kernel_H/IO/Pipe.cs b/src/Kernel/Atomix.Kernel_H/IO/Pipe.cs index a244ca2..3cd44f6 100644 --- a/src/Kernel/Atomix.Kernel_H/IO/Pipe.cs +++ b/src/Kernel/Atomix.Kernel_H/IO/Pipe.cs @@ -47,7 +47,7 @@ internal bool Write(byte* aData, bool Hangup = true) if (BufferStatus[WritingPointer]) return false; - Memory.FastCopy((uint)Buffer + (uint)(WritingPointer * PacketSize), (uint)aData, (uint)PacketSize); + Memory.FastCopy((uint)Buffer + (uint)(WritingPointer * PacketSize), (uint)aData, PacketSize); BufferStatus[WritingPointer] = true; WritingPointer = (WritingPointer + 1) % PacketsCount; @@ -59,7 +59,7 @@ internal bool Read(byte[] aData) while (!BufferStatus[ReadingPointer]) Task.Switch(); - Memory.FastCopy(aData.GetDataOffset(), (uint)Buffer + (uint)(ReadingPointer * PacketSize), (uint)PacketSize); + Memory.FastCopy(aData.GetDataOffset(), (uint)Buffer + (uint)(ReadingPointer * PacketSize), PacketSize); BufferStatus[ReadingPointer] = false; ReadingPointer = (ReadingPointer + 1) % PacketsCount; diff --git a/src/Kernel/Atomix.Kernel_H/IO/Stream.cs b/src/Kernel/Atomix.Kernel_H/IO/Stream.cs index 609b5ee..15e167b 100644 --- a/src/Kernel/Atomix.Kernel_H/IO/Stream.cs +++ b/src/Kernel/Atomix.Kernel_H/IO/Stream.cs @@ -5,40 +5,15 @@ * PROGRAMMERS: Aman Priyadarshi (aman.eureka@gmail.com) */ -using Atomix.Kernel_H.Core; - namespace Atomix.Kernel_H.IO { - public abstract class Stream + internal abstract class Stream { - internal readonly string FileName; - internal readonly int FileSize; - - internal Stream(string aFileName, int aSize) - { - FileName = aFileName; - FileSize = aSize; - } - - internal abstract bool CanSeek(); - internal abstract int Position(); - internal abstract bool CanRead(); - internal abstract bool CanWrite(); - - internal abstract unsafe int Write(byte* aBuffer, int aCount); - internal abstract unsafe int Read(byte* aBuffer, int aCount); - + internal abstract bool Seek(int aValue, FileSeek aSeek); internal abstract int Write(byte[] aBuffer, int aCount); + internal abstract int Write(byte[] aBuffer, int aOffset, int aCount); internal abstract int Read(byte[] aBuffer, int aCount); - internal abstract int Seek(int val, SEEK pos); - + internal abstract int Read(byte[] aBuffer, int aOffset, int aCount); internal abstract bool Close(); } - - public enum SEEK : int - { - SEEK_FROM_ORIGIN = 0, - SEEK_FROM_CURRENT = 1, - SEEK_FROM_END = 2, - } } diff --git a/src/Kernel/Atomix.Kernel_H/IO/VFN.cs b/src/Kernel/Atomix.Kernel_H/IO/VFN.cs new file mode 100644 index 0000000..746df54 --- /dev/null +++ b/src/Kernel/Atomix.Kernel_H/IO/VFN.cs @@ -0,0 +1,37 @@ +/* +* PROJECT: Atomix Development +* LICENSE: BSD 3-Clause (LICENSE.md) +* PURPOSE: Virtual File Node +* PROGRAMMERS: Aman Priyadarshi (aman.eureka@gmail.com) +*/ + +using Atomixilc.Lib; + +using Atomix.Kernel_H.Lib; + +namespace Atomix.Kernel_H.IO +{ + internal class VFN : Directory + { + IDictionary mEntries; + + internal VFN(string aName) + : base(aName) + { + mEntries = new IDictionary(Internals.GetHashCode, string.Equals); + } + + internal override FSObject FindEntry(string aName) + { + return mEntries.GetValue(aName, null); + } + + internal bool Mount(FSObject aObject) + { + if (mEntries.ContainsKey(aObject.Name)) + return false; + mEntries.Add(aObject.Name, aObject); + return true; + } + } +} \ No newline at end of file diff --git a/src/Kernel/Atomix.Kernel_H/IO/VirtualFileSystem.cs b/src/Kernel/Atomix.Kernel_H/IO/VirtualFileSystem.cs new file mode 100644 index 0000000..7a2a3f4 --- /dev/null +++ b/src/Kernel/Atomix.Kernel_H/IO/VirtualFileSystem.cs @@ -0,0 +1,56 @@ +/* +* PROJECT: Atomix Development +* LICENSE: BSD 3-Clause (LICENSE.md) +* PURPOSE: Virtual File System +* PROGRAMMERS: Aman Priyadarshi (aman.eureka@gmail.com) +*/ + +using Atomix.Kernel_H.Lib; +using Atomix.Kernel_H.Core; + +namespace Atomix.Kernel_H.IO +{ + internal static class VirtualFileSystem + { + static VFN mRoot; + + internal static void Install() + { + mRoot = new VFN(string.Empty); + } + + internal static FSObject Open(string aPath) + { + var paths = Marshal.Split(aPath, '/'); + + int count = paths.Length; + if (paths[0] != string.Empty) + return null; + + FSObject node = mRoot; + for (int i = 1; i < count; i++) + { + if (node == null || !(node is Directory)) + return null; + node = ((Directory)node).FindEntry(paths[i]); + } + + return node; + } + + internal static bool Mount(FSObject aObject, string aPath) + { + var node = Open(aPath); + if (node == null || !(node is VFN)) + return false; + Debug.Write("VFS Mounted: %s\n", aPath); + ((VFN)node).Mount(aObject); + return true; + } + + internal static bool Map(string aPath, string aName) + { + return Mount(new VFN(aName), aPath); + } + } +} \ No newline at end of file diff --git a/src/Kernel/Atomix.Kernel_H/Lib/Marshal.cs b/src/Kernel/Atomix.Kernel_H/Lib/Marshal.cs index 4ac9997..7886e88 100644 --- a/src/Kernel/Atomix.Kernel_H/Lib/Marshal.cs +++ b/src/Kernel/Atomix.Kernel_H/Lib/Marshal.cs @@ -36,7 +36,7 @@ internal static void Copy(string aStr, sbyte* aCstr, int aLen) internal static void Copy(char* aDes, string aSrc, int aLen) { - Memory.FastCopy((uint)aDes, aSrc.GetDataOffset(), (uint)(aLen * sizeof(char))); + Memory.FastCopy((uint)aDes, aSrc.GetDataOffset(), aLen * sizeof(char)); aDes[aLen] = '\0'; } diff --git a/src/Kernel/Atomix.Kernel_H/Start-x86.cs b/src/Kernel/Atomix.Kernel_H/Start-x86.cs index c6db023..1b8ae6f 100644 --- a/src/Kernel/Atomix.Kernel_H/Start-x86.cs +++ b/src/Kernel/Atomix.Kernel_H/Start-x86.cs @@ -13,11 +13,11 @@ using Atomixilc.Attributes; using Atomixilc.Machine.x86; +using Atomix.Kernel_H.IO; using Atomix.Kernel_H.Core; using Atomix.Kernel_H.Devices; using Atomix.Kernel_H.Arch.x86; using Atomix.Kernel_H.Drivers.Video; -using Atomix.Kernel_H.IO.FileSystem; namespace Atomix.Kernel_H { @@ -168,7 +168,7 @@ internal static void Start(uint magic, uint address, uint KernelDirectory, uint VBE.Init(); /* Initialise Virtual File system */ - VirtualFileSystem.Setup(); + VFS.Install(); /* Setup Syscall */ Syscall.Setup(); From 5747cdf9cf323ac9865ffc6619e2f5c64a0108c2 Mon Sep 17 00:00:00 2001 From: Aman Priyadarshi Date: Sat, 18 Mar 2017 16:57:34 +0530 Subject: [PATCH 2/4] Added FatDirectory and FatFile --- .../Atomix.Kernel_H/Atomix.Kernel_H.csproj | 17 +- .../IO/FileSystem/FAT/FatDirectory.cs | 33 ++++ .../IO/FileSystem/FAT/FatFile.cs | 33 ++++ .../IO/FileSystem/FAT/FatFileSystem.cs | 145 +----------------- .../IO/FileSystem/FAT/FileLocation.cs | 27 ---- .../IO/FileSystem/RFS/RamFileSystem.cs | 3 +- 6 files changed, 86 insertions(+), 172 deletions(-) create mode 100644 src/Kernel/Atomix.Kernel_H/IO/FileSystem/FAT/FatDirectory.cs create mode 100644 src/Kernel/Atomix.Kernel_H/IO/FileSystem/FAT/FatFile.cs delete mode 100644 src/Kernel/Atomix.Kernel_H/IO/FileSystem/FAT/FileLocation.cs diff --git a/src/Kernel/Atomix.Kernel_H/Atomix.Kernel_H.csproj b/src/Kernel/Atomix.Kernel_H/Atomix.Kernel_H.csproj index 0f7462d..10ec743 100644 --- a/src/Kernel/Atomix.Kernel_H/Atomix.Kernel_H.csproj +++ b/src/Kernel/Atomix.Kernel_H/Atomix.Kernel_H.csproj @@ -94,25 +94,30 @@ - + + + + - + + + - - - + + + - + diff --git a/src/Kernel/Atomix.Kernel_H/IO/FileSystem/FAT/FatDirectory.cs b/src/Kernel/Atomix.Kernel_H/IO/FileSystem/FAT/FatDirectory.cs new file mode 100644 index 0000000..309f19b --- /dev/null +++ b/src/Kernel/Atomix.Kernel_H/IO/FileSystem/FAT/FatDirectory.cs @@ -0,0 +1,33 @@ +/* +* PROJECT: Atomix Development +* LICENSE: BSD 3-Clause (LICENSE.md) +* PURPOSE: FAT Directory +* PROGRAMMERS: Aman Priyadarshi (aman.eureka@gmail.com) +*/ + +namespace Atomix.Kernel_H.IO.FileSystem.FAT +{ + internal class FatDirectory : Directory + { + internal readonly FatFileSystem FS; + internal readonly uint StartCluster; + internal readonly uint DirectorySector; + internal readonly int DirectoryIndex; + internal readonly int Size; + + internal FatDirectory(FatFileSystem aFS, string aName, uint aStartCluster, uint aDirectorySector, int aDirectoryIndex, int aSize) + : base(aName) + { + FS = aFS; + StartCluster = aStartCluster; + DirectorySector = aDirectorySector; + DirectoryIndex = aDirectoryIndex; + Size = aSize; + } + + internal override FSObject FindEntry(string aName) + { + return base.FindEntry(aName); + } + } +} diff --git a/src/Kernel/Atomix.Kernel_H/IO/FileSystem/FAT/FatFile.cs b/src/Kernel/Atomix.Kernel_H/IO/FileSystem/FAT/FatFile.cs new file mode 100644 index 0000000..e82ee4b --- /dev/null +++ b/src/Kernel/Atomix.Kernel_H/IO/FileSystem/FAT/FatFile.cs @@ -0,0 +1,33 @@ +/* +* PROJECT: Atomix Development +* LICENSE: BSD 3-Clause (LICENSE.md) +* PURPOSE: FAT Directory +* PROGRAMMERS: Aman Priyadarshi (aman.eureka@gmail.com) +*/ + +using System; + +namespace Atomix.Kernel_H.IO.FileSystem.FAT +{ + internal class FatFile : File + { + internal readonly uint StartCluster; + internal readonly uint DirectorySector; + internal readonly int DirectoryIndex; + internal readonly int Size; + + internal FatFile(string aName, uint aStartCluster, uint aDirectorySector, int aDirectoryIndex, int aSize) + : base(aName) + { + StartCluster = aStartCluster; + DirectorySector = aDirectorySector; + DirectoryIndex = aDirectoryIndex; + Size = aSize; + } + + internal override Stream Open(FileMode aMode) + { + throw new NotImplementedException(); + } + } +} diff --git a/src/Kernel/Atomix.Kernel_H/IO/FileSystem/FAT/FatFileSystem.cs b/src/Kernel/Atomix.Kernel_H/IO/FileSystem/FAT/FatFileSystem.cs index 70cd0d5..aa95db8 100644 --- a/src/Kernel/Atomix.Kernel_H/IO/FileSystem/FAT/FatFileSystem.cs +++ b/src/Kernel/Atomix.Kernel_H/IO/FileSystem/FAT/FatFileSystem.cs @@ -10,7 +10,6 @@ using Atomixilc.Lib; using Atomix.Kernel_H.Core; -using Atomix.Kernel_H.Devices; using Atomix.Kernel_H.IO.FileSystem.FAT; using Atomix.Kernel_H.IO.FileSystem.FAT.Find; @@ -75,7 +74,6 @@ internal override bool Detect() /* FAT 12 and FAT 16 ONLY */ SectorsPerFAT = BitConverter.ToUInt16(BootSector, 22); - if (SectorsPerFAT == 0) { /* FAT 32 ONLY */ @@ -104,7 +102,7 @@ internal override bool Detect() if (FatType == FatType.FAT32) { SerialNo = BitConverter.ToInt32(BootSector, 39); - VolumeLabel = new string((sbyte*)BootSector.GetDataOffset(), 71, 11); // for checking + VolumeLabel = new string((sbyte*)BootSector.GetDataOffset(), 71, 11); RootCluster = BitConverter.ToInt32(BootSector, 44); RootSector = 0; RootSectorCount = 0; @@ -118,157 +116,30 @@ internal override bool Detect() RootSectorCount = (DirectoryEntry * 32 + (BytePerSector - 1)) / BytePerSector; fatEntries = SectorsPerFAT * 512 / 4; } + /* Now it shows our forward path ;) */ EntriesPerSector = BytePerSector / 32; DataSector = ReservedSector + (TotalFAT * SectorsPerFAT) + RootSectorCount; return true; } - internal override Directory CreateDirectory(string aName) - { - return null; - } - - internal override File CreateFile(string aName) - { - return null; - } - internal override FSObject FindEntry(string aName) { throw new NotImplementedException(); } - internal override Stream GetFile(string[] path, int pointer) - { - FatFileLocation FileLocation = ChangeDirectory(path, pointer); - if (FileLocation == null) - return null; - - var xStream = new FatStream(this, path[path.Length - 1], FileLocation.FirstCluster, FileLocation.Size); - return xStream; - } - - private FatFileLocation ChangeDirectory(string[] path, int pointer) - { - int CurrentCluster = RootCluster; - var Compare = new WithName(null); - FatFileLocation location = null; - while (pointer < path.Length) - { - Compare.Name = path[pointer]; - location = FindEntry(Compare, CurrentCluster); - if (location == null) - return null; - CurrentCluster = location.FirstCluster; - pointer++; - } - - return location; - } - - private FatFileLocation FindEntry(Comparison compare, int startCluster) - { - int activeSector = ((startCluster - RootCluster) * SectorsPerCluster) + DataSector; - - if (startCluster == 0) - activeSector = (FatType == FatType.FAT32) ? GetSectorByCluster(RootCluster) : RootSector; - - byte[] aData = new byte[BytePerSector * SectorsPerCluster]; - ReadBlock(aData, activeSector, SectorsPerCluster); - - for (uint index = 0; index < EntriesPerSector * SectorsPerCluster; index++) - { - int offset = (int)(index * (int)Entry.EntrySize); - if (compare.Compare(aData, offset, FatType)) - { - FatFileAttributes attribute = (FatFileAttributes)aData[offset + (int)Entry.FileAttributes]; - return new FatFileLocation( - GetClusterEntry(aData, index, FatType), - activeSector, - index, - (attribute & FatFileAttributes.SubDirectory) != 0, - BitConverter.ToInt32(aData, offset + (int)Entry.FileSize)); - } - - if (aData[(int)Entry.DOSName + offset] == (int)FileNameAttribute.LastEntry) - break; - } - - return null; - } - - internal uint GetClusterEntryValue(int cluster) - { - int fatoffset = cluster<<2; - int sector = ReservedSector + (fatoffset / BytePerSector); - int sectorOffset = (int)(fatoffset % BytePerSector); - - var aData = new byte[512]; - ReadBlock(aData, sector, 1); - var xNextCluster = (BitConverter.ToUInt32(aData, sectorOffset) & 0x0FFFFFFF); - - return xNextCluster; - } - - private int GetSectorByCluster(int cluster) - { - return DataSector + ((cluster - RootCluster) * SectorsPerCluster); - } - - internal static uint GetClusterEntry(byte[] data, uint index, FatType type) - { - uint cluster = BitConverter.ToUInt16(data, (int)((uint)Entry.FirstCluster + (index * (uint)Entry.EntrySize))); - - if (type == FatType.FAT32) - cluster |= (uint)BitConverter.ToUInt16(data, (int)((uint)Entry.EAIndex + (index * (uint)Entry.EntrySize))) << 16; - - if (cluster == 0) - cluster = 2; - - return cluster; - } - - internal static bool IsClusterBad(uint Cluster) - { - // Values are depend only on FAT 32 FS - return (Cluster == 0x0FFFFFF7); - } - - internal static bool IsClusterFree(uint Cluster) - { - // Values are depend only on FAT 32 FS - return (Cluster == 0x0); - } - - internal static bool IsClusterReserved(uint Cluster) - { - // Values are depend only on FAT 32 FS - return ((Cluster == 0x0) || (Cluster >= 0xFFF0) && (Cluster < 0x0FFFFFF7)); - } - - internal static bool IsClusterLast(uint Cluster) - { - // Values are depend only on FAT 32 FS - return (Cluster == 0x0FFFFFF8); - } - internal bool ReadBlock(byte[] aBuffer, int aBlockIndex, int aBlockCount) { - int Count = BytePerSector * aBlockCount; - if (Count > aBuffer.Length) - return false; - Device.Seek(aBlockIndex * BytePerSector, FileSeek.Origin); - return Device.Read(aBuffer, Count) == Count; + int count = BytePerSector * aBlockCount; + int offset = aBlockIndex * BytePerSector; + return Device.Read(aBuffer, offset, count) == count; } internal bool WriteBlock(byte[] aBuffer, int aBlockIndex, int aBlockCount) { - int Count = BytePerSector * aBlockCount; - if (Count > aBuffer.Length) - return false; - Device.Seek(aBlockIndex * BytePerSector, FileSeek.Origin); - return Device.Write(aBuffer, Count) == Count; + int count = BytePerSector * aBlockCount; + int offset = aBlockIndex * BytePerSector; + return Device.Write(aBuffer, offset, count) == count; } internal void PrintDebugInfo() diff --git a/src/Kernel/Atomix.Kernel_H/IO/FileSystem/FAT/FileLocation.cs b/src/Kernel/Atomix.Kernel_H/IO/FileSystem/FAT/FileLocation.cs deleted file mode 100644 index ab09a6c..0000000 --- a/src/Kernel/Atomix.Kernel_H/IO/FileSystem/FAT/FileLocation.cs +++ /dev/null @@ -1,27 +0,0 @@ -/* -* PROJECT: Atomix Development -* LICENSE: BSD 3-Clause (LICENSE.md) -* PURPOSE: FAT File Location -* PROGRAMMERS: Aman Priyadarshi (aman.eureka@gmail.com) -*/ - -namespace Atomix.Kernel_H.IO.FileSystem.FAT -{ - internal class FatFileLocation - { - internal readonly uint FirstCluster; - internal readonly uint DirectorySector; - internal readonly uint DirectorySectorIndex; - internal readonly bool directory; - internal readonly int Size; - - internal FatFileLocation(uint aStartCluster, uint aDirectorySector, uint aDirectoryIndex, bool aDirectory, int aSize) - { - FirstCluster = aStartCluster; - DirectorySector = aDirectorySector; - DirectorySectorIndex = aDirectoryIndex; - directory = aDirectory; - Size = aSize; - } - } -} diff --git a/src/Kernel/Atomix.Kernel_H/IO/FileSystem/RFS/RamFileSystem.cs b/src/Kernel/Atomix.Kernel_H/IO/FileSystem/RFS/RamFileSystem.cs index e95c649..20a8101 100644 --- a/src/Kernel/Atomix.Kernel_H/IO/FileSystem/RFS/RamFileSystem.cs +++ b/src/Kernel/Atomix.Kernel_H/IO/FileSystem/RFS/RamFileSystem.cs @@ -5,7 +5,6 @@ * PROGRAMMERS: Aman Priyadarshi (aman.eureka@gmail.com) */ -using System; using System.Runtime.InteropServices; using Atomixilc.Lib; @@ -46,7 +45,7 @@ internal override bool Detect() internal override FSObject FindEntry(string aName) { - throw new NotImplementedException(); + return mFiles.GetValue(aName, null); } [StructLayout(LayoutKind.Explicit, Size = 40)] From 464f842c53a4868be0953ed73d844b5f1d85041f Mon Sep 17 00:00:00 2001 From: Aman Priyadarshi Date: Sat, 18 Mar 2017 18:03:13 +0530 Subject: [PATCH 3/4] Connecting FAT to VFS --- src/Kernel/Atomix.Kernel_H/Boot.cs | 2 +- .../IO/FileSystem/FAT/Entry.cs | 28 +++++++++---------- .../IO/FileSystem/FAT/FatFileSystem.cs | 28 +++++++++++++++++++ .../IO/FileSystem/FAT/FileNameAttribute.cs | 9 +++--- src/Kernel/Atomix.Kernel_H/Start-x86.cs | 2 +- 5 files changed, 48 insertions(+), 21 deletions(-) diff --git a/src/Kernel/Atomix.Kernel_H/Boot.cs b/src/Kernel/Atomix.Kernel_H/Boot.cs index 5c8ea6b..f917b87 100644 --- a/src/Kernel/Atomix.Kernel_H/Boot.cs +++ b/src/Kernel/Atomix.Kernel_H/Boot.cs @@ -8,12 +8,12 @@ using System; using Atomixilc.Lib; -using Atomix.Kernel_H.Lib.Cairo; using Atomix.Kernel_H.IO; using Atomix.Kernel_H.Gui; using Atomix.Kernel_H.Core; using Atomix.Kernel_H.Devices; using Atomix.Kernel_H.Arch.x86; +using Atomix.Kernel_H.Lib.Cairo; using Atomix.Kernel_H.Drivers.Video; using Atomix.Kernel_H.IO.FileSystem; diff --git a/src/Kernel/Atomix.Kernel_H/IO/FileSystem/FAT/Entry.cs b/src/Kernel/Atomix.Kernel_H/IO/FileSystem/FAT/Entry.cs index 0024942..04b3624 100644 --- a/src/Kernel/Atomix.Kernel_H/IO/FileSystem/FAT/Entry.cs +++ b/src/Kernel/Atomix.Kernel_H/IO/FileSystem/FAT/Entry.cs @@ -10,19 +10,19 @@ namespace Atomix.Kernel_H.IO.FileSystem.FAT { internal enum Entry : int { - DOSName = 0x00, // 8 - DOSExtension = 0x08, // 3 - FileAttributes = 0x0B, // 1 - Reserved = 0x0C, // 1 - CreationTimeFine = 0x0D, // 1 - CreationTime = 0x0E, // 2 - CreationDate = 0x10, // 2 - LastAccessDate = 0x12, // 2 - EAIndex = 0x14, // 2 - LastModifiedTime = 0x16, // 2 - LastModifiedDate = 0x18, // 2 - FirstCluster = 0x1A, // 2 - FileSize = 0x1C, // 4 - EntrySize = 32, + DOSName = 0x00, // 8 + DOSExtension = 0x08, // 3 + FileAttributes = 0x0B, // 1 + Reserved = 0x0C, // 1 + CreationTimeFine = 0x0D, // 1 + CreationTime = 0x0E, // 2 + CreationDate = 0x10, // 2 + LastAccessDate = 0x12, // 2 + EAIndex = 0x14, // 2 + LastModifiedTime = 0x16, // 2 + LastModifiedDate = 0x18, // 2 + FirstCluster = 0x1A, // 2 + FileSize = 0x1C, // 4 + EntrySize = 32, } } diff --git a/src/Kernel/Atomix.Kernel_H/IO/FileSystem/FAT/FatFileSystem.cs b/src/Kernel/Atomix.Kernel_H/IO/FileSystem/FAT/FatFileSystem.cs index aa95db8..8d9b1e2 100644 --- a/src/Kernel/Atomix.Kernel_H/IO/FileSystem/FAT/FatFileSystem.cs +++ b/src/Kernel/Atomix.Kernel_H/IO/FileSystem/FAT/FatFileSystem.cs @@ -128,6 +128,34 @@ internal override FSObject FindEntry(string aName) throw new NotImplementedException(); } + internal FSObject FindEntry(Comparison compare, int startCluster) + { + int activeSector = ((startCluster - RootCluster) * SectorsPerCluster) + DataSector; + + if (startCluster == 0) + { + activeSector = RootSector; + if (FatType == FatType.FAT32) + activeSector = GetSectorByCluster(RootCluster); + } + + byte[] aData = new byte[BytePerSector * SectorsPerCluster]; + ReadBlock(aData, activeSector, SectorsPerCluster); + + int offset = 0; + for (int index = 0; index < EntriesPerSector * SectorsPerCluster; index++) + { + offset += (int)Entry.EntrySize; + } + + return null; + } + + internal int GetSectorByCluster(int cluster) + { + return DataSector + ((cluster - RootCluster) * SectorsPerCluster); + } + internal bool ReadBlock(byte[] aBuffer, int aBlockIndex, int aBlockCount) { int count = BytePerSector * aBlockCount; diff --git a/src/Kernel/Atomix.Kernel_H/IO/FileSystem/FAT/FileNameAttribute.cs b/src/Kernel/Atomix.Kernel_H/IO/FileSystem/FAT/FileNameAttribute.cs index 5a1087d..0be3520 100644 --- a/src/Kernel/Atomix.Kernel_H/IO/FileSystem/FAT/FileNameAttribute.cs +++ b/src/Kernel/Atomix.Kernel_H/IO/FileSystem/FAT/FileNameAttribute.cs @@ -9,10 +9,9 @@ namespace Atomix.Kernel_H.IO.FileSystem.FAT { internal enum FileNameAttribute : uint { - LastEntry = 0x00, - /* special msdos hack where 0x05 really means 0xE5 (since 0xE5 was already used for delete) */ - Escape = 0x05, - Dot = 0x2E, - Deleted = 0xE5, + LastEntry = 0x00, + Escape = 0x05, + Dot = 0x2E, + Deleted = 0xE5, }; } diff --git a/src/Kernel/Atomix.Kernel_H/Start-x86.cs b/src/Kernel/Atomix.Kernel_H/Start-x86.cs index 1b8ae6f..ee22316 100644 --- a/src/Kernel/Atomix.Kernel_H/Start-x86.cs +++ b/src/Kernel/Atomix.Kernel_H/Start-x86.cs @@ -168,7 +168,7 @@ internal static void Start(uint magic, uint address, uint KernelDirectory, uint VBE.Init(); /* Initialise Virtual File system */ - VFS.Install(); + VirtualFileSystem.Install(); /* Setup Syscall */ Syscall.Setup(); From e6b9db792159c0bfb933ff0932884e674ef45a73 Mon Sep 17 00:00:00 2001 From: Aman Priyadarshi Date: Sat, 18 Mar 2017 23:08:07 +0530 Subject: [PATCH 4/4] syscall modified and FAT modified --- .../Atomix.Kernel_H/Arch/x86/Multiboot.cs | 8 +- .../Atomix.Kernel_H/Atomix.Kernel_H.csproj | 5 +- src/Kernel/Atomix.Kernel_H/Boot.cs | 10 +- src/Kernel/Atomix.Kernel_H/Core/Syscall.cs | 19 +- src/Kernel/Atomix.Kernel_H/Exec/ELF.cs | 375 ------------------ .../IO/FileSystem/FAT/Entry.cs | 63 ++- .../IO/FileSystem/FAT/FatDirectory.cs | 12 +- .../IO/FileSystem/FAT/FatFile.cs | 14 +- .../IO/FileSystem/FAT/FatFileSystem.cs | 56 ++- .../IO/FileSystem/FAT/FatStream.cs | 3 +- .../IO/FileSystem/FAT/Find/Any.cs | 28 -- .../IO/FileSystem/FAT/Find/ByCluster.cs | 38 -- .../IO/FileSystem/FAT/Find/Empty.cs | 22 - .../IO/FileSystem/FAT/Find/WithName.cs | 67 ---- .../IO/FileSystem/RFS/FileEntry.cs | 24 ++ .../IO/FileSystem/RFS/RamFileSystem.cs | 15 - src/Kernel/Atomix.Kernel_H/IO/MemoryStream.cs | 8 +- src/Kernel/Atomix.Kernel_H/IO/Stream.cs | 2 +- 18 files changed, 156 insertions(+), 613 deletions(-) delete mode 100644 src/Kernel/Atomix.Kernel_H/IO/FileSystem/FAT/Find/Any.cs delete mode 100644 src/Kernel/Atomix.Kernel_H/IO/FileSystem/FAT/Find/ByCluster.cs delete mode 100644 src/Kernel/Atomix.Kernel_H/IO/FileSystem/FAT/Find/Empty.cs delete mode 100644 src/Kernel/Atomix.Kernel_H/IO/FileSystem/FAT/Find/WithName.cs create mode 100644 src/Kernel/Atomix.Kernel_H/IO/FileSystem/RFS/FileEntry.cs diff --git a/src/Kernel/Atomix.Kernel_H/Arch/x86/Multiboot.cs b/src/Kernel/Atomix.Kernel_H/Arch/x86/Multiboot.cs index 3e2b7ab..09ecebf 100644 --- a/src/Kernel/Atomix.Kernel_H/Arch/x86/Multiboot.cs +++ b/src/Kernel/Atomix.Kernel_H/Arch/x86/Multiboot.cs @@ -109,7 +109,7 @@ internal static unsafe class Multiboot static Multiboot_Info* Mb_Info; static bool aIsValid; static uint Initrd; - static uint InitrdSize; + static int InitrdSize; internal static bool IsValid { get { return aIsValid; } } @@ -134,14 +134,14 @@ internal static uint RamDisk get { return Initrd; } } - internal static uint RamDiskSize + internal static int RamDiskSize { get { return InitrdSize; } } internal static uint RamDiskEnd { - get { return Initrd + InitrdSize; } + get { return Initrd + (uint)InitrdSize; } } internal static unsafe void Setup(uint xSig, uint Address) @@ -167,7 +167,7 @@ internal static unsafe void Setup(uint xSig, uint Address) if (Mb_Info->mods_count > 0) { Initrd = modules[0]; - InitrdSize = modules[1] - Initrd; + InitrdSize = (int)(modules[1] - Initrd); Initrd += 0xC0000000; Debug.Write(" RamDisk:%d\n", Initrd); Debug.Write(" RamDisk-Size:%d\n", InitrdSize); diff --git a/src/Kernel/Atomix.Kernel_H/Atomix.Kernel_H.csproj b/src/Kernel/Atomix.Kernel_H/Atomix.Kernel_H.csproj index 10ec743..c141db5 100644 --- a/src/Kernel/Atomix.Kernel_H/Atomix.Kernel_H.csproj +++ b/src/Kernel/Atomix.Kernel_H/Atomix.Kernel_H.csproj @@ -102,11 +102,8 @@ - - - - + diff --git a/src/Kernel/Atomix.Kernel_H/Boot.cs b/src/Kernel/Atomix.Kernel_H/Boot.cs index f917b87..94a665c 100644 --- a/src/Kernel/Atomix.Kernel_H/Boot.cs +++ b/src/Kernel/Atomix.Kernel_H/Boot.cs @@ -35,9 +35,9 @@ internal unsafe static void Init() #region InitRamDisk if (Multiboot.RamDisk != 0) { - var xFileSystem = new RamFileSystem(Multiboot.RamDisk, Multiboot.RamDiskSize); - if (xFileSystem.IsValid) - VirtualFileSystem.MountDevice(null, xFileSystem); + var xFileSystem = new RamFileSystem("disk0", new MemoryStream(Multiboot.RamDisk, Multiboot.RamDiskSize)); + if (xFileSystem.Detect()) + VirtualFileSystem.Mount(xFileSystem, "/"); else throw new Exception("RamDisk Corrupted!"); } @@ -250,11 +250,11 @@ internal static void LoadIDE(bool IsPrimary, bool IsMaster) /* * Iterate over all FileSystem Drivers and check which is valid */ - var xFileSystem = new FatFileSystem(xMBR.PartInfo[i]); + /*var xFileSystem = new FatFileSystem(xMBR.PartInfo[i]); if (xFileSystem.IsValid) { VirtualFileSystem.MountDevice(null, xFileSystem); - } + }*/ } } } diff --git a/src/Kernel/Atomix.Kernel_H/Core/Syscall.cs b/src/Kernel/Atomix.Kernel_H/Core/Syscall.cs index ff7d14d..ab8fa28 100644 --- a/src/Kernel/Atomix.Kernel_H/Core/Syscall.cs +++ b/src/Kernel/Atomix.Kernel_H/Core/Syscall.cs @@ -7,9 +7,10 @@ using System; +using Atomixilc.Lib; + using Atomix.Kernel_H.IO; using Atomix.Kernel_H.Arch.x86; -using Atomix.Kernel_H.IO.FileSystem; namespace Atomix.Kernel_H.Core { @@ -99,7 +100,10 @@ private static unsafe int sys_read(int fd, byte* buffer, int count) if (fd >= files.Count) return -1; var stream = Process.Files[fd]; - return stream.Read(buffer, count); + var data = new byte[count]; + int status = stream.Read(data, count); + Memory.FastCopy((uint)buffer, data.GetDataOffset(), count); + return status; } private static int sys_seek(int fd, int offset, int origin) @@ -113,7 +117,7 @@ private static int sys_seek(int fd, int offset, int origin) if (origin > 2) return -1; var stream = Process.Files[fd]; - return stream.Seek(offset, (SEEK)origin); + return stream.Seek(offset, (FileSeek)origin); } private static int sys_close(int fd) @@ -134,15 +138,16 @@ private static int sys_close(int fd) return 0; } - private static unsafe int sys_open(sbyte* file, int flags, int mode) + private static unsafe int sys_open(sbyte* name, int flags, int mode) { - var filename = new string(file); - var stream = VirtualFileSystem.GetFile(filename); + var filename = new string(name); + var file = VirtualFileSystem.Open(filename); Debug.Write("fopen: %s\n", filename); - if (stream == null) + if (file == null || !(file is File)) return -1; + var stream = ((File)file).Open(FileMode.Read); var Process = Scheduler.RunningProcess; var files = Process.Files; int count = files.Count; diff --git a/src/Kernel/Atomix.Kernel_H/Exec/ELF.cs b/src/Kernel/Atomix.Kernel_H/Exec/ELF.cs index 250ed73..9a06974 100644 --- a/src/Kernel/Atomix.Kernel_H/Exec/ELF.cs +++ b/src/Kernel/Atomix.Kernel_H/Exec/ELF.cs @@ -18,381 +18,6 @@ namespace Atomix.Kernel_H.Exec { internal unsafe static class ELF { - [StructLayout(LayoutKind.Explicit, Size = 52)] - struct Elf_Header - { - [FieldOffset(0)] - public fixed byte e_ident[16]; - [FieldOffset(16)] - public ushort e_type; - [FieldOffset(18)] - public ushort e_machine; - [FieldOffset(20)] - public uint e_version; - [FieldOffset(24)] - public uint e_entry; - [FieldOffset(28)] - public uint e_phoff; - [FieldOffset(32)] - public uint e_shoff; - [FieldOffset(36)] - public uint e_flags; - [FieldOffset(40)] - public ushort e_ehsize; - [FieldOffset(42)] - public ushort e_phentsize; - [FieldOffset(44)] - public ushort e_phnum; - [FieldOffset(46)] - public ushort e_shentsize; - [FieldOffset(48)] - public ushort e_shnum; - [FieldOffset(50)] - public ushort e_shstrndx; - }; - [StructLayout(LayoutKind.Explicit, Size = 40)] - struct Elf_Shdr - { - [FieldOffset(0)] - public uint sh_name; - [FieldOffset(4)] - public uint sh_type; - [FieldOffset(8)] - public uint sh_flags; - [FieldOffset(12)] - public uint sh_addr; - [FieldOffset(16)] - public uint sh_offset; - [FieldOffset(20)] - public uint sh_size; - [FieldOffset(24)] - public int sh_link; - [FieldOffset(28)] - public int sh_info; - [FieldOffset(32)] - public uint sh_addralign; - [FieldOffset(36)] - public uint sh_entsize; - }; - - [StructLayout(LayoutKind.Explicit, Size = 8)] - struct Elf32_Rel - { - [FieldOffset(0)] - public uint r_offset; - [FieldOffset(4)] - public uint r_info; - }; - - [StructLayout(LayoutKind.Explicit, Size = 16)] - struct Elf32_Sym - { - [FieldOffset(0)] - public uint st_name; - [FieldOffset(4)] - public uint st_value; - [FieldOffset(8)] - public uint st_size; - [FieldOffset(12)] - public byte st_info; - [FieldOffset(13)] - public byte st_other; - [FieldOffset(14)] - public ushort st_shndx; - }; - - /* Identification indexes for e_ident field in ELF header */ - const int EI_MAG0 = 0; /* file ID byte 0 */ - const int EI_MAG1 = 1; /* file ID byte 1 */ - const int EI_MAG2 = 2; /* file ID byte 2 */ - const int EI_MAG3 = 3; /* file ID byte 3 */ - const int EI_CLASS = 4; /* file class (capacity) */ - const int EI_DATA = 5; /* data encoding */ - const int EI_VERSION = 6; /* file version */ - const int EI_PAD = 7; /* start of padding bytes */ - const int EI_NIDENT = 16; /* size of e_ident[] */ - - /* "Magic number" in e_ident field of ELF header */ - const byte ELFMAG0 = 0x7F; - const byte ELFMAG1 = (byte)'E'; - const byte ELFMAG2 = (byte)'L'; - const byte ELFMAG3 = (byte)'F'; - - /* Relocation Type for i386 machine */ - const byte R_386_NONE = 0; - const byte R_386_32 = 1; /* S + A */ - const byte R_386_PC32 = 2; /* S + A - P */ - const byte R_386_GOT32 = 3; /* G + A */ - const byte R_386_PLT32 = 4; /* L + A - P */ - const byte R_386_COPY = 5; - const byte R_386_GLOB_DAT = 6; /* S */ - const byte R_386_JMP_SLOT = 7; /* S */ - const byte R_386_RELATIVE = 8; /* B + A */ - const byte R_386_GOTOFF = 9; /* S + A - GOT */ - const byte R_386_GOTPC = 10; /* GOT + A - P */ - const byte R_386_32PLT = 11; /* L + A */ - - /* File class (or capacity) in e_ident[4] of ELF header */ - const byte ELFCLASSNONE = 0; /* invalid class */ - const byte ELFCLASS32 = 1; /* 32-bit processor */ - const byte ELFCLASS64 = 2; /* 64-bit processor */ - - /* Data encoding in e_ident[5] of ELF header */ - const byte ELFDATANONE = 0; /* invalid data encoding */ - const byte ELFDATA2LSB = 1; /* little-endian format */ - const byte ELFDATA2MSB = 2; /* big-endian format */ - - /* Object file type in e_type field of ELF header */ - const ushort ET_NONE = 0; /* no file type */ - const ushort ET_REL = 1; /* relocatble file */ - const ushort ET_EXEC = 2; /* executable file */ - const ushort ET_DYN = 3; /* shared object file */ - const ushort ET_CORE = 4; /* core file */ - const ushort ET_LOPROC = 0xff00; /* processor-specific */ - const ushort ET_HIPROC = 0xffff; /* processor-specific */ - - /* Required architecture in e_machine field of ELF header */ - const ushort EM_NONE = 0; /* no machine */ - const ushort EM_M32 = 1; /* AT&T WE 32100 */ - const ushort EM_SPARC = 2; /* SPARC */ - const ushort EM_386 = 3; /* Intel 80386 */ - const ushort EM_68K = 4; /* Motorola 68000 */ - const ushort EM_88K = 5; /* Motorola 88000 */ - const ushort EM_860 = 7; /* Intel 80860 */ - const ushort EM_MIPS = 8; /* MIPS RS3000 */ - const ushort EM_ARM = 40; /* Advanced RISC Machines ARM */ - - /* Object file version in e_version field of ELF header */ - const uint EV_NONE = 0; /* invalid version */ - const uint EV_CURRENT = 1; /* current version */ - - /* Section's semantics in sh_type field of ELF section header */ - const uint SHT_NULL = 0; /* no section associated with header */ - const uint SHT_PROGBITS = 1; /* program-defined data */ - const uint SHT_SYMTAB = 2; /* link editing & dynamic linking symbols */ - const uint SHT_STRTAB = 3; /* string table */ - const uint SHT_RELA = 4; /* minimal set of dynamic linking symbols */ - const uint SHT_HASH = 5; /* relocation entries with explicit addends */ - const uint SHT_DYNAMIC = 6; /* symbol hash table (dynamic linking) */ - const uint SHT_NOTE = 7; /* dynamic linking info */ - const uint SHT_NOBITS = 8; /* file-marking information */ - const uint SHT_REL = 9; /* relocation entries without explicit addends */ - const uint SHT_SHLIB = 10; /* reserved */ - const uint SHT_DYNSYM = 11; /* dynamic linking symbol table */ - const uint SHT_LOPROC = 0x70000000; /* LB for processor-specific dynamics */ - const uint SHT_HIPROC = 0x7fffffff; /* UB for processor-specific dynamics */ - const uint SHT_LOUSER = 0x80000000; /* LB for application-specific dynamics */ - const uint SHT_HIUSER = 0x8fffffff; /* UB for application-specific dynamics */ - - /* Section's attribute flags in sh_flags field of ELF section header */ - const uint SHF_WRITE = 0x1; /* data writable during execution */ - const uint SHF_ALLOC = 0x2; /* occupies memory during execution */ - const uint SHF_EXECINSTR = 0x4; /* executable machine instructions */ - const uint SHF_MASKPROC = 0xf0000000; /* mask for processor-specific semantics */ - - /* Special section indexes (reserved values) */ - const ushort SHN_UNDEF = 0; /* undefined section index */ - const ushort SHN_LORESERVE = 0xff00; /* LB (lower bound) of ELF reserved indexes */ - const ushort SHN_LOPROC = 0xff00; /* LB of processor-specific semantics */ - const ushort SHN_HIPROC = 0xff1f; /* UB of processor-specific semantics */ - const ushort SHN_ABS = 0xfff1; /* absolute (not relocatable) section */ - const ushort SHN_COMMON = 0xfff2; /* C external variables section */ - const ushort SHN_HIRESERVE = 0xffff; /* UB (upper bound) of ELF reserved indexes */ - - /* Symbol binding */ - const uint STB_LOCAL = 0; /* Local scope */ - const uint STB_GLOBAL = 1; /* Global scope */ - const uint STB_WEAK = 2; /* Weak, (ie. __attribute__((weak))) */ - - internal static uint Load(string aPath) - { - Stream xStream = VirtualFileSystem.GetFile(aPath); - - if (xStream == null) - throw new Exception("[ELF]: File not found!"); - - var xData = new byte[xStream.FileSize]; - xStream.Read(xData, xData.Length); - - uint BaseAddress = xData.GetDataOffset(); - Elf_Header* Header = (Elf_Header*)BaseAddress; - - /* verify ELF header and if this code support this type of elf */ - CheckHeader(Header); - - /* prepare sections and allocate memory (if required) */ - Elf_Shdr* Shdr = (Elf_Shdr*)(BaseAddress + Header->e_shoff); - for (int i = 0; i < Header->e_shnum; i++, Shdr++) - { - Shdr->sh_addr = BaseAddress + Shdr->sh_offset; - if ((Shdr->sh_flags & SHF_ALLOC) != 0) - { - LoadSection(BaseAddress, Shdr); - } - } - - /* Iterate over all sections and perform relocations */ - Shdr = (Elf_Shdr*)(BaseAddress + Header->e_shoff); - for (int i = 0; i < Header->e_shnum; i++, Shdr++) - { - switch (Shdr->sh_type) - { - case SHT_SYMTAB: - { - RegisterSymbol(Header, Shdr, aPath); - } - break; - case SHT_REL: - { - Shdr->sh_addr = BaseAddress + Shdr->sh_offset; - Relocate(Header, Shdr); - } - break; - } - } - - return Header->e_entry; - } - - private static void Relocate(Elf_Header* aHeader, Elf_Shdr* aShdr) - { - uint BaseAddress = (uint)aHeader; - Elf32_Rel* Reloc = (Elf32_Rel*)aShdr->sh_addr; - Elf_Shdr* TargetSection = (Elf_Shdr*)(BaseAddress + aHeader->e_shoff) + aShdr->sh_info; - - uint RelocCount = aShdr->sh_size / aShdr->sh_entsize; - - byte SymIdx; - uint SymVal, RelocType; - for (uint i = 0; i < RelocCount; i++, Reloc++) - { - SymVal = 0; - SymIdx = (byte)(Reloc->r_info >> 8); - RelocType = Reloc->r_info & 0xFF; - - if (SymIdx != SHN_UNDEF) - { - if (RelocType == R_386_PLT32) - SymVal = 0; - else - SymVal = GetSymValue(aHeader, TargetSection->sh_link, SymIdx); - } - - uint* add_ref = (uint*)(TargetSection->sh_addr + Reloc->r_offset); - switch (RelocType) - { - case R_386_32: - *add_ref = SymVal + *add_ref; // S + A - break; - case R_386_PLT32: // L + A - P - case R_386_PC32: // S + A - P - default: - throw new Exception("[ELF]: Unsupported Relocation type"); - } - } - } - - private static void RegisterSymbol(Elf_Header* aHeader, Elf_Shdr* aShdr, string aPath) - { - uint BaseAddress = (uint)aHeader; - Elf32_Sym* SymTab = (Elf32_Sym*)aShdr->sh_addr; - var StrTabAdd = ((Elf_Shdr*)(BaseAddress + aHeader->e_shoff) + aShdr->sh_link)->sh_addr; - - uint count = aShdr->sh_size / aShdr->sh_entsize; - - uint Address; - for (uint i = 0; i < count; i++, SymTab++) - { - uint flag = (uint)(SymTab->st_info >> 4); - if (flag == STB_GLOBAL) - { - switch (SymTab->st_shndx) - { - case SHN_UNDEF: - continue; // for now ignore UNDEF Symbols - case SHN_ABS: - Address = SymTab->st_value; - break; - default: - var TargetSection = (Elf_Shdr*)(BaseAddress + aHeader->e_shoff) + SymTab->st_shndx; - Address = TargetSection->sh_addr + SymTab->st_value; - break; - } - - string SymName = new string((sbyte*)(StrTabAdd + SymTab->st_name)); - Debug.Write("Symbol: %s\n", SymName); - } - } - } - - private static uint GetSymValue(Elf_Header* aHeader, int aTableIdx, int aSymIdx) - { - uint BaseAddress = (uint)aHeader; - Elf_Shdr* SymSection = (Elf_Shdr*)(BaseAddress + aHeader->e_shoff) + aTableIdx; - Elf32_Sym* SymTab = (Elf32_Sym*)(SymSection->sh_addr) + aSymIdx; - - switch (SymTab->st_shndx) - { - case SHN_UNDEF: - { - var StrTabAdd = ((Elf_Shdr*)(BaseAddress + aHeader->e_shoff) + SymSection->sh_link)->sh_addr; - string SymName = new string((sbyte*)(StrTabAdd + SymTab->st_name)); - - Debug.Write("Undefined Symbol: %s\n", SymName); - throw new Exception("[ELF]: Extern Symbol not supported"); - } - case SHN_ABS: - return SymTab->st_value; - default: - Elf_Shdr* TargetSection = (Elf_Shdr*)(BaseAddress + aHeader->e_shoff) + SymTab->st_shndx; - return TargetSection->sh_addr + SymTab->st_value; - } - } - - private static uint LoadSection(uint aBaseAddress, Elf_Shdr* aShdr) - { - // make sure address if aligned - uint align = aShdr->sh_addralign; - uint addr = Heap.kmalloc(aShdr->sh_size + align); - - if (align != 0) - { - uint offset = addr & (align - 1); - addr += align - offset; - } - - if (aShdr->sh_type != SHT_NOBITS) - Memory.FastCopy(addr, aBaseAddress + aShdr->sh_offset, aShdr->sh_size); - - aShdr->sh_addr = addr; - return addr; - } - - private static void CheckHeader(Elf_Header* aHeader) - { - /* Check if we are supporting this standard */ - var ident = aHeader->e_ident; - if ((ident[EI_MAG0] != ELFMAG0) || - (ident[EI_MAG1] != ELFMAG1) || - (ident[EI_MAG2] != ELFMAG2) || - (ident[EI_MAG3] != ELFMAG3)) - throw new Exception("[ELF]: Invalid File format"); - - if (ident[EI_CLASS] != ELFCLASS32) - throw new Exception("[ELF]: Unsupported EI_CLASS"); - - if (ident[EI_DATA] != ELFDATA2LSB) - throw new Exception("[ELF]: Unsupported EI_DATA"); - - if (aHeader->e_machine != EM_386) - throw new Exception("[ELF]: Unsupported Machine Type"); - - if (aHeader->e_type != ET_REL) - throw new Exception("[ELF]: Unsupported ELF Type"); - - if (aHeader->e_version != EV_CURRENT) - throw new Exception("[ELF]: Unsupported ELF Version"); - } } } diff --git a/src/Kernel/Atomix.Kernel_H/IO/FileSystem/FAT/Entry.cs b/src/Kernel/Atomix.Kernel_H/IO/FileSystem/FAT/Entry.cs index 04b3624..e2e112f 100644 --- a/src/Kernel/Atomix.Kernel_H/IO/FileSystem/FAT/Entry.cs +++ b/src/Kernel/Atomix.Kernel_H/IO/FileSystem/FAT/Entry.cs @@ -1,28 +1,57 @@ /* * PROJECT: Atomix Development * LICENSE: BSD 3-Clause (LICENSE.md) -* PURPOSE: FAT Entry Enum +* PURPOSE: FAT Entry Structure * PROGRAMMERS: Aman Priyadarshi (aman.eureka@gmail.com) */ +using System.Runtime.InteropServices; namespace Atomix.Kernel_H.IO.FileSystem.FAT { - internal enum Entry : int + [StructLayout(LayoutKind.Explicit, Size = 40)] + internal unsafe struct Entry { - DOSName = 0x00, // 8 - DOSExtension = 0x08, // 3 - FileAttributes = 0x0B, // 1 - Reserved = 0x0C, // 1 - CreationTimeFine = 0x0D, // 1 - CreationTime = 0x0E, // 2 - CreationDate = 0x10, // 2 - LastAccessDate = 0x12, // 2 - EAIndex = 0x14, // 2 - LastModifiedTime = 0x16, // 2 - LastModifiedDate = 0x18, // 2 - FirstCluster = 0x1A, // 2 - FileSize = 0x1C, // 4 - EntrySize = 32, - } + [FieldOffset(0)] + public fixed sbyte DOSName[8]; + + [FieldOffset(8)] + public fixed sbyte DOSExtension[3]; + + [FieldOffset(11)] + public FatFileAttributes FileAttributes; + + [FieldOffset(12)] + public byte Reserved; + + [FieldOffset(13)] + public byte CreationTimeFine; + + [FieldOffset(14)] + public short CreationTime; + + [FieldOffset(16)] + public short CreationDate; + + [FieldOffset(18)] + public short LastAccessDate; + + [FieldOffset(20)] + public short EAIndex; + + [FieldOffset(22)] + public short LastModifiedTime; + + [FieldOffset(24)] + public short LastModifiedDate; + + [FieldOffset(26)] + public short FirstCluster; + + [FieldOffset(28)] + public uint FileSize; + + [FieldOffset(32)] + public uint EntrySize; + }; } diff --git a/src/Kernel/Atomix.Kernel_H/IO/FileSystem/FAT/FatDirectory.cs b/src/Kernel/Atomix.Kernel_H/IO/FileSystem/FAT/FatDirectory.cs index 309f19b..d4fad29 100644 --- a/src/Kernel/Atomix.Kernel_H/IO/FileSystem/FAT/FatDirectory.cs +++ b/src/Kernel/Atomix.Kernel_H/IO/FileSystem/FAT/FatDirectory.cs @@ -10,24 +10,20 @@ namespace Atomix.Kernel_H.IO.FileSystem.FAT internal class FatDirectory : Directory { internal readonly FatFileSystem FS; - internal readonly uint StartCluster; - internal readonly uint DirectorySector; - internal readonly int DirectoryIndex; - internal readonly int Size; + internal readonly int StartCluster; + internal readonly uint Size; - internal FatDirectory(FatFileSystem aFS, string aName, uint aStartCluster, uint aDirectorySector, int aDirectoryIndex, int aSize) + internal FatDirectory(FatFileSystem aFS, string aName, int aStartCluster, uint aSize) : base(aName) { FS = aFS; StartCluster = aStartCluster; - DirectorySector = aDirectorySector; - DirectoryIndex = aDirectoryIndex; Size = aSize; } internal override FSObject FindEntry(string aName) { - return base.FindEntry(aName); + return FS.FindEntry(aName, StartCluster); } } } diff --git a/src/Kernel/Atomix.Kernel_H/IO/FileSystem/FAT/FatFile.cs b/src/Kernel/Atomix.Kernel_H/IO/FileSystem/FAT/FatFile.cs index e82ee4b..2479b8c 100644 --- a/src/Kernel/Atomix.Kernel_H/IO/FileSystem/FAT/FatFile.cs +++ b/src/Kernel/Atomix.Kernel_H/IO/FileSystem/FAT/FatFile.cs @@ -11,17 +11,15 @@ namespace Atomix.Kernel_H.IO.FileSystem.FAT { internal class FatFile : File { - internal readonly uint StartCluster; - internal readonly uint DirectorySector; - internal readonly int DirectoryIndex; - internal readonly int Size; + internal readonly FatFileSystem FS; + internal readonly int StartCluster; + internal readonly uint Size; - internal FatFile(string aName, uint aStartCluster, uint aDirectorySector, int aDirectoryIndex, int aSize) + internal FatFile(FatFileSystem aFS, string aName, int aStartCluster, uint aSize) : base(aName) { - StartCluster = aStartCluster; - DirectorySector = aDirectorySector; - DirectoryIndex = aDirectoryIndex; + FS = aFS; + StartCluster = aStartCluster;; Size = aSize; } diff --git a/src/Kernel/Atomix.Kernel_H/IO/FileSystem/FAT/FatFileSystem.cs b/src/Kernel/Atomix.Kernel_H/IO/FileSystem/FAT/FatFileSystem.cs index 8d9b1e2..7206379 100644 --- a/src/Kernel/Atomix.Kernel_H/IO/FileSystem/FAT/FatFileSystem.cs +++ b/src/Kernel/Atomix.Kernel_H/IO/FileSystem/FAT/FatFileSystem.cs @@ -11,7 +11,6 @@ using Atomix.Kernel_H.Core; using Atomix.Kernel_H.IO.FileSystem.FAT; -using Atomix.Kernel_H.IO.FileSystem.FAT.Find; namespace Atomix.Kernel_H.IO.FileSystem { @@ -125,13 +124,15 @@ internal override bool Detect() internal override FSObject FindEntry(string aName) { - throw new NotImplementedException(); + return FindEntry(aName, RootCluster); } - internal FSObject FindEntry(Comparison compare, int startCluster) + internal FSObject FindEntry(string name, int startCluster) { - int activeSector = ((startCluster - RootCluster) * SectorsPerCluster) + DataSector; + int len = name.Length; + if (len > 12) return null; + int activeSector = ((startCluster - RootCluster) * SectorsPerCluster) + DataSector; if (startCluster == 0) { activeSector = RootSector; @@ -139,13 +140,50 @@ internal FSObject FindEntry(Comparison compare, int startCluster) activeSector = GetSectorByCluster(RootCluster); } - byte[] aData = new byte[BytePerSector * SectorsPerCluster]; - ReadBlock(aData, activeSector, SectorsPerCluster); + var data = new byte[BytePerSector * SectorsPerCluster]; + ReadBlock(data, activeSector, SectorsPerCluster); - int offset = 0; - for (int index = 0; index < EntriesPerSector * SectorsPerCluster; index++) + var entry = (Entry*)data.GetDataOffset(); + for (int index = 0; index < EntriesPerSector * SectorsPerCluster; index++, entry++) { - offset += (int)Entry.EntrySize; + var filename = entry->DOSName; + var EntryAttribute = filename[0]; + switch((FileNameAttribute)EntryAttribute) + { + case FileNameAttribute.Escape: + case FileNameAttribute.Deleted: + case FileNameAttribute.LastEntry: + continue; + } + + // compare name + int i = 0; + for (; i < len; i++) + if (filename[i] != name[i]) + break; + + if ((i < len) && (name[i] != '.' || filename[i] != '\0')) + continue; + + i++; + for (; i < len; i++) + if (filename[i - 1] != name[i]) + break; + + if (i < len || filename[i - 1] != '\0') + continue; + + // calculate cluster number + int cluster = entry->FirstCluster; + if (FatType == FatType.FAT32) + cluster |= entry->EAIndex << 16; + + if (cluster == 0) + cluster = 2; + + if ((entry->FileAttributes & FatFileAttributes.SubDirectory) != 0) + return new FatDirectory(this, name, cluster, entry->FileSize); + return new FatFile(this, name, cluster, entry->FileSize); } return null; diff --git a/src/Kernel/Atomix.Kernel_H/IO/FileSystem/FAT/FatStream.cs b/src/Kernel/Atomix.Kernel_H/IO/FileSystem/FAT/FatStream.cs index d5aa1ee..ed2492c 100644 --- a/src/Kernel/Atomix.Kernel_H/IO/FileSystem/FAT/FatStream.cs +++ b/src/Kernel/Atomix.Kernel_H/IO/FileSystem/FAT/FatStream.cs @@ -13,6 +13,7 @@ namespace Atomix.Kernel_H.IO.FileSystem.FAT { + /* internal unsafe class FatStream : Stream { private FatFileSystem mFS; @@ -134,5 +135,5 @@ internal override bool Close() Heap.Free((uint)mBufferCluster, (uint)mBufferLength); return true; } - } + }*/ } diff --git a/src/Kernel/Atomix.Kernel_H/IO/FileSystem/FAT/Find/Any.cs b/src/Kernel/Atomix.Kernel_H/IO/FileSystem/FAT/Find/Any.cs deleted file mode 100644 index 3ef4541..0000000 --- a/src/Kernel/Atomix.Kernel_H/IO/FileSystem/FAT/Find/Any.cs +++ /dev/null @@ -1,28 +0,0 @@ -/* -* PROJECT: Atomix Development -* LICENSE: BSD 3-Clause (LICENSE.md) -* PURPOSE: FAT Helper -* PROGRAMMERS: Aman Priyadarshi (aman.eureka@gmail.com) -*/ - -namespace Atomix.Kernel_H.IO.FileSystem.FAT.Find -{ - internal class Any : Comparison - { - internal Any() { } - - internal override bool Compare(byte[] data, int offset, FatType type) - { - switch ((FileNameAttribute)data[offset + (uint)Entry.DOSName]) - { - case FileNameAttribute.LastEntry: - case FileNameAttribute.Deleted: - case FileNameAttribute.Escape: - case FileNameAttribute.Dot: - return false; - default: - return true; - } - } - } -} diff --git a/src/Kernel/Atomix.Kernel_H/IO/FileSystem/FAT/Find/ByCluster.cs b/src/Kernel/Atomix.Kernel_H/IO/FileSystem/FAT/Find/ByCluster.cs deleted file mode 100644 index cf147b5..0000000 --- a/src/Kernel/Atomix.Kernel_H/IO/FileSystem/FAT/Find/ByCluster.cs +++ /dev/null @@ -1,38 +0,0 @@ -/* -* PROJECT: Atomix Development -* LICENSE: BSD 3-Clause (LICENSE.md) -* PURPOSE: FAT Helper -* PROGRAMMERS: Aman Priyadarshi (aman.eureka@gmail.com) -*/ - -namespace Atomix.Kernel_H.IO.FileSystem.FAT.Find -{ - internal class ByCluster : Comparison - { - internal readonly uint Cluster; - internal ByCluster(uint aCluster) - { - Cluster = aCluster; - } - - internal override bool Compare(byte[] data, int offset, FatType type) - { - switch ((FileNameAttribute)data[offset + (uint)Entry.DOSName]) - { - case FileNameAttribute.LastEntry: - case FileNameAttribute.Deleted: - case FileNameAttribute.Escape: - case FileNameAttribute.Dot: - return false; - default: - break; - } - - uint startcluster = FatFileSystem.GetClusterEntry(data, (uint)offset, type); - if (startcluster == Cluster) - return true; - - return false; - } - } -} diff --git a/src/Kernel/Atomix.Kernel_H/IO/FileSystem/FAT/Find/Empty.cs b/src/Kernel/Atomix.Kernel_H/IO/FileSystem/FAT/Find/Empty.cs deleted file mode 100644 index 64028ed..0000000 --- a/src/Kernel/Atomix.Kernel_H/IO/FileSystem/FAT/Find/Empty.cs +++ /dev/null @@ -1,22 +0,0 @@ -/* -* PROJECT: Atomix Development -* LICENSE: BSD 3-Clause (LICENSE.md) -* PURPOSE: FAT Helper -* PROGRAMMERS: Aman Priyadarshi (aman.eureka@gmail.com) -*/ - -namespace Atomix.Kernel_H.IO.FileSystem.FAT.Find -{ - internal class Empty : Comparison - { - internal Empty() { } - - internal override bool Compare(byte[] data, int offset, FatType type) - { - if ((FileNameAttribute)data[offset + (uint)Entry.DOSName] == FileNameAttribute.LastEntry) - return true; - - return false; - } - } -} diff --git a/src/Kernel/Atomix.Kernel_H/IO/FileSystem/FAT/Find/WithName.cs b/src/Kernel/Atomix.Kernel_H/IO/FileSystem/FAT/Find/WithName.cs deleted file mode 100644 index 4017926..0000000 --- a/src/Kernel/Atomix.Kernel_H/IO/FileSystem/FAT/Find/WithName.cs +++ /dev/null @@ -1,67 +0,0 @@ -/* -* PROJECT: Atomix Development -* LICENSE: BSD 3-Clause (LICENSE.md) -* PURPOSE: FAT Helper -* PROGRAMMERS: Aman Priyadarshi (aman.eureka@gmail.com) -*/ - -namespace Atomix.Kernel_H.IO.FileSystem.FAT.Find -{ - internal class WithName : Comparison - { - internal string Name; - - internal WithName(string aName) - { - Name = aName; - } - - internal override bool Compare(byte[] data, int offset, FatType type) - { - switch ((FileNameAttribute)data[offset + (int)Entry.DOSName]) - { - case FileNameAttribute.LastEntry: - case FileNameAttribute.Deleted: - case FileNameAttribute.Escape: - return false; - default: - break; - } - - int index; - for (index = 7; index >= 0 && data[offset + index] == ' '; index--) ; - index++; - - int dot = Name.IndexOf('.'); - if (dot == -1) - dot = Name.Length; - - if (dot != index) - return false; - - for (index = 0; index < dot; index++) - { - if ((data[offset + index] & 0xDF) != (Name[index] & 0xDF)) - return false; - } - - for (index = 10; index >= 8 && data[offset + index] == ' '; index--) ; - index -= 7; - - int index2 = Name.Length - dot - 1; - if (index2 < 0) index2 = 0; - - if (index2 != index) - return false; - - dot++; - for (index = 0; index < index2; index++) - { - if ((data[offset + index + 8] & 0xDF) != (Name[dot + index] & 0xDF)) - return false; - } - - return true; - } - } -} diff --git a/src/Kernel/Atomix.Kernel_H/IO/FileSystem/RFS/FileEntry.cs b/src/Kernel/Atomix.Kernel_H/IO/FileSystem/RFS/FileEntry.cs new file mode 100644 index 0000000..0a584ab --- /dev/null +++ b/src/Kernel/Atomix.Kernel_H/IO/FileSystem/RFS/FileEntry.cs @@ -0,0 +1,24 @@ +/* +* PROJECT: Atomix Development +* LICENSE: BSD 3-Clause (LICENSE.md) +* PURPOSE: Ram File Entry +* PROGRAMMERS: Aman Priyadarshi (aman.eureka@gmail.com) +*/ + +using System.Runtime.InteropServices; + +namespace Atomix.Kernel_H.IO.FileSystem.RFS +{ + [StructLayout(LayoutKind.Explicit, Size = 40)] + internal unsafe struct FileEntry + { + [FieldOffset(0)] + public fixed sbyte Name[32]; + + [FieldOffset(32)] + public uint StartAddress; + + [FieldOffset(36)] + public int Length; + } +} diff --git a/src/Kernel/Atomix.Kernel_H/IO/FileSystem/RFS/RamFileSystem.cs b/src/Kernel/Atomix.Kernel_H/IO/FileSystem/RFS/RamFileSystem.cs index 20a8101..ffc13c3 100644 --- a/src/Kernel/Atomix.Kernel_H/IO/FileSystem/RFS/RamFileSystem.cs +++ b/src/Kernel/Atomix.Kernel_H/IO/FileSystem/RFS/RamFileSystem.cs @@ -5,8 +5,6 @@ * PROGRAMMERS: Aman Priyadarshi (aman.eureka@gmail.com) */ -using System.Runtime.InteropServices; - using Atomixilc.Lib; using Atomix.Kernel_H.Lib; @@ -47,18 +45,5 @@ internal override FSObject FindEntry(string aName) { return mFiles.GetValue(aName, null); } - - [StructLayout(LayoutKind.Explicit, Size = 40)] - struct FileEntry - { - [FieldOffset(0)] - public fixed sbyte Name[32]; - - [FieldOffset(32)] - public uint StartAddress; - - [FieldOffset(36)] - public int Length; - } } } diff --git a/src/Kernel/Atomix.Kernel_H/IO/MemoryStream.cs b/src/Kernel/Atomix.Kernel_H/IO/MemoryStream.cs index 1ebe43d..be0adb9 100644 --- a/src/Kernel/Atomix.Kernel_H/IO/MemoryStream.cs +++ b/src/Kernel/Atomix.Kernel_H/IO/MemoryStream.cs @@ -65,7 +65,7 @@ internal override int Write(byte[] aBuffer, int aOffset, int aCount) return aCount; } - internal override bool Seek(int aValue, FileSeek aSeek) + internal override int Seek(int aValue, FileSeek aSeek) { switch (aSeek) { @@ -77,19 +77,19 @@ internal override bool Seek(int aValue, FileSeek aSeek) case FileSeek.Current: { if (mPointer + aValue > mLength) - return false; + break; mPointer += aValue; } break; case FileSeek.End: { if (aValue > mLength) - return false; + break; mPointer = mLength - aValue; } break; } - return true; + return mPointer; } internal override bool Close() diff --git a/src/Kernel/Atomix.Kernel_H/IO/Stream.cs b/src/Kernel/Atomix.Kernel_H/IO/Stream.cs index 15e167b..43add4c 100644 --- a/src/Kernel/Atomix.Kernel_H/IO/Stream.cs +++ b/src/Kernel/Atomix.Kernel_H/IO/Stream.cs @@ -9,7 +9,7 @@ namespace Atomix.Kernel_H.IO { internal abstract class Stream { - internal abstract bool Seek(int aValue, FileSeek aSeek); + internal abstract int Seek(int aValue, FileSeek aSeek); internal abstract int Write(byte[] aBuffer, int aCount); internal abstract int Write(byte[] aBuffer, int aOffset, int aCount); internal abstract int Read(byte[] aBuffer, int aCount);