mirror of
https://github.com/EnderIce2/Fennix.git
synced 2025-05-28 15:34:31 +00:00
refactor(kernel): ramfs loading
This commit is contained in:
parent
b1a30059ed
commit
d4346202ca
@ -139,6 +139,14 @@ namespace vfs
|
||||
|
||||
public:
|
||||
vfsInode *FileSystemRoots = nullptr;
|
||||
|
||||
/**
|
||||
* Default reserved roots:
|
||||
*
|
||||
* 0 - Native
|
||||
* 1 - Linux
|
||||
* 2 - Windows
|
||||
*/
|
||||
std::unordered_map<ino_t, FileNode *> FileRoots;
|
||||
|
||||
bool PathIsRelative(const char *Path);
|
||||
|
@ -127,11 +127,11 @@ namespace vfs
|
||||
bool TestArchive(uintptr_t Address);
|
||||
void ReadArchive(uintptr_t Address, size_t Size);
|
||||
|
||||
USTAR(){};
|
||||
~USTAR(){};
|
||||
USTAR() = default;
|
||||
~USTAR() = default;
|
||||
};
|
||||
}
|
||||
|
||||
bool TestAndInitializeUSTAR(uintptr_t Address, size_t Size);
|
||||
bool TestAndInitializeUSTAR(uintptr_t Address, size_t Size, size_t Index);
|
||||
|
||||
#endif // !__FENNIX_KERNEL_FILESYSTEM_USTAR_H__
|
||||
|
@ -31,30 +31,72 @@
|
||||
#include <vm.hpp>
|
||||
#include <vector>
|
||||
|
||||
cold int SpawnInit()
|
||||
int SpawnNativeInit()
|
||||
{
|
||||
const char *envp[] = {
|
||||
"PATH=/sys/bin:/usr/bin",
|
||||
"LD_LIBRARY_PATH=/sys/lib:/usr/lib",
|
||||
"TERM=tty",
|
||||
"HOME=/home/root",
|
||||
"USER=root",
|
||||
"TZ=UTC",
|
||||
nullptr};
|
||||
|
||||
const char *argv[] = {Config.InitPath, nullptr};
|
||||
|
||||
return Execute::Spawn(Config.InitPath, argv, envp, nullptr, false, Tasking::Native, true);
|
||||
}
|
||||
|
||||
int SpawnLinuxInit()
|
||||
{
|
||||
const char *envp[] = {
|
||||
"PATH=/bin:/usr/bin",
|
||||
"LD_LIBRARY_PATH=/sys/lib:/usr/lib",
|
||||
"LD_LIBRARY_PATH=/lib:/usr/lib",
|
||||
"TERM=tty",
|
||||
"HOME=/root",
|
||||
"USER=root",
|
||||
"TZ=UTC",
|
||||
nullptr};
|
||||
|
||||
const char *argv[] = {
|
||||
Config.InitPath,
|
||||
nullptr};
|
||||
std::string init = Config.InitPath;
|
||||
std::vector<std::string> fallbackPaths = {
|
||||
init,
|
||||
"/bin/init",
|
||||
"/sbin/init",
|
||||
"/system/init",
|
||||
"/usr/bin/init",
|
||||
"/boot/init",
|
||||
"/startup/init"};
|
||||
|
||||
Tasking::TaskCompatibility compat = Tasking::Native;
|
||||
if (Config.LinuxSubsystem)
|
||||
compat = Tasking::Linux;
|
||||
const char *foundPath = nullptr;
|
||||
for (const std::string &path : fallbackPaths)
|
||||
{
|
||||
if (!fs->PathExists(path.c_str(), fs->GetRoot(1)))
|
||||
continue;
|
||||
|
||||
return Execute::Spawn(Config.InitPath, argv, envp,
|
||||
nullptr, false, compat, true);
|
||||
foundPath = path.c_str();
|
||||
break;
|
||||
}
|
||||
|
||||
if (!foundPath)
|
||||
{
|
||||
error("No valid init found in fallback paths");
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
const char *argv[] = {foundPath, nullptr};
|
||||
return Execute::Spawn(foundPath, argv, envp, nullptr, false, Tasking::Linux, true);
|
||||
}
|
||||
|
||||
cold void KernelMainThread()
|
||||
int SpawnInit()
|
||||
{
|
||||
if (Config.LinuxSubsystem)
|
||||
return SpawnLinuxInit();
|
||||
else
|
||||
return SpawnNativeInit();
|
||||
}
|
||||
|
||||
void KernelMainThread()
|
||||
{
|
||||
thisThread->SetPriority(Tasking::Critical);
|
||||
|
||||
@ -129,7 +171,7 @@ Exit:
|
||||
}
|
||||
|
||||
NewLock(ShutdownLock);
|
||||
cold void __no_stack_protector KernelShutdownThread(bool Reboot)
|
||||
void __no_stack_protector KernelShutdownThread(bool Reboot)
|
||||
{
|
||||
SmartLock(ShutdownLock);
|
||||
debug("KernelShutdownThread(%s)", Reboot ? "true" : "false");
|
||||
|
@ -26,26 +26,26 @@ void SearchForInitrd()
|
||||
{
|
||||
for (size_t i = 0; i < MAX_MODULES; i++)
|
||||
{
|
||||
uintptr_t initrdAddress = (uintptr_t)bInfo.Modules[i].Address;
|
||||
uintptr_t moduleAddress = (uintptr_t)bInfo.Modules[i].Address;
|
||||
size_t moduleSize = bInfo.Modules[i].Size;
|
||||
const char *moduleCommand = bInfo.Modules[i].CommandLine;
|
||||
|
||||
if (!initrdAddress)
|
||||
if (moduleAddress == 0)
|
||||
continue;
|
||||
|
||||
if (strcmp(bInfo.Modules[i].CommandLine, "rootfs") != 0)
|
||||
continue;
|
||||
|
||||
KPrint("rootfs found at %#lx", initrdAddress);
|
||||
|
||||
Memory::Virtual vmm;
|
||||
if (!vmm.Check((void *)initrdAddress))
|
||||
if (!vmm.CheckRegion((void *)moduleAddress, moduleSize))
|
||||
{
|
||||
warn("Initrd is not mapped!");
|
||||
vmm.Map((void *)initrdAddress, (void *)initrdAddress,
|
||||
bInfo.Modules[i].Size, Memory::RW);
|
||||
warn("module entry is not mapped!");
|
||||
vmm.Map((void *)moduleAddress, (void *)moduleAddress, moduleSize, Memory::RW);
|
||||
}
|
||||
|
||||
if (TestAndInitializeUSTAR(initrdAddress, bInfo.Modules[i].Size))
|
||||
continue; /* Maybe add another root? */
|
||||
if (strcmp(moduleCommand, "rootfs") == 0)
|
||||
{
|
||||
KPrint("rootfs found at %#lx", moduleAddress);
|
||||
if (TestAndInitializeUSTAR(moduleAddress, moduleSize, 0))
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -16,7 +16,6 @@
|
||||
*/
|
||||
|
||||
#include <filesystem/ustar.hpp>
|
||||
|
||||
#include <memory.hpp>
|
||||
#include <functional>
|
||||
#include <debug.h>
|
||||
@ -160,10 +159,14 @@ namespace vfs
|
||||
node->Name.assign(basename, length);
|
||||
node->Path.assign(Name, strlen(Name));
|
||||
|
||||
Files.insert(std::make_pair(NextInode, node));
|
||||
*Result = &Files.at(NextInode)->Node;
|
||||
auto &&file = Files.insert(std::make_pair(NextInode, node));
|
||||
assert(file.second == true);
|
||||
*Result = &file.first->second->Node;
|
||||
if (Parent)
|
||||
Parent->Children.push_back(Files.at(NextInode));
|
||||
{
|
||||
Parent->Children.push_back(file.first->second);
|
||||
file.first->second->Parent = Parent;
|
||||
}
|
||||
NextInode++;
|
||||
return 0;
|
||||
}
|
||||
@ -491,6 +494,10 @@ namespace vfs
|
||||
FileHeader *header = (FileHeader *)Address;
|
||||
if (strncmp(header->signature, TMAGIC, TMAGLEN) != 0)
|
||||
{
|
||||
/* For some reason if GRUB inflates the archive, the magic is "ustar " */
|
||||
if (strncmp(header->signature, TMAGIC, TMAGLEN - 1) == 0)
|
||||
return true;
|
||||
|
||||
error("Invalid signature!");
|
||||
return false;
|
||||
}
|
||||
@ -564,7 +571,7 @@ namespace vfs
|
||||
|
||||
FileHeader *header = (FileHeader *)Address;
|
||||
|
||||
debug("USTAR signature valid! Name:%s Signature:%s Mode:%d Size:%lu",
|
||||
debug("USTAR signature valid! Name:\"%s\" Signature:\"%s\" Mode:%d Size:%lu",
|
||||
header->name, header->signature, StringToInt(header->mode), header->size);
|
||||
|
||||
Memory::Virtual vmm;
|
||||
@ -577,7 +584,7 @@ namespace vfs
|
||||
return;
|
||||
}
|
||||
|
||||
if (strncmp(header->signature, TMAGIC, TMAGLEN) != 0)
|
||||
if (strncmp(header->signature, TMAGIC, TMAGLEN - 1) != 0)
|
||||
break;
|
||||
// debug("\"%s\"", header->name);
|
||||
|
||||
@ -817,13 +824,13 @@ O2 int __ustar_Stat(struct Inode *Node, kstat *Stat)
|
||||
return ((vfs::USTAR *)Node->PrivateData)->Stat(Node, Stat);
|
||||
}
|
||||
|
||||
int __ustar_DestroyInode(FileSystemInfo *Info, Inode *Node)
|
||||
O2 int __ustar_DestroyInode(FileSystemInfo *Info, Inode *Node)
|
||||
{
|
||||
((vfs::USTAR::USTARInode *)Node)->Deleted = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int __ustar_Destroy(FileSystemInfo *fsi)
|
||||
O2 int __ustar_Destroy(FileSystemInfo *fsi)
|
||||
{
|
||||
assert(fsi->PrivateData);
|
||||
delete (vfs::USTAR *)fsi->PrivateData;
|
||||
@ -831,7 +838,7 @@ int __ustar_Destroy(FileSystemInfo *fsi)
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool TestAndInitializeUSTAR(uintptr_t Address, size_t Size)
|
||||
bool TestAndInitializeUSTAR(uintptr_t Address, size_t Size, size_t Index)
|
||||
{
|
||||
vfs::USTAR *ustar = new vfs::USTAR();
|
||||
if (!ustar->TestArchive(Address))
|
||||
@ -863,6 +870,6 @@ bool TestAndInitializeUSTAR(uintptr_t Address, size_t Size)
|
||||
fsi->PrivateData = ustar;
|
||||
fs->LateRegisterFileSystem(ustar->DeviceID, fsi, rootfs);
|
||||
|
||||
fs->AddRoot(rootfs);
|
||||
fs->AddRootAt(rootfs, Index);
|
||||
return true;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user