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/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 91c956a..c141db5 100644
--- a/src/Kernel/Atomix.Kernel_H/Atomix.Kernel_H.csproj
+++ b/src/Kernel/Atomix.Kernel_H/Atomix.Kernel_H.csproj
@@ -91,22 +91,30 @@
-
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
-
+
+
+
+
+
+
diff --git a/src/Kernel/Atomix.Kernel_H/Boot.cs b/src/Kernel/Atomix.Kernel_H/Boot.cs
index 365634f..94a665c 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;
@@ -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!");
}
@@ -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)
@@ -252,12 +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);
- Clean = false;
- }
+ }*/
}
}
}
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/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..e2e112f
--- /dev/null
+++ b/src/Kernel/Atomix.Kernel_H/IO/FileSystem/FAT/Entry.cs
@@ -0,0 +1,57 @@
+/*
+* PROJECT: Atomix Development
+* LICENSE: BSD 3-Clause (LICENSE.md)
+* PURPOSE: FAT Entry Structure
+* PROGRAMMERS: Aman Priyadarshi (aman.eureka@gmail.com)
+*/
+
+using System.Runtime.InteropServices;
+
+namespace Atomix.Kernel_H.IO.FileSystem.FAT
+{
+ [StructLayout(LayoutKind.Explicit, Size = 40)]
+ internal unsafe struct Entry
+ {
+ [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
new file mode 100644
index 0000000..d4fad29
--- /dev/null
+++ b/src/Kernel/Atomix.Kernel_H/IO/FileSystem/FAT/FatDirectory.cs
@@ -0,0 +1,29 @@
+/*
+* 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 int StartCluster;
+ internal readonly uint Size;
+
+ internal FatDirectory(FatFileSystem aFS, string aName, int aStartCluster, uint aSize)
+ : base(aName)
+ {
+ FS = aFS;
+ StartCluster = aStartCluster;
+ Size = aSize;
+ }
+
+ internal override FSObject FindEntry(string 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
new file mode 100644
index 0000000..2479b8c
--- /dev/null
+++ b/src/Kernel/Atomix.Kernel_H/IO/FileSystem/FAT/FatFile.cs
@@ -0,0 +1,31 @@
+/*
+* 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 FatFileSystem FS;
+ internal readonly int StartCluster;
+ internal readonly uint Size;
+
+ internal FatFile(FatFileSystem aFS, string aName, int aStartCluster, uint aSize)
+ : base(aName)
+ {
+ FS = aFS;
+ StartCluster = aStartCluster;;
+ Size = aSize;
+ }
+
+ internal override Stream Open(FileMode aMode)
+ {
+ throw new NotImplementedException();
+ }
+ }
+}
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/FAT/FatFileSystem.cs b/src/Kernel/Atomix.Kernel_H/IO/FileSystem/FAT/FatFileSystem.cs
new file mode 100644
index 0000000..7206379
--- /dev/null
+++ b/src/Kernel/Atomix.Kernel_H/IO/FileSystem/FAT/FatFileSystem.cs
@@ -0,0 +1,231 @@
+/*
+* PROJECT: Atomix Development
+* LICENSE: BSD 3-Clause (LICENSE.md)
+* PURPOSE: Fat File System
+* PROGRAMMERS: Aman Priyadarshi (aman.eureka@gmail.com)
+*/
+
+using System;
+
+using Atomixilc.Lib;
+
+using Atomix.Kernel_H.Core;
+using Atomix.Kernel_H.IO.FileSystem.FAT;
+
+namespace Atomix.Kernel_H.IO.FileSystem
+{
+ internal unsafe class FatFileSystem : GenericFileSystem
+ {
+ 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)
+ {
+ BytePerSector = 512;
+ }
+
+ internal override bool Detect()
+ {
+ var BootSector = new byte[512];
+
+ if (!ReadBlock(BootSector, 0, 1))
+ return false;
+
+ var xSig = BitConverter.ToUInt16(BootSector, 510);
+ if (xSig != 0xAA55)
+ return false;
+
+ /* BPB (BIOS Parameter Block) */
+ BytePerSector = BitConverter.ToUInt16(BootSector, 11);
+ SectorsPerCluster = BootSector[13];
+ ReservedSector = BitConverter.ToUInt16(BootSector, 14);
+ TotalFAT = BootSector[16];
+ DirectoryEntry = BitConverter.ToUInt16(BootSector, 17);
+
+ 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.ToInt32(BootSector, 32);
+ }
+ else
+ {
+ TotalSectors = BitConverter.ToUInt16(BootSector, 19);
+ }
+
+ /* FAT 12 and FAT 16 ONLY */
+ SectorsPerFAT = BitConverter.ToUInt16(BootSector, 22);
+ if (SectorsPerFAT == 0)
+ {
+ /* FAT 32 ONLY */
+ SectorsPerFAT = BitConverter.ToInt32(BootSector, 36);
+ }
+
+ /* Not Necessary, To Avoid Crashes during corrupted BPB Info */
+ // Just to prevent ourself from hacking
+ if (TotalFAT == 0 || TotalFAT > 2 || BytePerSector == 0 || TotalSectors == 0 || SectorsPerCluster == 0)
+ return false;
+
+ /* Some basic calculations to check basic error :P */
+ int RootDirSectors = 0;
+ DataSectorCount = TotalSectors - (ReservedSector + (TotalFAT * SectorsPerFAT) + RootDirSectors);
+ ClusterCount = DataSectorCount / SectorsPerCluster;
+
+ /* Finally we got key xD */
+ if (ClusterCount < 4085)
+ FatType = FatType.FAT12;
+ else if (ClusterCount < 65525)
+ FatType = FatType.FAT16;
+ else
+ FatType = FatType.FAT32;
+
+ /* Now we open door of gold coins xDD */
+ if (FatType == FatType.FAT32)
+ {
+ SerialNo = BitConverter.ToInt32(BootSector, 39);
+ VolumeLabel = new string((sbyte*)BootSector.GetDataOffset(), 71, 11);
+ RootCluster = BitConverter.ToInt32(BootSector, 44);
+ RootSector = 0;
+ RootSectorCount = 0;
+ }
+ /* The key is of another door */
+ else
+ {
+ SerialNo = BitConverter.ToInt32(BootSector, 67);
+ VolumeLabel = new string((sbyte*)BootSector.GetDataOffset(), 43, 11);
+ RootSector = ReservedSector + (TotalFAT * SectorsPerFAT);
+ 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 FSObject FindEntry(string aName)
+ {
+ return FindEntry(aName, RootCluster);
+ }
+
+ internal FSObject FindEntry(string name, int startCluster)
+ {
+ int len = name.Length;
+ if (len > 12) return null;
+
+ int activeSector = ((startCluster - RootCluster) * SectorsPerCluster) + DataSector;
+ if (startCluster == 0)
+ {
+ activeSector = RootSector;
+ if (FatType == FatType.FAT32)
+ activeSector = GetSectorByCluster(RootCluster);
+ }
+
+ var data = new byte[BytePerSector * SectorsPerCluster];
+ ReadBlock(data, activeSector, SectorsPerCluster);
+
+ var entry = (Entry*)data.GetDataOffset();
+ for (int index = 0; index < EntriesPerSector * SectorsPerCluster; index++, entry++)
+ {
+ 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;
+ }
+
+ internal int GetSectorByCluster(int cluster)
+ {
+ return DataSector + ((cluster - RootCluster) * SectorsPerCluster);
+ }
+
+ internal bool ReadBlock(byte[] aBuffer, int aBlockIndex, int aBlockCount)
+ {
+ 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;
+ int offset = aBlockIndex * BytePerSector;
+ return Device.Write(aBuffer, offset, count) == count;
+ }
+
+ internal void PrintDebugInfo()
+ {
+ Debug.Write("BytesPerSector\t\t:%d\n", BytePerSector);
+ Debug.Write("SectorsPerCluster\t\t:%d\n", SectorsPerCluster);
+ Debug.Write("ReservedSector\t\t:%d\n", ReservedSector);
+ Debug.Write("TotalFAT\t\t:%d\n", TotalFAT);
+ Debug.Write("TotalSectors\t\t:%d\n", TotalSectors);
+ Debug.Write("SectorsPerFAT\t\t:%d\n", SectorsPerFAT);
+ Debug.Write("DataSectorCount\t\t:%d\n", DataSectorCount);
+ Debug.Write("ClusterCount\t\t:%d\n", ClusterCount);
+ Debug.Write("SerialNo\t\t:%d\n", SerialNo);
+ Debug.Write("RootCluster\t\t:%d\n", RootCluster);
+ Debug.Write("RootSector\t\t:%d\n", RootSector);
+ Debug.Write("RootSectorCount\t\t:%d\n", RootSectorCount);
+ Debug.Write("DataSector\t\t:%d\n", DataSector);
+ Debug.Write("EntriesPerSector\t\t:%d\n", EntriesPerSector);
+ Debug.Write("fatEntries\t\t:%d\n", fatEntries);
+ Debug.Write("VolumeLabel\t\t:%s\n", VolumeLabel);
+ }
+ }
+}
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/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
deleted file mode 100644
index 38d2216..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 Helper
-* 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/FAT/FileNameAttribute.cs b/src/Kernel/Atomix.Kernel_H/IO/FileSystem/FAT/FileNameAttribute.cs
new file mode 100644
index 0000000..0be3520
--- /dev/null
+++ b/src/Kernel/Atomix.Kernel_H/IO/FileSystem/FAT/FileNameAttribute.cs
@@ -0,0 +1,17 @@
+/*
+* 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,
+ Escape = 0x05,
+ Dot = 0x2E,
+ Deleted = 0xE5,
+ };
+}
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/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/FatFileSystem.cs b/src/Kernel/Atomix.Kernel_H/IO/FileSystem/FatFileSystem.cs
deleted file mode 100644
index 4ee7484..0000000
--- a/src/Kernel/Atomix.Kernel_H/IO/FileSystem/FatFileSystem.cs
+++ /dev/null
@@ -1,275 +0,0 @@
-/*
-* PROJECT: Atomix Development
-* LICENSE: BSD 3-Clause (LICENSE.md)
-* PURPOSE: Fat File System
-* PROGRAMMERS: Aman Priyadarshi (aman.eureka@gmail.com)
-*/
-
-using System;
-
-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;
-
-namespace Atomix.Kernel_H.IO.FileSystem
-{
- internal 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)
- {
- IDevice = Device;
- mIsValid = IsFAT();
- }
-
- private unsafe bool IsFAT()
- {
- var BootSector = new byte[512];
-
- if (!IDevice.Read(0U, 1U, BootSector))
- return false;
-
- var xSig = BitConverter.ToUInt16(BootSector, 510);
- if (xSig != 0xAA55)
- return false;
-
- /* BPB (BIOS Parameter Block) */
- BytePerSector = BitConverter.ToUInt16(BootSector, 11);
- SectorsPerCluster = BootSector[13];
- ReservedSector = BitConverter.ToUInt16(BootSector, 14);
- TotalFAT = BootSector[16];
- DirectoryEntry = BitConverter.ToUInt16(BootSector, 17);
-
- 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);
- }
- else
- {
- TotalSectors = BitConverter.ToUInt16(BootSector, 19);
- }
-
- /* FAT 12 and FAT 16 ONLY */
- SectorsPerFAT = BitConverter.ToUInt16(BootSector, 22);
-
- if (SectorsPerFAT == 0)
- {
- /* FAT 32 ONLY */
- SectorsPerFAT = BitConverter.ToUInt32(BootSector, 36);
- }
-
- /* Not Necessary, To Avoid Crashes during corrupted BPB Info */
- // Just to prevent ourself from hacking
- if (TotalFAT == 0 || TotalFAT > 2 || BytePerSector == 0 || TotalSectors == 0 || SectorsPerCluster == 0)
- return false;
-
- /* Some basic calculations to check basic error :P */
- uint RootDirSectors = 0;
- DataSectorCount = TotalSectors - (ReservedSector + (TotalFAT * SectorsPerFAT) + RootDirSectors);
- ClusterCount = DataSectorCount / SectorsPerCluster;
-
- /* Finally we got key xD */
- if (ClusterCount < 4085)
- FatType = FatType.FAT12;
- else if (ClusterCount < 65525)
- FatType = FatType.FAT16;
- else
- FatType = FatType.FAT32;
-
- /* Now we open door of gold coins xDD */
- if (FatType == FatType.FAT32)
- {
- SerialNo = BitConverter.ToUInt32(BootSector, 39);
- VolumeLabel = new string((sbyte*)BootSector.GetDataOffset(), 71, 11); // for checking
- RootCluster = BitConverter.ToUInt32(BootSector, 44);
- RootSector = 0;
- RootSectorCount = 0;
- }
- /* The key is of another door */
- else
- {
- SerialNo = BitConverter.ToUInt32(BootSector, 67);
- VolumeLabel = new string((sbyte*)BootSector.GetDataOffset(), 43, 11);
- RootSector = ReservedSector + (TotalFAT * SectorsPerFAT);
- RootSectorCount = (UInt32)((DirectoryEntry * 32 + (BytePerSector - 1)) / BytePerSector);
- fatEntries = SectorsPerFAT * 512 / 4;
- }
- /* Now it shows our forward path ;) */
- EntriesPerSector = (UInt32)(BytePerSector / 32);
- DataSector = ReservedSector + (TotalFAT * SectorsPerFAT) + RootSectorCount;
-
- mFSType = FileSystemType.FAT;
- return true;
- }
-
- internal override bool CreateFile(string[] path, int pointer)
- {
- return false;
- }
-
- internal override Stream GetFile(string[] path, int pointer)
- {
- if (!mIsValid)
- return null;
-
- 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)
- {
- uint 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, uint startCluster)
- {
- uint 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);
-
- 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(uint cluster)
- {
- uint fatoffset = cluster<<2;
- uint sector = ReservedSector + (fatoffset / BytePerSector);
- int sectorOffset = (int)(fatoffset % BytePerSector);
-
- var aData = new byte[512];
- IDevice.Read(sector, 1U, aData);
- var xNextCluster = (BitConverter.ToUInt32(aData, sectorOffset) & 0x0FFFFFFF);
-
- return xNextCluster;
- }
-
- private uint GetSectorByCluster(uint 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 byte[] NewBlockArray
- { get { return new byte[SectorsPerCluster * BytePerSector]; } }
-
- internal void PrintDebugInfo()
- {
- Debug.Write("BytesPerSector\t\t:%d\n", BytePerSector);
- Debug.Write("SectorsPerCluster\t\t:%d\n", SectorsPerCluster);
- Debug.Write("ReservedSector\t\t:%d\n", ReservedSector);
- Debug.Write("TotalFAT\t\t:%d\n", TotalFAT);
- Debug.Write("TotalSectors\t\t:%d\n", TotalSectors);
- Debug.Write("SectorsPerFAT\t\t:%d\n", SectorsPerFAT);
- Debug.Write("DataSectorCount\t\t:%d\n", DataSectorCount);
- Debug.Write("ClusterCount\t\t:%d\n", ClusterCount);
- Debug.Write("SerialNo\t\t:%d\n", SerialNo);
- Debug.Write("RootCluster\t\t:%d\n", RootCluster);
- Debug.Write("RootSector\t\t:%d\n", RootSector);
- Debug.Write("RootSectorCount\t\t:%d\n", RootSectorCount);
- Debug.Write("DataSector\t\t:%d\n", DataSector);
- Debug.Write("EntriesPerSector\t\t:%d\n", EntriesPerSector);
- Debug.Write("fatEntries\t\t:%d\n", fatEntries);
- Debug.Write("VolumeLabel\t\t:%s\n", VolumeLabel);
- }
- }
-}
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/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/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..ffc13c3
--- /dev/null
+++ b/src/Kernel/Atomix.Kernel_H/IO/FileSystem/RFS/RamFileSystem.cs
@@ -0,0 +1,49 @@
+/*
+* 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;
+
+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)
+ {
+ return mFiles.GetValue(aName, null);
+ }
+ }
+}
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..be0adb9
--- /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 int Seek(int aValue, FileSeek aSeek)
+ {
+ switch (aSeek)
+ {
+ case FileSeek.Origin:
+ {
+ mPointer = 0;
+ }
+ break;
+ case FileSeek.Current:
+ {
+ if (mPointer + aValue > mLength)
+ break;
+ mPointer += aValue;
+ }
+ break;
+ case FileSeek.End:
+ {
+ if (aValue > mLength)
+ break;
+ mPointer = mLength - aValue;
+ }
+ break;
+ }
+ return mPointer;
+ }
+
+ 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..43add4c 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 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);
- 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..ee22316 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();
+ VirtualFileSystem.Install();
/* Setup Syscall */
Syscall.Setup();