mirror of
https://github.com/Fennix-Project/Kernel.git
synced 2025-05-28 15:34:33 +00:00
Rework virtual filesystem implementation
This commit is contained in:
parent
f2eab6c64f
commit
dc7b1fc4c9
@ -219,10 +219,10 @@ namespace Driver
|
|||||||
DriverConfigFile << "/config.ini";
|
DriverConfigFile << "/config.ini";
|
||||||
fixme("Loading driver config file: %s", DriverConfigFile.c_str());
|
fixme("Loading driver config file: %s", DriverConfigFile.c_str());
|
||||||
|
|
||||||
std::shared_ptr<VirtualFileSystem::File> DriverDirectory = vfs->Open(Config.DriverDirectory);
|
VirtualFileSystem::File DriverDirectory = vfs->Open(Config.DriverDirectory);
|
||||||
if (DriverDirectory->Status == VirtualFileSystem::FileStatus::OK)
|
if (DriverDirectory.IsOK())
|
||||||
{
|
{
|
||||||
foreach (auto driver in DriverDirectory->node->Children)
|
foreach (auto driver in DriverDirectory.node->Children)
|
||||||
if (driver->Flags == VirtualFileSystem::NodeFlags::FILE)
|
if (driver->Flags == VirtualFileSystem::NodeFlags::FILE)
|
||||||
if (cwk_path_has_extension(driver->Name))
|
if (cwk_path_has_extension(driver->Name))
|
||||||
{
|
{
|
||||||
@ -246,7 +246,7 @@ namespace Driver
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
KPrint("\eE85230Failed to open driver directory: %s! (Status: %#lx)", Config.DriverDirectory, DriverDirectory->Status);
|
KPrint("\eE85230Failed to open driver directory: %s! (Status: %#lx)", Config.DriverDirectory, DriverDirectory.Status);
|
||||||
CPU::Stop();
|
CPU::Stop();
|
||||||
}
|
}
|
||||||
vfs->Close(DriverDirectory);
|
vfs->Close(DriverDirectory);
|
||||||
|
@ -131,9 +131,9 @@ namespace Execute
|
|||||||
cwk_path_get_basename(Path, &BaseName, nullptr);
|
cwk_path_get_basename(Path, &BaseName, nullptr);
|
||||||
TaskArchitecture Arch = TaskArchitecture::UnknownArchitecture;
|
TaskArchitecture Arch = TaskArchitecture::UnknownArchitecture;
|
||||||
|
|
||||||
std::shared_ptr<File> ExFile = vfs->Open(Path);
|
File ExFile = vfs->Open(Path);
|
||||||
|
|
||||||
if (ExFile->Status != FileStatus::OK)
|
if (ExFile.Status != FileStatus::OK)
|
||||||
{
|
{
|
||||||
vfs->Close(ExFile);
|
vfs->Close(ExFile);
|
||||||
error("Failed to open file: %s", Path);
|
error("Failed to open file: %s", Path);
|
||||||
@ -141,7 +141,7 @@ namespace Execute
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (ExFile->node->Flags != NodeFlags::FILE)
|
if (ExFile.node->Flags != NodeFlags::FILE)
|
||||||
{
|
{
|
||||||
vfs->Close(ExFile);
|
vfs->Close(ExFile);
|
||||||
error("Invalid file path: %s", Path);
|
error("Invalid file path: %s", Path);
|
||||||
@ -155,12 +155,12 @@ namespace Execute
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t ExFileSize = ExFile->node->Length;
|
size_t ExFileSize = ExFile.node->Length;
|
||||||
|
|
||||||
/* Allocate elf in memory */
|
/* Allocate elf in memory */
|
||||||
void *ElfFile = KernelAllocator.RequestPages(TO_PAGES(ExFileSize + 1));
|
void *ElfFile = KernelAllocator.RequestPages(TO_PAGES(ExFileSize + 1));
|
||||||
/* Copy the file to the allocated memory */
|
/* Copy the file to the allocated memory */
|
||||||
memcpy(ElfFile, (void *)ExFile->node->Address, ExFileSize);
|
memcpy(ElfFile, (void *)ExFile.node->Address, ExFileSize);
|
||||||
debug("Image Size: %#lx - %#lx (length: %ld)", ElfFile, (uintptr_t)ElfFile + ExFileSize, ExFileSize);
|
debug("Image Size: %#lx - %#lx (length: %ld)", ElfFile, (uintptr_t)ElfFile + ExFileSize, ExFileSize);
|
||||||
|
|
||||||
Elf64_Ehdr *ELFHeader = (Elf64_Ehdr *)ElfFile;
|
Elf64_Ehdr *ELFHeader = (Elf64_Ehdr *)ElfFile;
|
||||||
@ -220,13 +220,13 @@ namespace Execute
|
|||||||
switch (ELFHeader->e_type)
|
switch (ELFHeader->e_type)
|
||||||
{
|
{
|
||||||
case ET_REL:
|
case ET_REL:
|
||||||
bl = ELFLoadRel(ElfFile, ExFile.get(), Process);
|
bl = ELFLoadRel(ElfFile, ExFile, Process);
|
||||||
break;
|
break;
|
||||||
case ET_EXEC:
|
case ET_EXEC:
|
||||||
bl = ELFLoadExec(ElfFile, ExFile.get(), Process);
|
bl = ELFLoadExec(ElfFile, ExFile, Process);
|
||||||
break;
|
break;
|
||||||
case ET_DYN:
|
case ET_DYN:
|
||||||
bl = ELFLoadDyn(ElfFile, ExFile.get(), Process);
|
bl = ELFLoadDyn(ElfFile, ExFile, Process);
|
||||||
break;
|
break;
|
||||||
case ET_CORE:
|
case ET_CORE:
|
||||||
{
|
{
|
||||||
|
@ -32,7 +32,7 @@ using namespace Tasking;
|
|||||||
namespace Execute
|
namespace Execute
|
||||||
{
|
{
|
||||||
ELFBaseLoad ELFLoadDyn(void *BaseImage,
|
ELFBaseLoad ELFLoadDyn(void *BaseImage,
|
||||||
VirtualFileSystem::File *ExFile,
|
VirtualFileSystem::File &ExFile,
|
||||||
Tasking::PCB *Process)
|
Tasking::PCB *Process)
|
||||||
{
|
{
|
||||||
fixme("Not implemented");
|
fixme("Not implemented");
|
||||||
|
@ -32,7 +32,7 @@ using namespace Tasking;
|
|||||||
namespace Execute
|
namespace Execute
|
||||||
{
|
{
|
||||||
ELFBaseLoad ELFLoadExec(void *ElfFile,
|
ELFBaseLoad ELFLoadExec(void *ElfFile,
|
||||||
VirtualFileSystem::File *ExFile,
|
VirtualFileSystem::File &ExFile,
|
||||||
Tasking::PCB *Process)
|
Tasking::PCB *Process)
|
||||||
{
|
{
|
||||||
debug("Executable");
|
debug("Executable");
|
||||||
@ -46,7 +46,7 @@ namespace Execute
|
|||||||
uintptr_t BaseAddress = UINTPTR_MAX;
|
uintptr_t BaseAddress = UINTPTR_MAX;
|
||||||
uint64_t ElfAppSize = 0;
|
uint64_t ElfAppSize = 0;
|
||||||
uintptr_t EntryPoint = ELFHeader->e_entry;
|
uintptr_t EntryPoint = ELFHeader->e_entry;
|
||||||
debug("%s's entry point is %#lx", ExFile->Name, EntryPoint);
|
debug("%s's entry point is %#lx", ExFile.Name, EntryPoint);
|
||||||
|
|
||||||
Elf64_Phdr ItrPhdr;
|
Elf64_Phdr ItrPhdr;
|
||||||
|
|
||||||
@ -171,8 +171,8 @@ namespace Execute
|
|||||||
memcpy((void *)InterpreterPath, (uint8_t *)ElfFile + ItrPhdr.p_offset, 256);
|
memcpy((void *)InterpreterPath, (uint8_t *)ElfFile + ItrPhdr.p_offset, 256);
|
||||||
debug("Interpreter: %s", InterpreterPath);
|
debug("Interpreter: %s", InterpreterPath);
|
||||||
|
|
||||||
std::shared_ptr<VirtualFileSystem::File> InterpreterFile = vfs->Open(InterpreterPath);
|
VirtualFileSystem::File InterpreterFile = vfs->Open(InterpreterPath);
|
||||||
if (InterpreterFile->Status != VirtualFileSystem::FileStatus::OK)
|
if (!InterpreterFile.IsOK())
|
||||||
warn("Failed to open interpreter file: %s", InterpreterPath);
|
warn("Failed to open interpreter file: %s", InterpreterPath);
|
||||||
|
|
||||||
vfs->Close(InterpreterFile);
|
vfs->Close(InterpreterFile);
|
||||||
@ -206,7 +206,7 @@ namespace Execute
|
|||||||
strcpy(aux_platform, "x86_64");
|
strcpy(aux_platform, "x86_64");
|
||||||
|
|
||||||
ELFBase.auxv.push_back({.archaux = {.a_type = AT_NULL, .a_un = {.a_val = 0}}});
|
ELFBase.auxv.push_back({.archaux = {.a_type = AT_NULL, .a_un = {.a_val = 0}}});
|
||||||
ELFBase.auxv.push_back({.archaux = {.a_type = AT_EXECFN, .a_un = {.a_val = (uint64_t)vfs->GetPathFromNode(ExFile->node).get()}}});
|
ELFBase.auxv.push_back({.archaux = {.a_type = AT_EXECFN, .a_un = {.a_val = (uint64_t)vfs->GetPathFromNode(ExFile.node).get()}}});
|
||||||
ELFBase.auxv.push_back({.archaux = {.a_type = AT_PLATFORM, .a_un = {.a_val = (uint64_t)aux_platform}}});
|
ELFBase.auxv.push_back({.archaux = {.a_type = AT_PLATFORM, .a_un = {.a_val = (uint64_t)aux_platform}}});
|
||||||
ELFBase.auxv.push_back({.archaux = {.a_type = AT_ENTRY, .a_un = {.a_val = (uint64_t)EntryPoint}}});
|
ELFBase.auxv.push_back({.archaux = {.a_type = AT_ENTRY, .a_un = {.a_val = (uint64_t)EntryPoint}}});
|
||||||
ELFBase.auxv.push_back({.archaux = {.a_type = AT_BASE, .a_un = {.a_val = (uint64_t)MemoryImage.Virtual}}});
|
ELFBase.auxv.push_back({.archaux = {.a_type = AT_BASE, .a_un = {.a_val = (uint64_t)MemoryImage.Virtual}}});
|
||||||
|
@ -232,9 +232,9 @@ namespace Execute
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* No need to check if it's valid, the GetBinaryType() call above does that. */
|
/* No need to check if it's valid, the GetBinaryType() call above does that. */
|
||||||
std::shared_ptr<VirtualFileSystem::File> File = vfs->Open(Interpreter);
|
VirtualFileSystem::File File = vfs->Open(Interpreter);
|
||||||
|
|
||||||
Elf64_Ehdr *ELFHeader = (Elf64_Ehdr *)File->node->Address;
|
Elf64_Ehdr *ELFHeader = (Elf64_Ehdr *)File.node->Address;
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
const char *InterpreterType[6] = {
|
const char *InterpreterType[6] = {
|
||||||
@ -259,7 +259,7 @@ namespace Execute
|
|||||||
for (Elf64_Half i = 0; i < ELFHeader->e_phnum; i++)
|
for (Elf64_Half i = 0; i < ELFHeader->e_phnum; i++)
|
||||||
{
|
{
|
||||||
memcpy(&ItrPhdr,
|
memcpy(&ItrPhdr,
|
||||||
(uint8_t *)File->node->Address + ELFHeader->e_phoff + ELFHeader->e_phentsize * i,
|
(uint8_t *)File.node->Address + ELFHeader->e_phoff + ELFHeader->e_phentsize * i,
|
||||||
sizeof(Elf64_Phdr));
|
sizeof(Elf64_Phdr));
|
||||||
|
|
||||||
BaseAddress = MIN(BaseAddress, ItrPhdr.p_vaddr);
|
BaseAddress = MIN(BaseAddress, ItrPhdr.p_vaddr);
|
||||||
@ -269,7 +269,7 @@ namespace Execute
|
|||||||
for (Elf64_Half i = 0; i < ELFHeader->e_phnum; i++)
|
for (Elf64_Half i = 0; i < ELFHeader->e_phnum; i++)
|
||||||
{
|
{
|
||||||
memcpy(&ItrPhdr,
|
memcpy(&ItrPhdr,
|
||||||
(uint8_t *)File->node->Address + ELFHeader->e_phoff + ELFHeader->e_phentsize * i,
|
(uint8_t *)File.node->Address + ELFHeader->e_phoff + ELFHeader->e_phentsize * i,
|
||||||
sizeof(Elf64_Phdr));
|
sizeof(Elf64_Phdr));
|
||||||
|
|
||||||
uintptr_t SegmentEnd;
|
uintptr_t SegmentEnd;
|
||||||
@ -277,12 +277,12 @@ namespace Execute
|
|||||||
ElfAppSize = MAX(ElfAppSize, SegmentEnd);
|
ElfAppSize = MAX(ElfAppSize, SegmentEnd);
|
||||||
}
|
}
|
||||||
|
|
||||||
MmImage MemoryImage = ELFCreateMemoryImage(mem, pV, (void *)File->node->Address, ElfAppSize);
|
MmImage MemoryImage = ELFCreateMemoryImage(mem, pV, (void *)File.node->Address, ElfAppSize);
|
||||||
|
|
||||||
for (Elf64_Half i = 0; i < ELFHeader->e_phnum; i++)
|
for (Elf64_Half i = 0; i < ELFHeader->e_phnum; i++)
|
||||||
{
|
{
|
||||||
memcpy(&ItrPhdr,
|
memcpy(&ItrPhdr,
|
||||||
(uint8_t *)File->node->Address + ELFHeader->e_phoff + ELFHeader->e_phentsize * i,
|
(uint8_t *)File.node->Address + ELFHeader->e_phoff + ELFHeader->e_phentsize * i,
|
||||||
sizeof(Elf64_Phdr));
|
sizeof(Elf64_Phdr));
|
||||||
|
|
||||||
if (ItrPhdr.p_type == PT_LOAD)
|
if (ItrPhdr.p_type == PT_LOAD)
|
||||||
@ -296,8 +296,8 @@ namespace Execute
|
|||||||
(ItrPhdr.p_flags & PF_W) ? "W" : "",
|
(ItrPhdr.p_flags & PF_W) ? "W" : "",
|
||||||
(ItrPhdr.p_flags & PF_X) ? "X" : "");
|
(ItrPhdr.p_flags & PF_X) ? "X" : "");
|
||||||
|
|
||||||
memcpy((void *)MAddr, (uint8_t *)File->node->Address + ItrPhdr.p_offset, ItrPhdr.p_filesz);
|
memcpy((void *)MAddr, (uint8_t *)File.node->Address + ItrPhdr.p_offset, ItrPhdr.p_filesz);
|
||||||
debug("memcpy: %#lx => %#lx (%ld bytes)", (uint8_t *)File->node->Address + ItrPhdr.p_offset, MAddr, ItrPhdr.p_filesz);
|
debug("memcpy: %#lx => %#lx (%ld bytes)", (uint8_t *)File.node->Address + ItrPhdr.p_offset, MAddr, ItrPhdr.p_filesz);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,7 +27,7 @@ namespace Execute
|
|||||||
/* Originally from https://wiki.osdev.org/ELF_Tutorial */
|
/* Originally from https://wiki.osdev.org/ELF_Tutorial */
|
||||||
|
|
||||||
ELFBaseLoad ELFLoadRel(void *BaseImage,
|
ELFBaseLoad ELFLoadRel(void *BaseImage,
|
||||||
VirtualFileSystem::File *ExFile,
|
VirtualFileSystem::File &ExFile,
|
||||||
Tasking::PCB *Process)
|
Tasking::PCB *Process)
|
||||||
{
|
{
|
||||||
debug("Relocatable");
|
debug("Relocatable");
|
||||||
|
@ -86,12 +86,12 @@ namespace Execute
|
|||||||
BinaryType GetBinaryType(char *Path)
|
BinaryType GetBinaryType(char *Path)
|
||||||
{
|
{
|
||||||
BinaryType Type = BinaryType::BinTypeInvalid;
|
BinaryType Type = BinaryType::BinTypeInvalid;
|
||||||
std::shared_ptr<VirtualFileSystem::File> ExFile = vfs->Open(Path);
|
VirtualFileSystem::File ExFile = vfs->Open(Path);
|
||||||
|
|
||||||
if (ExFile->Status == VirtualFileSystem::FileStatus::OK)
|
if (ExFile.IsOK())
|
||||||
{
|
{
|
||||||
debug("File opened: %s", Path);
|
debug("File opened: %s", Path);
|
||||||
Type = GetBinaryType((void *)ExFile->node->Address);
|
Type = GetBinaryType((void *)ExFile.node->Address);
|
||||||
}
|
}
|
||||||
|
|
||||||
vfs->Close(ExFile);
|
vfs->Close(ExFile);
|
||||||
|
@ -37,11 +37,11 @@ namespace Execute
|
|||||||
.Process = nullptr,
|
.Process = nullptr,
|
||||||
.Thread = nullptr};
|
.Thread = nullptr};
|
||||||
|
|
||||||
std::shared_ptr<VirtualFileSystem::File> ExFile = vfs->Open(Path);
|
VirtualFileSystem::File ExFile = vfs->Open(Path);
|
||||||
|
|
||||||
if (ExFile->Status == VirtualFileSystem::FileStatus::OK)
|
if (ExFile.IsOK())
|
||||||
{
|
{
|
||||||
if (ExFile->node->Flags != VirtualFileSystem::NodeFlags::FILE)
|
if (ExFile.node->Flags != VirtualFileSystem::NodeFlags::FILE)
|
||||||
{
|
{
|
||||||
ret.Status = ExStatus::InvalidFilePath;
|
ret.Status = ExStatus::InvalidFilePath;
|
||||||
goto Exit;
|
goto Exit;
|
||||||
@ -51,17 +51,17 @@ namespace Execute
|
|||||||
{
|
{
|
||||||
case BinaryType::BinTypeFex:
|
case BinaryType::BinTypeFex:
|
||||||
{
|
{
|
||||||
Fex *FexHdr = (Fex *)ExFile->node->Address;
|
Fex *FexHdr = (Fex *)ExFile.node->Address;
|
||||||
if (FexHdr->Type == FexFormatType::FexFormatType_Executable)
|
if (FexHdr->Type == FexFormatType::FexFormatType_Executable)
|
||||||
{
|
{
|
||||||
const char *BaseName;
|
const char *BaseName;
|
||||||
cwk_path_get_basename(Path, &BaseName, nullptr);
|
cwk_path_get_basename(Path, &BaseName, nullptr);
|
||||||
PCB *Process = TaskManager->CreateProcess(TaskManager->GetCurrentProcess(), BaseName, TaskTrustLevel::User);
|
PCB *Process = TaskManager->CreateProcess(TaskManager->GetCurrentProcess(), BaseName, TaskTrustLevel::User);
|
||||||
|
|
||||||
void *BaseImage = KernelAllocator.RequestPages(TO_PAGES(ExFile->node->Length + 1));
|
void *BaseImage = KernelAllocator.RequestPages(TO_PAGES(ExFile.node->Length + 1));
|
||||||
memcpy(BaseImage, (void *)ExFile->node->Address, ExFile->node->Length);
|
memcpy(BaseImage, (void *)ExFile.node->Address, ExFile.node->Length);
|
||||||
|
|
||||||
Memory::Virtual(Process->PageTable).Map((void *)BaseImage, (void *)BaseImage, ExFile->node->Length, Memory::PTFlag::RW | Memory::PTFlag::US);
|
Memory::Virtual(Process->PageTable).Map((void *)BaseImage, (void *)BaseImage, ExFile.node->Length, Memory::PTFlag::RW | Memory::PTFlag::US);
|
||||||
|
|
||||||
std::vector<AuxiliaryVector> auxv; // TODO!
|
std::vector<AuxiliaryVector> auxv; // TODO!
|
||||||
|
|
||||||
@ -97,7 +97,7 @@ namespace Execute
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (ExFile->Status == VirtualFileSystem::FileStatus::NotFound)
|
else if (ExFile.Status == VirtualFileSystem::FileStatus::NotFound)
|
||||||
ret.Status = ExStatus::InvalidFilePath;
|
ret.Status = ExStatus::InvalidFilePath;
|
||||||
else
|
else
|
||||||
ret.Status = ExStatus::InvalidFile;
|
ret.Status = ExStatus::InvalidFile;
|
||||||
|
@ -168,11 +168,11 @@ namespace VirtualFileSystem
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<File> Virtual::ConvertNodeToFILE(Node *node)
|
File Virtual::ConvertNodeToFILE(Node *node)
|
||||||
{
|
{
|
||||||
std::shared_ptr<File> file = std::make_shared<File>();
|
File file{};
|
||||||
file->Status = FileStatus::OK;
|
file.Status = FileStatus::OK;
|
||||||
file->node = node;
|
file.node = node;
|
||||||
return file;
|
return file;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -454,92 +454,86 @@ namespace VirtualFileSystem
|
|||||||
FileStatus Virtual::Delete(Node *Path, bool Recursive, Node *Parent) { return Delete(GetPathFromNode(Path).get(), Recursive, Parent); }
|
FileStatus Virtual::Delete(Node *Path, bool Recursive, Node *Parent) { return Delete(GetPathFromNode(Path).get(), Recursive, Parent); }
|
||||||
|
|
||||||
/* TODO: REWORK */
|
/* TODO: REWORK */
|
||||||
std::shared_ptr<File> Virtual::Mount(const char *Path, FileSystemOperations *Operator)
|
File Virtual::Mount(const char *Path, FileSystemOperations *Operator)
|
||||||
{
|
{
|
||||||
SmartLock(VFSLock);
|
SmartLock(VFSLock);
|
||||||
std::shared_ptr<File> file = std::make_shared<File>();
|
File file{};
|
||||||
|
|
||||||
if (unlikely(!Operator))
|
if (unlikely(!Operator))
|
||||||
{
|
{
|
||||||
file->Status = FileStatus::InvalidOperator;
|
file.Status = FileStatus::InvalidOperator;
|
||||||
return file;
|
return file;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (unlikely(isempty((char *)Path)))
|
if (unlikely(isempty((char *)Path)))
|
||||||
{
|
{
|
||||||
file->Status = FileStatus::InvalidParameter;
|
file.Status = FileStatus::InvalidParameter;
|
||||||
return file;
|
return file;
|
||||||
}
|
}
|
||||||
|
|
||||||
vfsdbg("Mounting %s", Path);
|
vfsdbg("Mounting %s", Path);
|
||||||
const char *PathCopy;
|
const char *PathCopy;
|
||||||
cwk_path_get_basename(Path, &PathCopy, 0);
|
cwk_path_get_basename(Path, &PathCopy, 0);
|
||||||
strcpy(file->Name, PathCopy);
|
strcpy(file.Name, PathCopy);
|
||||||
file->Status = FileStatus::OK;
|
file.Status = FileStatus::OK;
|
||||||
file->node = Create(Path, NodeFlags::MOUNTPOINT);
|
file.node = Create(Path, NodeFlags::MOUNTPOINT);
|
||||||
file->node->Operator = Operator;
|
file.node->Operator = Operator;
|
||||||
return file;
|
return file;
|
||||||
}
|
}
|
||||||
|
|
||||||
FileStatus Virtual::Unmount(std::shared_ptr<File> File)
|
FileStatus Virtual::Unmount(File &File)
|
||||||
{
|
{
|
||||||
SmartLock(VFSLock);
|
SmartLock(VFSLock);
|
||||||
if (unlikely(File.get()))
|
if (unlikely(!File.node))
|
||||||
return FileStatus::InvalidParameter;
|
return FileStatus::InvalidParameter;
|
||||||
fixme("Unmounting %s", File->Name);
|
fixme("Unmounting %s", File.Name);
|
||||||
return FileStatus::OK;
|
return FileStatus::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t Virtual::Read(std::shared_ptr<File> File, size_t Offset, uint8_t *Buffer, size_t Size)
|
size_t Virtual::Read(File &File, size_t Offset, uint8_t *Buffer, size_t Size)
|
||||||
{
|
{
|
||||||
SmartLock(VFSLock);
|
SmartLock(VFSLock);
|
||||||
if (unlikely(!File.get()))
|
if (unlikely(!File.node))
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (unlikely(!File->node))
|
|
||||||
{
|
{
|
||||||
File->Status = FileStatus::InvalidNode;
|
File.Status = FileStatus::InvalidNode;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (unlikely(!File->node->Operator))
|
if (unlikely(!File.node->Operator))
|
||||||
{
|
{
|
||||||
File->Status = FileStatus::InvalidOperator;
|
File.Status = FileStatus::InvalidOperator;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
File->Status = FileStatus::OK;
|
File.Status = FileStatus::OK;
|
||||||
|
|
||||||
vfsdbg("Reading %s out->%016x", File->Name, Buffer);
|
vfsdbg("Reading %s out->%016x", File.Name, Buffer);
|
||||||
return File->node->Operator->Read(File->node, Offset, Size, Buffer);
|
return File.node->Operator->Read(File.node, Offset, Size, Buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t Virtual::Write(std::shared_ptr<File> File, size_t Offset, uint8_t *Buffer, size_t Size)
|
size_t Virtual::Write(File &File, size_t Offset, uint8_t *Buffer, size_t Size)
|
||||||
{
|
{
|
||||||
SmartLock(VFSLock);
|
SmartLock(VFSLock);
|
||||||
if (unlikely(!File.get()))
|
if (unlikely(!File.node))
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (unlikely(!File->node))
|
|
||||||
{
|
{
|
||||||
File->Status = FileStatus::InvalidNode;
|
File.Status = FileStatus::InvalidNode;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (unlikely(!File->node->Operator))
|
if (unlikely(!File.node->Operator))
|
||||||
{
|
{
|
||||||
File->Status = FileStatus::InvalidOperator;
|
File.Status = FileStatus::InvalidOperator;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
File->Status = FileStatus::OK;
|
File.Status = FileStatus::OK;
|
||||||
|
|
||||||
vfsdbg("Writing %s out->%016x", File->Name, Buffer);
|
vfsdbg("Writing %s out->%016x", File.Name, Buffer);
|
||||||
return File->node->Operator->Write(File->node, Offset, Size, Buffer);
|
return File.node->Operator->Write(File.node, Offset, Size, Buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO: CHECK Open */
|
/* TODO: CHECK Open */
|
||||||
std::shared_ptr<File> Virtual::Open(const char *Path, Node *Parent)
|
File Virtual::Open(const char *Path, Node *Parent)
|
||||||
{
|
{
|
||||||
SmartLock(VFSLock);
|
SmartLock(VFSLock);
|
||||||
vfsdbg("Opening %s with parent %s", Path, Parent ? Parent->Name : "(null)");
|
vfsdbg("Opening %s with parent %s", Path, Parent ? Parent->Name : "(null)");
|
||||||
@ -547,41 +541,41 @@ namespace VirtualFileSystem
|
|||||||
|
|
||||||
if (strcmp(Path, "/") == 0)
|
if (strcmp(Path, "/") == 0)
|
||||||
{
|
{
|
||||||
std::shared_ptr<File> file = std::make_shared<File>();
|
File file{};
|
||||||
file->node = FileSystemRoot;
|
file.node = FileSystemRoot;
|
||||||
strcpy(file->Name, "/");
|
strcpy(file.Name, "/");
|
||||||
return file;
|
return file;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strcmp(Path, ".") == 0)
|
if (strcmp(Path, ".") == 0)
|
||||||
{
|
{
|
||||||
std::shared_ptr<File> file = std::make_shared<File>();
|
File file{};
|
||||||
file->node = Parent;
|
file.node = Parent;
|
||||||
if (unlikely(!file->node))
|
if (unlikely(!file.node))
|
||||||
file->Status = FileStatus::NotFound;
|
file.Status = FileStatus::NotFound;
|
||||||
cwk_path_get_basename(GetPathFromNode(Parent).get(), &basename, nullptr);
|
cwk_path_get_basename(GetPathFromNode(Parent).get(), &basename, nullptr);
|
||||||
strcpy(file->Name, basename);
|
strcpy(file.Name, basename);
|
||||||
return file;
|
return file;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strcmp(Path, "..") == 0)
|
if (strcmp(Path, "..") == 0)
|
||||||
{
|
{
|
||||||
std::shared_ptr<File> file = std::make_shared<File>();
|
File file{};
|
||||||
|
|
||||||
if (Parent->Parent != nullptr)
|
if (Parent->Parent != nullptr)
|
||||||
file->node = Parent->Parent;
|
file.node = Parent->Parent;
|
||||||
|
|
||||||
if (!file->node)
|
if (!file.node)
|
||||||
file->Status = FileStatus::NotFound;
|
file.Status = FileStatus::NotFound;
|
||||||
cwk_path_get_basename(GetPathFromNode(Parent).get(), &basename, nullptr);
|
cwk_path_get_basename(GetPathFromNode(Parent).get(), &basename, nullptr);
|
||||||
strcpy(file->Name, basename);
|
strcpy(file.Name, basename);
|
||||||
return file;
|
return file;
|
||||||
}
|
}
|
||||||
|
|
||||||
Node *CurrentParent = this->GetParent(Path, Parent);
|
Node *CurrentParent = this->GetParent(Path, Parent);
|
||||||
std::shared_ptr<char> CleanPath = NormalizePath(Path, CurrentParent);
|
std::shared_ptr<char> CleanPath = NormalizePath(Path, CurrentParent);
|
||||||
|
|
||||||
std::shared_ptr<File> file = std::make_shared<File>();
|
File file{};
|
||||||
/* TODO: Check for other errors */
|
/* TODO: Check for other errors */
|
||||||
|
|
||||||
if (!PathExists(CleanPath.get(), CurrentParent))
|
if (!PathExists(CleanPath.get(), CurrentParent))
|
||||||
@ -590,45 +584,45 @@ namespace VirtualFileSystem
|
|||||||
{
|
{
|
||||||
if (strcmp(Child->Name, CleanPath.get()) == 0)
|
if (strcmp(Child->Name, CleanPath.get()) == 0)
|
||||||
{
|
{
|
||||||
file->node = Child;
|
file.node = Child;
|
||||||
if (file->node == nullptr)
|
if (file.node == nullptr)
|
||||||
{
|
{
|
||||||
file->Status = FileStatus::UnknownFileStatusError;
|
file.Status = FileStatus::UnknownFileStatusError;
|
||||||
file->node = nullptr;
|
file.node = nullptr;
|
||||||
return file;
|
return file;
|
||||||
}
|
}
|
||||||
cwk_path_get_basename(GetPathFromNode(Child).get(), &basename, nullptr);
|
cwk_path_get_basename(GetPathFromNode(Child).get(), &basename, nullptr);
|
||||||
strcpy(file->Name, basename);
|
strcpy(file.Name, basename);
|
||||||
return file;
|
return file;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
file->node = GetNodeFromPath(CleanPath.get(), FileSystemRoot->Children[0]);
|
file.node = GetNodeFromPath(CleanPath.get(), FileSystemRoot->Children[0]);
|
||||||
if (file->node)
|
if (file.node)
|
||||||
{
|
{
|
||||||
cwk_path_get_basename(GetPathFromNode(file->node).get(), &basename, nullptr);
|
cwk_path_get_basename(GetPathFromNode(file.node).get(), &basename, nullptr);
|
||||||
strcpy(file->Name, basename);
|
strcpy(file.Name, basename);
|
||||||
return file;
|
return file;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
file->node = GetNodeFromPath(CleanPath.get(), CurrentParent);
|
file.node = GetNodeFromPath(CleanPath.get(), CurrentParent);
|
||||||
cwk_path_get_basename(CleanPath.get(), &basename, nullptr);
|
cwk_path_get_basename(CleanPath.get(), &basename, nullptr);
|
||||||
strcpy(file->Name, basename);
|
strcpy(file.Name, basename);
|
||||||
return file;
|
return file;
|
||||||
}
|
}
|
||||||
|
|
||||||
file->Status = FileStatus::NotFound;
|
file.Status = FileStatus::NotFound;
|
||||||
return file;
|
return file;
|
||||||
}
|
}
|
||||||
|
|
||||||
FileStatus Virtual::Close(std::shared_ptr<File> File)
|
FileStatus Virtual::Close(File &File)
|
||||||
{
|
{
|
||||||
SmartLock(VFSLock);
|
SmartLock(VFSLock);
|
||||||
if (unlikely(!File.get()))
|
if (unlikely(!File.node))
|
||||||
return FileStatus::InvalidHandle;
|
return FileStatus::InvalidHandle;
|
||||||
vfsdbg("Closing %s", File->Name);
|
vfsdbg("Closing %s", File.Name);
|
||||||
return FileStatus::OK;
|
return FileStatus::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
18
Kernel.cpp
18
Kernel.cpp
@ -426,42 +426,42 @@ EXTERNC NIF void Main(BootInfo *Info)
|
|||||||
DevFS = vfs->Create("/system/dev", NodeFlags::DIRECTORY);
|
DevFS = vfs->Create("/system/dev", NodeFlags::DIRECTORY);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
std::shared_ptr<File> dev = vfs->Open("/system/dev");
|
File dev = vfs->Open("/system/dev");
|
||||||
if (dev->node->Flags != NodeFlags::DIRECTORY)
|
if (dev.node->Flags != NodeFlags::DIRECTORY)
|
||||||
{
|
{
|
||||||
KPrint("\eE85230/system/dev is not a directory! Halting...");
|
KPrint("\eE85230/system/dev is not a directory! Halting...");
|
||||||
CPU::Stop();
|
CPU::Stop();
|
||||||
}
|
}
|
||||||
vfs->Close(dev);
|
vfs->Close(dev);
|
||||||
DevFS = dev->node;
|
DevFS = dev.node;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!vfs->PathExists("/system/mnt"))
|
if (!vfs->PathExists("/system/mnt"))
|
||||||
MntFS = vfs->Create("/system/mnt", NodeFlags::DIRECTORY);
|
MntFS = vfs->Create("/system/mnt", NodeFlags::DIRECTORY);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
std::shared_ptr<File> mnt = vfs->Open("/system/mnt");
|
File mnt = vfs->Open("/system/mnt");
|
||||||
if (mnt->node->Flags != NodeFlags::DIRECTORY)
|
if (mnt.node->Flags != NodeFlags::DIRECTORY)
|
||||||
{
|
{
|
||||||
KPrint("\eE85230/system/mnt is not a directory! Halting...");
|
KPrint("\eE85230/system/mnt is not a directory! Halting...");
|
||||||
CPU::Stop();
|
CPU::Stop();
|
||||||
}
|
}
|
||||||
vfs->Close(mnt);
|
vfs->Close(mnt);
|
||||||
MntFS = mnt->node;
|
MntFS = mnt.node;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!vfs->PathExists("/system/proc"))
|
if (!vfs->PathExists("/system/proc"))
|
||||||
ProcFS = vfs->Create("/system/proc", NodeFlags::DIRECTORY);
|
ProcFS = vfs->Create("/system/proc", NodeFlags::DIRECTORY);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
std::shared_ptr<File> proc = vfs->Open("/system/proc", nullptr);
|
File proc = vfs->Open("/system/proc", nullptr);
|
||||||
if (proc->node->Flags != NodeFlags::DIRECTORY)
|
if (proc.node->Flags != NodeFlags::DIRECTORY)
|
||||||
{
|
{
|
||||||
KPrint("\eE85230/system/proc is not a directory! Halting...");
|
KPrint("\eE85230/system/proc is not a directory! Halting...");
|
||||||
CPU::Stop();
|
CPU::Stop();
|
||||||
}
|
}
|
||||||
vfs->Close(proc);
|
vfs->Close(proc);
|
||||||
ProcFS = proc->node;
|
ProcFS = proc.node;
|
||||||
}
|
}
|
||||||
|
|
||||||
KPrint("\e058C19################################");
|
KPrint("\e058C19################################");
|
||||||
|
@ -176,17 +176,17 @@ void BootLogoAnimationThread()
|
|||||||
while (FrameCount < 27)
|
while (FrameCount < 27)
|
||||||
{
|
{
|
||||||
sprintf(BootAnimPath, "%d.tga", FrameCount);
|
sprintf(BootAnimPath, "%d.tga", FrameCount);
|
||||||
std::shared_ptr<File> ba = bootanim_vfs->Open(BootAnimPath);
|
File ba = bootanim_vfs->Open(BootAnimPath);
|
||||||
if (ba->Status != FileStatus::OK)
|
if (!ba.IsOK())
|
||||||
{
|
{
|
||||||
bootanim_vfs->Close(ba);
|
bootanim_vfs->Close(ba);
|
||||||
debug("Failed to load boot animation frame %s", BootAnimPath);
|
debug("Failed to load boot animation frame %s", BootAnimPath);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
FrameSizes[FrameCount] = s_cst(uint32_t, ba->node->Length);
|
FrameSizes[FrameCount] = s_cst(uint32_t, ba.node->Length);
|
||||||
Frames[FrameCount] = new uint8_t[ba->node->Length];
|
Frames[FrameCount] = new uint8_t[ba.node->Length];
|
||||||
memcpy((void *)Frames[FrameCount], (void *)ba->node->Address, ba->node->Length);
|
memcpy((void *)Frames[FrameCount], (void *)ba.node->Address, ba.node->Length);
|
||||||
bootanim_vfs->Close(ba);
|
bootanim_vfs->Close(ba);
|
||||||
FrameCount++;
|
FrameCount++;
|
||||||
}
|
}
|
||||||
|
@ -70,25 +70,25 @@ namespace Recovery
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<VirtualFileSystem::File> pcm = vfs->Open(AudioFile);
|
VirtualFileSystem::File pcm = vfs->Open(AudioFile);
|
||||||
|
|
||||||
if (pcm->Status != FileStatus::OK)
|
if (!pcm.IsOK())
|
||||||
{
|
{
|
||||||
error("Cannot open audio file! Cannot play audio!");
|
error("Cannot open audio file! Cannot play audio!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *PCMRaw = KernelAllocator.RequestPages(TO_PAGES(pcm->node->Length + 1));
|
void *PCMRaw = KernelAllocator.RequestPages(TO_PAGES(pcm.node->Length + 1));
|
||||||
memcpy(PCMRaw, (void *)pcm->node->Address, pcm->node->Length);
|
memcpy(PCMRaw, (void *)pcm.node->Address, pcm.node->Length);
|
||||||
|
|
||||||
KernelCallback callback{};
|
KernelCallback callback{};
|
||||||
callback.Reason = SendReason;
|
callback.Reason = SendReason;
|
||||||
callback.AudioCallback.Send.Data = (uint8_t *)PCMRaw;
|
callback.AudioCallback.Send.Data = (uint8_t *)PCMRaw;
|
||||||
callback.AudioCallback.Send.Length = pcm->node->Length;
|
callback.AudioCallback.Send.Length = pcm.node->Length;
|
||||||
debug("Playing audio...");
|
debug("Playing audio...");
|
||||||
int status = DriverManager->IOCB(AudioDrv.DriverUID, &callback);
|
int status = DriverManager->IOCB(AudioDrv.DriverUID, &callback);
|
||||||
debug("Audio played! %d", status);
|
debug("Audio played! %d", status);
|
||||||
KernelAllocator.FreePages((void *)PCMRaw, TO_PAGES(pcm->node->Length + 1));
|
KernelAllocator.FreePages((void *)PCMRaw, TO_PAGES(pcm.node->Length + 1));
|
||||||
vfs->Close(pcm);
|
vfs->Close(pcm);
|
||||||
TEXIT(0);
|
TEXIT(0);
|
||||||
}
|
}
|
||||||
|
@ -125,15 +125,15 @@ namespace Execute
|
|||||||
uintptr_t LoadELFInterpreter(Memory::MemMgr *mem, Memory::Virtual &pV, const char *Interpreter);
|
uintptr_t LoadELFInterpreter(Memory::MemMgr *mem, Memory::Virtual &pV, const char *Interpreter);
|
||||||
|
|
||||||
ELFBaseLoad ELFLoadRel(void *ElfFile,
|
ELFBaseLoad ELFLoadRel(void *ElfFile,
|
||||||
VirtualFileSystem::File *ExFile,
|
VirtualFileSystem::File &ExFile,
|
||||||
Tasking::PCB *Process);
|
Tasking::PCB *Process);
|
||||||
|
|
||||||
ELFBaseLoad ELFLoadExec(void *ElfFile,
|
ELFBaseLoad ELFLoadExec(void *ElfFile,
|
||||||
VirtualFileSystem::File *ExFile,
|
VirtualFileSystem::File &ExFile,
|
||||||
Tasking::PCB *Process);
|
Tasking::PCB *Process);
|
||||||
|
|
||||||
ELFBaseLoad ELFLoadDyn(void *ElfFile,
|
ELFBaseLoad ELFLoadDyn(void *ElfFile,
|
||||||
VirtualFileSystem::File *ExFile,
|
VirtualFileSystem::File &ExFile,
|
||||||
Tasking::PCB *Process);
|
Tasking::PCB *Process);
|
||||||
|
|
||||||
void StartExecuteService();
|
void StartExecuteService();
|
||||||
|
@ -19,7 +19,6 @@
|
|||||||
#define __FENNIX_KERNEL_FILESYSTEM_H__
|
#define __FENNIX_KERNEL_FILESYSTEM_H__
|
||||||
|
|
||||||
#include <types.h>
|
#include <types.h>
|
||||||
|
|
||||||
#include <smart_ptr.hpp>
|
#include <smart_ptr.hpp>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
@ -129,6 +128,8 @@ namespace VirtualFileSystem
|
|||||||
char Name[FILENAME_LENGTH];
|
char Name[FILENAME_LENGTH];
|
||||||
FileStatus Status;
|
FileStatus Status;
|
||||||
Node *node;
|
Node *node;
|
||||||
|
|
||||||
|
bool IsOK() { return Status == FileStatus::OK; }
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Manage / etc.. */
|
/* Manage / etc.. */
|
||||||
@ -140,7 +141,14 @@ namespace VirtualFileSystem
|
|||||||
public:
|
public:
|
||||||
std::shared_ptr<char> GetPathFromNode(Node *node);
|
std::shared_ptr<char> GetPathFromNode(Node *node);
|
||||||
Node *GetNodeFromPath(const char *Path, Node *Parent = nullptr);
|
Node *GetNodeFromPath(const char *Path, Node *Parent = nullptr);
|
||||||
std::shared_ptr<File> ConvertNodeToFILE(Node *node);
|
|
||||||
|
/**
|
||||||
|
* @brief Convert a Node to a File
|
||||||
|
*
|
||||||
|
* @param node Node to convert
|
||||||
|
* @return Converted node
|
||||||
|
*/
|
||||||
|
File ConvertNodeToFILE(Node *node);
|
||||||
|
|
||||||
Node *GetParent(const char *Path, Node *Parent);
|
Node *GetParent(const char *Path, Node *Parent);
|
||||||
Node *GetRootNode() { return FileSystemRoot; }
|
Node *GetRootNode() { return FileSystemRoot; }
|
||||||
@ -157,14 +165,14 @@ namespace VirtualFileSystem
|
|||||||
FileStatus Delete(const char *Path, bool Recursive = false, Node *Parent = nullptr);
|
FileStatus Delete(const char *Path, bool Recursive = false, Node *Parent = nullptr);
|
||||||
FileStatus Delete(Node *Path, bool Recursive = false, Node *Parent = nullptr);
|
FileStatus Delete(Node *Path, bool Recursive = false, Node *Parent = nullptr);
|
||||||
|
|
||||||
std::shared_ptr<File> Mount(const char *Path, FileSystemOperations *Operator);
|
File Mount(const char *Path, FileSystemOperations *Operator);
|
||||||
FileStatus Unmount(std::shared_ptr<File> File);
|
FileStatus Unmount(File &File);
|
||||||
|
|
||||||
size_t Read(std::shared_ptr<File> File, size_t Offset, uint8_t *Buffer, size_t Size);
|
size_t Read(File &File, size_t Offset, uint8_t *Buffer, size_t Size);
|
||||||
size_t Write(std::shared_ptr<File> File, size_t Offset, uint8_t *Buffer, size_t Size);
|
size_t Write(File &File, size_t Offset, uint8_t *Buffer, size_t Size);
|
||||||
|
|
||||||
std::shared_ptr<File> Open(const char *Path, Node *Parent = nullptr);
|
File Open(const char *Path, Node *Parent = nullptr);
|
||||||
FileStatus Close(std::shared_ptr<File> File);
|
FileStatus Close(File &File);
|
||||||
|
|
||||||
Virtual();
|
Virtual();
|
||||||
~Virtual();
|
~Virtual();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user