feat: GPT, FAT32 driver, disks app, userspace adapted for multiple drives, and more
This commit is contained in:
@@ -72,4 +72,8 @@ namespace Montauk {
|
||||
static int Sys_FCreate(const char* path) {
|
||||
return Fs::Vfs::VfsCreate(path);
|
||||
}
|
||||
|
||||
static int Sys_FDelete(const char* path) {
|
||||
return Fs::Vfs::VfsDelete(path);
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,123 @@
|
||||
/*
|
||||
* Storage.hpp
|
||||
* Storage, GPT, format, and mount syscall implementations
|
||||
* Copyright (c) 2026 Daniel Hammer
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <cstdint>
|
||||
#include <Drivers/Storage/BlockDevice.hpp>
|
||||
#include <Drivers/Storage/Gpt.hpp>
|
||||
#include <Fs/FsProbe.hpp>
|
||||
#include <Fs/Fat32.hpp>
|
||||
|
||||
#include "Syscall.hpp"
|
||||
|
||||
namespace Montauk {
|
||||
|
||||
static void dl_strcpy_s(char* dst, const char* src, int max) {
|
||||
int i = 0;
|
||||
for (; i < max - 1 && src[i]; i++) dst[i] = src[i];
|
||||
dst[i] = '\0';
|
||||
}
|
||||
|
||||
// Fill a user buffer with partition info. Returns the number of entries written.
|
||||
static int Sys_PartList(PartInfo* buf, int maxCount) {
|
||||
if (buf == nullptr || maxCount <= 0) return 0;
|
||||
|
||||
int total = Drivers::Storage::Gpt::GetPartitionCount();
|
||||
int count = total < maxCount ? total : maxCount;
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
auto* p = Drivers::Storage::Gpt::GetPartition(i);
|
||||
if (!p) break;
|
||||
|
||||
buf[i].blockDev = p->BlockDevIndex;
|
||||
buf[i]._pad0 = 0;
|
||||
buf[i].startLba = p->StartLba;
|
||||
buf[i].endLba = p->EndLba;
|
||||
buf[i].sectorCount = p->SectorCount;
|
||||
|
||||
// Copy GUIDs (layout-compatible)
|
||||
__builtin_memcpy(&buf[i].typeGuid, &p->TypeGuid, sizeof(PartGuid));
|
||||
__builtin_memcpy(&buf[i].uniqueGuid, &p->UniqueGuid, sizeof(PartGuid));
|
||||
|
||||
buf[i].attributes = p->Attributes;
|
||||
dl_strcpy_s(buf[i].name, p->Name, 72);
|
||||
dl_strcpy_s(buf[i].typeName,
|
||||
Drivers::Storage::Gpt::GetTypeName(p->TypeGuid), 24);
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
// Read sectors from a block device. Returns bytes read, or -1 on error.
|
||||
static int64_t Sys_DiskRead(int blockDev, uint64_t lba, uint32_t count, void* buffer) {
|
||||
if (buffer == nullptr || count == 0) return -1;
|
||||
if (count > 128) return -1; // same limit as AHCI
|
||||
|
||||
auto* dev = Drivers::Storage::GetBlockDevice(blockDev);
|
||||
if (!dev) return -1;
|
||||
|
||||
if (lba + count > dev->SectorCount) return -1;
|
||||
|
||||
if (!dev->ReadSectors(dev->Ctx, lba, count, buffer)) return -1;
|
||||
|
||||
return (int64_t)(count * dev->SectorSize);
|
||||
}
|
||||
|
||||
// Write sectors to a block device. Returns bytes written, or -1 on error.
|
||||
static int64_t Sys_DiskWrite(int blockDev, uint64_t lba, uint32_t count, const void* buffer) {
|
||||
if (buffer == nullptr || count == 0) return -1;
|
||||
if (count > 128) return -1;
|
||||
|
||||
auto* dev = Drivers::Storage::GetBlockDevice(blockDev);
|
||||
if (!dev) return -1;
|
||||
|
||||
if (lba + count > dev->SectorCount) return -1;
|
||||
|
||||
if (!dev->WriteSectors(dev->Ctx, lba, count, buffer)) return -1;
|
||||
|
||||
return (int64_t)(count * dev->SectorSize);
|
||||
}
|
||||
|
||||
// Initialize a new GPT on a block device. Returns 0 on success, -1 on error.
|
||||
static int64_t Sys_GptInit(int blockDev) {
|
||||
return (int64_t)Drivers::Storage::Gpt::InitializeGpt(blockDev);
|
||||
}
|
||||
|
||||
// Add a partition to an existing GPT. Returns partition index on success, -1 on error.
|
||||
static int64_t Sys_GptAdd(const GptAddParams* params) {
|
||||
if (params == nullptr) return -1;
|
||||
|
||||
Drivers::Storage::Gpt::Guid typeGuid;
|
||||
__builtin_memcpy(&typeGuid, ¶ms->typeGuid, sizeof(typeGuid));
|
||||
|
||||
return (int64_t)Drivers::Storage::Gpt::AddPartition(
|
||||
params->blockDev, params->startLba, params->endLba,
|
||||
typeGuid, params->name);
|
||||
}
|
||||
|
||||
// Mount a partition as a VFS drive. Returns 0 on success, -1 on error.
|
||||
static int64_t Sys_FsMount(int partIndex, int driveNum) {
|
||||
return (int64_t)Fs::FsProbe::MountPartition(partIndex, driveNum);
|
||||
}
|
||||
|
||||
// Format a partition with a filesystem. Returns 0 on success, -1 on error.
|
||||
static int64_t Sys_FsFormat(const FsFormatParams* params) {
|
||||
if (params == nullptr) return -1;
|
||||
|
||||
auto* part = Drivers::Storage::Gpt::GetPartition(params->partIndex);
|
||||
if (!part) return -1;
|
||||
|
||||
switch (params->fsType) {
|
||||
case FS_TYPE_FAT32:
|
||||
return (int64_t)Fs::Fat32::Format(
|
||||
part->BlockDevIndex, part->StartLba, part->SectorCount,
|
||||
params->label[0] ? params->label : nullptr);
|
||||
default:
|
||||
return -1; // unknown filesystem type
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
@@ -27,7 +27,8 @@
|
||||
#include "IoRedir.hpp" // SYS_SPAWN_REDIR, SYS_CHILDIO_READ, SYS_CHILDIO_WRITE, SYS_CHILDIO_WRITEKEY, SYS_CHILDIO_SETTERMSZ
|
||||
#include "Random.hpp" // SYS_GETRANDOM
|
||||
#include "MemInfo.hpp" // SYS_MEMSTATS
|
||||
#include "Device.hpp" // SYS_DEVLIST
|
||||
#include "Device.hpp" // SYS_DEVLIST, SYS_DISKINFO
|
||||
#include "Storage.hpp" // SYS_PARTLIST, SYS_DISKREAD, SYS_DISKWRITE
|
||||
#include "Window.hpp" // SYS_WINCREATE, SYS_WINDESTROY, SYS_WINPRESENT, SYS_WINPOLL, SYS_WINENUM, SYS_WINMAP, SYS_WINSENDEVENT, SYS_WINRESIZE, SYS_WINSETSCALE, SYS_WINGETSCALE
|
||||
|
||||
// Assembly entry point
|
||||
@@ -154,6 +155,8 @@ namespace Montauk {
|
||||
frame->arg3, frame->arg4);
|
||||
case SYS_FCREATE:
|
||||
return (int64_t)Sys_FCreate((const char*)frame->arg1);
|
||||
case SYS_FDELETE:
|
||||
return (int64_t)Sys_FDelete((const char*)frame->arg1);
|
||||
case SYS_TERMSCALE:
|
||||
return Sys_TermScale(frame->arg1, frame->arg2);
|
||||
case SYS_RESOLVE:
|
||||
@@ -220,6 +223,22 @@ namespace Montauk {
|
||||
case SYS_MEMSTATS:
|
||||
Sys_MemStats((MemStats*)frame->arg1);
|
||||
return 0;
|
||||
case SYS_PARTLIST:
|
||||
return (int64_t)Sys_PartList((PartInfo*)frame->arg1, (int)frame->arg2);
|
||||
case SYS_DISKREAD:
|
||||
return (int64_t)Sys_DiskRead((int)frame->arg1, frame->arg2,
|
||||
(uint32_t)frame->arg3, (void*)frame->arg4);
|
||||
case SYS_DISKWRITE:
|
||||
return (int64_t)Sys_DiskWrite((int)frame->arg1, frame->arg2,
|
||||
(uint32_t)frame->arg3, (const void*)frame->arg4);
|
||||
case SYS_GPTINIT:
|
||||
return (int64_t)Sys_GptInit((int)frame->arg1);
|
||||
case SYS_GPTADD:
|
||||
return (int64_t)Sys_GptAdd((const GptAddParams*)frame->arg1);
|
||||
case SYS_FSMOUNT:
|
||||
return (int64_t)Sys_FsMount((int)frame->arg1, (int)frame->arg2);
|
||||
case SYS_FSFORMAT:
|
||||
return (int64_t)Sys_FsFormat((const FsFormatParams*)frame->arg1);
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -90,6 +90,7 @@ namespace Montauk {
|
||||
/* Filesystem.hpp */
|
||||
static constexpr uint64_t SYS_FWRITE = 41;
|
||||
static constexpr uint64_t SYS_FCREATE = 42;
|
||||
static constexpr uint64_t SYS_FDELETE = 77;
|
||||
|
||||
/* Graphics.hpp */
|
||||
static constexpr uint64_t SYS_TERMSCALE = 43;
|
||||
@@ -137,6 +138,15 @@ namespace Montauk {
|
||||
/* MemInfo.hpp */
|
||||
static constexpr uint64_t SYS_MEMSTATS = 67;
|
||||
|
||||
/* Storage.hpp */
|
||||
static constexpr uint64_t SYS_PARTLIST = 70;
|
||||
static constexpr uint64_t SYS_DISKREAD = 71;
|
||||
static constexpr uint64_t SYS_DISKWRITE = 72;
|
||||
static constexpr uint64_t SYS_GPTINIT = 73;
|
||||
static constexpr uint64_t SYS_GPTADD = 74;
|
||||
static constexpr uint64_t SYS_FSMOUNT = 75;
|
||||
static constexpr uint64_t SYS_FSFORMAT = 76;
|
||||
|
||||
static constexpr int SOCK_TCP = 1;
|
||||
static constexpr int SOCK_UDP = 2;
|
||||
|
||||
@@ -254,6 +264,44 @@ namespace Montauk {
|
||||
char _pad2[1];
|
||||
};
|
||||
|
||||
struct PartGuid {
|
||||
uint32_t Data1;
|
||||
uint16_t Data2;
|
||||
uint16_t Data3;
|
||||
uint8_t Data4[8];
|
||||
};
|
||||
|
||||
struct PartInfo {
|
||||
int32_t blockDev; // block device index
|
||||
uint32_t _pad0;
|
||||
uint64_t startLba;
|
||||
uint64_t endLba;
|
||||
uint64_t sectorCount;
|
||||
PartGuid typeGuid;
|
||||
PartGuid uniqueGuid;
|
||||
uint64_t attributes;
|
||||
char name[72]; // ASCII partition name
|
||||
char typeName[24]; // human-readable type name
|
||||
};
|
||||
|
||||
struct GptAddParams {
|
||||
int32_t blockDev;
|
||||
uint32_t _pad0;
|
||||
uint64_t startLba; // 0 = auto (fill largest free region)
|
||||
uint64_t endLba; // 0 = auto
|
||||
PartGuid typeGuid;
|
||||
char name[72];
|
||||
};
|
||||
|
||||
// Filesystem type IDs for SYS_FSFORMAT
|
||||
static constexpr int FS_TYPE_FAT32 = 1;
|
||||
|
||||
struct FsFormatParams {
|
||||
int32_t partIndex; // global partition index
|
||||
int32_t fsType; // FS_TYPE_FAT32, etc.
|
||||
char label[32]; // volume label
|
||||
};
|
||||
|
||||
struct ProcInfo {
|
||||
int32_t pid;
|
||||
int32_t parentPid;
|
||||
|
||||
Reference in New Issue
Block a user