mirror of
https://github.com/Fennix-Project/Kernel.git
synced 2025-05-25 22:14:37 +00:00
Added filesystem
This commit is contained in:
parent
74a4685ba9
commit
c8e5ce1d36
117
Filesystem/FS/ustar.cpp
Normal file
117
Filesystem/FS/ustar.cpp
Normal file
@ -0,0 +1,117 @@
|
||||
#include <filesystem/ustar.hpp>
|
||||
|
||||
#include <memory.hpp>
|
||||
#include <debug.h>
|
||||
|
||||
#include "../../kernel.h"
|
||||
|
||||
namespace FileSystem
|
||||
{
|
||||
ReadFSFunction(USTAR_Read)
|
||||
{
|
||||
if (!Size)
|
||||
Size = Node->Length;
|
||||
if (Offset > Node->Length)
|
||||
return 0;
|
||||
if (Offset + Size > Node->Length)
|
||||
Size = Node->Length - Offset;
|
||||
memcpy(Buffer, (uint8_t *)(Node->Address + Offset), Size);
|
||||
return Size;
|
||||
}
|
||||
|
||||
FileSystemOpeations ustar = {
|
||||
.Name = "ustar",
|
||||
.Read = USTAR_Read,
|
||||
};
|
||||
|
||||
USTAR::USTAR(uint64_t Address, Virtual *vfs)
|
||||
{
|
||||
trace("Initializing USTAR with address %#llx", Address);
|
||||
|
||||
if (memcmp(((FileHeader *)Address)->signature, "ustar", 5) != 0)
|
||||
{
|
||||
error("ustar signature invalid!");
|
||||
return;
|
||||
}
|
||||
debug("USTAR signature valid! Name:%s Signature:%s Mode:%c Size:%lu",
|
||||
((FileHeader *)Address)->name,
|
||||
((FileHeader *)Address)->signature,
|
||||
string2int(((FileHeader *)Address)->mode),
|
||||
((FileHeader *)Address)->size);
|
||||
|
||||
vfs->CreateRoot(&ustar, "/");
|
||||
|
||||
uint64_t errorsallowed = 20;
|
||||
|
||||
for (uint64_t i = 0;; i++)
|
||||
{
|
||||
FileHeader *header = (FileHeader *)Address;
|
||||
if (memcmp(((FileHeader *)Address)->signature, "ustar", 5) != 0)
|
||||
break;
|
||||
memmove(header->name, header->name + 1, strlen(header->name));
|
||||
if (header->name[strlen(header->name) - 1] == '/')
|
||||
header->name[strlen(header->name) - 1] = 0;
|
||||
uint64_t size = getsize(header->size);
|
||||
FileSystemNode *node = nullptr;
|
||||
|
||||
if (!isempty((char *)header->name))
|
||||
KPrint("Adding file \e88AACC%s\eCCCCCC (\e88AACC%lu \eCCCCCCbytes)", header->name, size);
|
||||
else
|
||||
goto NextFileAddress;
|
||||
|
||||
node = vfs->Create(nullptr, header->name);
|
||||
debug("Added node: %s", node->Name);
|
||||
if (node == nullptr)
|
||||
{
|
||||
if (errorsallowed > 0)
|
||||
{
|
||||
errorsallowed--;
|
||||
goto NextFileAddress;
|
||||
}
|
||||
else
|
||||
{
|
||||
error("Adding USTAR files failed because too many files were corrputed or invalid.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
trace("%s %dKB Type:%c", header->name, TO_KB(size), header->typeflag[0]);
|
||||
node->Mode = string2int(header->mode);
|
||||
node->Address = (Address + 512);
|
||||
node->Length = size;
|
||||
node->GroupIdentifier = getsize(header->gid);
|
||||
node->UserIdentifier = getsize(header->uid);
|
||||
node->IndexNode = i;
|
||||
|
||||
switch (header->typeflag[0])
|
||||
{
|
||||
case REGULAR_FILE:
|
||||
node->Flags = NodeFlags::FS_FILE;
|
||||
break;
|
||||
case SYMLINK:
|
||||
node->Flags = NodeFlags::FS_SYMLINK;
|
||||
break;
|
||||
case DIRECTORY:
|
||||
node->Flags = NodeFlags::FS_DIRECTORY;
|
||||
break;
|
||||
case CHARDEV:
|
||||
node->Flags = NodeFlags::FS_CHARDEVICE;
|
||||
break;
|
||||
case BLOCKDEV:
|
||||
node->Flags = NodeFlags::FS_BLOCKDEVICE;
|
||||
break;
|
||||
default:
|
||||
warn("Unknown type: %d", header->typeflag[0]);
|
||||
break;
|
||||
}
|
||||
NextFileAddress:
|
||||
Address += ((size / 512) + 1) * 512;
|
||||
if (size % 512)
|
||||
Address += 512;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
USTAR::~USTAR() { warn("Destroyed"); }
|
||||
}
|
488
Filesystem/Filesystem.cpp
Normal file
488
Filesystem/Filesystem.cpp
Normal file
@ -0,0 +1,488 @@
|
||||
#include <filesystem.hpp>
|
||||
|
||||
#include <smartptr.hpp>
|
||||
#include <convert.h>
|
||||
#include <printf.h>
|
||||
#include <lock.hpp>
|
||||
#include <cwalk.h>
|
||||
#include <sys.h>
|
||||
|
||||
#include "../kernel.h"
|
||||
|
||||
NewLock(VFSLock);
|
||||
|
||||
namespace FileSystem
|
||||
{
|
||||
char *Virtual::GetPathFromNode(FileSystemNode *Node)
|
||||
{
|
||||
vfsdbg("GetPathFromNode( Node: \"%s\" )", Node->Name);
|
||||
FileSystemNode *Parent = Node;
|
||||
Vector<char *> Path;
|
||||
size_t Size = 1;
|
||||
|
||||
while (Parent != FileSystemRoot && Parent != nullptr)
|
||||
{
|
||||
foreach (auto var in FileSystemRoot->Children)
|
||||
if (var == Parent)
|
||||
goto PathFromNodeContinue;
|
||||
Path.push_back(Parent->Name);
|
||||
Path.push_back((char *)"/");
|
||||
Parent = Parent->Parent;
|
||||
}
|
||||
|
||||
PathFromNodeContinue:
|
||||
Path.reverse();
|
||||
|
||||
foreach (auto var in Path)
|
||||
Size += strlen(var);
|
||||
|
||||
char *FinalPath = new char[Size];
|
||||
|
||||
foreach (auto var in Path)
|
||||
strcat(FinalPath, var);
|
||||
|
||||
// for (size_t i = 0; i < Path.size(); i++)
|
||||
// strcat(FinalPath, Path[i]);
|
||||
|
||||
// for (size_t i = 0; i < Path.size(); i++)
|
||||
// Size += strlen(Path[i]);
|
||||
vfsdbg("GetPathFromNode()->\"%s\"", FinalPath);
|
||||
return FinalPath;
|
||||
}
|
||||
|
||||
FileSystemNode *Virtual::GetNodeFromPath(FileSystemNode *Parent, const char *Path)
|
||||
{
|
||||
vfsdbg("GetNodeFromPath( Parent: \"%s\" Path: \"%s\" )", Parent->Name, Path);
|
||||
|
||||
if (Parent == nullptr)
|
||||
Parent = FileSystemRoot;
|
||||
|
||||
if (strcmp(Parent->Name, Path))
|
||||
{
|
||||
cwk_segment segment;
|
||||
if (!cwk_path_get_first_segment(Path, &segment))
|
||||
{
|
||||
error("Path doesn't have any segments.");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
char *SegmentName = new char[segment.end - segment.begin + 1];
|
||||
memcpy(SegmentName, segment.begin, segment.end - segment.begin);
|
||||
GetNodeFromPathNextParent:
|
||||
foreach (auto var in Parent->Children)
|
||||
{
|
||||
if (!strcmp(var->Name, SegmentName))
|
||||
{
|
||||
Parent = var;
|
||||
goto GetNodeFromPathNextParent;
|
||||
}
|
||||
}
|
||||
delete[] SegmentName;
|
||||
} while (cwk_path_get_next_segment(&segment));
|
||||
const char *basename;
|
||||
cwk_path_get_basename(Path, &basename, nullptr);
|
||||
if (!strcmp(basename, Parent->Name))
|
||||
{
|
||||
vfsdbg("GetNodeFromPath()->\"%s\"", Parent->Name);
|
||||
return Parent;
|
||||
}
|
||||
|
||||
vfsdbg("GetNodeFromPath()->\"%s\"", nullptr);
|
||||
return nullptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
vfsdbg("GetNodeFromPath()->\"%s\"", Parent->Name);
|
||||
return Parent;
|
||||
}
|
||||
}
|
||||
|
||||
FileSystemNode *AddNewChild(FileSystemNode *Parent, const char *Name)
|
||||
{
|
||||
vfsdbg("AddNewChild( Parent: \"%s\" Name: \"%s\" )", Parent->Name, Name);
|
||||
FileSystemNode *newNode = new FileSystemNode;
|
||||
newNode->Parent = Parent;
|
||||
strcpy(newNode->Name, Name);
|
||||
if (Parent)
|
||||
newNode->Operator = Parent->Operator;
|
||||
else
|
||||
newNode->Operator = nullptr;
|
||||
|
||||
if (Parent)
|
||||
Parent->Children.push_back(newNode);
|
||||
vfsdbg("AddNewChild()->\"%s\"", newNode->Name);
|
||||
return newNode;
|
||||
}
|
||||
|
||||
FileSystemNode *GetChild(FileSystemNode *Parent, const char *Name)
|
||||
{
|
||||
vfsdbg("GetChild( Parent: \"%s\" Name: \"%s\" )", Parent->Name, Name);
|
||||
if (Parent)
|
||||
foreach (auto var in Parent->Children)
|
||||
if (strcmp(var->Name, Name) == 0)
|
||||
{
|
||||
vfsdbg("GetChild()->\"%s\"", var->Name);
|
||||
return var;
|
||||
}
|
||||
vfsdbg("GetChild()->nullptr");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
FileStatus RemoveChild(FileSystemNode *Parent, const char *Name)
|
||||
{
|
||||
vfsdbg("RemoveChild( Parent: \"%s\" Name: \"%s\" )", Parent->Name, Name);
|
||||
for (uint64_t i = 0; i < Parent->Children.size(); i++)
|
||||
if (strcmp(Parent->Children[i]->Name, Name) == 0)
|
||||
{
|
||||
Parent->Children.remove(i);
|
||||
vfsdbg("RemoveChild()->OK");
|
||||
return FileStatus::OK;
|
||||
}
|
||||
vfsdbg("RemoveChild()->NOT_FOUND");
|
||||
return FileStatus::NOT_FOUND;
|
||||
}
|
||||
|
||||
char *Virtual::NormalizePath(FileSystemNode *Parent, const char *Path)
|
||||
{
|
||||
vfsdbg("NormalizePath( Parent: \"%s\" Path: \"%s\" )", Parent->Name, Path);
|
||||
char *NormalizedPath = new char[strlen((char *)Path) + 1];
|
||||
char *RelativePath = nullptr;
|
||||
|
||||
cwk_path_normalize(Path, NormalizedPath, strlen((char *)Path) + 1);
|
||||
|
||||
if (cwk_path_is_relative(NormalizedPath))
|
||||
{
|
||||
char *ParentPath = GetPathFromNode(Parent);
|
||||
size_t PathSize = cwk_path_get_absolute(ParentPath, NormalizedPath, nullptr, 0);
|
||||
RelativePath = new char[PathSize + 1];
|
||||
cwk_path_get_absolute(ParentPath, NormalizedPath, RelativePath, PathSize + 1);
|
||||
delete[] ParentPath;
|
||||
}
|
||||
else
|
||||
{
|
||||
RelativePath = new char[strlen(NormalizedPath) + 1];
|
||||
strcpy(RelativePath, NormalizedPath);
|
||||
}
|
||||
delete[] NormalizedPath;
|
||||
vfsdbg("NormalizePath()->\"%s\"", RelativePath);
|
||||
return RelativePath;
|
||||
}
|
||||
|
||||
FileStatus Virtual::FileExists(FileSystemNode *Parent, const char *Path)
|
||||
{
|
||||
vfsdbg("FileExists( Parent: \"%s\" Path: \"%s\" )", Parent->Name, Path);
|
||||
if (isempty((char *)Path))
|
||||
return FileStatus::INVALID_PATH;
|
||||
if (Parent == nullptr)
|
||||
Parent = FileSystemRoot;
|
||||
|
||||
char *NormalizedPath = NormalizePath(Parent, Path);
|
||||
FileSystemNode *Node = GetNodeFromPath(Parent, NormalizedPath);
|
||||
|
||||
if (Node == nullptr)
|
||||
{
|
||||
vfsdbg("FileExists()->NOT_FOUND");
|
||||
return FileStatus::NOT_FOUND;
|
||||
}
|
||||
else
|
||||
{
|
||||
vfsdbg("FileExists()->OK");
|
||||
return FileStatus::OK;
|
||||
}
|
||||
}
|
||||
|
||||
FileSystemNode *Virtual::Create(FileSystemNode *Parent, const char *Path)
|
||||
{
|
||||
SmartLock(VFSLock);
|
||||
|
||||
if (isempty((char *)Path))
|
||||
return nullptr;
|
||||
|
||||
vfsdbg("Virtual::Create( Parent: \"%s\" Path: \"%s\" )", Parent->Name, Path);
|
||||
|
||||
FileSystemNode *CurrentParent = nullptr;
|
||||
|
||||
if (Parent == nullptr)
|
||||
{
|
||||
if (FileSystemRoot->Children.size() >= 1)
|
||||
{
|
||||
if (FileSystemRoot->Children[0] == nullptr)
|
||||
panic("Root node is null!");
|
||||
|
||||
CurrentParent = FileSystemRoot->Children[0]; // 0 - filesystem root
|
||||
}
|
||||
else
|
||||
{
|
||||
// TODO: check if here is a bug or something...
|
||||
const char *PathCopy;
|
||||
size_t length;
|
||||
PathCopy = (char *)Path;
|
||||
cwk_path_get_root(PathCopy, &length); // not working?
|
||||
foreach (auto var in FileSystemRoot->Children)
|
||||
if (!strcmp(var->Name, PathCopy))
|
||||
{
|
||||
CurrentParent = var;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
CurrentParent = Parent;
|
||||
|
||||
char *CleanPath = NormalizePath(CurrentParent, Path);
|
||||
|
||||
if (FileExists(CurrentParent, CleanPath) != FileStatus::NOT_FOUND)
|
||||
{
|
||||
error("File %s already exists.", CleanPath);
|
||||
goto CreatePathError;
|
||||
}
|
||||
|
||||
cwk_segment segment;
|
||||
if (!cwk_path_get_first_segment(CleanPath, &segment))
|
||||
{
|
||||
error("Path doesn't have any segments.");
|
||||
goto CreatePathError;
|
||||
}
|
||||
|
||||
warn("Virtual::Create( ) is not working properly.");
|
||||
do
|
||||
{
|
||||
char *SegmentName = new char[segment.end - segment.begin + 1];
|
||||
memcpy(SegmentName, segment.begin, segment.end - segment.begin);
|
||||
|
||||
if (GetChild(CurrentParent, SegmentName) == nullptr)
|
||||
CurrentParent = AddNewChild(CurrentParent, SegmentName);
|
||||
else
|
||||
CurrentParent = GetChild(CurrentParent, SegmentName);
|
||||
|
||||
delete[] SegmentName;
|
||||
} while (cwk_path_get_next_segment(&segment));
|
||||
|
||||
delete CleanPath;
|
||||
vfsdbg("Virtual::Create()->\"%s\"", CurrentParent->Name);
|
||||
return CurrentParent;
|
||||
|
||||
CreatePathError:
|
||||
vfsdbg("Virtual::Create()->nullptr");
|
||||
delete CleanPath;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
FileSystemNode *Virtual::CreateRoot(FileSystemOpeations *Operator, const char *RootName)
|
||||
{
|
||||
if (Operator == nullptr)
|
||||
return nullptr;
|
||||
vfsdbg("Setting root to %s", RootName);
|
||||
FileSystemNode *newNode = new FileSystemNode;
|
||||
strcpy(newNode->Name, RootName);
|
||||
newNode->Flags = NodeFlags::FS_DIRECTORY;
|
||||
newNode->Operator = Operator;
|
||||
FileSystemRoot->Children.push_back(newNode);
|
||||
return newNode;
|
||||
}
|
||||
|
||||
FILE *Virtual::Mount(FileSystemOpeations *Operator, const char *Path)
|
||||
{
|
||||
SmartLock(VFSLock);
|
||||
|
||||
if (Operator == nullptr)
|
||||
return nullptr;
|
||||
|
||||
if (isempty((char *)Path))
|
||||
return nullptr;
|
||||
|
||||
vfsdbg("Mounting %s", Path);
|
||||
FILE *file = new FILE;
|
||||
cwk_path_get_basename(Path, &file->Name, 0);
|
||||
file->Status = FileStatus::OK;
|
||||
file->Node = Create(nullptr, Path);
|
||||
file->Node->Operator = Operator;
|
||||
file->Node->Flags = NodeFlags::FS_MOUNTPOINT;
|
||||
return file;
|
||||
}
|
||||
|
||||
FileStatus Virtual::Unmount(FILE *File)
|
||||
{
|
||||
SmartLock(VFSLock);
|
||||
if (File == nullptr)
|
||||
return FileStatus::INVALID_PARAMETER;
|
||||
vfsdbg("Unmounting %s", File->Name);
|
||||
return FileStatus::OK;
|
||||
}
|
||||
|
||||
FILE *Virtual::Open(const char *Path, FileSystemNode *Parent)
|
||||
{
|
||||
SmartLock(VFSLock);
|
||||
vfsdbg("Opening %s with parent %s", Path, Parent->Name);
|
||||
|
||||
if (strcmp(Path, ".") == 0)
|
||||
{
|
||||
FILE *file = new FILE;
|
||||
FileStatus filestatus = FileStatus::OK;
|
||||
file->Node = Parent;
|
||||
if (file->Node == nullptr)
|
||||
file->Status = FileStatus::NOT_FOUND;
|
||||
const char *basename;
|
||||
cwk_path_get_basename(GetPathFromNode(Parent), &basename, nullptr);
|
||||
file->Name = basename;
|
||||
return file;
|
||||
}
|
||||
|
||||
if (strcmp(Path, "..") == 0)
|
||||
{
|
||||
if (Parent->Parent != nullptr)
|
||||
Parent = Parent->Parent;
|
||||
|
||||
FILE *file = new FILE;
|
||||
FileStatus filestatus = FileStatus::OK;
|
||||
file->Node = Parent;
|
||||
if (file->Node == nullptr)
|
||||
file->Status = FileStatus::NOT_FOUND;
|
||||
const char *basename;
|
||||
cwk_path_get_basename(GetPathFromNode(Parent), &basename, nullptr);
|
||||
file->Name = basename;
|
||||
return file;
|
||||
}
|
||||
|
||||
if (Parent == nullptr)
|
||||
{
|
||||
if (FileSystemRoot->Children.size() >= 1)
|
||||
Parent = FileSystemRoot->Children[0]; // 0 - filesystem root
|
||||
else
|
||||
{
|
||||
// TODO: check if here is a bug or something...
|
||||
const char *PathCopy;
|
||||
size_t length;
|
||||
PathCopy = (char *)Path;
|
||||
cwk_path_get_root(PathCopy, &length); // not working?
|
||||
foreach (auto var in FileSystemRoot->Children)
|
||||
if (!strcmp(var->Name, PathCopy))
|
||||
{
|
||||
Parent = var;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
char *CleanPath = NormalizePath(Parent, Path);
|
||||
|
||||
FILE *file = new FILE;
|
||||
FileStatus filestatus = FileStatus::OK;
|
||||
filestatus = FileExists(Parent, CleanPath);
|
||||
/* TODO: Check for other errors */
|
||||
|
||||
if (filestatus != FileStatus::OK)
|
||||
{
|
||||
foreach (auto var in FileSystemRoot->Children)
|
||||
if (!strcmp(var->Name, CleanPath))
|
||||
{
|
||||
file->Node = var;
|
||||
if (file->Node == nullptr)
|
||||
goto OpenNodeFail;
|
||||
const char *basename;
|
||||
cwk_path_get_basename(GetPathFromNode(var), &basename, nullptr);
|
||||
file->Name = basename;
|
||||
goto OpenNodeExit;
|
||||
}
|
||||
|
||||
file->Node = GetNodeFromPath(FileSystemRoot->Children[0], CleanPath);
|
||||
if (file->Node != nullptr)
|
||||
{
|
||||
const char *basename;
|
||||
cwk_path_get_basename(GetPathFromNode(file->Node), &basename, nullptr);
|
||||
file->Name = basename;
|
||||
goto OpenNodeExit;
|
||||
}
|
||||
|
||||
OpenNodeFail:
|
||||
file->Status = filestatus;
|
||||
file->Node = nullptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
file->Node = GetNodeFromPath(Parent, CleanPath);
|
||||
if (file->Node == nullptr)
|
||||
file->Status = FileStatus::NOT_FOUND;
|
||||
const char *basename;
|
||||
cwk_path_get_basename(CleanPath, &basename, nullptr);
|
||||
file->Name = basename;
|
||||
return file;
|
||||
}
|
||||
OpenNodeExit:
|
||||
return file;
|
||||
}
|
||||
|
||||
uint64_t Virtual::Read(FILE *File, uint64_t Offset, uint8_t *Buffer, uint64_t Size)
|
||||
{
|
||||
SmartLock(VFSLock);
|
||||
if (File == nullptr)
|
||||
return 0;
|
||||
|
||||
File->Status = FileStatus::OK;
|
||||
|
||||
if (File->Node == nullptr)
|
||||
{
|
||||
File->Status = FileStatus::INVALID_PARAMETER;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (File->Node->Operator == nullptr)
|
||||
{
|
||||
File->Status = FileStatus::INVALID_PARAMETER;
|
||||
return 0;
|
||||
}
|
||||
vfsdbg("Reading %s out->%016x", File->Name, Buffer);
|
||||
return File->Node->Operator->Read(File->Node, Offset, Size, Buffer);
|
||||
}
|
||||
|
||||
uint64_t Virtual::Write(FILE *File, uint64_t Offset, uint8_t *Buffer, uint64_t Size)
|
||||
{
|
||||
SmartLock(VFSLock);
|
||||
if (File == nullptr)
|
||||
return 0;
|
||||
|
||||
File->Status = FileStatus::OK;
|
||||
|
||||
if (File->Node == nullptr)
|
||||
{
|
||||
File->Status = FileStatus::INVALID_PARAMETER;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (File->Node->Operator == nullptr)
|
||||
{
|
||||
File->Status = FileStatus::INVALID_PARAMETER;
|
||||
return 0;
|
||||
}
|
||||
vfsdbg("Writing %s out->%016x", File->Name, Buffer);
|
||||
return File->Node->Operator->Write(File->Node, Offset, Size, Buffer);
|
||||
}
|
||||
|
||||
FileStatus Virtual::Close(FILE *File)
|
||||
{
|
||||
SmartLock(VFSLock);
|
||||
if (File == nullptr)
|
||||
return FileStatus::INVALID_HANDLE;
|
||||
vfsdbg("Closing %s", File->Name);
|
||||
delete File;
|
||||
return FileStatus::OK;
|
||||
}
|
||||
|
||||
Virtual::Virtual()
|
||||
{
|
||||
trace("Initializing virtual file system...");
|
||||
FileSystemRoot = new FileSystemNode;
|
||||
FileSystemRoot->Flags = NodeFlags::FS_MOUNTPOINT;
|
||||
FileSystemRoot->Operator = nullptr;
|
||||
FileSystemRoot->Parent = nullptr;
|
||||
strcpy(FileSystemRoot->Name, "root");
|
||||
cwk_path_set_style(CWK_STYLE_UNIX);
|
||||
}
|
||||
|
||||
Virtual::~Virtual()
|
||||
{
|
||||
warn("Tried to uninitialize Virtual File System!");
|
||||
}
|
||||
}
|
218
KThread.cpp
218
KThread.cpp
@ -1,157 +1,19 @@
|
||||
#include "kernel.h"
|
||||
|
||||
#include <filesystem/ustar.hpp>
|
||||
#include <power.hpp>
|
||||
#include <lock.hpp>
|
||||
#include <printf.h>
|
||||
|
||||
void kerneltest1()
|
||||
void StartFilesystem()
|
||||
{
|
||||
uint32_t Color = 0x000000;
|
||||
int BoxSize = 64;
|
||||
while (1)
|
||||
{
|
||||
Color++;
|
||||
for (int i = 0; i < BoxSize; i++)
|
||||
for (int j = 0; j < BoxSize; j++)
|
||||
Display->SetPixel(i + 64, j, Color, 0);
|
||||
Display->SetBuffer(0);
|
||||
if (Color > 0xFFFFFF)
|
||||
break;
|
||||
}
|
||||
}
|
||||
void kerneltest2()
|
||||
{
|
||||
uint32_t Color = 0x000000;
|
||||
int BoxSize = 64;
|
||||
while (1)
|
||||
{
|
||||
Color++;
|
||||
for (int i = 0; i < BoxSize; i++)
|
||||
for (int j = 0; j < BoxSize; j++)
|
||||
Display->SetPixel(i + 128, j, Color, 0);
|
||||
Display->SetBuffer(0);
|
||||
if (Color > 0xFFFFFF)
|
||||
break;
|
||||
}
|
||||
}
|
||||
void kerneltest3()
|
||||
{
|
||||
uint32_t Color = 0x000000;
|
||||
int BoxSize = 64;
|
||||
while (1)
|
||||
{
|
||||
Color++;
|
||||
for (int i = 0; i < BoxSize; i++)
|
||||
for (int j = 0; j < BoxSize; j++)
|
||||
Display->SetPixel(i + 192, j, Color, 0);
|
||||
Display->SetBuffer(0);
|
||||
if (Color > 0xFFFFFF)
|
||||
break;
|
||||
}
|
||||
}
|
||||
void kerneltest4()
|
||||
{
|
||||
uint32_t Color = 0x000000;
|
||||
int BoxSize = 64;
|
||||
while (1)
|
||||
{
|
||||
Color++;
|
||||
for (int i = 0; i < BoxSize; i++)
|
||||
for (int j = 0; j < BoxSize; j++)
|
||||
Display->SetPixel(i + 256, j, Color, 0);
|
||||
Display->SetBuffer(0);
|
||||
if (Color > 0xFFFFFF)
|
||||
break;
|
||||
}
|
||||
}
|
||||
void kerneltest5()
|
||||
{
|
||||
uint32_t Color = 0x000000;
|
||||
int BoxSize = 64;
|
||||
while (1)
|
||||
{
|
||||
Color++;
|
||||
for (int i = 0; i < BoxSize; i++)
|
||||
for (int j = 0; j < BoxSize; j++)
|
||||
Display->SetPixel(i + 320, j, Color, 0);
|
||||
Display->SetBuffer(0);
|
||||
if (Color > 0xFFFFFF)
|
||||
break;
|
||||
}
|
||||
}
|
||||
void kerneltest6()
|
||||
{
|
||||
uint32_t Color = 0x000000;
|
||||
int BoxSize = 64;
|
||||
while (1)
|
||||
{
|
||||
Color++;
|
||||
for (int i = 0; i < BoxSize; i++)
|
||||
for (int j = 0; j < BoxSize; j++)
|
||||
Display->SetPixel(i + 384, j, Color, 0);
|
||||
Display->SetBuffer(0);
|
||||
if (Color > 0xFFFFFF)
|
||||
break;
|
||||
}
|
||||
}
|
||||
void kerneltest7()
|
||||
{
|
||||
uint32_t Color = 0x000000;
|
||||
int BoxSize = 64;
|
||||
while (1)
|
||||
{
|
||||
Color++;
|
||||
for (int i = 0; i < BoxSize; i++)
|
||||
for (int j = 0; j < BoxSize; j++)
|
||||
Display->SetPixel(i + 448, j, Color, 0);
|
||||
Display->SetBuffer(0);
|
||||
if (Color > 0xFFFFFF)
|
||||
break;
|
||||
}
|
||||
}
|
||||
void kerneltest8()
|
||||
{
|
||||
uint32_t Color = 0x000000;
|
||||
int BoxSize = 64;
|
||||
while (1)
|
||||
{
|
||||
Color++;
|
||||
for (int i = 0; i < BoxSize; i++)
|
||||
for (int j = 0; j < BoxSize; j++)
|
||||
Display->SetPixel(i + 512, j, Color, 0);
|
||||
Display->SetBuffer(0);
|
||||
if (Color > 0xFFFFFF)
|
||||
break;
|
||||
}
|
||||
}
|
||||
void kerneltest9()
|
||||
{
|
||||
uint32_t Color = 0x000000;
|
||||
int BoxSize = 64;
|
||||
while (1)
|
||||
{
|
||||
Color++;
|
||||
for (int i = 0; i < BoxSize; i++)
|
||||
for (int j = 0; j < BoxSize; j++)
|
||||
Display->SetPixel(i + 576, j, Color, 0);
|
||||
Display->SetBuffer(0);
|
||||
if (Color > 0xFFFFFF)
|
||||
break;
|
||||
}
|
||||
}
|
||||
void kerneltest10()
|
||||
{
|
||||
uint32_t Color = 0x000000;
|
||||
int BoxSize = 64;
|
||||
while (1)
|
||||
{
|
||||
Color++;
|
||||
for (int i = 0; i < BoxSize; i++)
|
||||
for (int j = 0; j < BoxSize; j++)
|
||||
Display->SetPixel(i + 640, j, Color, 0);
|
||||
Display->SetBuffer(0);
|
||||
if (Color > 0xFFFFFF)
|
||||
break;
|
||||
}
|
||||
KPrint("Initializing Filesystem...");
|
||||
TaskManager->GetCurrentThread()->SetPriority(100);
|
||||
vfs = new FileSystem::Virtual;
|
||||
new FileSystem::USTAR((uint64_t)bInfo->Modules[0].Address, vfs); // TODO: Detect initrd
|
||||
TaskManager->GetCurrentThread()->SetPriority(1);
|
||||
debug("Filesystem service idling...");
|
||||
CPU::Halt(true);
|
||||
}
|
||||
|
||||
void KernelMainThread()
|
||||
@ -161,64 +23,12 @@ void KernelMainThread()
|
||||
KPrint("Kernel Compiled at: %s %s with C++ Standard: %d", __DATE__, __TIME__, CPP_LANGUAGE_STANDARD);
|
||||
KPrint("C++ Language Version (__cplusplus) :%ld", __cplusplus);
|
||||
|
||||
// asm("int $0x1");
|
||||
|
||||
KPrint("\e22AA11Starting color test.");
|
||||
|
||||
CPU::Interrupts(CPU::Disable);
|
||||
TaskManager->CreateThread(TaskManager->GetCurrentProcess(), (Tasking::IP)kerneltest1);
|
||||
KPrint("\e22AA11Thread 1 created.");
|
||||
TaskManager->CreateThread(TaskManager->GetCurrentProcess(), (Tasking::IP)kerneltest2);
|
||||
KPrint("\e22AA11Thread 2 created.");
|
||||
TaskManager->CreateThread(TaskManager->GetCurrentProcess(), (Tasking::IP)kerneltest3);
|
||||
KPrint("\e22AA11Thread 3 created.");
|
||||
TaskManager->CreateThread(TaskManager->GetCurrentProcess(), (Tasking::IP)kerneltest4);
|
||||
KPrint("\e22AA11Thread 4 created.");
|
||||
TaskManager->CreateThread(TaskManager->GetCurrentProcess(), (Tasking::IP)kerneltest5);
|
||||
KPrint("\e22AA11Thread 5 created.");
|
||||
TaskManager->CreateThread(TaskManager->GetCurrentProcess(), (Tasking::IP)kerneltest6);
|
||||
KPrint("\e22AA11Thread 6 created.");
|
||||
TaskManager->CreateThread(TaskManager->GetCurrentProcess(), (Tasking::IP)kerneltest7);
|
||||
KPrint("\e22AA11Thread 7 created.");
|
||||
TaskManager->CreateThread(TaskManager->GetCurrentProcess(), (Tasking::IP)kerneltest8);
|
||||
KPrint("\e22AA11Thread 8 created.");
|
||||
TaskManager->CreateThread(TaskManager->GetCurrentProcess(), (Tasking::IP)kerneltest9);
|
||||
KPrint("\e22AA11Thread 9 created.");
|
||||
TaskManager->CreateThread(TaskManager->GetCurrentProcess(), (Tasking::IP)kerneltest10);
|
||||
KPrint("\e22AA11Thread 10 created.");
|
||||
|
||||
TaskManager->CreateThread(TaskManager->GetCurrentProcess(), (Tasking::IP)StartFilesystem)->Rename("Filesystem Service");
|
||||
|
||||
CPU::Interrupts(CPU::Enable);
|
||||
|
||||
uint32_t Color = 0x000000;
|
||||
int BoxSize = 64;
|
||||
uint32_t x, y;
|
||||
|
||||
Display->GetBufferCursor(0, &x, &y);
|
||||
|
||||
while (1)
|
||||
{
|
||||
Color++;
|
||||
|
||||
Display->SetBufferCursor(0, 0, 0);
|
||||
|
||||
for (int i = 0; i < BoxSize; i++)
|
||||
for (int j = 0; j < BoxSize; j++)
|
||||
Display->SetPixel(i, j, Color, 0);
|
||||
|
||||
int r = (Color >> 16) & 0xFF;
|
||||
int g = (Color >> 8) & 0xFF;
|
||||
int b = (Color >> 0) & 0xFF;
|
||||
printf_("\e%02x%02x%02x0x%06X",
|
||||
255 - r, 255 - g, 255 - b,
|
||||
Color);
|
||||
|
||||
Display->SetBuffer(0);
|
||||
if (Color > 0xFFFFFF)
|
||||
break;
|
||||
}
|
||||
|
||||
Display->SetBufferCursor(0, x, y);
|
||||
KPrint("\e22AA11Color test finished.");
|
||||
|
||||
TaskManager->GetCurrentThread()->SetPriority(1);
|
||||
CPU::Halt(true);
|
||||
}
|
||||
|
||||
|
@ -20,6 +20,7 @@ Power::Power *PowerManager = nullptr;
|
||||
PCI::PCI *PCIManager = nullptr;
|
||||
Tasking::Task *TaskManager = nullptr;
|
||||
Time::time *TimeManager = nullptr;
|
||||
FileSystem::Virtual *vfs = nullptr;
|
||||
|
||||
KernelConfig Config;
|
||||
Time::Clock BootClock;
|
||||
|
167
include/filesystem.hpp
Normal file
167
include/filesystem.hpp
Normal file
@ -0,0 +1,167 @@
|
||||
#ifndef __FENNIX_KERNEL_FILESYSTEM_H__
|
||||
#define __FENNIX_KERNEL_FILESYSTEM_H__
|
||||
|
||||
#include <types.h>
|
||||
|
||||
#include <vector.hpp>
|
||||
|
||||
// show debug messages
|
||||
// #define DEBUG_FILESYSTEM 1
|
||||
|
||||
#ifdef DEBUG_FILESYSTEM
|
||||
#define vfsdbg(m, ...) debug(m, ##__VA_ARGS__)
|
||||
#else
|
||||
#define vfsdbg(m, ...)
|
||||
#endif
|
||||
|
||||
namespace FileSystem
|
||||
{
|
||||
#define FILENAME_LENGTH 256
|
||||
|
||||
struct FileSystemNode;
|
||||
|
||||
typedef uint64_t (*OperationMount)(const char *, unsigned long, const void *);
|
||||
typedef uint64_t (*OperationUmount)(int);
|
||||
typedef uint64_t (*OperationRead)(FileSystemNode *Node, uint64_t Offset, uint64_t Size, uint8_t *Buffer);
|
||||
typedef uint64_t (*OperationWrite)(FileSystemNode *Node, uint64_t Offset, uint64_t Size, uint8_t *Buffer);
|
||||
typedef void (*OperationOpen)(FileSystemNode *Node, uint8_t Mode, uint8_t Flags);
|
||||
typedef void (*OperationClose)(FileSystemNode *Node);
|
||||
typedef uint64_t (*OperationSync)(void);
|
||||
typedef void (*OperationCreate)(FileSystemNode *Node, char *Name, uint16_t NameLength);
|
||||
typedef void (*OperationMkdir)(FileSystemNode *Node, char *Name, uint16_t NameLength);
|
||||
|
||||
#define MountFSFunction(name) uint64_t name(const char *unknown0, unsigned long unknown1, const uint8_t *unknown2)
|
||||
#define UMountFSFunction(name) uint64_t name(int unknown0)
|
||||
|
||||
#define ReadFSFunction(name) uint64_t name(FileSystem::FileSystemNode *Node, uint64_t Offset, uint64_t Size, uint8_t *Buffer)
|
||||
#define WriteFSFunction(name) uint64_t name(FileSystem::FileSystemNode *Node, uint64_t Offset, uint64_t Size, uint8_t *Buffer)
|
||||
#define OpenFSFunction(name) void name(FileSystem::FileSystemNode *Node, uint8_t Mode, uint8_t Flags)
|
||||
#define CloseFSFunction(name) void name(FileSystem::FileSystemNode *Node)
|
||||
#define SyncFSFunction(name) uint64_t name(void)
|
||||
#define CreateFSFunction(name) void name(FileSystem::FileSystemNode *Node, char *Name, uint16_t NameLength)
|
||||
#define MkdirFSFunction(name) void name(FileSystem::FileSystemNode *Node, char *Name, uint16_t NameLength)
|
||||
|
||||
enum FileStatus
|
||||
{
|
||||
OK = 0,
|
||||
NOT_FOUND = 1,
|
||||
ACCESS_DENIED = 2,
|
||||
INVALID_NAME = 3,
|
||||
INVALID_PARAMETER = 4,
|
||||
INVALID_HANDLE = 5,
|
||||
INVALID_PATH = 6,
|
||||
INVALID_FILE = 7,
|
||||
INVALID_DEVICE = 8,
|
||||
NOT_EMPTY = 9,
|
||||
NOT_SUPPORTED = 10,
|
||||
INVALID_DRIVE = 11,
|
||||
VOLUME_IN_USE = 12,
|
||||
TIMEOUT = 13,
|
||||
NO_MORE_FILES = 14,
|
||||
END_OF_FILE = 15,
|
||||
FILE_EXISTS = 16,
|
||||
PIPE_BUSY = 17,
|
||||
PIPE_DISCONNECTED = 18,
|
||||
MORE_DATA = 19,
|
||||
NO_DATA = 20,
|
||||
PIPE_NOT_CONNECTED = 21,
|
||||
MORE_ENTRIES = 22,
|
||||
DIRECTORY_NOT_EMPTY = 23,
|
||||
NOT_A_DIRECTORY = 24,
|
||||
FILE_IS_A_DIRECTORY = 25,
|
||||
DIRECTORY_NOT_ROOT = 26,
|
||||
DIRECTORY_NOT_EMPTY_2 = 27,
|
||||
END_OF_MEDIA = 28,
|
||||
NO_MEDIA = 29,
|
||||
UNRECOGNIZED_MEDIA = 30,
|
||||
SECTOR_NOT_FOUND = 31
|
||||
};
|
||||
|
||||
enum NodeFlags
|
||||
{
|
||||
FS_ERROR = 0x0,
|
||||
FS_FILE = 0x01,
|
||||
FS_DIRECTORY = 0x02,
|
||||
FS_CHARDEVICE = 0x03,
|
||||
FS_BLOCKDEVICE = 0x04,
|
||||
FS_PIPE = 0x05,
|
||||
FS_SYMLINK = 0x06,
|
||||
FS_MOUNTPOINT = 0x08
|
||||
};
|
||||
|
||||
struct FileSystemOpeations
|
||||
{
|
||||
char Name[FILENAME_LENGTH];
|
||||
OperationMount Mount = nullptr;
|
||||
OperationUmount Umount = nullptr;
|
||||
OperationRead Read = nullptr;
|
||||
OperationWrite Write = nullptr;
|
||||
OperationOpen Open = nullptr;
|
||||
OperationClose Close = nullptr;
|
||||
OperationCreate Create = nullptr;
|
||||
OperationMkdir MakeDirectory = nullptr;
|
||||
};
|
||||
|
||||
struct FileSystemNode
|
||||
{
|
||||
char Name[FILENAME_LENGTH];
|
||||
uint64_t IndexNode = 0;
|
||||
uint64_t Mask = 0;
|
||||
uint64_t Mode = 0;
|
||||
uint64_t Flags = NodeFlags::FS_ERROR;
|
||||
uint64_t UserIdentifier = 0, GroupIdentifier = 0;
|
||||
uint64_t Address = 0;
|
||||
uint64_t Length = 0;
|
||||
FileSystemNode *Parent = nullptr;
|
||||
FileSystemOpeations *Operator = nullptr;
|
||||
/* For root node:
|
||||
0 - root "/"
|
||||
1 - etc
|
||||
...
|
||||
*/
|
||||
Vector<FileSystemNode *> Children;
|
||||
};
|
||||
|
||||
struct FILE
|
||||
{
|
||||
const char *Name;
|
||||
FileStatus Status;
|
||||
FileSystemNode *Node;
|
||||
};
|
||||
|
||||
/* Manage / etc.. */
|
||||
class Virtual
|
||||
{
|
||||
private:
|
||||
FileSystemNode *FileSystemRoot = nullptr;
|
||||
|
||||
public:
|
||||
FileSystemNode *GetRootNode() { return FileSystemRoot; }
|
||||
FILE *ConvertNodeToFILE(FileSystemNode *Node)
|
||||
{
|
||||
FILE *File = new FILE;
|
||||
File->Name = Node->Name;
|
||||
File->Status = FileStatus::OK;
|
||||
File->Node = Node;
|
||||
return File;
|
||||
}
|
||||
char *GetPathFromNode(FileSystemNode *Node);
|
||||
FileSystemNode *GetNodeFromPath(FileSystemNode *Parent, const char *Path);
|
||||
char *NormalizePath(FileSystemNode *Parent, const char *Path);
|
||||
|
||||
FileStatus FileExists(FileSystemNode *Parent, const char *Path);
|
||||
FILE *Mount(FileSystemOpeations *Operator, const char *Path);
|
||||
FileStatus Unmount(FILE *File);
|
||||
FILE *Open(const char *Path, FileSystemNode *Parent = nullptr);
|
||||
uint64_t Read(FILE *File, uint64_t Offset, uint8_t *Buffer, uint64_t Size);
|
||||
uint64_t Write(FILE *File, uint64_t Offset, uint8_t *Buffer, uint64_t Size);
|
||||
FileStatus Close(FILE *File);
|
||||
FileSystemNode *CreateRoot(FileSystemOpeations *Operator, const char *RootName);
|
||||
FileSystemNode *Create(FileSystemNode *Parent, const char *Path);
|
||||
|
||||
Virtual();
|
||||
~Virtual();
|
||||
};
|
||||
}
|
||||
|
||||
#endif // !__FENNIX_KERNEL_FILESYSTEM_H__
|
74
include/filesystem/ext2.hpp
Normal file
74
include/filesystem/ext2.hpp
Normal file
@ -0,0 +1,74 @@
|
||||
#ifndef __FENNIX_KERNEL_FILESYSTEM_EXT2_H__
|
||||
#define __FENNIX_KERNEL_FILESYSTEM_EXT2_H__
|
||||
|
||||
#include <types.h>
|
||||
|
||||
#include <filesystem.hpp>
|
||||
|
||||
namespace FileSystem
|
||||
{
|
||||
class EXT2
|
||||
{
|
||||
public:
|
||||
struct SuperBlock
|
||||
{
|
||||
uint32_t Inodes;
|
||||
uint32_t Blocks;
|
||||
uint32_t ReservedBlocks;
|
||||
uint32_t FreeBlock;
|
||||
uint32_t FreeInodes;
|
||||
uint32_t FirstDataBlock;
|
||||
uint32_t LogBlockSize;
|
||||
uint32_t LogFragSize;
|
||||
uint32_t BlocksPerGroup;
|
||||
uint32_t FragsPerGroup;
|
||||
uint32_t InodesPerGroup;
|
||||
uint32_t LastMountTime;
|
||||
uint32_t LastWrittenTime;
|
||||
uint16_t MountedTimes;
|
||||
uint16_t MaximumMountedTimes;
|
||||
uint16_t Magic;
|
||||
uint16_t State;
|
||||
uint16_t Errors;
|
||||
uint16_t MinorRevLevel;
|
||||
uint32_t LastCheck;
|
||||
uint32_t CheckInternval;
|
||||
uint32_t SystemID;
|
||||
uint32_t RevLevel;
|
||||
uint16_t ReservedBlocksUserID;
|
||||
uint16_t ReservedBlocksGroupID;
|
||||
|
||||
uint32_t FirstInode;
|
||||
uint16_t InodeSize;
|
||||
uint16_t BlockGroups;
|
||||
uint32_t FeatureCompatibility;
|
||||
uint32_t FeatureIncompatibility;
|
||||
uint32_t FeatureRoCompatibility;
|
||||
uint8_t UUID[16];
|
||||
char VolumeName[16];
|
||||
char LastMounted[64];
|
||||
uint32_t BitmapAlogrithm;
|
||||
|
||||
uint8_t PreallocatedBlocks;
|
||||
uint8_t PreallocatedDirectoryBlocks;
|
||||
|
||||
uint16_t Padding;
|
||||
uint8_t JournalUUID[16];
|
||||
uint32_t JournalInum;
|
||||
uint32_t JournalDev;
|
||||
uint32_t LastOrphan;
|
||||
uint32_t HashSeed[4];
|
||||
uint8_t DefHashVersion;
|
||||
uint8_t ReservedCharPad;
|
||||
uint16_t ReservedWordPad;
|
||||
uint32_t DefaultMountOptions;
|
||||
uint32_t FirstMetaBg;
|
||||
uint32_t Reserved[190];
|
||||
};
|
||||
|
||||
EXT2(void *partition);
|
||||
~EXT2();
|
||||
};
|
||||
}
|
||||
|
||||
#endif // !__FENNIX_KERNEL_FILESYSTEM_EXT2_H__
|
60
include/filesystem/fat.hpp
Normal file
60
include/filesystem/fat.hpp
Normal file
@ -0,0 +1,60 @@
|
||||
#ifndef __FENNIX_KERNEL_FILESYSTEM_FAT_H__
|
||||
#define __FENNIX_KERNEL_FILESYSTEM_FAT_H__
|
||||
|
||||
#include <types.h>
|
||||
|
||||
#include <filesystem.hpp>
|
||||
|
||||
namespace FileSystem
|
||||
{
|
||||
class FAT
|
||||
{
|
||||
public:
|
||||
enum FatType
|
||||
{
|
||||
Unknown,
|
||||
FAT12,
|
||||
FAT16,
|
||||
FAT32
|
||||
};
|
||||
|
||||
/* https://wiki.osdev.org/FAT */
|
||||
struct BIOSParameterBlock
|
||||
{
|
||||
/** @brief The first three bytes EB 3C 90 disassemble to JMP SHORT 3C NOP. (The 3C value may be different.) The reason for this is to jump over the disk format information (the BPB and EBPB). Since the first sector of the disk is loaded into ram at location 0x0000:0x7c00 and executed, without this jump, the processor would attempt to execute data that isn't code. Even for non-bootable volumes, code matching this pattern (or using the E9 jump opcode) is required to be present by both Windows and OS X. To fulfil this requirement, an infinite loop can be placed here with the bytes EB FE 90. */
|
||||
uint8_t JumpBoot[3];
|
||||
/** @brief OEM identifier. The first 8 Bytes (3 - 10) is the version of DOS being used. The next eight Bytes 29 3A 63 7E 2D 49 48 and 43 read out the name of the version. The official FAT Specification from Microsoft says that this field is really meaningless and is ignored by MS FAT Drivers, however it does recommend the value "MSWIN4.1" as some 3rd party drivers supposedly check it and expect it to have that value. Older versions of dos also report MSDOS5.1, linux-formatted floppy will likely to carry "mkdosfs" here, and FreeDOS formatted disks have been observed to have "FRDOS5.1" here. If the string is less than 8 bytes, it is padded with spaces. */
|
||||
uint8_t OEM[8];
|
||||
/** @brief The number of Bytes per sector (remember, all numbers are in the little-endian format). */
|
||||
uint16_t BytesPerSector;
|
||||
/** @brief Number of sectors per cluster. */
|
||||
uint8_t SectorsPerCluster;
|
||||
/** @brief Number of reserved sectors. The boot record sectors are included in this value. */
|
||||
uint16_t ReservedSectors;
|
||||
/** @brief Number of File Allocation Tables (FAT's) on the storage media. Often this value is 2. */
|
||||
uint8_t NumberOfFATs;
|
||||
/** @brief Number of root directory entries (must be set so that the root directory occupies entire sectors). */
|
||||
uint16_t RootDirectoryEntries;
|
||||
/** @brief The total sectors in the logical volume. If this value is 0, it means there are more than 65535 sectors in the volume, and the actual count is stored in the Large Sector Count entry at 0x20. */
|
||||
uint16_t Sectors16;
|
||||
/** @brief This Byte indicates the media descriptor type. */
|
||||
uint8_t Media;
|
||||
/** @brief Number of sectors per FAT. FAT12/FAT16 only. */
|
||||
uint16_t SectorsPerFAT;
|
||||
/** @brief Number of sectors per track. */
|
||||
uint16_t SectorsPerTrack;
|
||||
/** @brief Number of heads or sides on the storage media. */
|
||||
uint16_t NumberOfHeads;
|
||||
/** @brief Number of hidden sectors. (i.e. the LBA of the beginning of the partition). */
|
||||
uint32_t HiddenSectors;
|
||||
/** @brief Large sector count. This field is set if there are more than 65535 sectors in the volume, resulting in a value which does not fit in the Number of Sectors entry at 0x13. */
|
||||
uint32_t Sectors32;
|
||||
} __attribute__((__packed__));
|
||||
|
||||
FatType GetFATType(BIOSParameterBlock *bpb);
|
||||
FAT(void *partition);
|
||||
~FAT();
|
||||
};
|
||||
}
|
||||
|
||||
#endif // !__FENNIX_KERNEL_FILESYSTEM_FAT_H__
|
31
include/filesystem/initrd.hpp
Normal file
31
include/filesystem/initrd.hpp
Normal file
@ -0,0 +1,31 @@
|
||||
#ifndef __FENNIX_KERNEL_FILESYSTEM_INITRD_H__
|
||||
#define __FENNIX_KERNEL_FILESYSTEM_INITRD_H__
|
||||
|
||||
#include <types.h>
|
||||
|
||||
#include <filesystem.hpp>
|
||||
|
||||
namespace FileSystem
|
||||
{
|
||||
class Initrd
|
||||
{
|
||||
public:
|
||||
struct InitrdHeader
|
||||
{
|
||||
uint32_t nfiles;
|
||||
};
|
||||
|
||||
struct InitrdFileHeader
|
||||
{
|
||||
uint8_t magic;
|
||||
char name[64];
|
||||
uint32_t offset;
|
||||
uint32_t length;
|
||||
};
|
||||
|
||||
Initrd(uint64_t Address);
|
||||
~Initrd();
|
||||
};
|
||||
}
|
||||
|
||||
#endif // !__FENNIX_KERNEL_FILESYSTEM_INITRD_H__
|
97
include/filesystem/mounts.hpp
Normal file
97
include/filesystem/mounts.hpp
Normal file
@ -0,0 +1,97 @@
|
||||
#ifndef __FENNIX_KERNEL_FILESYSTEM_DEV_H__
|
||||
#define __FENNIX_KERNEL_FILESYSTEM_DEV_H__
|
||||
|
||||
#include <types.h>
|
||||
|
||||
#include <filesystem.hpp>
|
||||
|
||||
namespace FileSystem
|
||||
{
|
||||
/* Manage /system/dev */
|
||||
class Device
|
||||
{
|
||||
public:
|
||||
FileSystemNode *AddFileSystem(FileSystemOpeations *Operator, uint64_t Mode, const char *Name, int Flags);
|
||||
Device();
|
||||
~Device();
|
||||
};
|
||||
|
||||
/* Manage /system/mnt */
|
||||
class Mount
|
||||
{
|
||||
public:
|
||||
FileSystemNode *MountFileSystem(FileSystemOpeations *Operator, uint64_t Mode, const char *Name);
|
||||
void DetectAndMountFS(void *drive);
|
||||
Mount();
|
||||
~Mount();
|
||||
};
|
||||
|
||||
/* Manage /system/prc */
|
||||
class Process
|
||||
{
|
||||
public:
|
||||
Process();
|
||||
~Process();
|
||||
};
|
||||
|
||||
/* Manage /system/drv */
|
||||
class Driver
|
||||
{
|
||||
public:
|
||||
FileSystemNode *AddDriver(struct FileSystemOpeations *Operator, uint64_t Mode, const char *Name, int Flags);
|
||||
Driver();
|
||||
~Driver();
|
||||
};
|
||||
|
||||
/* Manage /system/net */
|
||||
class Network
|
||||
{
|
||||
public:
|
||||
FileSystemNode *AddNetworkCard(struct FileSystemOpeations *Operator, uint64_t Mode, const char *Name, int Flags);
|
||||
Network();
|
||||
~Network();
|
||||
};
|
||||
|
||||
/* Manage /system/dev/serialX */
|
||||
class Serial
|
||||
{
|
||||
public:
|
||||
Serial();
|
||||
~Serial();
|
||||
};
|
||||
|
||||
/* Manage /system/dev/random */
|
||||
class Random
|
||||
{
|
||||
public:
|
||||
Random();
|
||||
~Random();
|
||||
};
|
||||
|
||||
/* Manage /system/dev/null */
|
||||
class Null
|
||||
{
|
||||
public:
|
||||
Null();
|
||||
~Null();
|
||||
};
|
||||
|
||||
/* Manage /system/dev/zero */
|
||||
class Zero
|
||||
{
|
||||
public:
|
||||
Zero();
|
||||
~Zero();
|
||||
};
|
||||
|
||||
/* Manage /system/dev/fbX */
|
||||
class FB
|
||||
{
|
||||
public:
|
||||
void SetFrameBufferData(uint64_t Address, uint64_t Size, uint32_t Width, uint32_t Height, uint32_t PixelsPerScanLine);
|
||||
FB();
|
||||
~FB();
|
||||
};
|
||||
}
|
||||
|
||||
#endif // !__FENNIX_KERNEL_FILESYSTEM_DEV_H__
|
71
include/filesystem/ustar.hpp
Normal file
71
include/filesystem/ustar.hpp
Normal file
@ -0,0 +1,71 @@
|
||||
#ifndef __FENNIX_KERNEL_FILESYSTEM_USTAR_H__
|
||||
#define __FENNIX_KERNEL_FILESYSTEM_USTAR_H__
|
||||
|
||||
#include <types.h>
|
||||
|
||||
#include <filesystem.hpp>
|
||||
|
||||
namespace FileSystem
|
||||
{
|
||||
class USTAR
|
||||
{
|
||||
enum FileType
|
||||
{
|
||||
REGULAR_FILE = '0',
|
||||
HARDLINK = '1',
|
||||
SYMLINK = '2',
|
||||
CHARDEV = '3',
|
||||
BLOCKDEV = '4',
|
||||
DIRECTORY = '5',
|
||||
FIFO = '6'
|
||||
};
|
||||
|
||||
struct FileHeader
|
||||
{
|
||||
char name[100];
|
||||
char mode[8];
|
||||
char uid[8];
|
||||
char gid[8];
|
||||
char size[12];
|
||||
char mtime[12];
|
||||
char chksum[8];
|
||||
char typeflag[1];
|
||||
char link[100];
|
||||
char signature[6];
|
||||
char version[2];
|
||||
char owner[32];
|
||||
char group[32];
|
||||
char dev_maj[8];
|
||||
char dev_min[8];
|
||||
char prefix[155];
|
||||
char pad[12];
|
||||
};
|
||||
|
||||
private:
|
||||
uint32_t getsize(const char *s)
|
||||
{
|
||||
uint64_t ret = 0;
|
||||
while (*s)
|
||||
{
|
||||
ret *= 8;
|
||||
ret += *s - '0';
|
||||
s++;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int string2int(const char *str)
|
||||
{
|
||||
int res = 0;
|
||||
for (int i = 0; str[i] != '\0'; ++i)
|
||||
res = res * 10 + str[i] - '0';
|
||||
return res;
|
||||
}
|
||||
|
||||
public:
|
||||
USTAR(uint64_t Address, Virtual *vfs);
|
||||
~USTAR();
|
||||
};
|
||||
}
|
||||
|
||||
#endif // !__FENNIX_KERNEL_FILESYSTEM_USTAR_H__
|
@ -2,7 +2,13 @@
|
||||
#define __FENNIX_KERNEL_SYSTEM_H__
|
||||
|
||||
#include <types.h>
|
||||
#include <cpu.hpp>
|
||||
|
||||
|
||||
// TODO: Add actual panic screen
|
||||
#define panic(msg) \
|
||||
{ \
|
||||
error(msg); \
|
||||
CPU::Stop(); \
|
||||
}
|
||||
|
||||
#endif // !__FENNIX_KERNEL_SYSTEM_H__
|
||||
|
2
kernel.h
2
kernel.h
@ -5,6 +5,7 @@
|
||||
|
||||
#include <boot/binfo.h>
|
||||
#ifdef __cplusplus
|
||||
#include <filesystem.hpp>
|
||||
#include <display.hpp>
|
||||
#include <symbols.hpp>
|
||||
#include <kconfig.hpp>
|
||||
@ -23,6 +24,7 @@ extern PCI::PCI *PCIManager;
|
||||
extern KernelConfig Config;
|
||||
extern Tasking::Task *TaskManager;
|
||||
extern Time::time *TimeManager;
|
||||
extern FileSystem::Virtual *vfs;
|
||||
#endif
|
||||
|
||||
EXTERNC void KPrint(const char *format, ...);
|
||||
|
Loading…
x
Reference in New Issue
Block a user