feat: ext2 filesystem, installer updates, add update feature, and more
This commit is contained in:
@@ -32,9 +32,9 @@ namespace Montauk {
|
||||
|
||||
static int Sys_ReadDir(const char* path, const char** outNames, int maxEntries) {
|
||||
// Get entries from VFS into a kernel-local array
|
||||
const char* kernelNames[64];
|
||||
const char* kernelNames[256];
|
||||
int max = maxEntries;
|
||||
if (max > 64) max = 64;
|
||||
if (max > 256) max = 256;
|
||||
int count = Fs::Vfs::VfsReadDir(path, kernelNames, max);
|
||||
if (count <= 0) return count;
|
||||
|
||||
@@ -47,7 +47,7 @@ namespace Montauk {
|
||||
uint64_t physAddr = Memory::SubHHDM((uint64_t)page);
|
||||
uint64_t userVa = proc->heapNext;
|
||||
proc->heapNext += 0x1000;
|
||||
Memory::VMM::Paging::MapUserIn(proc->pml4Phys, physAddr, userVa);
|
||||
if (!Memory::VMM::Paging::MapUserIn(proc->pml4Phys, physAddr, userVa)) return -1;
|
||||
|
||||
// Copy strings into the user page and write pointers to outNames
|
||||
uint64_t offset = 0;
|
||||
|
||||
@@ -50,11 +50,13 @@ namespace Montauk {
|
||||
constexpr uint64_t userVa = 0x50000000ULL;
|
||||
|
||||
for (uint64_t i = 0; i < numPages; i++) {
|
||||
Memory::VMM::Paging::MapUserInWC(
|
||||
if (!Memory::VMM::Paging::MapUserInWC(
|
||||
proc->pml4Phys,
|
||||
fbPhys + i * 0x1000,
|
||||
userVa + i * 0x1000
|
||||
);
|
||||
)) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return userVa;
|
||||
|
||||
@@ -48,7 +48,7 @@ namespace Montauk {
|
||||
void* page = Memory::g_pfa->AllocateZeroed();
|
||||
if (page == nullptr) return 0;
|
||||
uint64_t physAddr = Memory::SubHHDM((uint64_t)page);
|
||||
Memory::VMM::Paging::MapUserIn(proc->pml4Phys, physAddr, userVa + i * 0x1000);
|
||||
if (!Memory::VMM::Paging::MapUserIn(proc->pml4Phys, physAddr, userVa + i * 0x1000)) return 0;
|
||||
}
|
||||
|
||||
proc->heapNext += size;
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include <Drivers/Storage/Gpt.hpp>
|
||||
#include <Fs/FsProbe.hpp>
|
||||
#include <Fs/Fat32.hpp>
|
||||
#include <Fs/Ext2.hpp>
|
||||
|
||||
#include "Syscall.hpp"
|
||||
|
||||
@@ -115,6 +116,10 @@ namespace Montauk {
|
||||
return (int64_t)Fs::Fat32::Format(
|
||||
part->BlockDevIndex, part->StartLba, part->SectorCount,
|
||||
params->label[0] ? params->label : nullptr);
|
||||
case FS_TYPE_EXT2:
|
||||
return (int64_t)Fs::Ext2::Format(
|
||||
part->BlockDevIndex, part->StartLba, part->SectorCount,
|
||||
params->label[0] ? params->label : nullptr);
|
||||
default:
|
||||
return -1; // unknown filesystem type
|
||||
}
|
||||
|
||||
@@ -297,6 +297,7 @@ namespace Montauk {
|
||||
|
||||
// Filesystem type IDs for SYS_FSFORMAT
|
||||
static constexpr int FS_TYPE_FAT32 = 1;
|
||||
static constexpr int FS_TYPE_EXT2 = 2;
|
||||
|
||||
struct FsFormatParams {
|
||||
int32_t partIndex; // global partition index
|
||||
|
||||
@@ -23,6 +23,8 @@ namespace Montauk {
|
||||
return;
|
||||
}
|
||||
}
|
||||
// Don't draw over the framebuffer once the GUI is active
|
||||
if (Kt::g_suppressKernelLog) return;
|
||||
Kt::Print(text);
|
||||
}
|
||||
|
||||
@@ -35,6 +37,8 @@ namespace Montauk {
|
||||
return;
|
||||
}
|
||||
}
|
||||
// Don't draw over the framebuffer once the GUI is active
|
||||
if (Kt::g_suppressKernelLog) return;
|
||||
Kt::Putchar(c);
|
||||
}
|
||||
};
|
||||
@@ -67,7 +67,10 @@ namespace WinServer {
|
||||
}
|
||||
uint64_t physAddr = Memory::SubHHDM((uint64_t)page);
|
||||
slot.pixelPhysPages[i] = physAddr;
|
||||
Memory::VMM::Paging::MapUserIn(ownerPml4, physAddr, userVa + (uint64_t)i * 0x1000);
|
||||
if (!Memory::VMM::Paging::MapUserIn(ownerPml4, physAddr, userVa + (uint64_t)i * 0x1000)) {
|
||||
slot.used = false;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
slot.ownerVa = userVa;
|
||||
@@ -173,8 +176,10 @@ namespace WinServer {
|
||||
uint64_t userVa = heapNext;
|
||||
|
||||
for (int i = 0; i < slot.pixelNumPages; i++) {
|
||||
Memory::VMM::Paging::MapUserIn(callerPml4, slot.pixelPhysPages[i],
|
||||
userVa + (uint64_t)i * 0x1000);
|
||||
if (!Memory::VMM::Paging::MapUserIn(callerPml4, slot.pixelPhysPages[i],
|
||||
userVa + (uint64_t)i * 0x1000)) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
slot.desktopVa = userVa;
|
||||
@@ -230,7 +235,9 @@ namespace WinServer {
|
||||
if (page == nullptr) return -1;
|
||||
uint64_t physAddr = Memory::SubHHDM((uint64_t)page);
|
||||
slot.pixelPhysPages[i] = physAddr;
|
||||
Memory::VMM::Paging::MapUserIn(ownerPml4, physAddr, userVa + (uint64_t)i * 0x1000);
|
||||
if (!Memory::VMM::Paging::MapUserIn(ownerPml4, physAddr, userVa + (uint64_t)i * 0x1000)) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
slot.width = newW;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Ext2.hpp
|
||||
* ext2 filesystem driver
|
||||
* Copyright (c) 2026 Daniel Hammer
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <cstdint>
|
||||
#include <Fs/Vfs.hpp>
|
||||
|
||||
namespace Fs::Ext2 {
|
||||
|
||||
// Try to mount an ext2 filesystem at the given partition range.
|
||||
// Returns a FsDriver* on success, nullptr if not a valid ext2 volume.
|
||||
Vfs::FsDriver* Mount(int blockDevIndex, uint64_t startLba, uint64_t sectorCount);
|
||||
|
||||
// Register Ext2::Mount as a filesystem probe with FsProbe.
|
||||
void RegisterProbe();
|
||||
|
||||
// Format a partition as ext2.
|
||||
// Returns 0 on success, -1 on error.
|
||||
int Format(int blockDevIndex, uint64_t startLba, uint64_t sectorCount,
|
||||
const char* volumeLabel);
|
||||
|
||||
};
|
||||
@@ -79,6 +79,11 @@ namespace Fs::Fat32 {
|
||||
uint8_t* clusterBuf;
|
||||
int clusterBufPages;
|
||||
|
||||
// In-memory FAT cache (page-allocated)
|
||||
uint32_t* fatCache;
|
||||
int fatCachePages;
|
||||
uint32_t fatCacheEntries; // number of valid 4-byte entries
|
||||
|
||||
// Open file handles
|
||||
Fat32File files[MaxFilesPerInstance];
|
||||
|
||||
@@ -127,6 +132,12 @@ namespace Fs::Fat32 {
|
||||
}
|
||||
|
||||
static uint32_t GetNextCluster(const Fat32Instance& inst, uint32_t cluster) {
|
||||
// Use in-memory FAT cache if available (avoids disk I/O per lookup)
|
||||
if (inst.fatCache && cluster < inst.fatCacheEntries) {
|
||||
return inst.fatCache[cluster] & 0x0FFFFFFF;
|
||||
}
|
||||
|
||||
// Fallback: read from disk
|
||||
uint32_t fatOffset = cluster * 4;
|
||||
uint32_t fatSector = fatOffset / inst.bytesPerSector;
|
||||
uint32_t entryOffset = fatOffset % inst.bytesPerSector;
|
||||
@@ -183,10 +194,30 @@ namespace Fs::Fat32 {
|
||||
if (!WritePartSectors(inst, fatStart + fatSector, 1, sectorBuf)) return false;
|
||||
}
|
||||
|
||||
// Keep in-memory FAT cache in sync
|
||||
if (inst.fatCache && cluster < inst.fatCacheEntries) {
|
||||
uint32_t existing = inst.fatCache[cluster];
|
||||
inst.fatCache[cluster] = (existing & 0xF0000000) | (value & 0x0FFFFFFF);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static uint32_t AllocateCluster(Fat32Instance& inst) {
|
||||
// Fast path: scan the in-memory FAT cache
|
||||
if (inst.fatCache) {
|
||||
uint32_t limit = inst.clusterCount + 2;
|
||||
if (limit > inst.fatCacheEntries) limit = inst.fatCacheEntries;
|
||||
for (uint32_t cluster = 2; cluster < limit; cluster++) {
|
||||
if ((inst.fatCache[cluster] & 0x0FFFFFFF) == CLUSTER_FREE) {
|
||||
if (!WriteFatEntry(inst, cluster, 0x0FFFFFFF)) return 0;
|
||||
return cluster;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Slow path: read FAT sectors from disk
|
||||
uint8_t sectorBuf[512];
|
||||
uint32_t entriesPerSector = inst.bytesPerSector / 4;
|
||||
|
||||
@@ -1575,6 +1606,31 @@ namespace Fs::Fat32 {
|
||||
nullptr, inst.clusterBufPages);
|
||||
}
|
||||
|
||||
// Load entire FAT into memory for fast cluster chain lookups.
|
||||
// fatSize32 is in sectors; each sector is bytesPerSector bytes.
|
||||
uint64_t fatBytes = (uint64_t)fatSize32 * bytesPerSector;
|
||||
inst.fatCachePages = (int)((fatBytes + 0xFFF) / 0x1000);
|
||||
inst.fatCacheEntries = (uint32_t)(fatBytes / 4);
|
||||
inst.fatCache = (uint32_t*)Memory::g_pfa->ReallocConsecutive(
|
||||
nullptr, inst.fatCachePages);
|
||||
if (inst.fatCache) {
|
||||
uint8_t* dst = (uint8_t*)inst.fatCache;
|
||||
uint64_t remaining = fatBytes;
|
||||
uint64_t fatPartSector = reservedSectors;
|
||||
while (remaining > 0) {
|
||||
uint32_t chunk = (remaining > 4096) ? 4096 : (uint32_t)remaining;
|
||||
uint32_t secs = (chunk + bytesPerSector - 1) / bytesPerSector;
|
||||
if (!ReadPartSectors(inst, fatPartSector, secs, dst)) {
|
||||
// If read fails, disable cache and fall back to per-lookup reads
|
||||
inst.fatCache = nullptr;
|
||||
break;
|
||||
}
|
||||
dst += secs * bytesPerSector;
|
||||
fatPartSector += secs;
|
||||
remaining -= secs * bytesPerSector;
|
||||
}
|
||||
}
|
||||
|
||||
// Clear file handles
|
||||
for (int i = 0; i < MaxFilesPerInstance; i++) {
|
||||
inst.files[i].inUse = false;
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include "FsProbe.hpp"
|
||||
#include <Drivers/Storage/Gpt.hpp>
|
||||
#include <Terminal/Terminal.hpp>
|
||||
#include <Libraries/Memory.hpp>
|
||||
|
||||
namespace Fs::FsProbe {
|
||||
|
||||
@@ -19,15 +20,24 @@ namespace Fs::FsProbe {
|
||||
}
|
||||
}
|
||||
|
||||
static bool IsEfiPartition(const Drivers::Storage::Gpt::PartitionInfo* part) {
|
||||
auto& a = part->TypeGuid;
|
||||
auto& b = Drivers::Storage::Gpt::GUID_EFI_SYSTEM;
|
||||
return a.Data1 == b.Data1 && a.Data2 == b.Data2 && a.Data3 == b.Data3 &&
|
||||
memcmp(a.Data4, b.Data4, 8) == 0;
|
||||
}
|
||||
|
||||
void MountPartitions(int firstDrive) {
|
||||
int partCount = Drivers::Storage::Gpt::GetPartitionCount();
|
||||
if (partCount == 0 || g_probeCount == 0) return;
|
||||
|
||||
int driveNum = firstDrive;
|
||||
|
||||
// First pass: mount non-EFI partitions so they get lower drive numbers
|
||||
for (int i = 0; i < partCount && driveNum < Vfs::MaxDrives; i++) {
|
||||
auto* part = Drivers::Storage::Gpt::GetPartition(i);
|
||||
if (!part) continue;
|
||||
if (IsEfiPartition(part)) continue;
|
||||
|
||||
for (int p = 0; p < g_probeCount; p++) {
|
||||
Vfs::FsDriver* driver = g_probes[p](
|
||||
@@ -42,6 +52,26 @@ namespace Fs::FsProbe {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Second pass: mount EFI system partitions after all others
|
||||
for (int i = 0; i < partCount && driveNum < Vfs::MaxDrives; i++) {
|
||||
auto* part = Drivers::Storage::Gpt::GetPartition(i);
|
||||
if (!part) continue;
|
||||
if (!IsEfiPartition(part)) continue;
|
||||
|
||||
for (int p = 0; p < g_probeCount; p++) {
|
||||
Vfs::FsDriver* driver = g_probes[p](
|
||||
part->BlockDevIndex, part->StartLba, part->SectorCount);
|
||||
|
||||
if (driver) {
|
||||
Vfs::RegisterDrive(driveNum, driver);
|
||||
Kt::KernelLogStream(Kt::OK, "FsProbe") << "Mounted EFI partition "
|
||||
<< i << " as drive " << driveNum;
|
||||
driveNum++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int MountPartition(int partIndex, int driveNum) {
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
#include <Fs/Ramdisk.hpp>
|
||||
#include <Fs/Vfs.hpp>
|
||||
#include <Fs/Fat32.hpp>
|
||||
#include <Fs/Ext2.hpp>
|
||||
#include <Fs/FsProbe.hpp>
|
||||
#include <Sched/Scheduler.hpp>
|
||||
#include <Api/Syscall.hpp>
|
||||
@@ -206,6 +207,7 @@ extern "C" void kmain() {
|
||||
// Register filesystem probes and auto-mount partitions.
|
||||
// When no ramdisk, disk partitions start at drive 0 so init.elf is found there.
|
||||
Fs::Fat32::RegisterProbe();
|
||||
Fs::Ext2::RegisterProbe();
|
||||
Fs::FsProbe::MountPartitions(hasRamdisk ? 1 : 0);
|
||||
|
||||
Hal::LoadTSS();
|
||||
|
||||
@@ -49,11 +49,14 @@ namespace Memory::VMM {
|
||||
PageTableEntry* entry = (PageTableEntry*)Memory::HHDM(&table->entries[virtualAddress.GetIndex(level)]);
|
||||
|
||||
if (!entry->Present) {
|
||||
void* newPage = Memory::g_pfa->AllocateZeroed();
|
||||
if (newPage == nullptr) {
|
||||
Panic("OOM in Paging::HandleLevel (kernel page table allocation)", nullptr);
|
||||
}
|
||||
uint64_t downLevelAddr = Memory::SubHHDM((uint64_t)newPage);
|
||||
|
||||
entry->Present = true;
|
||||
entry->Writable = true;
|
||||
|
||||
uint64_t downLevelAddr = Memory::SubHHDM((uint64_t)Memory::g_pfa->AllocateZeroed());
|
||||
|
||||
entry->Address = downLevelAddr >> 12;
|
||||
|
||||
return (PageTable*)downLevelAddr;
|
||||
@@ -66,12 +69,15 @@ namespace Memory::VMM {
|
||||
PageTableEntry* entry = (PageTableEntry*)Memory::HHDM(&table->entries[virtualAddress.GetIndex(level)]);
|
||||
|
||||
if (!entry->Present) {
|
||||
void* newPage = Memory::g_pfa->AllocateZeroed();
|
||||
if (newPage == nullptr) {
|
||||
Panic("OOM in Paging::HandleLevelUser (page table allocation)", nullptr);
|
||||
}
|
||||
uint64_t downLevelAddr = Memory::SubHHDM((uint64_t)newPage);
|
||||
|
||||
entry->Present = true;
|
||||
entry->Writable = true;
|
||||
entry->Supervisor = 1; // User-accessible
|
||||
|
||||
uint64_t downLevelAddr = Memory::SubHHDM((uint64_t)Memory::g_pfa->AllocateZeroed());
|
||||
|
||||
entry->Address = downLevelAddr >> 12;
|
||||
|
||||
return (PageTable*)downLevelAddr;
|
||||
@@ -177,21 +183,24 @@ namespace Memory::VMM {
|
||||
return newPml4Phys;
|
||||
}
|
||||
|
||||
void Paging::MapUserIn(std::uint64_t pml4Phys, std::uint64_t physicalAddress, std::uint64_t virtualAddress) {
|
||||
bool Paging::MapUserIn(std::uint64_t pml4Phys, std::uint64_t physicalAddress, std::uint64_t virtualAddress) {
|
||||
if (virtualAddress % 0x1000 != 0 || physicalAddress % 0x1000 != 0) {
|
||||
Panic("Non-aligned address in Paging::MapUserIn!", nullptr);
|
||||
}
|
||||
|
||||
VirtualAddress va(virtualAddress);
|
||||
|
||||
// Walk/create page tables from the given PML4, setting User bit at each level
|
||||
// Walk/create page tables from the given PML4, setting User bit at each level.
|
||||
// Returns nullptr on OOM.
|
||||
auto walkLevel = [](PageTable* table, uint64_t index) -> PageTable* {
|
||||
PageTableEntry* entry = (PageTableEntry*)Memory::HHDM(&table->entries[index]);
|
||||
if (!entry->Present) {
|
||||
void* newPage = Memory::g_pfa->AllocateZeroed();
|
||||
if (newPage == nullptr) return nullptr;
|
||||
uint64_t newPhys = Memory::SubHHDM((uint64_t)newPage);
|
||||
entry->Present = true;
|
||||
entry->Writable = true;
|
||||
entry->Supervisor = 1; // User-accessible
|
||||
uint64_t newPhys = Memory::SubHHDM((uint64_t)Memory::g_pfa->AllocateZeroed());
|
||||
entry->Address = newPhys >> 12;
|
||||
return (PageTable*)newPhys;
|
||||
} else {
|
||||
@@ -202,17 +211,21 @@ namespace Memory::VMM {
|
||||
|
||||
PageTable* pml4 = (PageTable*)pml4Phys;
|
||||
auto pml3 = walkLevel(pml4, va.GetL4Index());
|
||||
if (!pml3) return false;
|
||||
auto pml2 = walkLevel(pml3, va.GetL3Index());
|
||||
if (!pml2) return false;
|
||||
auto pml1 = walkLevel(pml2, va.GetL2Index());
|
||||
if (!pml1) return false;
|
||||
|
||||
PageTableEntry* pageEntry = (PageTableEntry*)Memory::HHDM(&pml1->entries[va.GetPageIndex()]);
|
||||
pageEntry->Present = true;
|
||||
pageEntry->Writable = true;
|
||||
pageEntry->Supervisor = 1;
|
||||
pageEntry->Address = physicalAddress >> 12;
|
||||
return true;
|
||||
}
|
||||
|
||||
void Paging::MapUserInWC(std::uint64_t pml4Phys, std::uint64_t physicalAddress, std::uint64_t virtualAddress) {
|
||||
bool Paging::MapUserInWC(std::uint64_t pml4Phys, std::uint64_t physicalAddress, std::uint64_t virtualAddress) {
|
||||
if (virtualAddress % 0x1000 != 0 || physicalAddress % 0x1000 != 0) {
|
||||
Panic("Non-aligned address in Paging::MapUserInWC!", nullptr);
|
||||
}
|
||||
@@ -222,10 +235,12 @@ namespace Memory::VMM {
|
||||
auto walkLevel = [](PageTable* table, uint64_t index) -> PageTable* {
|
||||
PageTableEntry* entry = (PageTableEntry*)Memory::HHDM(&table->entries[index]);
|
||||
if (!entry->Present) {
|
||||
void* newPage = Memory::g_pfa->AllocateZeroed();
|
||||
if (newPage == nullptr) return nullptr;
|
||||
uint64_t newPhys = Memory::SubHHDM((uint64_t)newPage);
|
||||
entry->Present = true;
|
||||
entry->Writable = true;
|
||||
entry->Supervisor = 1;
|
||||
uint64_t newPhys = Memory::SubHHDM((uint64_t)Memory::g_pfa->AllocateZeroed());
|
||||
entry->Address = newPhys >> 12;
|
||||
return (PageTable*)newPhys;
|
||||
} else {
|
||||
@@ -236,8 +251,11 @@ namespace Memory::VMM {
|
||||
|
||||
PageTable* pml4 = (PageTable*)pml4Phys;
|
||||
auto pml3 = walkLevel(pml4, va.GetL4Index());
|
||||
if (!pml3) return false;
|
||||
auto pml2 = walkLevel(pml3, va.GetL3Index());
|
||||
if (!pml2) return false;
|
||||
auto pml1 = walkLevel(pml2, va.GetL2Index());
|
||||
if (!pml1) return false;
|
||||
|
||||
PageTableEntry* pageEntry = (PageTableEntry*)Memory::HHDM(&pml1->entries[va.GetPageIndex()]);
|
||||
pageEntry->Present = true;
|
||||
@@ -245,6 +263,7 @@ namespace Memory::VMM {
|
||||
pageEntry->Supervisor = 1;
|
||||
pageEntry->WriteThrough = true; // PWT=1, PCD=0 → PAT entry 1 = WC
|
||||
pageEntry->Address = physicalAddress >> 12;
|
||||
return true;
|
||||
}
|
||||
|
||||
void Paging::UnmapUserIn(std::uint64_t pml4Phys, std::uint64_t virtualAddress) {
|
||||
|
||||
@@ -104,10 +104,10 @@ public:
|
||||
static std::uint64_t CreateUserPML4();
|
||||
|
||||
// Map a page into an arbitrary PML4 (specified by physical address) with User bit set.
|
||||
static void MapUserIn(std::uint64_t pml4Phys, std::uint64_t physicalAddress, std::uint64_t virtualAddress);
|
||||
static bool MapUserIn(std::uint64_t pml4Phys, std::uint64_t physicalAddress, std::uint64_t virtualAddress);
|
||||
|
||||
// Map a page into an arbitrary PML4 with User + Write-Combining attributes.
|
||||
static void MapUserInWC(std::uint64_t pml4Phys, std::uint64_t physicalAddress, std::uint64_t virtualAddress);
|
||||
static bool MapUserInWC(std::uint64_t pml4Phys, std::uint64_t physicalAddress, std::uint64_t virtualAddress);
|
||||
|
||||
// Unmap a single page from an arbitrary PML4 (clears PTE + invalidates TLB).
|
||||
static void UnmapUserIn(std::uint64_t pml4Phys, std::uint64_t virtualAddress);
|
||||
|
||||
@@ -115,7 +115,11 @@ namespace Sched {
|
||||
uint64_t virtAddr = segBase + p * 0x1000;
|
||||
|
||||
// Map into the process's PML4 with User bit set
|
||||
Memory::VMM::Paging::MapUserIn(pml4Phys, physAddr, virtAddr);
|
||||
if (!Memory::VMM::Paging::MapUserIn(pml4Phys, physAddr, virtAddr)) {
|
||||
Kt::KernelLogStream(Kt::ERROR, "ELF") << "Failed to map page";
|
||||
Memory::g_heap->Free(fileData);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Copy file data that overlaps this page (via HHDM)
|
||||
uint64_t pageStart = virtAddr;
|
||||
|
||||
@@ -149,7 +149,10 @@ namespace Sched {
|
||||
return -1;
|
||||
}
|
||||
uint64_t physAddr = Memory::SubHHDM((uint64_t)page);
|
||||
Memory::VMM::Paging::MapUserIn(pml4Phys, physAddr, userStackBase + i * 0x1000);
|
||||
if (!Memory::VMM::Paging::MapUserIn(pml4Phys, physAddr, userStackBase + i * 0x1000)) {
|
||||
Kt::KernelLogStream(Kt::ERROR, "Sched") << "Failed to map user stack page";
|
||||
return -1;
|
||||
}
|
||||
if (i == UserStackPages - 1) topStackPagePhys = physAddr;
|
||||
}
|
||||
|
||||
@@ -162,7 +165,10 @@ namespace Sched {
|
||||
return -1;
|
||||
}
|
||||
uint64_t stubPhys = Memory::SubHHDM((uint64_t)stubPage);
|
||||
Memory::VMM::Paging::MapUserIn(pml4Phys, stubPhys, ExitStubAddr);
|
||||
if (!Memory::VMM::Paging::MapUserIn(pml4Phys, stubPhys, ExitStubAddr)) {
|
||||
Kt::KernelLogStream(Kt::ERROR, "Sched") << "Failed to map exit stub";
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Write: xor edi, edi; xor eax, eax; syscall
|
||||
uint8_t* stub = (uint8_t*)stubPage;
|
||||
|
||||
Reference in New Issue
Block a user