move keyboard and mouse out of HAL into a standalone ps2.sys driver, implement usb stack with xhci controller discovery, hid keyboard/mouse, and bulk-only mass storage, add pci msi support with capability chain walking and software irq vector allocation (slots 16-23), rewrite user virtual memory as a USER_VA_REGION descriptor arena with per-process ownership tracking and guard page support, replacing the old bump allocator and top-down image region, add MmCreateUserRegion/MmDestroyAllUserRegions so process teardown reclaims all user va in one pass, allocate a pool-backed shadow framebuffer in hal_screen to fix cursor tearing and scroll corruption, reserve ap trampoline page below 1mb in uefi bootloader before boot services exit, rewrite memset/memcpy/memmove/memcmp with __stosq/__movsq intrinsics, promote driver flag literals to macros and add multi-tu STANDALONE_DRIVERS table to build.c, split rtl8139/rtl816x into header+source, rename KbReadScancode to KbReadKey, improve page fault output with MmDebugDescribeAddress and user region dump, fix %p to %016llX throughout.

This commit is contained in:
maksw committed 2026-06-02 00:01:20 +02:00
1 parent b970d7f59c
commit b838f8d83d
130 files changed
+8137 -2932

No files matched your search

+119 -154
View File
@@ -1,54 +1,5 @@
// fat32.c - FAT32 filesystem driver
// Read + write support: file data, cluster allocation, directory entries.
//
// Performance improvements over the original:
//
// 1. FAT sector cache (FAT_CACHE_SLOTS write-back entries).
// FatEntry() and WriteFatEntry() go through the cache; the hot FAT
// region stays in RAM instead of being read from disk on every chain
// traversal step. A 32-slot cache covers 32 x (512/4) = 4096
// consecutive cluster entries — enough to keep the entire FAT of a
// small partition in memory, and to avoid repeated reads even on large
// ones.
//
// 2. Fat32ReadDir() cluster buffer cached in FAT32_DIR_CTX.
// The original re-read the same cluster from disk on every call
// (allocate -> read -> return one entry -> free). Now the buffer is
// allocated once in Fat32OpenDir, freed in Fat32CloseDir, and only
// re-read when the iteration moves to a new cluster.
//
// 3. AllocCluster() next-free hint.
// The search now starts from the cluster after the last allocation
// (volume NextFreeHint) and wraps around once, so repeated allocations
// on a fragmented volume don't rescan from sector 0 every time.
//
// 4. Contiguous-cluster run coalescing in Fat32Read() and Fat32Write().
// After fetching a cluster's FAT entry the code peeks ahead: if the
// next cluster is physically adjacent (cluster+1) it extends the run
// rather than issuing a separate ReadSectors/WriteSectors call. A
// freshly-written unfragmented file now transfers in one or a handful
// of large DMA bursts instead of SectorsPerCluster-sized slices.
//
// 5. FAT write batching via a dirty-sector cache.
// WriteFatEntry() marks modified FAT cache slots dirty instead of
// flushing immediately. FlushFatCache() (called from Fat32Close,
// Fat32Truncate, and Fat32Delete) writes each dirty slot once for
// every FAT copy, collapsing the 2x(read+write) per-entry cost of the
// original into a single write per dirty sector per FAT copy.
#include <stdint.h>
#include <stddef.h>
#include <stdbool.h>
#include <string.h>
#include <ntlite/ddi/io_driver.h>
#include <ntlite/ddi/hal_api.h>
#include <kernel/io_file.h>
#include <kernel/mm_virt.h>
#include <kernel/ke_debug.h>
#include <kernel/ke_irp.h>
#include <kernel/ke_semaphore.h>
#include <kernel/ke_thread.h>
#include <kernel/ke_sched.h>
// fat32.c - FAT32 filesystem core, directory, cache, and I/O implementation.
#include "fat32.h"
// ---------------------------------------------------------------------------
// On-disk structures
@@ -1042,7 +993,7 @@ static int FindFreeDirentRun(FAT32_VOL *v, uint32_t dirCluster, uint32_t needed,
// ---------------------------------------------------------------------------
// Open / Close
// ---------------------------------------------------------------------------
static KSTATUS Fat32Open(IO_FILESYSTEM *fs, SYS_STRING_VIEW path, void **fileCtx) {
KSTATUS Fat32Open(IO_FILESYSTEM *fs, SYS_STRING_VIEW path, void **fileCtx) {
if (!fs || !fileCtx || !SysSvIsValid(path) || path.Length == 0)
return STATUS_INVALID_PARAMETER;
@@ -1059,7 +1010,7 @@ static KSTATUS Fat32Open(IO_FILESYSTEM *fs, SYS_STRING_VIEW path, void **fileCtx
return STATUS_SUCCESS;
}
static void Fat32Close(IO_FILESYSTEM *fs, void *fileCtx) {
void Fat32Close(IO_FILESYSTEM *fs, void *fileCtx) {
(void)fs;
FAT32_FILE *f = (FAT32_FILE *)fileCtx;
FlushFatCache(f->Vol);
@@ -1079,7 +1030,7 @@ static void Fat32Close(IO_FILESYSTEM *fs, void *fileCtx) {
#define MAX_RUN_SECTORS 128u
static KSTATUS Fat32Read(IO_FILESYSTEM *fs, void *fileCtx,
KSTATUS Fat32Read(IO_FILESYSTEM *fs, void *fileCtx,
uint64_t offset, void *buf,
size_t size, size_t *bytesRead) {
(void)fs;
@@ -1174,7 +1125,7 @@ static KSTATUS Fat32Read(IO_FILESYSTEM *fs, void *fileCtx,
// Same strategy as read. Whole-cluster-aligned runs skip the read-modify-
// write; partial head/tail clusters still require it.
static KSTATUS Fat32Write(IO_FILESYSTEM *fs, void *fileCtx,
KSTATUS Fat32Write(IO_FILESYSTEM *fs, void *fileCtx,
uint64_t offset, const void *buf,
size_t size, size_t *bytesWritten) {
(void)fs;
@@ -1279,9 +1230,9 @@ static KSTATUS Fat32Write(IO_FILESYSTEM *fs, void *fileCtx,
// ---------------------------------------------------------------------------
// Create
// ---------------------------------------------------------------------------
static KSTATUS Fat32Truncate(IO_FILESYSTEM *fs, void *fileCtx, uint64_t newSize);
KSTATUS Fat32Truncate(IO_FILESYSTEM *fs, void *fileCtx, uint64_t newSize);
static KSTATUS Fat32Create(IO_FILESYSTEM *fs, SYS_STRING_VIEW path, void **fileCtx) {
KSTATUS Fat32Create(IO_FILESYSTEM *fs, SYS_STRING_VIEW path, void **fileCtx) {
if (!fs || !fileCtx || !SysSvIsValid(path) || path.Length == 0)
return STATUS_INVALID_PARAMETER;
@@ -1385,7 +1336,7 @@ static KSTATUS Fat32Create(IO_FILESYSTEM *fs, SYS_STRING_VIEW path, void **fileC
// ---------------------------------------------------------------------------
// Truncate
// ---------------------------------------------------------------------------
static KSTATUS Fat32Truncate(IO_FILESYSTEM *fs, void *fileCtx, uint64_t newSize) {
KSTATUS Fat32Truncate(IO_FILESYSTEM *fs, void *fileCtx, uint64_t newSize) {
(void)fs;
FAT32_FILE *f = (FAT32_FILE *)fileCtx;
FAT32_VOL *v = f->Vol;
@@ -1445,7 +1396,7 @@ update_size:
// ---------------------------------------------------------------------------
// Delete
// ---------------------------------------------------------------------------
static KSTATUS Fat32Delete(IO_FILESYSTEM *fs, SYS_STRING_VIEW path) {
KSTATUS Fat32Delete(IO_FILESYSTEM *fs, SYS_STRING_VIEW path) {
if (!fs || !SysSvIsValid(path) || path.Length == 0)
return STATUS_INVALID_PARAMETER;
@@ -1467,7 +1418,7 @@ static KSTATUS Fat32Delete(IO_FILESYSTEM *fs, SYS_STRING_VIEW path) {
return STATUS_SUCCESS;
}
static uint64_t Fat32GetSize(IO_FILESYSTEM *fs, void *fileCtx) {
uint64_t Fat32GetSize(IO_FILESYSTEM *fs, void *fileCtx) {
(void)fs; return ((FAT32_FILE *)fileCtx)->FileSize;
}
@@ -1489,7 +1440,7 @@ typedef struct {
uint8_t *ClusterBuf; // allocated once in OpenDir, freed in CloseDir
} FAT32_DIR_CTX;
static KSTATUS Fat32OpenDir(IO_FILESYSTEM *fs, SYS_STRING_VIEW dirPath, void **dirCtx) {
KSTATUS Fat32OpenDir(IO_FILESYSTEM *fs, SYS_STRING_VIEW dirPath, void **dirCtx) {
if (!fs || !dirCtx || !SysSvIsValid(dirPath))
return STATUS_INVALID_PARAMETER;
@@ -1520,7 +1471,7 @@ static KSTATUS Fat32OpenDir(IO_FILESYSTEM *fs, SYS_STRING_VIEW dirPath, void **d
return STATUS_SUCCESS;
}
static KSTATUS Fat32ReadDir(IO_FILESYSTEM *fs, void *dirCtx, KDIR_ENTRY *out) {
KSTATUS Fat32ReadDir(IO_FILESYSTEM *fs, void *dirCtx, KDIR_ENTRY *out) {
(void)fs;
FAT32_DIR_CTX *ctx = (FAT32_DIR_CTX *)dirCtx;
FAT32_VOL *v = ctx->Vol;
@@ -1575,7 +1526,7 @@ static KSTATUS Fat32ReadDir(IO_FILESYSTEM *fs, void *dirCtx, KDIR_ENTRY *out) {
return STATUS_NO_MORE_FILES;
}
static void Fat32CloseDir(IO_FILESYSTEM *fs, void *dirCtx) {
void Fat32CloseDir(IO_FILESYSTEM *fs, void *dirCtx) {
(void)fs;
FAT32_DIR_CTX *ctx = (FAT32_DIR_CTX *)dirCtx;
MmFreePool(ctx->ClusterBuf);
@@ -1934,7 +1885,7 @@ static void Fat32AsyncReadSubmitNext(FAT32_ASYNC_RW* ctx) {
Fat32AsyncFinish(ctx, s, ctx->Done);
}
static KSTATUS Fat32ReadAsync(IO_FILESYSTEM *fs, void *fileCtx,
KSTATUS Fat32ReadAsync(IO_FILESYSTEM *fs, void *fileCtx,
uint64_t offset, void *buf, size_t size,
IO_FS_ASYNC_COMPLETE complete,
void *completeContext) {
@@ -2087,7 +2038,7 @@ static void Fat32AsyncWriteSubmitNext(FAT32_ASYNC_RW* ctx) {
Fat32AsyncFinish(ctx, s, ctx->Done);
}
static KSTATUS Fat32WriteAsync(IO_FILESYSTEM *fs, void *fileCtx,
KSTATUS Fat32WriteAsync(IO_FILESYSTEM *fs, void *fileCtx,
uint64_t offset, const void *buf, size_t size,
IO_FS_ASYNC_COMPLETE complete,
void *completeContext) {
@@ -2174,22 +2125,101 @@ static KSTATUS Fat32WriteAsync(IO_FILESYSTEM *fs, void *fileCtx,
static FAT32_VOL gVols[FAT32_MAX_VOLUMES];
static IO_FILESYSTEM gFs[FAT32_MAX_VOLUMES];
static void Fat32InitVtable(IO_FILESYSTEM* fs, FAT32_VOL* vol) {
memset(fs, 0, sizeof(*fs));
fs->Open = Fat32Open;
fs->Read = Fat32Read;
fs->Write = Fat32Write;
fs->ReadAsync = Fat32ReadAsync;
fs->WriteAsync = Fat32WriteAsync;
fs->Create = Fat32Create;
fs->Delete = Fat32Delete;
fs->Truncate = Fat32Truncate;
fs->GetSize = Fat32GetSize;
fs->Close = Fat32Close;
fs->DriverCtx = vol;
fs->OpenDir = Fat32OpenDir;
fs->ReadDir = Fat32ReadDir;
fs->CloseDir = Fat32CloseDir;
static uint32_t gMountedCount;
static bool gDiskScanned[FAT32_MAX_VOLUMES];
static uint32_t Fat32TryMountDisk(uint8_t disk) {
if (disk >= FAT32_MAX_VOLUMES)
return 0;
if (gDiskScanned[disk])
return 0;
gDiskScanned[disk] = true;
if (!IoDiskDevicePresent(disk))
return 0;
uint32_t mountedHere = 0;
FAT32_PARTITION_CANDIDATE parts[FAT32_MAX_PARTITIONS_PER_DISK];
uint32_t partCount = Fat32EnumerateDiskVolumes(disk, parts, FAT32_MAX_PARTITIONS_PER_DISK);
if (!partCount) {
DbgPrint("FAT32: disk %u: no FAT32 volumes\n", disk);
return 0;
}
for (uint32_t part = 0; part < partCount && gMountedCount < FAT32_MAX_VOLUMES; part++) {
uint8_t volumeIndex = (uint8_t)gMountedCount;
FAT32_VOL* v = &gVols[volumeIndex];
memset(v, 0, sizeof(*v));
v->DriveIndex = disk;
v->PartitionLba = parts[part].StartLba;
v->PartitionSize = parts[part].SectorCount;
uint8_t sector[512];
if (!KSUCCESS(ReadSectors(v, v->PartitionLba, 1, sector))) {
DbgPrint("FAT32: disk %u part %u: failed to read VBR\n", disk, part);
continue;
}
BPB *bpb = (BPB *)sector;
if (!IsFat32Vbr(v, v->PartitionLba)) {
DbgPrint("FAT32: disk %u part %u: unsupported FAT variant\n", disk, part);
continue;
}
v->BytesPerSector = bpb->BytesPerSector;
v->SectorsPerCluster = bpb->SectorsPerCluster;
v->BytesPerCluster = bpb->BytesPerSector * bpb->SectorsPerCluster;
v->ReservedSectors = bpb->ReservedSectors;
v->NumFats = bpb->NumFats;
v->FatSize = bpb->FatSize32;
v->RootCluster = bpb->RootCluster;
v->DataStart = v->PartitionLba + bpb->ReservedSectors + (uint64_t)bpb->NumFats * bpb->FatSize32;
v->NextFreeHint = 2;
uint32_t totalSectors = bpb->TotalSectors16 ? bpb->TotalSectors16 : bpb->TotalSectors32;
uint32_t dataSectors = totalSectors - bpb->ReservedSectors - bpb->NumFats * bpb->FatSize32;
v->TotalClusters = dataSectors / bpb->SectorsPerCluster;
if (v->PartitionSize == 0 || v->PartitionSize > totalSectors)
v->PartitionSize = totalSectors;
Fat32InitVtable(&gFs[volumeIndex], v);
IO_VOLUME_PARAMS volParams;
volParams.DiskIndex = v->DriveIndex;
volParams.PartitionLba = v->PartitionLba;
volParams.PartitionSize = v->PartitionSize;
KSTATUS status = IoRegisterFilesystem(volumeIndex, &gFs[volumeIndex], &volParams);
if (KSUCCESS(status)) {
gMountedCount++;
mountedHere++;
DbgPrint("FAT32: disk %u part %u mounted as drive %u (lba=%llu clusters=%u).\n",
disk, part, volumeIndex, (unsigned long long)v->PartitionLba, v->TotalClusters);
} else {
DbgPrint("FAT32: disk %u part %u mount as drive %u failed status=%d.\n",
disk, part, volumeIndex, status);
}
}
if (partCount && !mountedHere && gMountedCount >= FAT32_MAX_VOLUMES) {
DbgPrint("FAT32: disk %u: volume table full\n", disk);
}
return mountedHere;
}
static void Fat32DiskArrival(uint8_t driveIndex, DEVICE_OBJECT* device, void* context) {
(void)device;
(void)context;
uint32_t before = gMountedCount;
uint32_t mounted = Fat32TryMountDisk(driveIndex);
if (mounted) {
DbgPrint("FAT32: hotplug scan mounted %u new volume(s); total=%u\n",
mounted, gMountedCount);
} else if (gMountedCount != before) {
DbgPrint("FAT32: hotplug scan total=%u\n", gMountedCount);
}
}
KSTATUS DriverEntry(const HAL_API *hal) {
@@ -2198,84 +2228,19 @@ KSTATUS DriverEntry(const HAL_API *hal) {
FatCacheInvalidate();
(void)hal;
gMountedCount = 0;
memset(gDiskScanned, 0, sizeof(gDiskScanned));
uint32_t mounted = 0;
KSTATUS lastStatus = STATUS_NOT_SUPPORTED;
for (uint8_t disk = 0; disk < FAT32_MAX_VOLUMES && mounted < FAT32_MAX_VOLUMES; disk++) {
if (!IoDiskDevicePresent(disk))
continue;
FAT32_PARTITION_CANDIDATE parts[FAT32_MAX_PARTITIONS_PER_DISK];
uint32_t partCount = Fat32EnumerateDiskVolumes(disk, parts, FAT32_MAX_PARTITIONS_PER_DISK);
if (!partCount) {
DbgPrint("FAT32: disk %u: no FAT32 volumes\n", disk);
continue;
}
for (uint32_t part = 0; part < partCount && mounted < FAT32_MAX_VOLUMES; part++) {
uint8_t volumeIndex = (uint8_t)mounted;
FAT32_VOL* v = &gVols[volumeIndex];
memset(v, 0, sizeof(*v));
v->DriveIndex = disk;
v->PartitionLba = parts[part].StartLba;
v->PartitionSize = parts[part].SectorCount;
uint8_t sector[512];
if (!KSUCCESS(ReadSectors(v, v->PartitionLba, 1, sector))) {
lastStatus = STATUS_DEVICE_ERROR;
DbgPrint("FAT32: disk %u part %u: failed to read VBR\n", disk, part);
continue;
}
BPB *bpb = (BPB *)sector;
if (!IsFat32Vbr(v, v->PartitionLba)) {
lastStatus = STATUS_NOT_SUPPORTED;
DbgPrint("FAT32: disk %u part %u: unsupported FAT variant\n", disk, part);
continue;
}
v->BytesPerSector = bpb->BytesPerSector;
v->SectorsPerCluster = bpb->SectorsPerCluster;
v->BytesPerCluster = bpb->BytesPerSector * bpb->SectorsPerCluster;
v->ReservedSectors = bpb->ReservedSectors;
v->NumFats = bpb->NumFats;
v->FatSize = bpb->FatSize32;
v->RootCluster = bpb->RootCluster;
v->DataStart = v->PartitionLba + bpb->ReservedSectors + (uint64_t)bpb->NumFats * bpb->FatSize32;
v->NextFreeHint = 2;
uint32_t totalSectors = bpb->TotalSectors16 ? bpb->TotalSectors16 : bpb->TotalSectors32;
uint32_t dataSectors = totalSectors - bpb->ReservedSectors - bpb->NumFats * bpb->FatSize32;
v->TotalClusters = dataSectors / bpb->SectorsPerCluster;
if (v->PartitionSize == 0 || v->PartitionSize > totalSectors)
v->PartitionSize = totalSectors;
Fat32InitVtable(&gFs[volumeIndex], v);
IO_VOLUME_PARAMS volParams;
volParams.DiskIndex = v->DriveIndex;
volParams.PartitionLba = v->PartitionLba;
volParams.PartitionSize = v->PartitionSize;
KSTATUS status = IoRegisterFilesystem(volumeIndex, &gFs[volumeIndex], &volParams);
if (KSUCCESS(status)) {
mounted++;
DbgPrint("FAT32: disk %u part %u mounted as drive %u (lba=%llu clusters=%u).\n",
disk, part, volumeIndex, (unsigned long long)v->PartitionLba, v->TotalClusters);
} else {
lastStatus = status;
DbgPrint("FAT32: disk %u part %u mount as drive %u failed status=%d.\n",
disk, part, volumeIndex, status);
}
}
KSTATUS cbStatus = IoRegisterDiskArrivalCallback(Fat32DiskArrival, (void*)0);
if (!KSUCCESS(cbStatus)) {
DbgPrint("FAT32: disk-arrival callback registration failed st=0x%x\n", cbStatus);
}
if (!mounted) {
if (!gMountedCount) {
DbgPrint("FAT32: no mountable FAT32 volumes found.\n");
return lastStatus;
return STATUS_NOT_SUPPORTED;
}
DbgPrint("FAT32: Init complete; mounted %u volume(s).\n", mounted);
DbgPrint("FAT32: Init complete; mounted %u volume(s).\n", gMountedCount);
return STATUS_SUCCESS;
}