feat: GPT, FAT32 driver, disks app, userspace adapted for multiple drives, and more

This commit is contained in:
2026-03-07 15:58:27 +01:00
parent 8c5c259f5d
commit 4d0177d55e
48 changed files with 5777 additions and 873 deletions
+48
View File
@@ -54,6 +54,7 @@ namespace Montauk {
static constexpr uint64_t SYS_RECVFROM = 40;
static constexpr uint64_t SYS_FWRITE = 41;
static constexpr uint64_t SYS_FCREATE = 42;
static constexpr uint64_t SYS_FDELETE = 77;
static constexpr uint64_t SYS_TERMSCALE = 43;
static constexpr uint64_t SYS_RESOLVE = 44;
static constexpr uint64_t SYS_GETRANDOM = 45;
@@ -88,6 +89,15 @@ namespace Montauk {
// Kernel introspection syscalls
static constexpr uint64_t SYS_MEMSTATS = 67;
// Storage / partition syscalls
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;
@@ -198,6 +208,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;
+4
View File
@@ -76,6 +76,9 @@ struct DesktopState {
SvgIcon icon_folder_lg;
SvgIcon icon_file_lg;
SvgIcon icon_exec_lg;
SvgIcon icon_drive;
SvgIcon icon_drive_lg;
SvgIcon icon_delete;
SvgIcon icon_settings;
SvgIcon icon_reboot;
@@ -88,6 +91,7 @@ struct DesktopState {
SvgIcon icon_mandelbrot;
SvgIcon icon_devexplorer;
SvgIcon icon_spreadsheet;
SvgIcon icon_disks;
bool ctx_menu_open;
int ctx_menu_x, ctx_menu_y;
+70 -1
View File
@@ -161,6 +161,23 @@ inline int svg_parse_fixed(const char* s, fixed_t* out) {
val += (int32_t)(((int64_t)frac << 16) / frac_div);
}
// Scientific notation (e.g. 2e-3, 7e-3)
if (*p == 'e' || *p == 'E') {
++p;
bool exp_neg = false;
if (*p == '-') { exp_neg = true; ++p; }
else if (*p == '+') { ++p; }
int exp_val = 0;
while (*p >= '0' && *p <= '9') {
exp_val = exp_val * 10 + (*p - '0');
++p;
}
for (int i = 0; i < exp_val; i++) {
if (exp_neg) val /= 10;
else val *= 10;
}
}
if (neg) val = -val;
*out = val;
return (int)(p - s);
@@ -1207,6 +1224,12 @@ inline SvgIcon svg_render(const char* svg_data, int svg_len, int target_w, int t
// Heap-allocated path data buffer (avoids 8 KiB on the stack)
char* d_buf = (char*)montauk::malloc(SVG_MAX_PATH_LEN);
// Group fill inheritance stack: track <g fill="..."> so child elements inherit
static constexpr int MAX_GROUP_DEPTH = 8;
struct GroupFill { Color color; bool has_fill; };
GroupFill g_stack[MAX_GROUP_DEPTH];
int g_depth = 0;
// Scan for <path, <circle, <rect elements — rasterize each individually
// Skip elements inside <defs> blocks (they define reusable items, not rendered directly)
const char* p = svg_data;
@@ -1230,6 +1253,42 @@ inline SvgIcon svg_render(const char* svg_data, int svg_len, int target_w, int t
continue;
}
// Track </g> closing tags to pop the group fill stack
if (remaining > 3 && svg_strncmp(p, "</g>", 4)) {
if (g_depth > 0) g_depth--;
p += 4;
continue;
}
// Track <g> opening tags for fill inheritance
if (remaining > 2 && svg_strncmp(p, "<g", 2) && (svg_char_is_ws(p[2]) || p[2] == '>')) {
const char* g_start = p;
const char* g_end = p;
while (g_end < end && *g_end != '>') ++g_end;
if (g_end < end) ++g_end;
int g_len = (int)(g_end - g_start);
if (g_depth < MAX_GROUP_DEPTH) {
g_stack[g_depth].has_fill = false;
Color gc = fill_color;
char fbuf[64];
int fLen = svg_get_attr(g_start, g_len, " fill", fbuf, sizeof(fbuf));
if (fLen > 0) {
int fr = svg_resolve_fill_value(fbuf, &gc, &grads);
if (fr == 1) {
g_stack[g_depth].color = gc;
g_stack[g_depth].has_fill = true;
} else if (fr == -1) {
// fill="none" on group — children inherit none
g_stack[g_depth].has_fill = false;
}
}
g_depth++;
}
p = g_end;
continue;
}
// Check for <path
if (remaining > 5 && svg_strncmp(p, "<path", 5) && (svg_char_is_ws(p[5]) || p[5] == '/')) {
const char* elem_start = p;
@@ -1244,8 +1303,12 @@ inline SvgIcon svg_render(const char* svg_data, int svg_len, int target_w, int t
continue;
}
// Determine fill color for this element
// Determine fill color: element's own fill, or inherit from nearest <g>
Color elem_color = fill_color;
// Apply inherited group fill as default
for (int gi = g_depth - 1; gi >= 0; gi--) {
if (g_stack[gi].has_fill) { elem_color = g_stack[gi].color; break; }
}
int fillResult = svg_get_element_fill(elem_start, elem_len, &elem_color, &grads, &css);
if (fillResult == -1) { p = elem_end; continue; } // fill="none"
@@ -1278,6 +1341,9 @@ inline SvgIcon svg_render(const char* svg_data, int svg_len, int target_w, int t
}
Color elem_color = fill_color;
for (int gi = g_depth - 1; gi >= 0; gi--) {
if (g_stack[gi].has_fill) { elem_color = g_stack[gi].color; break; }
}
int fillResult = svg_get_element_fill(elem_start, elem_len, &elem_color, &grads, &css);
if (fillResult == -1) { p = elem_end; continue; }
@@ -1321,6 +1387,9 @@ inline SvgIcon svg_render(const char* svg_data, int svg_len, int target_w, int t
}
Color elem_color = fill_color;
for (int gi = g_depth - 1; gi >= 0; gi--) {
if (g_stack[gi].has_fill) { elem_color = g_stack[gi].color; break; }
}
int fillResult = svg_get_element_fill(elem_start, elem_len, &elem_color, &grads, &css);
if (fillResult == -1) { p = elem_end; continue; }
+32
View File
@@ -143,6 +143,9 @@ namespace montauk {
inline int fcreate(const char* path) {
return (int)syscall1(Montauk::SYS_FCREATE, (uint64_t)path);
}
inline int fdelete(const char* path) {
return (int)syscall1(Montauk::SYS_FDELETE, (uint64_t)path);
}
// Memory
inline void* alloc(uint64_t size) { return (void*)syscall1(Montauk::SYS_ALLOC, size); }
@@ -298,6 +301,35 @@ namespace montauk {
return (int)syscall2(Montauk::SYS_DISKINFO, (uint64_t)buf, (uint64_t)port);
}
// Partition table
inline int partlist(Montauk::PartInfo* buf, int max) {
return (int)syscall2(Montauk::SYS_PARTLIST, (uint64_t)buf, (uint64_t)max);
}
// Raw block device I/O (driver-agnostic)
inline int64_t disk_read(int blockDev, uint64_t lba, uint32_t sectorCount, void* buf) {
return syscall4(Montauk::SYS_DISKREAD, (uint64_t)blockDev, lba,
(uint64_t)sectorCount, (uint64_t)buf);
}
inline int64_t disk_write(int blockDev, uint64_t lba, uint32_t sectorCount, const void* buf) {
return syscall4(Montauk::SYS_DISKWRITE, (uint64_t)blockDev, lba,
(uint64_t)sectorCount, (uint64_t)buf);
}
// GPT management
inline int gpt_init(int blockDev) {
return (int)syscall1(Montauk::SYS_GPTINIT, (uint64_t)blockDev);
}
inline int gpt_add(const Montauk::GptAddParams* params) {
return (int)syscall1(Montauk::SYS_GPTADD, (uint64_t)params);
}
inline int fs_mount(int partIndex, int driveNum) {
return (int)syscall2(Montauk::SYS_FSMOUNT, (uint64_t)partIndex, (uint64_t)driveNum);
}
inline int fs_format(const Montauk::FsFormatParams* params) {
return (int)syscall1(Montauk::SYS_FSFORMAT, (uint64_t)params);
}
// Kernel introspection
inline void memstats(Montauk::MemStats* out) { syscall1(Montauk::SYS_MEMSTATS, (uint64_t)out); }