128 lines
4.7 KiB
C++
128 lines
4.7 KiB
C++
/*
|
|
* Boot.cpp
|
|
* Boot-time filesystem initialization
|
|
* Copyright (c) 2026 Daniel Hammer
|
|
*/
|
|
|
|
#include "Boot.hpp"
|
|
#include <Terminal/Terminal.hpp>
|
|
#include <Fs/Ramdisk.hpp>
|
|
#include <Fs/Vfs.hpp>
|
|
#include <Fs/Fat32.hpp>
|
|
#include <Fs/Ext2.hpp>
|
|
#include <Fs/FsProbe.hpp>
|
|
|
|
namespace Fs {
|
|
|
|
namespace {
|
|
|
|
bool StringsEqual(const char* lhs, const char* rhs) {
|
|
if (lhs == nullptr || rhs == nullptr) return false;
|
|
|
|
while (*lhs != '\0' && *rhs != '\0') {
|
|
if (*lhs != *rhs) return false;
|
|
lhs++;
|
|
rhs++;
|
|
}
|
|
|
|
return *lhs == *rhs;
|
|
}
|
|
|
|
bool InitializeRamdiskFromModules(const montauk::boot::ModuleList& modules) {
|
|
if (modules.modules == nullptr || modules.count == 0) {
|
|
Kt::KernelLogStream(Kt::WARNING, "Modules") << "No modules loaded (ramdisk unavailable)";
|
|
return false;
|
|
}
|
|
|
|
Kt::KernelLogStream(Kt::OK, "Modules")
|
|
<< "Found " << modules.count << " module(s)";
|
|
|
|
bool hasRamdisk = false;
|
|
for (uint64_t i = 0; i < modules.count; i++) {
|
|
const montauk::boot::Module& module = modules.modules[i];
|
|
if (!StringsEqual(module.name, "ramdisk")) {
|
|
continue;
|
|
}
|
|
|
|
Kt::KernelLogStream(Kt::OK, "Modules")
|
|
<< "Ramdisk module at " << kcp::hex << (uint64_t)module.address
|
|
<< kcp::dec << ", size=" << module.size;
|
|
Ramdisk::Initialize(module.address, module.size);
|
|
hasRamdisk = true;
|
|
}
|
|
|
|
return hasRamdisk;
|
|
}
|
|
|
|
// The ramdisk is a singleton, so it has no per-mount state and ignores
|
|
// ctx. These shims exist only to match the FsDriver signature.
|
|
int RdOpen(void*, const char* p) { return Ramdisk::Open(p); }
|
|
int RdRead(void*, int h, uint8_t* b, uint64_t o, uint64_t s) { return Ramdisk::Read(h, b, o, s); }
|
|
uint64_t RdGetSize(void*, int h) { return Ramdisk::GetSize(h); }
|
|
void RdClose(void*, int h) { Ramdisk::Close(h); }
|
|
int RdReadDir(void*, const char* p, const char** o, int m) { return Ramdisk::ReadDir(p, o, m); }
|
|
int RdWrite(void*, int h, const uint8_t* b, uint64_t o, uint64_t s) { return Ramdisk::Write(h, b, o, s); }
|
|
int RdCreate(void*, const char* p) { return Ramdisk::Create(p); }
|
|
int RdDelete(void*, const char* p) { return Ramdisk::Delete(p); }
|
|
int RdMkdir(void*, const char* p) { return Ramdisk::Mkdir(p); }
|
|
int RdRename(void*, const char* o, const char* n) { return Ramdisk::Rename(o, n); }
|
|
const char* RdGetLabel(void*) { return Ramdisk::GetLabel(); }
|
|
const char* RdGetFsType(void*) { return "ramdisk"; }
|
|
int RdReadDirAt(void*, const char* p, const char** o, int m, int s) { return Ramdisk::ReadDirAt(p, o, m, s); }
|
|
|
|
int RdStat(void*, const char* p, Vfs::StatInfo* out) {
|
|
if (out == nullptr) return -1;
|
|
|
|
Ramdisk::StatResult st;
|
|
if (Ramdisk::Stat(p, &st) != 0) return -1;
|
|
|
|
out->size = st.size;
|
|
// The USTAR header carries a single timestamp; report it for all
|
|
// three rather than leaving ctime/atime at the epoch.
|
|
out->mtime = st.mtime;
|
|
out->ctime = st.mtime;
|
|
out->atime = st.mtime;
|
|
out->mode = (st.isDirectory ? Vfs::ModeDir : Vfs::ModeReg) | (st.mode & 07777);
|
|
out->isDir = st.isDirectory;
|
|
return 0;
|
|
}
|
|
|
|
Vfs::FsDriver g_ramdiskDriver = {
|
|
.ctx = nullptr,
|
|
.Open = RdOpen,
|
|
.Read = RdRead,
|
|
.GetSize = RdGetSize,
|
|
.Close = RdClose,
|
|
.ReadDir = RdReadDir,
|
|
.Write = RdWrite,
|
|
.Create = RdCreate,
|
|
.Delete = RdDelete,
|
|
.Mkdir = RdMkdir,
|
|
.Rename = RdRename,
|
|
.GetLabel = RdGetLabel,
|
|
.GetFsType = RdGetFsType,
|
|
.ReadDirAt = RdReadDirAt,
|
|
.Stat = RdStat,
|
|
.SetTimes = nullptr,
|
|
// Statically allocated: nothing to release.
|
|
.Unmount = nullptr,
|
|
};
|
|
|
|
}
|
|
|
|
void InitializeBootFilesystems(const montauk::boot::ModuleList& modules) {
|
|
bool hasRamdisk = InitializeRamdiskFromModules(modules);
|
|
|
|
Vfs::Initialize();
|
|
if (hasRamdisk) {
|
|
Vfs::RegisterDrive(0, &g_ramdiskDriver);
|
|
}
|
|
|
|
// When no ramdisk, disk partitions start at drive 0 so init.elf is found there.
|
|
Fat32::RegisterProbe();
|
|
Ext2::RegisterProbe();
|
|
FsProbe::MountPartitions(hasRamdisk ? 1 : 0);
|
|
}
|
|
|
|
}
|